LCOV - code coverage report
Current view: top level - src - objects.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2755 3122 88.2 %
Date: 2019-03-21 Functions: 426 500 85.2 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/objects.h"
       6             : 
       7             : #include <algorithm>
       8             : #include <cmath>
       9             : #include <memory>
      10             : #include <sstream>
      11             : #include <vector>
      12             : 
      13             : #include "src/objects-inl.h"
      14             : 
      15             : #include "src/accessors.h"
      16             : #include "src/allocation-site-scopes.h"
      17             : #include "src/api-arguments-inl.h"
      18             : #include "src/api-natives.h"
      19             : #include "src/api.h"
      20             : #include "src/arguments.h"
      21             : #include "src/ast/ast.h"
      22             : #include "src/ast/scopes.h"
      23             : #include "src/base/bits.h"
      24             : #include "src/base/overflowing-math.h"
      25             : #include "src/base/utils/random-number-generator.h"
      26             : #include "src/bootstrapper.h"
      27             : #include "src/builtins/builtins.h"
      28             : #include "src/compiler.h"
      29             : #include "src/counters-inl.h"
      30             : #include "src/counters.h"
      31             : #include "src/date.h"
      32             : #include "src/debug/debug.h"
      33             : #include "src/elements.h"
      34             : #include "src/execution.h"
      35             : #include "src/field-index-inl.h"
      36             : #include "src/field-index.h"
      37             : #include "src/field-type.h"
      38             : #include "src/frames-inl.h"
      39             : #include "src/function-kind.h"
      40             : #include "src/globals.h"
      41             : #include "src/heap/heap-inl.h"
      42             : #include "src/heap/read-only-heap.h"
      43             : #include "src/ic/ic.h"
      44             : #include "src/identity-map.h"
      45             : #include "src/isolate-inl.h"
      46             : #include "src/keys.h"
      47             : #include "src/log.h"
      48             : #include "src/lookup-inl.h"
      49             : #include "src/map-updater.h"
      50             : #include "src/message-template.h"
      51             : #include "src/microtask-queue.h"
      52             : #include "src/objects-body-descriptors-inl.h"
      53             : #include "src/objects/allocation-site-inl.h"
      54             : #include "src/objects/api-callbacks.h"
      55             : #include "src/objects/arguments-inl.h"
      56             : #include "src/objects/bigint.h"
      57             : #include "src/objects/cell-inl.h"
      58             : #include "src/objects/code-inl.h"
      59             : #include "src/objects/compilation-cache-inl.h"
      60             : #include "src/objects/debug-objects-inl.h"
      61             : #include "src/objects/embedder-data-array-inl.h"
      62             : #include "src/objects/foreign.h"
      63             : #include "src/objects/frame-array-inl.h"
      64             : #include "src/objects/free-space-inl.h"
      65             : #include "src/objects/hash-table-inl.h"
      66             : #include "src/objects/js-array-inl.h"
      67             : #ifdef V8_INTL_SUPPORT
      68             : #include "src/objects/js-break-iterator.h"
      69             : #include "src/objects/js-collator.h"
      70             : #endif  // V8_INTL_SUPPORT
      71             : #include "src/objects/js-collection-inl.h"
      72             : #ifdef V8_INTL_SUPPORT
      73             : #include "src/objects/js-date-time-format.h"
      74             : #endif  // V8_INTL_SUPPORT
      75             : #include "src/objects/js-generator-inl.h"
      76             : #ifdef V8_INTL_SUPPORT
      77             : #include "src/objects/js-list-format.h"
      78             : #include "src/objects/js-locale.h"
      79             : #include "src/objects/js-number-format.h"
      80             : #include "src/objects/js-plural-rules.h"
      81             : #endif  // V8_INTL_SUPPORT
      82             : #include "src/objects/js-regexp-inl.h"
      83             : #include "src/objects/js-regexp-string-iterator.h"
      84             : #ifdef V8_INTL_SUPPORT
      85             : #include "src/objects/js-relative-time-format.h"
      86             : #include "src/objects/js-segment-iterator.h"
      87             : #include "src/objects/js-segmenter.h"
      88             : #endif  // V8_INTL_SUPPORT
      89             : #include "src/objects/js-weak-refs-inl.h"
      90             : #include "src/objects/literal-objects-inl.h"
      91             : #include "src/objects/map-inl.h"
      92             : #include "src/objects/map.h"
      93             : #include "src/objects/microtask-inl.h"
      94             : #include "src/objects/module-inl.h"
      95             : #include "src/objects/promise-inl.h"
      96             : #include "src/objects/slots-atomic-inl.h"
      97             : #include "src/objects/stack-frame-info-inl.h"
      98             : #include "src/objects/string-comparator.h"
      99             : #include "src/objects/struct-inl.h"
     100             : #include "src/ostreams.h"
     101             : #include "src/parsing/preparse-data.h"
     102             : #include "src/property-descriptor.h"
     103             : #include "src/prototype.h"
     104             : #include "src/regexp/jsregexp.h"
     105             : #include "src/source-position-table.h"
     106             : #include "src/string-builder-inl.h"
     107             : #include "src/string-search.h"
     108             : #include "src/string-stream.h"
     109             : #include "src/transitions-inl.h"
     110             : #include "src/unicode-decoder.h"
     111             : #include "src/unicode-inl.h"
     112             : #include "src/utils-inl.h"
     113             : #include "src/wasm/wasm-engine.h"
     114             : #include "src/wasm/wasm-objects.h"
     115             : #include "src/zone/zone.h"
     116             : 
     117             : namespace v8 {
     118             : namespace internal {
     119             : 
     120      205977 : ShouldThrow GetShouldThrow(Isolate* isolate, Maybe<ShouldThrow> should_throw) {
     121      211215 :   if (should_throw.IsJust()) return should_throw.FromJust();
     122             : 
     123      200739 :   LanguageMode mode = isolate->context()->scope_info()->language_mode();
     124      200739 :   if (mode == LanguageMode::kStrict) return kThrowOnError;
     125             : 
     126      584440 :   for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
     127     1134765 :     if (!(it.frame()->is_optimized() || it.frame()->is_interpreted())) {
     128      385347 :       continue;
     129             :     }
     130             :     // Get the language mode from closure.
     131             :     JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(it.frame());
     132             :     std::vector<SharedFunctionInfo> functions;
     133      199068 :     js_frame->GetFunctions(&functions);
     134             :     LanguageMode closure_language_mode = functions.back()->language_mode();
     135      199068 :     if (closure_language_mode > mode) {
     136             :       mode = closure_language_mode;
     137             :     }
     138             :     break;
     139             :   }
     140             : 
     141      199093 :   return is_sloppy(mode) ? kDontThrow : kThrowOnError;
     142             : }
     143             : 
     144     4424945 : bool ComparisonResultToBool(Operation op, ComparisonResult result) {
     145     4424945 :   switch (op) {
     146             :     case Operation::kLessThan:
     147       17519 :       return result == ComparisonResult::kLessThan;
     148             :     case Operation::kLessThanOrEqual:
     149     3114601 :       return result == ComparisonResult::kLessThan ||
     150     3114601 :              result == ComparisonResult::kEqual;
     151             :     case Operation::kGreaterThan:
     152         981 :       return result == ComparisonResult::kGreaterThan;
     153             :     case Operation::kGreaterThanOrEqual:
     154     1291844 :       return result == ComparisonResult::kGreaterThan ||
     155     1291844 :              result == ComparisonResult::kEqual;
     156             :     default:
     157             :       break;
     158             :   }
     159           0 :   UNREACHABLE();
     160             : }
     161             : 
     162       39947 : std::ostream& operator<<(std::ostream& os, InstanceType instance_type) {
     163       39947 :   switch (instance_type) {
     164             : #define WRITE_TYPE(TYPE) \
     165             :   case TYPE:             \
     166             :     return os << #TYPE;
     167       39947 :     INSTANCE_TYPE_LIST(WRITE_TYPE)
     168             : #undef WRITE_TYPE
     169             :   }
     170           0 :   UNREACHABLE();
     171             : }
     172             : 
     173    17096319 : Handle<FieldType> Object::OptimalType(Isolate* isolate,
     174             :                                       Representation representation) {
     175    17096319 :   if (representation.IsNone()) return FieldType::None(isolate);
     176    16879026 :   if (FLAG_track_field_types) {
     177    26401961 :     if (representation.IsHeapObject() && IsHeapObject()) {
     178             :       // We can track only JavaScript objects with stable maps.
     179             :       Handle<Map> map(HeapObject::cast(*this)->map(), isolate);
     180    19227358 :       if (map->is_stable() && map->IsJSReceiverMap()) {
     181     5759529 :         return FieldType::Class(map, isolate);
     182             :       }
     183             :     }
     184             :   }
     185    11119504 :   return FieldType::Any(isolate);
     186             : }
     187             : 
     188        2125 : Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object,
     189             :                                      Representation representation) {
     190        2125 :   if (!representation.IsDouble()) return object;
     191             :   auto result = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
     192        2125 :   if (object->IsUninitialized(isolate)) {
     193             :     result->set_value_as_bits(kHoleNanInt64);
     194        1397 :   } else if (object->IsMutableHeapNumber()) {
     195             :     // Ensure that all bits of the double value are preserved.
     196             :     result->set_value_as_bits(
     197             :         MutableHeapNumber::cast(*object)->value_as_bits());
     198             :   } else {
     199             :     result->set_value(object->Number());
     200             :   }
     201        2125 :   return result;
     202             : }
     203             : 
     204    11767429 : Handle<Object> Object::WrapForRead(Isolate* isolate, Handle<Object> object,
     205             :                                    Representation representation) {
     206             :   DCHECK(!object->IsUninitialized(isolate));
     207    11767429 :   if (!representation.IsDouble()) {
     208             :     DCHECK(object->FitsRepresentation(representation));
     209    11736479 :     return object;
     210             :   }
     211             :   return isolate->factory()->NewHeapNumber(
     212       30950 :       MutableHeapNumber::cast(*object)->value());
     213             : }
     214             : 
     215        6813 : MaybeHandle<JSReceiver> Object::ToObjectImpl(Isolate* isolate,
     216             :                                              Handle<Object> object,
     217             :                                              const char* method_name) {
     218             :   DCHECK(!object->IsJSReceiver());  // Use ToObject() for fast path.
     219        6813 :   Handle<Context> native_context = isolate->native_context();
     220             :   Handle<JSFunction> constructor;
     221        6813 :   if (object->IsSmi()) {
     222         948 :     constructor = handle(native_context->number_function(), isolate);
     223             :   } else {
     224             :     int constructor_function_index =
     225             :         Handle<HeapObject>::cast(object)->map()->GetConstructorFunctionIndex();
     226        6339 :     if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
     227        1428 :       if (method_name != nullptr) {
     228        1350 :         THROW_NEW_ERROR(
     229             :             isolate,
     230             :             NewTypeError(
     231             :                 MessageTemplate::kCalledOnNullOrUndefined,
     232             :                 isolate->factory()->NewStringFromAsciiChecked(method_name)),
     233             :             JSReceiver);
     234             :       }
     235        1956 :       THROW_NEW_ERROR(isolate,
     236             :                       NewTypeError(MessageTemplate::kUndefinedOrNullToObject),
     237             :                       JSReceiver);
     238             :     }
     239             :     constructor = handle(
     240             :         JSFunction::cast(native_context->get(constructor_function_index)),
     241        4911 :         isolate);
     242             :   }
     243        5385 :   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
     244        5385 :   Handle<JSValue>::cast(result)->set_value(*object);
     245        5385 :   return result;
     246             : }
     247             : 
     248             : // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
     249             : // static
     250         180 : MaybeHandle<JSReceiver> Object::ConvertReceiver(Isolate* isolate,
     251             :                                                 Handle<Object> object) {
     252         180 :   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
     253         180 :   if (object->IsNullOrUndefined(isolate)) {
     254           6 :     return isolate->global_proxy();
     255             :   }
     256         174 :   return Object::ToObject(isolate, object);
     257             : }
     258             : 
     259             : // static
     260     3209626 : MaybeHandle<Object> Object::ConvertToNumberOrNumeric(Isolate* isolate,
     261             :                                                      Handle<Object> input,
     262             :                                                      Conversion mode) {
     263             :   while (true) {
     264     3215205 :     if (input->IsNumber()) {
     265      106364 :       return input;
     266             :     }
     267     3108841 :     if (input->IsString()) {
     268        3214 :       return String::ToNumber(isolate, Handle<String>::cast(input));
     269             :     }
     270     3105627 :     if (input->IsOddball()) {
     271     3095093 :       return Oddball::ToNumber(isolate, Handle<Oddball>::cast(input));
     272             :     }
     273       10534 :     if (input->IsSymbol()) {
     274        7546 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber),
     275             :                       Object);
     276             :     }
     277        6761 :     if (input->IsBigInt()) {
     278         581 :       if (mode == Conversion::kToNumeric) return input;
     279             :       DCHECK_EQ(mode, Conversion::kToNumber);
     280        1162 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kBigIntToNumber),
     281             :                       Object);
     282             :     }
     283       12360 :     ASSIGN_RETURN_ON_EXCEPTION(
     284             :         isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
     285             :                                                 ToPrimitiveHint::kNumber),
     286             :         Object);
     287             :   }
     288             : }
     289             : 
     290             : // static
     291      105654 : MaybeHandle<Object> Object::ConvertToInteger(Isolate* isolate,
     292             :                                              Handle<Object> input) {
     293      211308 :   ASSIGN_RETURN_ON_EXCEPTION(
     294             :       isolate, input,
     295             :       ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber), Object);
     296      105438 :   if (input->IsSmi()) return input;
     297      104538 :   return isolate->factory()->NewNumber(DoubleToInteger(input->Number()));
     298             : }
     299             : 
     300             : // static
     301        1576 : MaybeHandle<Object> Object::ConvertToInt32(Isolate* isolate,
     302             :                                            Handle<Object> input) {
     303        3152 :   ASSIGN_RETURN_ON_EXCEPTION(
     304             :       isolate, input,
     305             :       ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber), Object);
     306        1564 :   if (input->IsSmi()) return input;
     307        1366 :   return isolate->factory()->NewNumberFromInt(DoubleToInt32(input->Number()));
     308             : }
     309             : 
     310             : // static
     311      422390 : MaybeHandle<Object> Object::ConvertToUint32(Isolate* isolate,
     312             :                                             Handle<Object> input) {
     313      844780 :   ASSIGN_RETURN_ON_EXCEPTION(
     314             :       isolate, input,
     315             :       ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber), Object);
     316      844591 :   if (input->IsSmi()) return handle(Smi::cast(*input)->ToUint32Smi(), isolate);
     317         147 :   return isolate->factory()->NewNumberFromUint(DoubleToUint32(input->Number()));
     318             : }
     319             : 
     320             : // static
     321       85419 : MaybeHandle<Name> Object::ConvertToName(Isolate* isolate,
     322             :                                         Handle<Object> input) {
     323      170838 :   ASSIGN_RETURN_ON_EXCEPTION(
     324             :       isolate, input, Object::ToPrimitive(input, ToPrimitiveHint::kString),
     325             :       Name);
     326       85183 :   if (input->IsName()) return Handle<Name>::cast(input);
     327       79528 :   return ToString(isolate, input);
     328             : }
     329             : 
     330             : // ES6 7.1.14
     331             : // static
     332         486 : MaybeHandle<Object> Object::ConvertToPropertyKey(Isolate* isolate,
     333             :                                                  Handle<Object> value) {
     334             :   // 1. Let key be ToPrimitive(argument, hint String).
     335             :   MaybeHandle<Object> maybe_key =
     336         486 :       Object::ToPrimitive(value, ToPrimitiveHint::kString);
     337             :   // 2. ReturnIfAbrupt(key).
     338             :   Handle<Object> key;
     339         486 :   if (!maybe_key.ToHandle(&key)) return key;
     340             :   // 3. If Type(key) is Symbol, then return key.
     341         486 :   if (key->IsSymbol()) return key;
     342             :   // 4. Return ToString(key).
     343             :   // Extending spec'ed behavior, we'd be happy to return an element index.
     344         486 :   if (key->IsSmi()) return key;
     345         486 :   if (key->IsHeapNumber()) {
     346             :     uint32_t uint_value;
     347          45 :     if (value->ToArrayLength(&uint_value) &&
     348           9 :         uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) {
     349           0 :       return handle(Smi::FromInt(static_cast<int>(uint_value)), isolate);
     350             :     }
     351             :   }
     352         486 :   return Object::ToString(isolate, key);
     353             : }
     354             : 
     355             : // static
     356     4580284 : MaybeHandle<String> Object::ConvertToString(Isolate* isolate,
     357             :                                             Handle<Object> input) {
     358             :   while (true) {
     359     4580514 :     if (input->IsOddball()) {
     360     2618667 :       return handle(Handle<Oddball>::cast(input)->to_string(), isolate);
     361             :     }
     362     1961847 :     if (input->IsNumber()) {
     363       85156 :       return isolate->factory()->NumberToString(input);
     364             :     }
     365     1876691 :     if (input->IsSymbol()) {
     366          90 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToString),
     367             :                       String);
     368             :     }
     369     1876646 :     if (input->IsBigInt()) {
     370        8842 :       return BigInt::ToString(isolate, Handle<BigInt>::cast(input));
     371             :     }
     372     3735608 :     ASSIGN_RETURN_ON_EXCEPTION(
     373             :         isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
     374             :                                                 ToPrimitiveHint::kString),
     375             :         String);
     376             :     // The previous isString() check happened in Object::ToString and thus we
     377             :     // put it at the end of the loop in this helper.
     378     1859631 :     if (input->IsString()) {
     379     1859401 :       return Handle<String>::cast(input);
     380             :     }
     381             :   }
     382             : }
     383             : 
     384             : namespace {
     385             : 
     386       32235 : bool IsErrorObject(Isolate* isolate, Handle<Object> object) {
     387       32235 :   if (!object->IsJSReceiver()) return false;
     388             :   Handle<Symbol> symbol = isolate->factory()->stack_trace_symbol();
     389       64470 :   return JSReceiver::HasOwnProperty(Handle<JSReceiver>::cast(object), symbol)
     390             :       .FromMaybe(false);
     391             : }
     392             : 
     393       29496 : Handle<String> AsStringOrEmpty(Isolate* isolate, Handle<Object> object) {
     394             :   return object->IsString() ? Handle<String>::cast(object)
     395       58992 :                             : isolate->factory()->empty_string();
     396             : }
     397             : 
     398        5851 : Handle<String> NoSideEffectsErrorToString(Isolate* isolate,
     399             :                                           Handle<Object> input) {
     400        5851 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
     401             : 
     402             :   Handle<Name> name_key = isolate->factory()->name_string();
     403        5851 :   Handle<Object> name = JSReceiver::GetDataProperty(receiver, name_key);
     404        5851 :   Handle<String> name_str = AsStringOrEmpty(isolate, name);
     405             : 
     406             :   Handle<Name> msg_key = isolate->factory()->message_string();
     407        5851 :   Handle<Object> msg = JSReceiver::GetDataProperty(receiver, msg_key);
     408        5851 :   Handle<String> msg_str = AsStringOrEmpty(isolate, msg);
     409             : 
     410        5851 :   if (name_str->length() == 0) return msg_str;
     411        5833 :   if (msg_str->length() == 0) return name_str;
     412             : 
     413        5661 :   IncrementalStringBuilder builder(isolate);
     414        5661 :   builder.AppendString(name_str);
     415             :   builder.AppendCString(": ");
     416        5661 :   builder.AppendString(msg_str);
     417             : 
     418       11322 :   return builder.Finish().ToHandleChecked();
     419             : }
     420             : 
     421             : }  // namespace
     422             : 
     423             : // static
     424     3467043 : Handle<String> Object::NoSideEffectsToString(Isolate* isolate,
     425             :                                              Handle<Object> input) {
     426     6934086 :   DisallowJavascriptExecution no_js(isolate);
     427             : 
     428     8709864 :   if (input->IsString() || input->IsNumber() || input->IsOddball()) {
     429     6864860 :     return Object::ToString(isolate, input).ToHandleChecked();
     430       34613 :   } else if (input->IsBigInt()) {
     431             :     MaybeHandle<String> maybe_string =
     432          14 :         BigInt::ToString(isolate, Handle<BigInt>::cast(input), 10, kDontThrow);
     433             :     Handle<String> result;
     434          14 :     if (maybe_string.ToHandle(&result)) return result;
     435             :     // BigInt-to-String conversion can fail on 32-bit platforms where
     436             :     // String::kMaxLength is too small to fit this BigInt.
     437             :     return isolate->factory()->NewStringFromStaticChars(
     438           0 :         "<a very large BigInt>");
     439       34599 :   } else if (input->IsFunction()) {
     440             :     // -- F u n c t i o n
     441             :     Handle<String> fun_str;
     442         549 :     if (input->IsJSBoundFunction()) {
     443           0 :       fun_str = JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(input));
     444             :     } else {
     445             :       DCHECK(input->IsJSFunction());
     446         549 :       fun_str = JSFunction::ToString(Handle<JSFunction>::cast(input));
     447             :     }
     448             : 
     449         549 :     if (fun_str->length() > 128) {
     450           9 :       IncrementalStringBuilder builder(isolate);
     451           9 :       builder.AppendString(isolate->factory()->NewSubString(fun_str, 0, 111));
     452             :       builder.AppendCString("...<omitted>...");
     453           9 :       builder.AppendString(isolate->factory()->NewSubString(
     454           9 :           fun_str, fun_str->length() - 2, fun_str->length()));
     455             : 
     456          18 :       return builder.Finish().ToHandleChecked();
     457             :     }
     458         540 :     return fun_str;
     459       34050 :   } else if (input->IsSymbol()) {
     460             :     // -- S y m b o l
     461             :     Handle<Symbol> symbol = Handle<Symbol>::cast(input);
     462             : 
     463        1815 :     if (symbol->is_private_name()) {
     464           9 :       return Handle<String>(String::cast(symbol->name()), isolate);
     465             :     }
     466             : 
     467        1806 :     IncrementalStringBuilder builder(isolate);
     468             :     builder.AppendCString("Symbol(");
     469        1806 :     if (symbol->name()->IsString()) {
     470        1266 :       builder.AppendString(handle(String::cast(symbol->name()), isolate));
     471             :     }
     472             :     builder.AppendCharacter(')');
     473             : 
     474        3612 :     return builder.Finish().ToHandleChecked();
     475       32235 :   } else if (input->IsJSReceiver()) {
     476             :     // -- J S R e c e i v e r
     477       32235 :     Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
     478             :     Handle<Object> to_string = JSReceiver::GetDataProperty(
     479       32235 :         receiver, isolate->factory()->toString_string());
     480             : 
     481       58628 :     if (IsErrorObject(isolate, input) ||
     482       26393 :         *to_string == *isolate->error_to_string()) {
     483             :       // When internally formatting error objects, use a side-effects-free
     484             :       // version of Error.prototype.toString independent of the actually
     485             :       // installed toString method.
     486       28756 :       return NoSideEffectsErrorToString(isolate, input);
     487       52768 :     } else if (*to_string == *isolate->object_to_string()) {
     488             :       Handle<Object> ctor = JSReceiver::GetDataProperty(
     489       18019 :           receiver, isolate->factory()->constructor_string());
     490       18019 :       if (ctor->IsFunction()) {
     491             :         Handle<String> ctor_name;
     492       17794 :         if (ctor->IsJSBoundFunction()) {
     493           0 :           ctor_name = JSBoundFunction::GetName(
     494             :                           isolate, Handle<JSBoundFunction>::cast(ctor))
     495             :                           .ToHandleChecked();
     496       17794 :         } else if (ctor->IsJSFunction()) {
     497             :           Handle<Object> ctor_name_obj =
     498       17794 :               JSFunction::GetName(isolate, Handle<JSFunction>::cast(ctor));
     499       17794 :           ctor_name = AsStringOrEmpty(isolate, ctor_name_obj);
     500             :         }
     501             : 
     502       17794 :         if (ctor_name->length() != 0) {
     503       17054 :           IncrementalStringBuilder builder(isolate);
     504             :           builder.AppendCString("#<");
     505       17054 :           builder.AppendString(ctor_name);
     506             :           builder.AppendCString(">");
     507             : 
     508       34108 :           return builder.Finish().ToHandleChecked();
     509             :         }
     510             :       }
     511             :     }
     512             :   }
     513             : 
     514             :   // At this point, input is either none of the above or a JSReceiver.
     515             : 
     516             :   Handle<JSReceiver> receiver;
     517        9330 :   if (input->IsJSReceiver()) {
     518             :     receiver = Handle<JSReceiver>::cast(input);
     519             :   } else {
     520             :     // This is the only case where Object::ToObject throws.
     521             :     DCHECK(!input->IsSmi());
     522             :     int constructor_function_index =
     523             :         Handle<HeapObject>::cast(input)->map()->GetConstructorFunctionIndex();
     524           0 :     if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
     525           0 :       return isolate->factory()->NewStringFromAsciiChecked("[object Unknown]");
     526             :     }
     527             : 
     528           0 :     receiver = Object::ToObjectImpl(isolate, input).ToHandleChecked();
     529             :   }
     530             : 
     531       18660 :   Handle<String> builtin_tag = handle(receiver->class_name(), isolate);
     532             :   Handle<Object> tag_obj = JSReceiver::GetDataProperty(
     533        9330 :       receiver, isolate->factory()->to_string_tag_symbol());
     534             :   Handle<String> tag =
     535        9330 :       tag_obj->IsString() ? Handle<String>::cast(tag_obj) : builtin_tag;
     536             : 
     537        9330 :   IncrementalStringBuilder builder(isolate);
     538             :   builder.AppendCString("[object ");
     539        9330 :   builder.AppendString(tag);
     540             :   builder.AppendCString("]");
     541             : 
     542       18660 :   return builder.Finish().ToHandleChecked();
     543             : }
     544             : 
     545             : // static
     546        2268 : MaybeHandle<Object> Object::ConvertToLength(Isolate* isolate,
     547             :                                             Handle<Object> input) {
     548        4536 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(isolate, input), Object);
     549        2097 :   if (input->IsSmi()) {
     550        1647 :     int value = std::max(Smi::ToInt(*input), 0);
     551         549 :     return handle(Smi::FromInt(value), isolate);
     552             :   }
     553        1548 :   double len = DoubleToInteger(input->Number());
     554        1548 :   if (len <= 0.0) {
     555        1107 :     return handle(Smi::kZero, isolate);
     556         441 :   } else if (len >= kMaxSafeInteger) {
     557             :     len = kMaxSafeInteger;
     558             :   }
     559         441 :   return isolate->factory()->NewNumber(len);
     560             : }
     561             : 
     562             : // static
     563        1309 : MaybeHandle<Object> Object::ConvertToIndex(Isolate* isolate,
     564             :                                            Handle<Object> input,
     565             :                                            MessageTemplate error_index) {
     566        2150 :   if (input->IsUndefined(isolate)) return handle(Smi::kZero, isolate);
     567         936 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(isolate, input), Object);
     568         562 :   if (input->IsSmi() && Smi::ToInt(*input) >= 0) return input;
     569         396 :   double len = DoubleToInteger(input->Number()) + 0.0;
     570         396 :   auto js_len = isolate->factory()->NewNumber(len);
     571         396 :   if (len < 0.0 || len > kMaxSafeInteger) {
     572         216 :     THROW_NEW_ERROR(isolate, NewRangeError(error_index, js_len), Object);
     573             :   }
     574         288 :   return js_len;
     575             : }
     576             : 
     577    91999610 : bool Object::BooleanValue(Isolate* isolate) {
     578    92005093 :   if (IsSmi()) return Smi::ToInt(*this) != 0;
     579             :   DCHECK(IsHeapObject());
     580    93293411 :   if (IsBoolean()) return IsTrue(isolate);
     581    90694209 :   if (IsNullOrUndefined(isolate)) return false;
     582    89697137 :   if (IsUndetectable()) return false;  // Undetectable object is false.
     583    97321886 :   if (IsString()) return String::cast(*this)->length() != 0;
     584    82543917 :   if (IsHeapNumber()) return DoubleToBoolean(HeapNumber::cast(*this)->value());
     585    81604204 :   if (IsBigInt()) return BigInt::cast(*this)->ToBoolean();
     586             :   return true;
     587             : }
     588             : 
     589           0 : Object Object::ToBoolean(Isolate* isolate) {
     590           0 :   if (IsBoolean()) return *this;
     591           0 :   return isolate->heap()->ToBoolean(BooleanValue(isolate));
     592             : }
     593             : 
     594             : namespace {
     595             : 
     596             : // TODO(bmeurer): Maybe we should introduce a marker interface Number,
     597             : // where we put all these methods at some point?
     598             : ComparisonResult NumberCompare(double x, double y) {
     599         528 :   if (std::isnan(x) || std::isnan(y)) {
     600             :     return ComparisonResult::kUndefined;
     601         384 :   } else if (x < y) {
     602             :     return ComparisonResult::kLessThan;
     603         208 :   } else if (x > y) {
     604             :     return ComparisonResult::kGreaterThan;
     605             :   } else {
     606             :     return ComparisonResult::kEqual;
     607             :   }
     608             : }
     609             : 
     610             : bool NumberEquals(double x, double y) {
     611             :   // Must check explicitly for NaN's on Windows, but -0 works fine.
     612       10110 :   if (std::isnan(x)) return false;
     613       10028 :   if (std::isnan(y)) return false;
     614        9969 :   return x == y;
     615             : }
     616             : 
     617       10110 : bool NumberEquals(const Object x, const Object y) {
     618       10110 :   return NumberEquals(x->Number(), y->Number());
     619             : }
     620             : 
     621             : bool NumberEquals(Handle<Object> x, Handle<Object> y) {
     622        4156 :   return NumberEquals(*x, *y);
     623             : }
     624             : 
     625             : ComparisonResult Reverse(ComparisonResult result) {
     626         153 :   if (result == ComparisonResult::kLessThan) {
     627             :     return ComparisonResult::kGreaterThan;
     628             :   }
     629         135 :   if (result == ComparisonResult::kGreaterThan) {
     630             :     return ComparisonResult::kLessThan;
     631             :   }
     632             :   return result;
     633             : }
     634             : 
     635             : }  // anonymous namespace
     636             : 
     637             : // static
     638         929 : Maybe<ComparisonResult> Object::Compare(Isolate* isolate, Handle<Object> x,
     639             :                                         Handle<Object> y) {
     640             :   // ES6 section 7.2.11 Abstract Relational Comparison step 3 and 4.
     641        2787 :   if (!Object::ToPrimitive(x, ToPrimitiveHint::kNumber).ToHandle(&x) ||
     642         929 :       !Object::ToPrimitive(y, ToPrimitiveHint::kNumber).ToHandle(&y)) {
     643             :     return Nothing<ComparisonResult>();
     644             :   }
     645        1104 :   if (x->IsString() && y->IsString()) {
     646             :     // ES6 section 7.2.11 Abstract Relational Comparison step 5.
     647          32 :     return Just(String::Compare(isolate, Handle<String>::cast(x),
     648             :                                 Handle<String>::cast(y)));
     649             :   }
     650        1104 :   if (x->IsBigInt() && y->IsString()) {
     651          63 :     return Just(BigInt::CompareToString(isolate, Handle<BigInt>::cast(x),
     652             :                                         Handle<String>::cast(y)));
     653             :   }
     654         977 :   if (x->IsString() && y->IsBigInt()) {
     655          63 :     return Just(Reverse(BigInt::CompareToString(
     656             :         isolate, Handle<BigInt>::cast(y), Handle<String>::cast(x))));
     657             :   }
     658             :   // ES6 section 7.2.11 Abstract Relational Comparison step 6.
     659        2304 :   if (!Object::ToNumeric(isolate, x).ToHandle(&x) ||
     660         762 :       !Object::ToNumeric(isolate, y).ToHandle(&y)) {
     661             :     return Nothing<ComparisonResult>();
     662             :   }
     663             : 
     664             :   bool x_is_number = x->IsNumber();
     665             :   bool y_is_number = y->IsNumber();
     666         753 :   if (x_is_number && y_is_number) {
     667             :     return Just(NumberCompare(x->Number(), y->Number()));
     668         225 :   } else if (!x_is_number && !y_is_number) {
     669          45 :     return Just(BigInt::CompareToBigInt(Handle<BigInt>::cast(x),
     670             :                                         Handle<BigInt>::cast(y)));
     671         180 :   } else if (x_is_number) {
     672          90 :     return Just(Reverse(BigInt::CompareToNumber(Handle<BigInt>::cast(y), x)));
     673             :   } else {
     674          90 :     return Just(BigInt::CompareToNumber(Handle<BigInt>::cast(x), y));
     675             :   }
     676             : }
     677             : 
     678             : 
     679             : // static
     680      170153 : Maybe<bool> Object::Equals(Isolate* isolate, Handle<Object> x,
     681             :                            Handle<Object> y) {
     682             :   // This is the generic version of Abstract Equality Comparison. Must be in
     683             :   // sync with CodeStubAssembler::Equal.
     684             :   while (true) {
     685      170231 :     if (x->IsNumber()) {
     686        4489 :       if (y->IsNumber()) {
     687             :         return Just(NumberEquals(x, y));
     688         442 :       } else if (y->IsBoolean()) {
     689           0 :         return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
     690         442 :       } else if (y->IsString()) {
     691          64 :         return Just(NumberEquals(
     692             :             x, String::ToNumber(isolate, Handle<String>::cast(y))));
     693         378 :       } else if (y->IsBigInt()) {
     694         378 :         return Just(BigInt::EqualToNumber(Handle<BigInt>::cast(y), x));
     695           0 :       } else if (y->IsJSReceiver()) {
     696           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     697             :                  .ToHandle(&y)) {
     698             :           return Nothing<bool>();
     699             :         }
     700             :       } else {
     701             :         return Just(false);
     702             :       }
     703      165742 :     } else if (x->IsString()) {
     704      150244 :       if (y->IsString()) {
     705      150037 :         return Just(String::Equals(isolate, Handle<String>::cast(x),
     706             :                                    Handle<String>::cast(y)));
     707         207 :       } else if (y->IsNumber()) {
     708          45 :         x = String::ToNumber(isolate, Handle<String>::cast(x));
     709             :         return Just(NumberEquals(x, y));
     710         162 :       } else if (y->IsBoolean()) {
     711           0 :         x = String::ToNumber(isolate, Handle<String>::cast(x));
     712           0 :         return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
     713         162 :       } else if (y->IsBigInt()) {
     714         162 :         return Just(BigInt::EqualToString(isolate, Handle<BigInt>::cast(y),
     715             :                                           Handle<String>::cast(x)));
     716           0 :       } else if (y->IsJSReceiver()) {
     717           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     718             :                  .ToHandle(&y)) {
     719             :           return Nothing<bool>();
     720             :         }
     721             :       } else {
     722             :         return Just(false);
     723             :       }
     724       15498 :     } else if (x->IsBoolean()) {
     725         816 :       if (y->IsOddball()) {
     726             :         return Just(x.is_identical_to(y));
     727         216 :       } else if (y->IsNumber()) {
     728           0 :         return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
     729         216 :       } else if (y->IsString()) {
     730           0 :         y = String::ToNumber(isolate, Handle<String>::cast(y));
     731           0 :         return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
     732         216 :       } else if (y->IsBigInt()) {
     733         216 :         x = Oddball::ToNumber(isolate, Handle<Oddball>::cast(x));
     734         216 :         return Just(BigInt::EqualToNumber(Handle<BigInt>::cast(y), x));
     735           0 :       } else if (y->IsJSReceiver()) {
     736           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     737             :                  .ToHandle(&y)) {
     738             :           return Nothing<bool>();
     739             :         }
     740           0 :         x = Oddball::ToNumber(isolate, Handle<Oddball>::cast(x));
     741             :       } else {
     742             :         return Just(false);
     743             :       }
     744       14682 :     } else if (x->IsSymbol()) {
     745          90 :       if (y->IsSymbol()) {
     746             :         return Just(x.is_identical_to(y));
     747          36 :       } else if (y->IsJSReceiver()) {
     748           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     749             :                  .ToHandle(&y)) {
     750             :           return Nothing<bool>();
     751             :         }
     752             :       } else {
     753             :         return Just(false);
     754             :       }
     755       14592 :     } else if (x->IsBigInt()) {
     756         477 :       if (y->IsBigInt()) {
     757          81 :         return Just(BigInt::EqualToBigInt(BigInt::cast(*x), BigInt::cast(*y)));
     758             :       }
     759         396 :       return Equals(isolate, y, x);
     760       14115 :     } else if (x->IsJSReceiver()) {
     761       14018 :       if (y->IsJSReceiver()) {
     762             :         return Just(x.is_identical_to(y));
     763          78 :       } else if (y->IsUndetectable()) {
     764             :         return Just(x->IsUndetectable());
     765          78 :       } else if (y->IsBoolean()) {
     766           0 :         y = Oddball::ToNumber(isolate, Handle<Oddball>::cast(y));
     767         156 :       } else if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x))
     768             :                       .ToHandle(&x)) {
     769             :         return Nothing<bool>();
     770             :       }
     771             :     } else {
     772         194 :       return Just(x->IsUndetectable() && y->IsUndetectable());
     773             :     }
     774             :   }
     775             : }
     776             : 
     777        9505 : bool Object::StrictEquals(Object that) {
     778        9505 :   if (this->IsNumber()) {
     779        6495 :     if (!that->IsNumber()) return false;
     780        5954 :     return NumberEquals(*this, that);
     781        3010 :   } else if (this->IsString()) {
     782        1657 :     if (!that->IsString()) return false;
     783        1426 :     return String::cast(*this)->Equals(String::cast(that));
     784        1353 :   } else if (this->IsBigInt()) {
     785          90 :     if (!that->IsBigInt()) return false;
     786          72 :     return BigInt::EqualToBigInt(BigInt::cast(*this), BigInt::cast(that));
     787             :   }
     788        1263 :   return *this == that;
     789             : }
     790             : 
     791             : // static
     792       12585 : Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
     793       12585 :   if (object->IsNumber()) return isolate->factory()->number_string();
     794       12259 :   if (object->IsOddball())
     795             :     return handle(Oddball::cast(*object)->type_of(), isolate);
     796       10696 :   if (object->IsUndetectable()) {
     797             :     return isolate->factory()->undefined_string();
     798             :   }
     799       10696 :   if (object->IsString()) return isolate->factory()->string_string();
     800       10473 :   if (object->IsSymbol()) return isolate->factory()->symbol_string();
     801       10424 :   if (object->IsBigInt()) return isolate->factory()->bigint_string();
     802       10406 :   if (object->IsCallable()) return isolate->factory()->function_string();
     803             :   return isolate->factory()->object_string();
     804             : }
     805             : 
     806             : 
     807             : // static
     808          36 : MaybeHandle<Object> Object::Add(Isolate* isolate, Handle<Object> lhs,
     809             :                                 Handle<Object> rhs) {
     810          72 :   if (lhs->IsNumber() && rhs->IsNumber()) {
     811          36 :     return isolate->factory()->NewNumber(lhs->Number() + rhs->Number());
     812           0 :   } else if (lhs->IsString() && rhs->IsString()) {
     813             :     return isolate->factory()->NewConsString(Handle<String>::cast(lhs),
     814           0 :                                              Handle<String>::cast(rhs));
     815             :   }
     816           0 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToPrimitive(lhs), Object);
     817           0 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToPrimitive(rhs), Object);
     818           0 :   if (lhs->IsString() || rhs->IsString()) {
     819           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToString(isolate, rhs),
     820             :                                Object);
     821           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToString(isolate, lhs),
     822             :                                Object);
     823             :     return isolate->factory()->NewConsString(Handle<String>::cast(lhs),
     824           0 :                                              Handle<String>::cast(rhs));
     825             :   }
     826           0 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(isolate, rhs),
     827             :                              Object);
     828           0 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(isolate, lhs),
     829             :                              Object);
     830           0 :   return isolate->factory()->NewNumber(lhs->Number() + rhs->Number());
     831             : }
     832             : 
     833             : 
     834             : // static
     835      107687 : MaybeHandle<Object> Object::OrdinaryHasInstance(Isolate* isolate,
     836             :                                                 Handle<Object> callable,
     837             :                                                 Handle<Object> object) {
     838             :   // The {callable} must have a [[Call]] internal method.
     839      107725 :   if (!callable->IsCallable()) return isolate->factory()->false_value();
     840             : 
     841             :   // Check if {callable} is a bound function, and if so retrieve its
     842             :   // [[BoundTargetFunction]] and use that instead of {callable}.
     843      107649 :   if (callable->IsJSBoundFunction()) {
     844             :     Handle<Object> bound_callable(
     845             :         Handle<JSBoundFunction>::cast(callable)->bound_target_function(),
     846             :         isolate);
     847         294 :     return Object::InstanceOf(isolate, object, bound_callable);
     848             :   }
     849             : 
     850             :   // If {object} is not a receiver, return false.
     851      114765 :   if (!object->IsJSReceiver()) return isolate->factory()->false_value();
     852             : 
     853             :   // Get the "prototype" of {callable}; raise an error if it's not a receiver.
     854             :   Handle<Object> prototype;
     855      199890 :   ASSIGN_RETURN_ON_EXCEPTION(
     856             :       isolate, prototype,
     857             :       Object::GetProperty(isolate, callable,
     858             :                           isolate->factory()->prototype_string()),
     859             :       Object);
     860       99945 :   if (!prototype->IsJSReceiver()) {
     861      199206 :     THROW_NEW_ERROR(
     862             :         isolate,
     863             :         NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype),
     864             :         Object);
     865             :   }
     866             : 
     867             :   // Return whether or not {prototype} is in the prototype chain of {object}.
     868             :   Maybe<bool> result = JSReceiver::HasInPrototypeChain(
     869         342 :       isolate, Handle<JSReceiver>::cast(object), prototype);
     870         342 :   if (result.IsNothing()) return MaybeHandle<Object>();
     871         342 :   return isolate->factory()->ToBoolean(result.FromJust());
     872             : }
     873             : 
     874             : // static
     875       10924 : MaybeHandle<Object> Object::InstanceOf(Isolate* isolate, Handle<Object> object,
     876             :                                        Handle<Object> callable) {
     877             :   // The {callable} must be a receiver.
     878       10924 :   if (!callable->IsJSReceiver()) {
     879           0 :     THROW_NEW_ERROR(isolate,
     880             :                     NewTypeError(MessageTemplate::kNonObjectInInstanceOfCheck),
     881             :                     Object);
     882             :   }
     883             : 
     884             :   // Lookup the @@hasInstance method on {callable}.
     885             :   Handle<Object> inst_of_handler;
     886       21848 :   ASSIGN_RETURN_ON_EXCEPTION(
     887             :       isolate, inst_of_handler,
     888             :       Object::GetMethod(Handle<JSReceiver>::cast(callable),
     889             :                         isolate->factory()->has_instance_symbol()),
     890             :       Object);
     891       10924 :   if (!inst_of_handler->IsUndefined(isolate)) {
     892             :     // Call the {inst_of_handler} on the {callable}.
     893             :     Handle<Object> result;
     894       21836 :     ASSIGN_RETURN_ON_EXCEPTION(
     895             :         isolate, result,
     896             :         Execution::Call(isolate, inst_of_handler, callable, 1, &object),
     897             :         Object);
     898       10912 :     return isolate->factory()->ToBoolean(result->BooleanValue(isolate));
     899             :   }
     900             : 
     901             :   // The {callable} must have a [[Call]] internal method.
     902           6 :   if (!callable->IsCallable()) {
     903          12 :     THROW_NEW_ERROR(
     904             :         isolate, NewTypeError(MessageTemplate::kNonCallableInInstanceOfCheck),
     905             :         Object);
     906             :   }
     907             : 
     908             :   // Fall back to OrdinaryHasInstance with {callable} and {object}.
     909             :   Handle<Object> result;
     910           0 :   ASSIGN_RETURN_ON_EXCEPTION(
     911             :       isolate, result, Object::OrdinaryHasInstance(isolate, callable, object),
     912             :       Object);
     913           0 :   return result;
     914             : }
     915             : 
     916             : // static
     917     7243481 : MaybeHandle<Object> Object::GetMethod(Handle<JSReceiver> receiver,
     918             :                                       Handle<Name> name) {
     919             :   Handle<Object> func;
     920             :   Isolate* isolate = receiver->GetIsolate();
     921    14486962 :   ASSIGN_RETURN_ON_EXCEPTION(
     922             :       isolate, func, JSReceiver::GetProperty(isolate, receiver, name), Object);
     923     7212036 :   if (func->IsNullOrUndefined(isolate)) {
     924     6156019 :     return isolate->factory()->undefined_value();
     925             :   }
     926     1056017 :   if (!func->IsCallable()) {
     927         514 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kPropertyNotFunction,
     928             :                                           func, name, receiver),
     929             :                     Object);
     930             :   }
     931     1055760 :   return func;
     932             : }
     933             : 
     934             : namespace {
     935             : 
     936       17699 : MaybeHandle<FixedArray> CreateListFromArrayLikeFastPath(
     937             :     Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
     938       17699 :   if (element_types == ElementTypes::kAll) {
     939       16529 :     if (object->IsJSArray()) {
     940             :       Handle<JSArray> array = Handle<JSArray>::cast(object);
     941             :       uint32_t length;
     942        1176 :       if (!array->HasArrayPrototype(isolate) ||
     943        1780 :           !array->length()->ToUint32(&length) || !array->HasFastElements() ||
     944         212 :           !JSObject::PrototypeHasNoElements(isolate, *array)) {
     945         276 :         return MaybeHandle<FixedArray>();
     946             :       }
     947         232 :       return array->GetElementsAccessor()->CreateListFromArrayLike(
     948         232 :           isolate, array, length);
     949       16137 :     } else if (object->IsJSTypedArray()) {
     950             :       Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(object);
     951             :       size_t length = array->length_value();
     952         595 :       if (array->WasDetached() ||
     953             :           length > static_cast<size_t>(FixedArray::kMaxLength)) {
     954           0 :         return MaybeHandle<FixedArray>();
     955             :       }
     956        1190 :       return array->GetElementsAccessor()->CreateListFromArrayLike(
     957        1190 :           isolate, array, static_cast<uint32_t>(length));
     958             :     }
     959             :   }
     960       16712 :   return MaybeHandle<FixedArray>();
     961             : }
     962             : 
     963             : }  // namespace
     964             : 
     965             : // static
     966       17699 : MaybeHandle<FixedArray> Object::CreateListFromArrayLike(
     967             :     Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
     968             :   // Fast-path for JSArray and JSTypedArray.
     969             :   MaybeHandle<FixedArray> fast_result =
     970       17699 :       CreateListFromArrayLikeFastPath(isolate, object, element_types);
     971       17699 :   if (!fast_result.is_null()) return fast_result;
     972             :   // 1. ReturnIfAbrupt(object).
     973             :   // 2. (default elementTypes -- not applicable.)
     974             :   // 3. If Type(obj) is not Object, throw a TypeError exception.
     975       16988 :   if (!object->IsJSReceiver()) {
     976        1377 :     THROW_NEW_ERROR(isolate,
     977             :                     NewTypeError(MessageTemplate::kCalledOnNonObject,
     978             :                                  isolate->factory()->NewStringFromAsciiChecked(
     979             :                                      "CreateListFromArrayLike")),
     980             :                     FixedArray);
     981             :   }
     982             : 
     983             :   // 4. Let len be ? ToLength(? Get(obj, "length")).
     984       16529 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
     985             :   Handle<Object> raw_length_number;
     986       33058 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, raw_length_number,
     987             :                              Object::GetLengthFromArrayLike(isolate, receiver),
     988             :                              FixedArray);
     989             :   uint32_t len;
     990       32977 :   if (!raw_length_number->ToUint32(&len) ||
     991       16484 :       len > static_cast<uint32_t>(FixedArray::kMaxLength)) {
     992          54 :     THROW_NEW_ERROR(isolate,
     993             :                     NewRangeError(MessageTemplate::kInvalidArrayLength),
     994             :                     FixedArray);
     995             :   }
     996             :   // 5. Let list be an empty List.
     997       16466 :   Handle<FixedArray> list = isolate->factory()->NewFixedArray(len);
     998             :   // 6. Let index be 0.
     999             :   // 7. Repeat while index < len:
    1000    80303586 :   for (uint32_t index = 0; index < len; ++index) {
    1001             :     // 7a. Let indexName be ToString(index).
    1002             :     // 7b. Let next be ? Get(obj, indexName).
    1003             :     Handle<Object> next;
    1004    80287264 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, next,
    1005             :                                JSReceiver::GetElement(isolate, receiver, index),
    1006             :                                FixedArray);
    1007    40143596 :     switch (element_types) {
    1008             :       case ElementTypes::kAll:
    1009             :         // Nothing to do.
    1010             :         break;
    1011             :       case ElementTypes::kStringAndSymbol: {
    1012             :         // 7c. If Type(next) is not an element of elementTypes, throw a
    1013             :         //     TypeError exception.
    1014        3042 :         if (!next->IsName()) {
    1015          72 :           THROW_NEW_ERROR(isolate,
    1016             :                           NewTypeError(MessageTemplate::kNotPropertyName, next),
    1017             :                           FixedArray);
    1018             :         }
    1019             :         // 7d. Append next as the last element of list.
    1020             :         // Internalize on the fly so we can use pointer identity later.
    1021        3006 :         next = isolate->factory()->InternalizeName(Handle<Name>::cast(next));
    1022        3006 :         break;
    1023             :       }
    1024             :     }
    1025    80287120 :     list->set(index, *next);
    1026             :     // 7e. Set index to index + 1. (See loop header.)
    1027             :   }
    1028             :   // 8. Return list.
    1029       16394 :   return list;
    1030             : }
    1031             : 
    1032             : 
    1033             : // static
    1034       53732 : MaybeHandle<Object> Object::GetLengthFromArrayLike(Isolate* isolate,
    1035             :                                                    Handle<JSReceiver> object) {
    1036             :   Handle<Object> val;
    1037             :   Handle<Name> key = isolate->factory()->length_string();
    1038      107464 :   ASSIGN_RETURN_ON_EXCEPTION(
    1039             :       isolate, val, JSReceiver::GetProperty(isolate, object, key), Object);
    1040       53642 :   return Object::ToLength(isolate, val);
    1041             : }
    1042             : 
    1043             : // static
    1044    42095970 : MaybeHandle<Object> Object::GetProperty(LookupIterator* it,
    1045             :                                         OnNonExistent on_non_existent) {
    1046    43680580 :   for (; it->IsFound(); it->Next()) {
    1047    21055449 :     switch (it->state()) {
    1048             :       case LookupIterator::NOT_FOUND:
    1049             :       case LookupIterator::TRANSITION:
    1050           0 :         UNREACHABLE();
    1051             :       case LookupIterator::JSPROXY: {
    1052             :         bool was_found;
    1053             :         Handle<Object> receiver = it->GetReceiver();
    1054             :         // In case of global IC, the receiver is the global object. Replace by
    1055             :         // the global proxy.
    1056      209815 :         if (receiver->IsJSGlobalObject()) {
    1057             :           receiver = handle(JSGlobalObject::cast(*receiver)->global_proxy(),
    1058             :                             it->isolate());
    1059             :         }
    1060             :         MaybeHandle<Object> result =
    1061             :             JSProxy::GetProperty(it->isolate(), it->GetHolder<JSProxy>(),
    1062      209815 :                                  it->GetName(), receiver, &was_found);
    1063      209815 :         if (!was_found) it->NotFound();
    1064      209815 :         return result;
    1065             :       }
    1066             :       case LookupIterator::INTERCEPTOR: {
    1067             :         bool done;
    1068             :         Handle<Object> result;
    1069      251320 :         ASSIGN_RETURN_ON_EXCEPTION(
    1070             :             it->isolate(), result,
    1071             :             JSObject::GetPropertyWithInterceptor(it, &done), Object);
    1072      125642 :         if (done) return result;
    1073      122448 :         break;
    1074             :       }
    1075             :       case LookupIterator::ACCESS_CHECK:
    1076      671026 :         if (it->HasAccess()) break;
    1077        1174 :         return JSObject::GetPropertyWithFailedAccessCheck(it);
    1078             :       case LookupIterator::ACCESSOR:
    1079      916412 :         return GetPropertyWithAccessor(it);
    1080             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1081        2798 :         return it->isolate()->factory()->undefined_value();
    1082             :       case LookupIterator::DATA:
    1083    19129746 :         return it->GetDataValue();
    1084             :     }
    1085             :   }
    1086             : 
    1087    21832839 :   if (on_non_existent == OnNonExistent::kThrowReferenceError) {
    1088          70 :     THROW_NEW_ERROR(it->isolate(),
    1089             :                     NewReferenceError(MessageTemplate::kNotDefined, it->name()),
    1090             :                     Object);
    1091             :   }
    1092    21832804 :   return it->isolate()->factory()->undefined_value();
    1093             : }
    1094             : 
    1095             : 
    1096             : // static
    1097      209815 : MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate,
    1098             :                                          Handle<JSProxy> proxy,
    1099             :                                          Handle<Name> name,
    1100             :                                          Handle<Object> receiver,
    1101             :                                          bool* was_found) {
    1102      209815 :   *was_found = true;
    1103             : 
    1104             :   DCHECK(!name->IsPrivate());
    1105      209815 :   STACK_CHECK(isolate, MaybeHandle<Object>());
    1106             :   Handle<Name> trap_name = isolate->factory()->get_string();
    1107             :   // 1. Assert: IsPropertyKey(P) is true.
    1108             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    1109             :   Handle<Object> handler(proxy->handler(), isolate);
    1110             :   // 3. If handler is null, throw a TypeError exception.
    1111             :   // 4. Assert: Type(handler) is Object.
    1112      209653 :   if (proxy->IsRevoked()) {
    1113          72 :     THROW_NEW_ERROR(isolate,
    1114             :                     NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
    1115             :                     Object);
    1116             :   }
    1117             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    1118             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    1119             :   // 6. Let trap be ? GetMethod(handler, "get").
    1120             :   Handle<Object> trap;
    1121      419234 :   ASSIGN_RETURN_ON_EXCEPTION(
    1122             :       isolate, trap,
    1123             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), Object);
    1124             :   // 7. If trap is undefined, then
    1125      178546 :   if (trap->IsUndefined(isolate)) {
    1126             :     // 7.a Return target.[[Get]](P, Receiver).
    1127             :     LookupIterator it =
    1128      146214 :         LookupIterator::PropertyOrElement(isolate, receiver, name, target);
    1129      146214 :     MaybeHandle<Object> result = Object::GetProperty(&it);
    1130      146214 :     *was_found = it.IsFound();
    1131      146214 :     return result;
    1132             :   }
    1133             :   // 8. Let trapResult be ? Call(trap, handler, «target, P, Receiver»).
    1134             :   Handle<Object> trap_result;
    1135       32332 :   Handle<Object> args[] = {target, name, receiver};
    1136       64664 :   ASSIGN_RETURN_ON_EXCEPTION(
    1137             :       isolate, trap_result,
    1138             :       Execution::Call(isolate, trap, handler, arraysize(args), args), Object);
    1139             : 
    1140             :   MaybeHandle<Object> result =
    1141       24574 :       JSProxy::CheckGetSetTrapResult(isolate, name, target, trap_result, kGet);
    1142       24574 :   if (result.is_null()) {
    1143          45 :     return result;
    1144             :   }
    1145             : 
    1146             :   // 11. Return trap_result
    1147       24529 :   return trap_result;
    1148             : }
    1149             : 
    1150             : // static
    1151       27234 : MaybeHandle<Object> JSProxy::CheckGetSetTrapResult(Isolate* isolate,
    1152             :                                                    Handle<Name> name,
    1153             :                                                    Handle<JSReceiver> target,
    1154             :                                                    Handle<Object> trap_result,
    1155             :                                                    AccessKind access_kind) {
    1156             :   // 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
    1157             :   PropertyDescriptor target_desc;
    1158             :   Maybe<bool> target_found =
    1159       27234 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    1160       27234 :   MAYBE_RETURN_NULL(target_found);
    1161             :   // 10. If targetDesc is not undefined, then
    1162       27225 :   if (target_found.FromJust()) {
    1163             :     // 10.a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is
    1164             :     //       false and targetDesc.[[Writable]] is false, then
    1165             :     // 10.a.i. If SameValue(trapResult, targetDesc.[[Value]]) is false,
    1166             :     //        throw a TypeError exception.
    1167        8060 :     bool inconsistent = PropertyDescriptor::IsDataDescriptor(&target_desc) &&
    1168        2435 :                         !target_desc.configurable() &&
    1169       10099 :                         !target_desc.writable() &&
    1170       10099 :                         !trap_result->SameValue(*target_desc.value());
    1171        8438 :     if (inconsistent) {
    1172         239 :       if (access_kind == kGet) {
    1173         108 :         THROW_NEW_ERROR(
    1174             :             isolate,
    1175             :             NewTypeError(MessageTemplate::kProxyGetNonConfigurableData, name,
    1176             :                          target_desc.value(), trap_result),
    1177             :             Object);
    1178             :       } else {
    1179         370 :         isolate->Throw(*isolate->factory()->NewTypeError(
    1180         370 :             MessageTemplate::kProxySetFrozenData, name));
    1181         185 :         return MaybeHandle<Object>();
    1182             :       }
    1183             :     }
    1184             :     // 10.b. If IsAccessorDescriptor(targetDesc) and targetDesc.[[Configurable]]
    1185             :     //       is false and targetDesc.[[Get]] is undefined, then
    1186             :     // 10.b.i. If trapResult is not undefined, throw a TypeError exception.
    1187        8199 :     if (access_kind == kGet) {
    1188           0 :       inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
    1189           0 :                      !target_desc.configurable() &&
    1190        6813 :                      target_desc.get()->IsUndefined(isolate) &&
    1191             :                      !trap_result->IsUndefined(isolate);
    1192             :     } else {
    1193         378 :       inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
    1194        1575 :                      !target_desc.configurable() &&
    1195             :                      target_desc.set()->IsUndefined(isolate);
    1196             :     }
    1197        8199 :     if (inconsistent) {
    1198         189 :       if (access_kind == kGet) {
    1199           0 :         THROW_NEW_ERROR(
    1200             :             isolate,
    1201             :             NewTypeError(MessageTemplate::kProxyGetNonConfigurableAccessor,
    1202             :                          name, trap_result),
    1203             :             Object);
    1204             :       } else {
    1205         378 :         isolate->Throw(*isolate->factory()->NewTypeError(
    1206         378 :             MessageTemplate::kProxySetFrozenAccessor, name));
    1207         189 :         return MaybeHandle<Object>();
    1208             :       }
    1209             :     }
    1210             :   }
    1211       26797 :   return isolate->factory()->undefined_value();
    1212             : }
    1213             : 
    1214             : 
    1215             : 
    1216     8438539 : bool Object::ToInt32(int32_t* value) {
    1217     8438539 :   if (IsSmi()) {
    1218     8438368 :     *value = Smi::ToInt(*this);
    1219     8438368 :     return true;
    1220             :   }
    1221         171 :   if (IsHeapNumber()) {
    1222             :     double num = HeapNumber::cast(*this)->value();
    1223             :     // Check range before conversion to avoid undefined behavior.
    1224         135 :     if (num >= kMinInt && num <= kMaxInt && FastI2D(FastD2I(num)) == num) {
    1225           0 :       *value = FastD2I(num);
    1226           0 :       return true;
    1227             :     }
    1228             :   }
    1229             :   return false;
    1230             : }
    1231             : 
    1232             : // static constexpr object declarations need a definition to make the
    1233             : // compiler happy.
    1234             : constexpr Object Smi::kZero;
    1235             : constexpr Object SharedFunctionInfo::kNoSharedNameSentinel;
    1236             : 
    1237     3710765 : Handle<SharedFunctionInfo> FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(
    1238             :     Isolate* isolate, Handle<FunctionTemplateInfo> info,
    1239             :     MaybeHandle<Name> maybe_name) {
    1240             :   Object current_info = info->shared_function_info();
    1241     3710765 :   if (current_info->IsSharedFunctionInfo()) {
    1242             :     return handle(SharedFunctionInfo::cast(current_info), isolate);
    1243             :   }
    1244             :   Handle<Name> name;
    1245             :   Handle<String> name_string;
    1246     7074590 :   if (maybe_name.ToHandle(&name) && name->IsString()) {
    1247             :     name_string = Handle<String>::cast(name);
    1248      123188 :   } else if (info->class_name()->IsString()) {
    1249             :     name_string = handle(String::cast(info->class_name()), isolate);
    1250             :   } else {
    1251             :     name_string = isolate->factory()->empty_string();
    1252             :   }
    1253             :   FunctionKind function_kind;
    1254     3598887 :   if (info->remove_prototype()) {
    1255             :     function_kind = kConciseMethod;
    1256             :   } else {
    1257             :     function_kind = kNormalFunction;
    1258             :   }
    1259             :   Handle<SharedFunctionInfo> result =
    1260             :       isolate->factory()->NewSharedFunctionInfoForApiFunction(name_string, info,
    1261     7197774 :                                                               function_kind);
    1262             : 
    1263             :   result->set_length(info->length());
    1264             :   result->DontAdaptArguments();
    1265             :   DCHECK(result->IsApiFunction());
    1266             : 
    1267     7197760 :   info->set_shared_function_info(*result);
    1268     3598881 :   return result;
    1269             : }
    1270             : 
    1271        5457 : bool FunctionTemplateInfo::IsTemplateFor(Map map) {
    1272             :   // There is a constraint on the object; check.
    1273        5457 :   if (!map->IsJSObjectMap()) return false;
    1274             :   // Fetch the constructor function of the object.
    1275        5457 :   Object cons_obj = map->GetConstructor();
    1276             :   Object type;
    1277        5457 :   if (cons_obj->IsJSFunction()) {
    1278             :     JSFunction fun = JSFunction::cast(cons_obj);
    1279             :     type = fun->shared()->function_data();
    1280          14 :   } else if (cons_obj->IsFunctionTemplateInfo()) {
    1281             :     type = FunctionTemplateInfo::cast(cons_obj);
    1282             :   } else {
    1283             :     return false;
    1284             :   }
    1285             :   // Iterate through the chain of inheriting function templates to
    1286             :   // see if the required one occurs.
    1287        7611 :   while (type->IsFunctionTemplateInfo()) {
    1288        5369 :     if (type == *this) return true;
    1289        1077 :     type = FunctionTemplateInfo::cast(type)->GetParentTemplate();
    1290             :   }
    1291             :   // Didn't find the required type in the inheritance chain.
    1292             :   return false;
    1293             : }
    1294             : 
    1295             : // static
    1296      569336 : FunctionTemplateRareData FunctionTemplateInfo::AllocateFunctionTemplateRareData(
    1297             :     Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info) {
    1298             :   DCHECK(function_template_info->rare_data()->IsUndefined(isolate));
    1299             :   Handle<Struct> struct_obj = isolate->factory()->NewStruct(
    1300      569336 :       FUNCTION_TEMPLATE_RARE_DATA_TYPE, AllocationType::kOld);
    1301             :   Handle<FunctionTemplateRareData> rare_data =
    1302             :       i::Handle<FunctionTemplateRareData>::cast(struct_obj);
    1303     1138670 :   function_template_info->set_rare_data(*rare_data);
    1304      569336 :   return *rare_data;
    1305             : }
    1306             : 
    1307             : // static
    1308      375670 : Handle<TemplateList> TemplateList::New(Isolate* isolate, int size) {
    1309             :   Handle<FixedArray> list =
    1310      375670 :       isolate->factory()->NewFixedArray(kLengthIndex + size);
    1311      375670 :   list->set(kLengthIndex, Smi::kZero);
    1312      375670 :   return Handle<TemplateList>::cast(list);
    1313             : }
    1314             : 
    1315             : // static
    1316     6271348 : Handle<TemplateList> TemplateList::Add(Isolate* isolate,
    1317             :                                        Handle<TemplateList> list,
    1318             :                                        Handle<i::Object> value) {
    1319             :   STATIC_ASSERT(kFirstElementIndex == 1);
    1320     6271348 :   int index = list->length() + 1;
    1321             :   Handle<i::FixedArray> fixed_array = Handle<FixedArray>::cast(list);
    1322     6271348 :   fixed_array = FixedArray::SetAndGrow(isolate, fixed_array, index, value);
    1323             :   fixed_array->set(kLengthIndex, Smi::FromInt(index));
    1324     6271348 :   return Handle<TemplateList>::cast(fixed_array);
    1325             : }
    1326             : 
    1327             : 
    1328             : // ES6 9.5.1
    1329             : // static
    1330     3728845 : MaybeHandle<Object> JSProxy::GetPrototype(Handle<JSProxy> proxy) {
    1331             :   Isolate* isolate = proxy->GetIsolate();
    1332             :   Handle<String> trap_name = isolate->factory()->getPrototypeOf_string();
    1333             : 
    1334     3728845 :   STACK_CHECK(isolate, MaybeHandle<Object>());
    1335             : 
    1336             :   // 1. Let handler be the value of the [[ProxyHandler]] internal slot.
    1337             :   // 2. If handler is null, throw a TypeError exception.
    1338             :   // 3. Assert: Type(handler) is Object.
    1339             :   // 4. Let target be the value of the [[ProxyTarget]] internal slot.
    1340     3728836 :   if (proxy->IsRevoked()) {
    1341          36 :     THROW_NEW_ERROR(isolate,
    1342             :                     NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
    1343             :                     Object);
    1344             :   }
    1345             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    1346             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    1347             : 
    1348             :   // 5. Let trap be ? GetMethod(handler, "getPrototypeOf").
    1349             :   Handle<Object> trap;
    1350     7457636 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, trap,
    1351             :                              Object::GetMethod(handler, trap_name), Object);
    1352             :   // 6. If trap is undefined, then return target.[[GetPrototypeOf]]().
    1353     3728818 :   if (trap->IsUndefined(isolate)) {
    1354     2806840 :     return JSReceiver::GetPrototype(isolate, target);
    1355             :   }
    1356             :   // 7. Let handlerProto be ? Call(trap, handler, «target»).
    1357             :   Handle<Object> argv[] = {target};
    1358             :   Handle<Object> handler_proto;
    1359     1843956 :   ASSIGN_RETURN_ON_EXCEPTION(
    1360             :       isolate, handler_proto,
    1361             :       Execution::Call(isolate, trap, handler, arraysize(argv), argv), Object);
    1362             :   // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError.
    1363      921906 :   if (!(handler_proto->IsJSReceiver() || handler_proto->IsNull(isolate))) {
    1364          18 :     THROW_NEW_ERROR(isolate,
    1365             :                     NewTypeError(MessageTemplate::kProxyGetPrototypeOfInvalid),
    1366             :                     Object);
    1367             :   }
    1368             :   // 9. Let extensibleTarget be ? IsExtensible(target).
    1369      921870 :   Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
    1370      921870 :   MAYBE_RETURN_NULL(is_extensible);
    1371             :   // 10. If extensibleTarget is true, return handlerProto.
    1372      921870 :   if (is_extensible.FromJust()) return handler_proto;
    1373             :   // 11. Let targetProto be ? target.[[GetPrototypeOf]]().
    1374             :   Handle<Object> target_proto;
    1375           0 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, target_proto,
    1376             :                              JSReceiver::GetPrototype(isolate, target), Object);
    1377             :   // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError.
    1378           0 :   if (!handler_proto->SameValue(*target_proto)) {
    1379           0 :     THROW_NEW_ERROR(
    1380             :         isolate,
    1381             :         NewTypeError(MessageTemplate::kProxyGetPrototypeOfNonExtensible),
    1382             :         Object);
    1383             :   }
    1384             :   // 13. Return handlerProto.
    1385           0 :   return handler_proto;
    1386             : }
    1387             : 
    1388      916751 : MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
    1389             :   Isolate* isolate = it->isolate();
    1390      916751 :   Handle<Object> structure = it->GetAccessors();
    1391             :   Handle<Object> receiver = it->GetReceiver();
    1392             :   // In case of global IC, the receiver is the global object. Replace by the
    1393             :   // global proxy.
    1394      916752 :   if (receiver->IsJSGlobalObject()) {
    1395             :     receiver = handle(JSGlobalObject::cast(*receiver)->global_proxy(), isolate);
    1396             :   }
    1397             : 
    1398             :   // We should never get here to initialize a const with the hole value since a
    1399             :   // const declaration would conflict with the getter.
    1400             :   DCHECK(!structure->IsForeign());
    1401             : 
    1402             :   // API style callbacks.
    1403             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1404      916751 :   if (structure->IsAccessorInfo()) {
    1405      639574 :     Handle<Name> name = it->GetName();
    1406             :     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
    1407      639575 :     if (!info->IsCompatibleReceiver(*receiver)) {
    1408         180 :       THROW_NEW_ERROR(isolate,
    1409             :                       NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
    1410             :                                    name, receiver),
    1411             :                       Object);
    1412             :     }
    1413             : 
    1414      639604 :     if (!info->has_getter()) return isolate->factory()->undefined_value();
    1415             : 
    1416      764998 :     if (info->is_sloppy() && !receiver->IsJSReceiver()) {
    1417          30 :       ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
    1418             :                                  Object::ConvertReceiver(isolate, receiver),
    1419             :                                  Object);
    1420             :     }
    1421             : 
    1422             :     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
    1423      639364 :                                    Just(kDontThrow));
    1424      639364 :     Handle<Object> result = args.CallAccessorGetter(info, name);
    1425      639363 :     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1426      646818 :     if (result.is_null()) return isolate->factory()->undefined_value();
    1427             :     Handle<Object> reboxed_result = handle(*result, isolate);
    1428      630737 :     if (info->replace_on_access() && receiver->IsJSReceiver()) {
    1429          30 :       RETURN_ON_EXCEPTION(isolate,
    1430             :                           Accessors::ReplaceAccessorWithDataProperty(
    1431             :                               receiver, holder, name, result),
    1432             :                           Object);
    1433             :     }
    1434      630722 :     return reboxed_result;
    1435             :   }
    1436             : 
    1437             :   // AccessorPair with 'cached' private property.
    1438      277177 :   if (it->TryLookupCachedProperty()) {
    1439          45 :     return Object::GetProperty(it);
    1440             :   }
    1441             : 
    1442             :   // Regular accessor.
    1443             :   Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate);
    1444      277133 :   if (getter->IsFunctionTemplateInfo()) {
    1445      204142 :     SaveAndSwitchContext save(isolate, *holder->GetCreationContext());
    1446             :     return Builtins::InvokeApiFunction(
    1447             :         isolate, false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0,
    1448      102071 :         nullptr, isolate->factory()->undefined_value());
    1449      175062 :   } else if (getter->IsCallable()) {
    1450             :     // TODO(rossberg): nicer would be to cast to some JSCallable here...
    1451             :     return Object::GetPropertyWithDefinedGetter(
    1452      170753 :         receiver, Handle<JSReceiver>::cast(getter));
    1453             :   }
    1454             :   // Getter is not a function.
    1455        4309 :   return isolate->factory()->undefined_value();
    1456             : }
    1457             : 
    1458             : // static
    1459           0 : Address AccessorInfo::redirect(Address address, AccessorComponent component) {
    1460             :   ApiFunction fun(address);
    1461             :   DCHECK_EQ(ACCESSOR_GETTER, component);
    1462             :   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
    1463      185022 :   return ExternalReference::Create(&fun, type).address();
    1464             : }
    1465             : 
    1466       92533 : Address AccessorInfo::redirected_getter() const {
    1467             :   Address accessor = v8::ToCData<Address>(getter());
    1468       92533 :   if (accessor == kNullAddress) return kNullAddress;
    1469       92511 :   return redirect(accessor, ACCESSOR_GETTER);
    1470             : }
    1471             : 
    1472     3485571 : Address CallHandlerInfo::redirected_callback() const {
    1473             :   Address address = v8::ToCData<Address>(callback());
    1474             :   ApiFunction fun(address);
    1475             :   ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
    1476     6971145 :   return ExternalReference::Create(&fun, type).address();
    1477             : }
    1478             : 
    1479       97521 : bool AccessorInfo::IsCompatibleReceiverMap(Handle<AccessorInfo> info,
    1480             :                                            Handle<Map> map) {
    1481       97521 :   if (!info->HasExpectedReceiverType()) return true;
    1482          60 :   if (!map->IsJSObjectMap()) return false;
    1483         120 :   return FunctionTemplateInfo::cast(info->expected_receiver_type())
    1484          60 :       ->IsTemplateFor(*map);
    1485             : }
    1486             : 
    1487      492252 : Maybe<bool> Object::SetPropertyWithAccessor(
    1488             :     LookupIterator* it, Handle<Object> value,
    1489             :     Maybe<ShouldThrow> maybe_should_throw) {
    1490             :   Isolate* isolate = it->isolate();
    1491      492252 :   Handle<Object> structure = it->GetAccessors();
    1492             :   Handle<Object> receiver = it->GetReceiver();
    1493             :   // In case of global IC, the receiver is the global object. Replace by the
    1494             :   // global proxy.
    1495      492252 :   if (receiver->IsJSGlobalObject()) {
    1496             :     receiver = handle(JSGlobalObject::cast(*receiver)->global_proxy(), isolate);
    1497             :   }
    1498             : 
    1499             :   // We should never get here to initialize a const with the hole value since a
    1500             :   // const declaration would conflict with the setter.
    1501             :   DCHECK(!structure->IsForeign());
    1502             : 
    1503             :   // API style callbacks.
    1504             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1505      492252 :   if (structure->IsAccessorInfo()) {
    1506      248769 :     Handle<Name> name = it->GetName();
    1507             :     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
    1508      248769 :     if (!info->IsCompatibleReceiver(*receiver)) {
    1509         180 :       isolate->Throw(*isolate->factory()->NewTypeError(
    1510         180 :           MessageTemplate::kIncompatibleMethodReceiver, name, receiver));
    1511             :       return Nothing<bool>();
    1512             :     }
    1513             : 
    1514      248679 :     if (!info->has_setter()) {
    1515             :       // TODO(verwaest): We should not get here anymore once all AccessorInfos
    1516             :       // are marked as special_data_property. They cannot both be writable and
    1517             :       // not have a setter.
    1518             :       return Just(true);
    1519             :     }
    1520             : 
    1521      369339 :     if (info->is_sloppy() && !receiver->IsJSReceiver()) {
    1522           0 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1523             :           isolate, receiver, Object::ConvertReceiver(isolate, receiver),
    1524             :           Nothing<bool>());
    1525             :     }
    1526             : 
    1527             :     // The actual type of setter callback is either
    1528             :     // v8::AccessorNameSetterCallback or
    1529             :     // i::Accesors::AccessorNameBooleanSetterCallback, depending on whether the
    1530             :     // AccessorInfo was created by the API or internally (see accessors.cc).
    1531             :     // Here we handle both cases using GenericNamedPropertySetterCallback and
    1532             :     // its Call method.
    1533             :     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
    1534      248613 :                                    maybe_should_throw);
    1535      248613 :     Handle<Object> result = args.CallAccessorSetter(info, name, value);
    1536             :     // In the case of AccessorNameSetterCallback, we know that the result value
    1537             :     // cannot have been set, so the result of Call will be null.  In the case of
    1538             :     // AccessorNameBooleanSetterCallback, the result will either be null
    1539             :     // (signalling an exception) or a boolean Oddball.
    1540      248613 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    1541      248394 :     if (result.is_null()) return Just(true);
    1542             :     DCHECK(result->BooleanValue(isolate) ||
    1543             :            GetShouldThrow(isolate, maybe_should_throw) == kDontThrow);
    1544      255478 :     return Just(result->BooleanValue(isolate));
    1545             :   }
    1546             : 
    1547             :   // Regular accessor.
    1548             :   Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
    1549      243483 :   if (setter->IsFunctionTemplateInfo()) {
    1550        1314 :     SaveAndSwitchContext save(isolate, *holder->GetCreationContext());
    1551         657 :     Handle<Object> argv[] = {value};
    1552        1314 :     RETURN_ON_EXCEPTION_VALUE(
    1553             :         isolate, Builtins::InvokeApiFunction(
    1554             :                      isolate, false, Handle<FunctionTemplateInfo>::cast(setter),
    1555             :                      receiver, arraysize(argv), argv,
    1556             :                      isolate->factory()->undefined_value()),
    1557             :         Nothing<bool>());
    1558             :     return Just(true);
    1559      242826 :   } else if (setter->IsCallable()) {
    1560             :     // TODO(rossberg): nicer would be to cast to some JSCallable here...
    1561             :     return SetPropertyWithDefinedSetter(
    1562      231265 :         receiver, Handle<JSReceiver>::cast(setter), value, maybe_should_throw);
    1563             :   }
    1564             : 
    1565       28790 :   RETURN_FAILURE(isolate, GetShouldThrow(isolate, maybe_should_throw),
    1566             :                  NewTypeError(MessageTemplate::kNoSetterInCallback,
    1567             :                               it->GetName(), it->GetHolder<JSObject>()));
    1568             : }
    1569             : 
    1570      170752 : MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
    1571             :     Handle<Object> receiver,
    1572             :     Handle<JSReceiver> getter) {
    1573             :   Isolate* isolate = getter->GetIsolate();
    1574             : 
    1575             :   // Platforms with simulators like arm/arm64 expose a funny issue. If the
    1576             :   // simulator has a separate JS stack pointer from the C++ stack pointer, it
    1577             :   // can miss C++ stack overflows in the stack guard at the start of JavaScript
    1578             :   // functions. It would be very expensive to check the C++ stack pointer at
    1579             :   // that location. The best solution seems to be to break the impasse by
    1580             :   // adding checks at possible recursion points. What's more, we don't put
    1581             :   // this stack check behind the USE_SIMULATOR define in order to keep
    1582             :   // behavior the same between hardware and simulators.
    1583             :   StackLimitCheck check(isolate);
    1584      170752 :   if (check.JsHasOverflowed()) {
    1585           9 :     isolate->StackOverflow();
    1586           9 :     return MaybeHandle<Object>();
    1587             :   }
    1588             : 
    1589      170743 :   return Execution::Call(isolate, getter, receiver, 0, nullptr);
    1590             : }
    1591             : 
    1592      231265 : Maybe<bool> Object::SetPropertyWithDefinedSetter(
    1593             :     Handle<Object> receiver, Handle<JSReceiver> setter, Handle<Object> value,
    1594             :     Maybe<ShouldThrow> should_throw) {
    1595             :   Isolate* isolate = setter->GetIsolate();
    1596             : 
    1597      231265 :   Handle<Object> argv[] = { value };
    1598      462530 :   RETURN_ON_EXCEPTION_VALUE(isolate, Execution::Call(isolate, setter, receiver,
    1599             :                                                      arraysize(argv), argv),
    1600             :                             Nothing<bool>());
    1601             :   return Just(true);
    1602             : }
    1603             : 
    1604      368959 : Map Object::GetPrototypeChainRootMap(Isolate* isolate) const {
    1605             :   DisallowHeapAllocation no_alloc;
    1606      368959 :   if (IsSmi()) {
    1607       25194 :     Context native_context = isolate->context()->native_context();
    1608       50388 :     return native_context->number_function()->initial_map();
    1609             :   }
    1610             : 
    1611             :   const HeapObject heap_object = HeapObject::cast(*this);
    1612      343765 :   return heap_object->map()->GetPrototypeChainRootMap(isolate);
    1613             : }
    1614             : 
    1615    10217247 : Smi Object::GetOrCreateHash(Isolate* isolate) {
    1616             :   DisallowHeapAllocation no_gc;
    1617    10217247 :   Object hash = Object::GetSimpleHash(*this);
    1618    10217247 :   if (hash->IsSmi()) return Smi::cast(hash);
    1619             : 
    1620             :   DCHECK(IsJSReceiver());
    1621       20494 :   return JSReceiver::cast(*this)->GetOrCreateIdentityHash(isolate);
    1622             : }
    1623             : 
    1624      720835 : bool Object::SameValue(Object other) {
    1625      720835 :   if (other == *this) return true;
    1626             : 
    1627      212198 :   if (IsNumber() && other->IsNumber()) {
    1628             :     double this_value = Number();
    1629             :     double other_value = other->Number();
    1630             :     // SameValue(NaN, NaN) is true.
    1631       21304 :     if (this_value != other_value) {
    1632       18680 :       return std::isnan(this_value) && std::isnan(other_value);
    1633             :     }
    1634             :     // SameValue(0.0, -0.0) is false.
    1635        2624 :     return (std::signbit(this_value) == std::signbit(other_value));
    1636             :   }
    1637      289349 :   if (IsString() && other->IsString()) {
    1638      128281 :     return String::cast(*this)->Equals(String::cast(other));
    1639             :   }
    1640       32199 :   if (IsBigInt() && other->IsBigInt()) {
    1641          27 :     return BigInt::EqualToBigInt(BigInt::cast(*this), BigInt::cast(other));
    1642             :   }
    1643             :   return false;
    1644             : }
    1645             : 
    1646    24242711 : bool Object::SameValueZero(Object other) {
    1647    24242711 :   if (other == *this) return true;
    1648             : 
    1649    28280071 :   if (IsNumber() && other->IsNumber()) {
    1650             :     double this_value = Number();
    1651             :     double other_value = other->Number();
    1652             :     // +0 == -0 is true
    1653     9289151 :     return this_value == other_value ||
    1654           0 :            (std::isnan(this_value) && std::isnan(other_value));
    1655             :   }
    1656    19386984 :   if (IsString() && other->IsString()) {
    1657     9376626 :     return String::cast(*this)->Equals(String::cast(other));
    1658             :   }
    1659      322033 :   if (IsBigInt() && other->IsBigInt()) {
    1660           0 :     return BigInt::EqualToBigInt(BigInt::cast(*this), BigInt::cast(other));
    1661             :   }
    1662             :   return false;
    1663             : }
    1664             : 
    1665       14891 : MaybeHandle<Object> Object::ArraySpeciesConstructor(
    1666             :     Isolate* isolate, Handle<Object> original_array) {
    1667       14891 :   Handle<Object> default_species = isolate->array_function();
    1668       26347 :   if (original_array->IsJSArray() &&
    1669       36506 :       Handle<JSArray>::cast(original_array)->HasArrayPrototype(isolate) &&
    1670             :       isolate->IsArraySpeciesLookupChainIntact()) {
    1671        9189 :     return default_species;
    1672             :   }
    1673             :   Handle<Object> constructor = isolate->factory()->undefined_value();
    1674             :   Maybe<bool> is_array = Object::IsArray(original_array);
    1675        5702 :   MAYBE_RETURN_NULL(is_array);
    1676        5702 :   if (is_array.FromJust()) {
    1677        4642 :     ASSIGN_RETURN_ON_EXCEPTION(
    1678             :         isolate, constructor,
    1679             :         Object::GetProperty(isolate, original_array,
    1680             :                             isolate->factory()->constructor_string()),
    1681             :         Object);
    1682        2312 :     if (constructor->IsConstructor()) {
    1683             :       Handle<Context> constructor_context;
    1684        4000 :       ASSIGN_RETURN_ON_EXCEPTION(
    1685             :           isolate, constructor_context,
    1686             :           JSReceiver::GetFunctionRealm(Handle<JSReceiver>::cast(constructor)),
    1687             :           Object);
    1688        6018 :       if (*constructor_context != *isolate->native_context() &&
    1689        2018 :           *constructor == constructor_context->array_function()) {
    1690             :         constructor = isolate->factory()->undefined_value();
    1691             :       }
    1692             :     }
    1693        2312 :     if (constructor->IsJSReceiver()) {
    1694        4036 :       ASSIGN_RETURN_ON_EXCEPTION(
    1695             :           isolate, constructor,
    1696             :           JSReceiver::GetProperty(isolate,
    1697             :                                   Handle<JSReceiver>::cast(constructor),
    1698             :                                   isolate->factory()->species_symbol()),
    1699             :           Object);
    1700        2009 :       if (constructor->IsNull(isolate)) {
    1701             :         constructor = isolate->factory()->undefined_value();
    1702             :       }
    1703             :     }
    1704             :   }
    1705        5684 :   if (constructor->IsUndefined(isolate)) {
    1706        3702 :     return default_species;
    1707             :   } else {
    1708        1982 :     if (!constructor->IsConstructor()) {
    1709           0 :       THROW_NEW_ERROR(isolate,
    1710             :           NewTypeError(MessageTemplate::kSpeciesNotConstructor),
    1711             :           Object);
    1712             :     }
    1713        1982 :     return constructor;
    1714             :   }
    1715             : }
    1716             : 
    1717             : // ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
    1718         773 : V8_WARN_UNUSED_RESULT MaybeHandle<Object> Object::SpeciesConstructor(
    1719             :     Isolate* isolate, Handle<JSReceiver> recv,
    1720             :     Handle<JSFunction> default_ctor) {
    1721             :   Handle<Object> ctor_obj;
    1722        1546 :   ASSIGN_RETURN_ON_EXCEPTION(
    1723             :       isolate, ctor_obj,
    1724             :       JSObject::GetProperty(isolate, recv,
    1725             :                             isolate->factory()->constructor_string()),
    1726             :       Object);
    1727             : 
    1728         773 :   if (ctor_obj->IsUndefined(isolate)) return default_ctor;
    1729             : 
    1730         764 :   if (!ctor_obj->IsJSReceiver()) {
    1731           0 :     THROW_NEW_ERROR(isolate,
    1732             :                     NewTypeError(MessageTemplate::kConstructorNotReceiver),
    1733             :                     Object);
    1734             :   }
    1735             : 
    1736         764 :   Handle<JSReceiver> ctor = Handle<JSReceiver>::cast(ctor_obj);
    1737             : 
    1738             :   Handle<Object> species;
    1739        1528 :   ASSIGN_RETURN_ON_EXCEPTION(
    1740             :       isolate, species,
    1741             :       JSObject::GetProperty(isolate, ctor,
    1742             :                             isolate->factory()->species_symbol()),
    1743             :       Object);
    1744             : 
    1745         764 :   if (species->IsNullOrUndefined(isolate)) {
    1746           0 :     return default_ctor;
    1747             :   }
    1748             : 
    1749         764 :   if (species->IsConstructor()) return species;
    1750             : 
    1751           0 :   THROW_NEW_ERROR(
    1752             :       isolate, NewTypeError(MessageTemplate::kSpeciesNotConstructor), Object);
    1753             : }
    1754             : 
    1755           0 : bool Object::IterationHasObservableEffects() {
    1756             :   // Check that this object is an array.
    1757           0 :   if (!IsJSArray()) return true;
    1758           0 :   JSArray array = JSArray::cast(*this);
    1759             :   Isolate* isolate = array->GetIsolate();
    1760             : 
    1761             : #ifdef V8_ENABLE_FORCE_SLOW_PATH
    1762             :   if (isolate->force_slow_path()) return true;
    1763             : #endif
    1764             : 
    1765             :   // Check that we have the original ArrayPrototype.
    1766           0 :   if (!array->map()->prototype()->IsJSObject()) return true;
    1767           0 :   JSObject array_proto = JSObject::cast(array->map()->prototype());
    1768           0 :   if (!isolate->is_initial_array_prototype(array_proto)) return true;
    1769             : 
    1770             :   // Check that the ArrayPrototype hasn't been modified in a way that would
    1771             :   // affect iteration.
    1772           0 :   if (!isolate->IsArrayIteratorLookupChainIntact()) return true;
    1773             : 
    1774             :   // For FastPacked kinds, iteration will have the same effect as simply
    1775             :   // accessing each property in order.
    1776           0 :   ElementsKind array_kind = array->GetElementsKind();
    1777           0 :   if (IsFastPackedElementsKind(array_kind)) return false;
    1778             : 
    1779             :   // For FastHoley kinds, an element access on a hole would cause a lookup on
    1780             :   // the prototype. This could have different results if the prototype has been
    1781             :   // changed.
    1782           0 :   if (IsHoleyElementsKind(array_kind) &&
    1783           0 :       isolate->IsNoElementsProtectorIntact()) {
    1784             :     return false;
    1785             :   }
    1786           0 :   return true;
    1787             : }
    1788             : 
    1789        6816 : void Object::ShortPrint(FILE* out) const {
    1790       13632 :   OFStream os(out);
    1791        6816 :   os << Brief(*this);
    1792        6816 : }
    1793             : 
    1794       13970 : void Object::ShortPrint(StringStream* accumulator) const {
    1795       27940 :   std::ostringstream os;
    1796       13970 :   os << Brief(*this);
    1797       27940 :   accumulator->Add(os.str().c_str());
    1798       13970 : }
    1799             : 
    1800       86104 : void Object::ShortPrint(std::ostream& os) const { os << Brief(*this); }
    1801             : 
    1802           2 : std::ostream& operator<<(std::ostream& os, const Object& obj) {
    1803             :   obj.ShortPrint(os);
    1804           2 :   return os;
    1805             : }
    1806             : 
    1807           0 : void MaybeObject::ShortPrint(FILE* out) {
    1808           0 :   OFStream os(out);
    1809           0 :   os << Brief(*this);
    1810           0 : }
    1811             : 
    1812           0 : void MaybeObject::ShortPrint(StringStream* accumulator) {
    1813           0 :   std::ostringstream os;
    1814           0 :   os << Brief(*this);
    1815           0 :   accumulator->Add(os.str().c_str());
    1816           0 : }
    1817             : 
    1818           0 : void MaybeObject::ShortPrint(std::ostream& os) { os << Brief(*this); }
    1819             : 
    1820      292151 : Brief::Brief(const Object v) : value(v->ptr()) {}
    1821           0 : Brief::Brief(const MaybeObject v) : value(v.ptr()) {}
    1822             : 
    1823      177995 : std::ostream& operator<<(std::ostream& os, const Brief& v) {
    1824      177995 :   MaybeObject maybe_object(v.value);
    1825             :   Smi smi;
    1826      177995 :   HeapObject heap_object;
    1827      177995 :   if (maybe_object->ToSmi(&smi)) {
    1828             :     smi->SmiPrint(os);
    1829      159401 :   } else if (maybe_object->IsCleared()) {
    1830           0 :     os << "[cleared]";
    1831      159401 :   } else if (maybe_object->GetHeapObjectIfWeak(&heap_object)) {
    1832           0 :     os << "[weak] ";
    1833           0 :     heap_object->HeapObjectShortPrint(os);
    1834      159401 :   } else if (maybe_object->GetHeapObjectIfStrong(&heap_object)) {
    1835      159401 :     heap_object->HeapObjectShortPrint(os);
    1836             :   } else {
    1837           0 :     UNREACHABLE();
    1838             :   }
    1839      177995 :   return os;
    1840             : }
    1841             : 
    1842         725 : void Smi::SmiPrint(std::ostream& os) const {  // NOLINT
    1843       19319 :   os << value();
    1844         725 : }
    1845             : 
    1846             : 
    1847             : 
    1848      159401 : void HeapObject::HeapObjectShortPrint(std::ostream& os) {  // NOLINT
    1849      159401 :   os << AsHex::Address(this->ptr()) << " ";
    1850             : 
    1851      159401 :   if (IsString()) {
    1852             :     HeapStringAllocator allocator;
    1853             :     StringStream accumulator(&allocator);
    1854       39039 :     String::cast(*this)->StringShortPrint(&accumulator);
    1855      117117 :     os << accumulator.ToCString().get();
    1856             :     return;
    1857             :   }
    1858      120362 :   if (IsJSObject()) {
    1859             :     HeapStringAllocator allocator;
    1860             :     StringStream accumulator(&allocator);
    1861       34856 :     JSObject::cast(*this)->JSObjectShortPrint(&accumulator);
    1862      104568 :     os << accumulator.ToCString().get();
    1863             :     return;
    1864             :   }
    1865       85506 :   switch (map()->instance_type()) {
    1866             :     case MAP_TYPE: {
    1867        1780 :       os << "<Map";
    1868             :       Map mapInstance = Map::cast(*this);
    1869        1780 :       if (mapInstance->IsJSObjectMap()) {
    1870        3508 :         os << "(" << ElementsKindToString(mapInstance->elements_kind()) << ")";
    1871          26 :       } else if (mapInstance->instance_size() != kVariableSizeSentinel) {
    1872          26 :         os << "[" << mapInstance->instance_size() << "]";
    1873             :       }
    1874        1780 :       os << ">";
    1875        1780 :     } break;
    1876             :     case AWAIT_CONTEXT_TYPE: {
    1877           0 :       os << "<AwaitContext generator= ";
    1878             :       HeapStringAllocator allocator;
    1879             :       StringStream accumulator(&allocator);
    1880           0 :       Context::cast(*this)->extension()->ShortPrint(&accumulator);
    1881           0 :       os << accumulator.ToCString().get();
    1882             :       os << '>';
    1883             :       break;
    1884             :     }
    1885             :     case BLOCK_CONTEXT_TYPE:
    1886           0 :       os << "<BlockContext[" << Context::cast(*this)->length() << "]>";
    1887           0 :       break;
    1888             :     case CATCH_CONTEXT_TYPE:
    1889           0 :       os << "<CatchContext[" << Context::cast(*this)->length() << "]>";
    1890           0 :       break;
    1891             :     case DEBUG_EVALUATE_CONTEXT_TYPE:
    1892           0 :       os << "<DebugEvaluateContext[" << Context::cast(*this)->length() << "]>";
    1893           0 :       break;
    1894             :     case EVAL_CONTEXT_TYPE:
    1895           0 :       os << "<EvalContext[" << Context::cast(*this)->length() << "]>";
    1896           0 :       break;
    1897             :     case FUNCTION_CONTEXT_TYPE:
    1898           0 :       os << "<FunctionContext[" << Context::cast(*this)->length() << "]>";
    1899           0 :       break;
    1900             :     case MODULE_CONTEXT_TYPE:
    1901           0 :       os << "<ModuleContext[" << Context::cast(*this)->length() << "]>";
    1902           0 :       break;
    1903             :     case NATIVE_CONTEXT_TYPE:
    1904         574 :       os << "<NativeContext[" << Context::cast(*this)->length() << "]>";
    1905         574 :       break;
    1906             :     case SCRIPT_CONTEXT_TYPE:
    1907           0 :       os << "<ScriptContext[" << Context::cast(*this)->length() << "]>";
    1908           0 :       break;
    1909             :     case WITH_CONTEXT_TYPE:
    1910           0 :       os << "<WithContext[" << Context::cast(*this)->length() << "]>";
    1911           0 :       break;
    1912             :     case SCRIPT_CONTEXT_TABLE_TYPE:
    1913           0 :       os << "<ScriptContextTable[" << FixedArray::cast(*this)->length() << "]>";
    1914           0 :       break;
    1915             :     case HASH_TABLE_TYPE:
    1916           0 :       os << "<HashTable[" << FixedArray::cast(*this)->length() << "]>";
    1917           0 :       break;
    1918             :     case ORDERED_HASH_MAP_TYPE:
    1919           0 :       os << "<OrderedHashMap[" << FixedArray::cast(*this)->length() << "]>";
    1920           0 :       break;
    1921             :     case ORDERED_HASH_SET_TYPE:
    1922           0 :       os << "<OrderedHashSet[" << FixedArray::cast(*this)->length() << "]>";
    1923           0 :       break;
    1924             :     case ORDERED_NAME_DICTIONARY_TYPE:
    1925           0 :       os << "<OrderedNameDictionary[" << FixedArray::cast(*this)->length()
    1926           0 :          << "]>";
    1927           0 :       break;
    1928             :     case NAME_DICTIONARY_TYPE:
    1929           0 :       os << "<NameDictionary[" << FixedArray::cast(*this)->length() << "]>";
    1930           0 :       break;
    1931             :     case GLOBAL_DICTIONARY_TYPE:
    1932           0 :       os << "<GlobalDictionary[" << FixedArray::cast(*this)->length() << "]>";
    1933           0 :       break;
    1934             :     case NUMBER_DICTIONARY_TYPE:
    1935           0 :       os << "<NumberDictionary[" << FixedArray::cast(*this)->length() << "]>";
    1936           0 :       break;
    1937             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
    1938           0 :       os << "<SimpleNumberDictionary[" << FixedArray::cast(*this)->length()
    1939           0 :          << "]>";
    1940           0 :       break;
    1941             :     case STRING_TABLE_TYPE:
    1942           0 :       os << "<StringTable[" << FixedArray::cast(*this)->length() << "]>";
    1943           0 :       break;
    1944             :     case FIXED_ARRAY_TYPE:
    1945           0 :       os << "<FixedArray[" << FixedArray::cast(*this)->length() << "]>";
    1946           0 :       break;
    1947             :     case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
    1948             :       os << "<ObjectBoilerplateDescription["
    1949          28 :          << FixedArray::cast(*this)->length() << "]>";
    1950          28 :       break;
    1951             :     case FIXED_DOUBLE_ARRAY_TYPE:
    1952           0 :       os << "<FixedDoubleArray[" << FixedDoubleArray::cast(*this)->length()
    1953           0 :          << "]>";
    1954           0 :       break;
    1955             :     case BYTE_ARRAY_TYPE:
    1956           0 :       os << "<ByteArray[" << ByteArray::cast(*this)->length() << "]>";
    1957           0 :       break;
    1958             :     case BYTECODE_ARRAY_TYPE:
    1959         240 :       os << "<BytecodeArray[" << BytecodeArray::cast(*this)->length() << "]>";
    1960         240 :       break;
    1961             :     case DESCRIPTOR_ARRAY_TYPE:
    1962             :       os << "<DescriptorArray["
    1963       31542 :          << DescriptorArray::cast(*this)->number_of_descriptors() << "]>";
    1964       15771 :       break;
    1965             :     case TRANSITION_ARRAY_TYPE:
    1966         125 :       os << "<TransitionArray[" << TransitionArray::cast(*this)->length()
    1967         125 :          << "]>";
    1968         125 :       break;
    1969             :     case PROPERTY_ARRAY_TYPE:
    1970           0 :       os << "<PropertyArray[" << PropertyArray::cast(*this)->length() << "]>";
    1971           0 :       break;
    1972             :     case FEEDBACK_CELL_TYPE: {
    1973             :       {
    1974             :         ReadOnlyRoots roots = GetReadOnlyRoots();
    1975           0 :         os << "<FeedbackCell[";
    1976           0 :         if (map() == roots.no_closures_cell_map()) {
    1977           0 :           os << "no feedback";
    1978           0 :         } else if (map() == roots.no_closures_cell_map()) {
    1979           0 :           os << "no closures";
    1980           0 :         } else if (map() == roots.one_closure_cell_map()) {
    1981           0 :           os << "one closure";
    1982           0 :         } else if (map() == roots.many_closures_cell_map()) {
    1983           0 :           os << "many closures";
    1984             :         } else {
    1985           0 :           os << "!!!INVALID MAP!!!";
    1986             :         }
    1987           0 :         os << "]>";
    1988             :       }
    1989           0 :       break;
    1990             :     }
    1991             :     case FEEDBACK_VECTOR_TYPE:
    1992           0 :       os << "<FeedbackVector[" << FeedbackVector::cast(*this)->length() << "]>";
    1993           0 :       break;
    1994             :     case FREE_SPACE_TYPE:
    1995           0 :       os << "<FreeSpace[" << FreeSpace::cast(*this)->size() << "]>";
    1996           0 :       break;
    1997             : #define TYPED_ARRAY_SHORT_PRINT(Type, type, TYPE, ctype)                       \
    1998             :   case FIXED_##TYPE##_ARRAY_TYPE:                                              \
    1999             :     os << "<Fixed" #Type "Array[" << Fixed##Type##Array::cast(*this)->length() \
    2000             :        << "]>";                                                                \
    2001             :     break;
    2002             : 
    2003           0 :       TYPED_ARRAYS(TYPED_ARRAY_SHORT_PRINT)
    2004             : #undef TYPED_ARRAY_SHORT_PRINT
    2005             : 
    2006             :     case PREPARSE_DATA_TYPE: {
    2007             :       PreparseData data = PreparseData::cast(*this);
    2008           0 :       os << "<PreparseData[data=" << data->data_length()
    2009           0 :          << " children=" << data->children_length() << "]>";
    2010             :       break;
    2011             :     }
    2012             : 
    2013             :     case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE: {
    2014             :       UncompiledDataWithoutPreparseData data =
    2015             :           UncompiledDataWithoutPreparseData::cast(*this);
    2016           0 :       os << "<UncompiledDataWithoutPreparseData (" << data->start_position()
    2017           0 :          << ", " << data->end_position() << ")]>";
    2018             :       break;
    2019             :     }
    2020             : 
    2021             :     case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE: {
    2022             :       UncompiledDataWithPreparseData data =
    2023             :           UncompiledDataWithPreparseData::cast(*this);
    2024           0 :       os << "<UncompiledDataWithPreparseData (" << data->start_position()
    2025           0 :          << ", " << data->end_position()
    2026           0 :          << ") preparsed=" << Brief(data->preparse_data()) << ">";
    2027             :       break;
    2028             :     }
    2029             : 
    2030             :     case SHARED_FUNCTION_INFO_TYPE: {
    2031          74 :       SharedFunctionInfo shared = SharedFunctionInfo::cast(*this);
    2032          74 :       std::unique_ptr<char[]> debug_name = shared->DebugName()->ToCString();
    2033          74 :       if (debug_name[0] != 0) {
    2034          74 :         os << "<SharedFunctionInfo " << debug_name.get() << ">";
    2035             :       } else {
    2036           0 :         os << "<SharedFunctionInfo>";
    2037             :       }
    2038             :       break;
    2039             :     }
    2040             :     case JS_MESSAGE_OBJECT_TYPE:
    2041           0 :       os << "<JSMessageObject>";
    2042           0 :       break;
    2043             : #define MAKE_STRUCT_CASE(TYPE, Name, name)    \
    2044             :   case TYPE:                                  \
    2045             :     os << "<" #Name;                          \
    2046             :     Name::cast(*this)->BriefPrintDetails(os); \
    2047             :     os << ">";                                \
    2048             :     break;
    2049           0 :       STRUCT_LIST(MAKE_STRUCT_CASE)
    2050             : #undef MAKE_STRUCT_CASE
    2051             :     case ALLOCATION_SITE_TYPE: {
    2052           0 :       os << "<AllocationSite";
    2053             :       AllocationSite::cast(*this)->BriefPrintDetails(os);
    2054           0 :       os << ">";
    2055           0 :       break;
    2056             :     }
    2057             :     case SCOPE_INFO_TYPE: {
    2058           0 :       ScopeInfo scope = ScopeInfo::cast(*this);
    2059           0 :       os << "<ScopeInfo";
    2060           0 :       if (scope->length()) os << " " << scope->scope_type() << " ";
    2061           0 :       os << "[" << scope->length() << "]>";
    2062             :       break;
    2063             :     }
    2064             :     case CODE_TYPE: {
    2065             :       Code code = Code::cast(*this);
    2066          98 :       os << "<Code " << Code::Kind2String(code->kind());
    2067          49 :       if (code->is_builtin()) {
    2068          98 :         os << " " << Builtins::name(code->builtin_index());
    2069             :       }
    2070          49 :       os << ">";
    2071             :       break;
    2072             :     }
    2073             :     case ODDBALL_TYPE: {
    2074       20942 :       if (IsUndefined()) {
    2075       12286 :         os << "<undefined>";
    2076        8656 :       } else if (IsTheHole()) {
    2077           0 :         os << "<the_hole>";
    2078        8656 :       } else if (IsNull()) {
    2079        6309 :         os << "<null>";
    2080        2347 :       } else if (IsTrue()) {
    2081         105 :         os << "<true>";
    2082        2242 :       } else if (IsFalse()) {
    2083          34 :         os << "<false>";
    2084             :       } else {
    2085        2208 :         os << "<Odd Oddball: ";
    2086        6624 :         os << Oddball::cast(*this)->to_string()->ToCString().get();
    2087        2208 :         os << ">";
    2088             :       }
    2089             :       break;
    2090             :     }
    2091             :     case SYMBOL_TYPE: {
    2092        4276 :       Symbol symbol = Symbol::cast(*this);
    2093        4276 :       symbol->SymbolShortPrint(os);
    2094             :       break;
    2095             :     }
    2096             :     case HEAP_NUMBER_TYPE: {
    2097          79 :       os << "<HeapNumber ";
    2098          79 :       HeapNumber::cast(*this)->HeapNumberPrint(os);
    2099          79 :       os << ">";
    2100          79 :       break;
    2101             :     }
    2102             :     case MUTABLE_HEAP_NUMBER_TYPE: {
    2103           0 :       os << "<MutableHeapNumber ";
    2104           0 :       MutableHeapNumber::cast(*this)->MutableHeapNumberPrint(os);
    2105             :       os << '>';
    2106             :       break;
    2107             :     }
    2108             :     case BIGINT_TYPE: {
    2109           0 :       os << "<BigInt ";
    2110           0 :       BigInt::cast(*this)->BigIntShortPrint(os);
    2111           0 :       os << ">";
    2112           0 :       break;
    2113             :     }
    2114             :     case JS_PROXY_TYPE:
    2115           9 :       os << "<JSProxy>";
    2116           9 :       break;
    2117             :     case FOREIGN_TYPE:
    2118           0 :       os << "<Foreign>";
    2119           0 :       break;
    2120             :     case CELL_TYPE: {
    2121       13104 :       os << "<Cell value= ";
    2122             :       HeapStringAllocator allocator;
    2123             :       StringStream accumulator(&allocator);
    2124       13104 :       Cell::cast(*this)->value()->ShortPrint(&accumulator);
    2125       39312 :       os << accumulator.ToCString().get();
    2126             :       os << '>';
    2127             :       break;
    2128             :     }
    2129             :     case PROPERTY_CELL_TYPE: {
    2130             :       PropertyCell cell = PropertyCell::cast(*this);
    2131           0 :       os << "<PropertyCell name=";
    2132           0 :       cell->name()->ShortPrint(os);
    2133           0 :       os << " value=";
    2134             :       HeapStringAllocator allocator;
    2135             :       StringStream accumulator(&allocator);
    2136           0 :       cell->value()->ShortPrint(&accumulator);
    2137           0 :       os << accumulator.ToCString().get();
    2138             :       os << '>';
    2139             :       break;
    2140             :     }
    2141             :     case CALL_HANDLER_INFO_TYPE: {
    2142           0 :       CallHandlerInfo info = CallHandlerInfo::cast(*this);
    2143           0 :       os << "<CallHandlerInfo ";
    2144           0 :       os << "callback= " << Brief(info->callback());
    2145           0 :       os << ", js_callback= " << Brief(info->js_callback());
    2146           0 :       os << ", data= " << Brief(info->data());
    2147           0 :       if (info->IsSideEffectFreeCallHandlerInfo()) {
    2148           0 :         os << ", side_effect_free= true>";
    2149             :       } else {
    2150           0 :         os << ", side_effect_free= false>";
    2151             :       }
    2152             :       break;
    2153             :     }
    2154             :     default:
    2155       31542 :       os << "<Other heap object (" << map()->instance_type() << ")>";
    2156       15771 :       break;
    2157             :   }
    2158             : }
    2159             : 
    2160           0 : void Struct::BriefPrintDetails(std::ostream& os) {}
    2161             : 
    2162           0 : void Tuple2::BriefPrintDetails(std::ostream& os) {
    2163           0 :   os << " " << Brief(value1()) << ", " << Brief(value2());
    2164           0 : }
    2165             : 
    2166           0 : void Tuple3::BriefPrintDetails(std::ostream& os) {
    2167           0 :   os << " " << Brief(value1()) << ", " << Brief(value2()) << ", "
    2168           0 :      << Brief(value3());
    2169           0 : }
    2170             : 
    2171           0 : void ClassPositions::BriefPrintDetails(std::ostream& os) {
    2172           0 :   os << " " << start() << ", " << end();
    2173           0 : }
    2174             : 
    2175           0 : void ArrayBoilerplateDescription::BriefPrintDetails(std::ostream& os) {
    2176           0 :   os << " " << elements_kind() << ", " << Brief(constant_elements());
    2177           0 : }
    2178             : 
    2179           0 : void CallableTask::BriefPrintDetails(std::ostream& os) {
    2180           0 :   os << " callable=" << Brief(callable());
    2181           0 : }
    2182             : 
    2183    13466481 : void HeapObject::Iterate(ObjectVisitor* v) { IterateFast<ObjectVisitor>(v); }
    2184             : 
    2185             : 
    2186           0 : void HeapObject::IterateBody(ObjectVisitor* v) {
    2187             :   Map m = map();
    2188           0 :   IterateBodyFast<ObjectVisitor>(m, SizeFromMap(m), v);
    2189           0 : }
    2190             : 
    2191     1922718 : void HeapObject::IterateBody(Map map, int object_size, ObjectVisitor* v) {
    2192             :   IterateBodyFast<ObjectVisitor>(map, object_size, v);
    2193     1922718 : }
    2194             : 
    2195             : 
    2196             : struct CallIsValidSlot {
    2197             :   template <typename BodyDescriptor>
    2198             :   static bool apply(Map map, HeapObject obj, int offset, int) {
    2199           0 :     return BodyDescriptor::IsValidSlot(map, obj, offset);
    2200             :   }
    2201             : };
    2202             : 
    2203      791825 : bool HeapObject::IsValidSlot(Map map, int offset) {
    2204             :   DCHECK_NE(0, offset);
    2205      791825 :   return BodyDescriptorApply<CallIsValidSlot, bool>(map->instance_type(), map,
    2206      791825 :                                                     *this, offset, 0);
    2207             : }
    2208             : 
    2209  2117638385 : int HeapObject::SizeFromMap(Map map) const {
    2210             :   int instance_size = map->instance_size();
    2211  2117638385 :   if (instance_size != kVariableSizeSentinel) return instance_size;
    2212             :   // Only inline the most frequent cases.
    2213             :   InstanceType instance_type = map->instance_type();
    2214   962145204 :   if (IsInRange(instance_type, FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE)) {
    2215             :     return FixedArray::SizeFor(
    2216             :         FixedArray::unchecked_cast(*this)->synchronized_length());
    2217             :   }
    2218   892535841 :   if (IsInRange(instance_type, FIRST_CONTEXT_TYPE, LAST_CONTEXT_TYPE)) {
    2219             :     // Native context has fixed size.
    2220             :     DCHECK_NE(instance_type, NATIVE_CONTEXT_TYPE);
    2221             :     return Context::SizeFor(Context::unchecked_cast(*this)->length());
    2222             :   }
    2223  1776325118 :   if (instance_type == EMPTY_STRING_TYPE ||
    2224  1677190520 :       instance_type == ONE_BYTE_STRING_TYPE ||
    2225             :       instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) {
    2226             :     // Strings may get concurrently truncated, hence we have to access its
    2227             :     // length synchronized.
    2228             :     return SeqOneByteString::SizeFor(
    2229             :         SeqOneByteString::unchecked_cast(*this)->synchronized_length());
    2230             :   }
    2231   660752890 :   if (instance_type == BYTE_ARRAY_TYPE) {
    2232             :     return ByteArray::SizeFor(
    2233             :         ByteArray::unchecked_cast(*this)->synchronized_length());
    2234             :   }
    2235   640518977 :   if (instance_type == BYTECODE_ARRAY_TYPE) {
    2236             :     return BytecodeArray::SizeFor(
    2237             :         BytecodeArray::unchecked_cast(*this)->synchronized_length());
    2238             :   }
    2239   631832955 :   if (instance_type == FREE_SPACE_TYPE) {
    2240             :     return FreeSpace::unchecked_cast(*this)->relaxed_read_size();
    2241             :   }
    2242  1261368894 :   if (instance_type == STRING_TYPE ||
    2243   630684447 :       instance_type == INTERNALIZED_STRING_TYPE) {
    2244             :     // Strings may get concurrently truncated, hence we have to access its
    2245             :     // length synchronized.
    2246             :     return SeqTwoByteString::SizeFor(
    2247             :         SeqTwoByteString::unchecked_cast(*this)->synchronized_length());
    2248             :   }
    2249   525274055 :   if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
    2250             :     return FixedDoubleArray::SizeFor(
    2251             :         FixedDoubleArray::unchecked_cast(*this)->synchronized_length());
    2252             :   }
    2253   524488295 :   if (instance_type == FEEDBACK_METADATA_TYPE) {
    2254             :     return FeedbackMetadata::SizeFor(
    2255             :         FeedbackMetadata::unchecked_cast(*this)->synchronized_slot_count());
    2256             :   }
    2257   519186329 :   if (instance_type == DESCRIPTOR_ARRAY_TYPE) {
    2258    76174694 :     return DescriptorArray::SizeFor(
    2259             :         DescriptorArray::unchecked_cast(*this)->number_of_all_descriptors());
    2260             :   }
    2261   443011635 :   if (IsInRange(instance_type, FIRST_WEAK_FIXED_ARRAY_TYPE,
    2262             :                 LAST_WEAK_FIXED_ARRAY_TYPE)) {
    2263             :     return WeakFixedArray::SizeFor(
    2264             :         WeakFixedArray::unchecked_cast(*this)->synchronized_length());
    2265             :   }
    2266   432146707 :   if (instance_type == WEAK_ARRAY_LIST_TYPE) {
    2267             :     return WeakArrayList::SizeForCapacity(
    2268             :         WeakArrayList::unchecked_cast(*this)->synchronized_capacity());
    2269             :   }
    2270   428099944 :   if (IsInRange(instance_type, FIRST_FIXED_TYPED_ARRAY_TYPE,
    2271             :                 LAST_FIXED_TYPED_ARRAY_TYPE)) {
    2272     1081651 :     return FixedTypedArrayBase::unchecked_cast(*this)->TypedArraySize(
    2273             :         instance_type);
    2274             :   }
    2275   427559104 :   if (instance_type == SMALL_ORDERED_HASH_SET_TYPE) {
    2276             :     return SmallOrderedHashSet::SizeFor(
    2277             :         SmallOrderedHashSet::unchecked_cast(*this)->Capacity());
    2278             :   }
    2279   427559104 :   if (instance_type == SMALL_ORDERED_HASH_MAP_TYPE) {
    2280             :     return SmallOrderedHashMap::SizeFor(
    2281             :         SmallOrderedHashMap::unchecked_cast(*this)->Capacity());
    2282             :   }
    2283   427559104 :   if (instance_type == SMALL_ORDERED_NAME_DICTIONARY_TYPE) {
    2284             :     return SmallOrderedNameDictionary::SizeFor(
    2285             :         SmallOrderedNameDictionary::unchecked_cast(*this)->Capacity());
    2286             :   }
    2287   427559104 :   if (instance_type == PROPERTY_ARRAY_TYPE) {
    2288             :     return PropertyArray::SizeFor(
    2289             :         PropertyArray::cast(*this)->synchronized_length());
    2290             :   }
    2291   384497322 :   if (instance_type == FEEDBACK_VECTOR_TYPE) {
    2292             :     return FeedbackVector::SizeFor(
    2293             :         FeedbackVector::unchecked_cast(*this)->length());
    2294             :   }
    2295   369428683 :   if (instance_type == BIGINT_TYPE) {
    2296             :     return BigInt::SizeFor(BigInt::unchecked_cast(*this)->length());
    2297             :   }
    2298   369418259 :   if (instance_type == PREPARSE_DATA_TYPE) {
    2299             :     PreparseData data = PreparseData::unchecked_cast(*this);
    2300             :     return PreparseData::SizeFor(data->data_length(), data->children_length());
    2301             :   }
    2302   369230307 :   if (instance_type == CODE_TYPE) {
    2303   737440281 :     return Code::unchecked_cast(*this)->CodeSize();
    2304             :   }
    2305             :   DCHECK_EQ(instance_type, EMBEDDER_DATA_ARRAY_TYPE);
    2306             :   return EmbedderDataArray::SizeFor(
    2307             :       EmbedderDataArray::unchecked_cast(*this)->length());
    2308             : }
    2309             : 
    2310   377314303 : bool HeapObject::NeedsRehashing() const {
    2311   377314303 :   switch (map()->instance_type()) {
    2312             :     case DESCRIPTOR_ARRAY_TYPE:
    2313    16460771 :       return DescriptorArray::cast(*this)->number_of_descriptors() > 1;
    2314             :     case TRANSITION_ARRAY_TYPE:
    2315     1268488 :       return TransitionArray::cast(*this)->number_of_entries() > 1;
    2316             :     case ORDERED_HASH_MAP_TYPE:
    2317       61683 :       return OrderedHashMap::cast(*this)->NumberOfElements() > 0;
    2318             :     case ORDERED_HASH_SET_TYPE:
    2319       61678 :       return OrderedHashSet::cast(*this)->NumberOfElements() > 0;
    2320             :     case NAME_DICTIONARY_TYPE:
    2321             :     case GLOBAL_DICTIONARY_TYPE:
    2322             :     case NUMBER_DICTIONARY_TYPE:
    2323             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
    2324             :     case STRING_TABLE_TYPE:
    2325             :     case HASH_TABLE_TYPE:
    2326             :     case SMALL_ORDERED_HASH_MAP_TYPE:
    2327             :     case SMALL_ORDERED_HASH_SET_TYPE:
    2328             :     case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
    2329             :       return true;
    2330             :     default:
    2331   359731757 :       return false;
    2332             :   }
    2333             : }
    2334             : 
    2335       38184 : bool HeapObject::CanBeRehashed() const {
    2336             :   DCHECK(NeedsRehashing());
    2337       38184 :   switch (map()->instance_type()) {
    2338             :     case ORDERED_HASH_MAP_TYPE:
    2339             :     case ORDERED_HASH_SET_TYPE:
    2340             :     case ORDERED_NAME_DICTIONARY_TYPE:
    2341             :       // TODO(yangguo): actually support rehashing OrderedHash{Map,Set}.
    2342             :       return false;
    2343             :     case NAME_DICTIONARY_TYPE:
    2344             :     case GLOBAL_DICTIONARY_TYPE:
    2345             :     case NUMBER_DICTIONARY_TYPE:
    2346             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
    2347             :     case STRING_TABLE_TYPE:
    2348        1315 :       return true;
    2349             :     case DESCRIPTOR_ARRAY_TYPE:
    2350       36859 :       return true;
    2351             :     case TRANSITION_ARRAY_TYPE:
    2352           5 :       return true;
    2353             :     case SMALL_ORDERED_HASH_MAP_TYPE:
    2354           0 :       return SmallOrderedHashMap::cast(*this)->NumberOfElements() == 0;
    2355             :     case SMALL_ORDERED_HASH_SET_TYPE:
    2356           0 :       return SmallOrderedHashMap::cast(*this)->NumberOfElements() == 0;
    2357             :     case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
    2358           0 :       return SmallOrderedNameDictionary::cast(*this)->NumberOfElements() == 0;
    2359             :     default:
    2360             :       return false;
    2361             :   }
    2362             :   return false;
    2363             : }
    2364             : 
    2365    45570560 : void HeapObject::RehashBasedOnMap(ReadOnlyRoots roots) {
    2366    45570560 :   switch (map()->instance_type()) {
    2367             :     case HASH_TABLE_TYPE:
    2368           0 :       UNREACHABLE();
    2369             :       break;
    2370             :     case NAME_DICTIONARY_TYPE:
    2371       61473 :       NameDictionary::cast(*this)->Rehash(roots);
    2372       61472 :       break;
    2373             :     case GLOBAL_DICTIONARY_TYPE:
    2374       90364 :       GlobalDictionary::cast(*this)->Rehash(roots);
    2375       90364 :       break;
    2376             :     case NUMBER_DICTIONARY_TYPE:
    2377       61423 :       NumberDictionary::cast(*this)->Rehash(roots);
    2378       61423 :       break;
    2379             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
    2380       90364 :       SimpleNumberDictionary::cast(*this)->Rehash(roots);
    2381       90364 :       break;
    2382             :     case STRING_TABLE_TYPE:
    2383       61417 :       StringTable::cast(*this)->Rehash(roots);
    2384       61418 :       break;
    2385             :     case DESCRIPTOR_ARRAY_TYPE:
    2386             :       DCHECK_LE(1, DescriptorArray::cast(*this)->number_of_descriptors());
    2387    14006446 :       DescriptorArray::cast(*this)->Sort();
    2388    14006439 :       break;
    2389             :     case TRANSITION_ARRAY_TYPE:
    2390           5 :       TransitionArray::cast(*this)->Sort();
    2391           5 :       break;
    2392             :     case SMALL_ORDERED_HASH_MAP_TYPE:
    2393             :       DCHECK_EQ(0, SmallOrderedHashMap::cast(*this)->NumberOfElements());
    2394             :       break;
    2395             :     case SMALL_ORDERED_HASH_SET_TYPE:
    2396             :       DCHECK_EQ(0, SmallOrderedHashSet::cast(*this)->NumberOfElements());
    2397             :       break;
    2398             :     case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
    2399             :       DCHECK_EQ(0, SmallOrderedNameDictionary::cast(*this)->NumberOfElements());
    2400             :       break;
    2401             :     case EMPTY_STRING_TYPE:
    2402             :     case INTERNALIZED_STRING_TYPE:
    2403             :     case ONE_BYTE_INTERNALIZED_STRING_TYPE:
    2404             :       // Rare case, rehash read-only space strings before they are sealed.
    2405             :       DCHECK(ReadOnlyHeap::Contains(*this));
    2406    31199165 :       String::cast(*this)->Hash();
    2407    31199171 :       break;
    2408             :     default:
    2409           0 :       UNREACHABLE();
    2410             :   }
    2411    45570559 : }
    2412             : 
    2413      305154 : bool HeapObject::IsExternal(Isolate* isolate) const {
    2414      610308 :   return map()->FindRootMap(isolate) == isolate->heap()->external_map();
    2415             : }
    2416             : 
    2417     5564257 : void DescriptorArray::GeneralizeAllFields() {
    2418     5564257 :   int length = number_of_descriptors();
    2419    15021913 :   for (int i = 0; i < length; i++) {
    2420     4728816 :     PropertyDetails details = GetDetails(i);
    2421             :     details = details.CopyWithRepresentation(Representation::Tagged());
    2422     4728822 :     if (details.location() == kField) {
    2423             :       DCHECK_EQ(kData, details.kind());
    2424             :       details = details.CopyWithConstness(PropertyConstness::kMutable);
    2425     8126112 :       SetValue(i, FieldType::Any());
    2426             :     }
    2427     4728822 :     set(ToDetailsIndex(i), MaybeObject::FromObject(details.AsSmi()));
    2428             :   }
    2429     5564269 : }
    2430             : 
    2431     3834086 : MaybeHandle<Object> Object::SetProperty(Isolate* isolate, Handle<Object> object,
    2432             :                                         Handle<Name> name, Handle<Object> value,
    2433             :                                         StoreOrigin store_origin,
    2434             :                                         Maybe<ShouldThrow> should_throw) {
    2435     3834086 :   LookupIterator it(isolate, object, name);
    2436     7668172 :   MAYBE_RETURN_NULL(SetProperty(&it, value, store_origin, should_throw));
    2437     3833726 :   return value;
    2438             : }
    2439             : 
    2440     6085782 : Maybe<bool> Object::SetPropertyInternal(LookupIterator* it,
    2441             :                                         Handle<Object> value,
    2442             :                                         Maybe<ShouldThrow> should_throw,
    2443             :                                         StoreOrigin store_origin, bool* found) {
    2444     6085782 :   it->UpdateProtector();
    2445             :   DCHECK(it->IsFound());
    2446             : 
    2447             :   // Make sure that the top context does not change when doing callbacks or
    2448             :   // interceptor calls.
    2449             :   AssertNoContextChange ncc(it->isolate());
    2450             : 
    2451      273995 :   do {
    2452     6229461 :     switch (it->state()) {
    2453             :       case LookupIterator::NOT_FOUND:
    2454           0 :         UNREACHABLE();
    2455             : 
    2456             :       case LookupIterator::ACCESS_CHECK:
    2457       81195 :         if (it->HasAccess()) break;
    2458             :         // Check whether it makes sense to reuse the lookup iterator. Here it
    2459             :         // might still call into setters up the prototype chain.
    2460             :         return JSObject::SetPropertyWithFailedAccessCheck(it, value,
    2461         103 :                                                           should_throw);
    2462             : 
    2463             :       case LookupIterator::JSPROXY: {
    2464             :         Handle<Object> receiver = it->GetReceiver();
    2465             :         // In case of global IC, the receiver is the global object. Replace by
    2466             :         // the global proxy.
    2467       56377 :         if (receiver->IsJSGlobalObject()) {
    2468             :           receiver = handle(JSGlobalObject::cast(*receiver)->global_proxy(),
    2469             :                             it->isolate());
    2470             :         }
    2471             :         return JSProxy::SetProperty(it->GetHolder<JSProxy>(), it->GetName(),
    2472       56377 :                                     value, receiver, should_throw);
    2473             :       }
    2474             : 
    2475             :       case LookupIterator::INTERCEPTOR: {
    2476      202314 :         if (it->HolderIsReceiverOrHiddenPrototype()) {
    2477             :           Maybe<bool> result =
    2478      193061 :               JSObject::SetPropertyWithInterceptor(it, should_throw, value);
    2479      386122 :           if (result.IsNothing() || result.FromJust()) return result;
    2480             :         } else {
    2481             :           Maybe<PropertyAttributes> maybe_attributes =
    2482        9253 :               JSObject::GetPropertyAttributesWithInterceptor(it);
    2483       18396 :           if (maybe_attributes.IsNothing()) return Nothing<bool>();
    2484        9253 :           if ((maybe_attributes.FromJust() & READ_ONLY) != 0) {
    2485           0 :             return WriteToReadOnlyProperty(it, value, should_throw);
    2486             :           }
    2487        9253 :           if (maybe_attributes.FromJust() == ABSENT) break;
    2488        9143 :           *found = false;
    2489             :           return Nothing<bool>();
    2490             :         }
    2491             :         break;
    2492             :       }
    2493             : 
    2494             :       case LookupIterator::ACCESSOR: {
    2495      489228 :         if (it->IsReadOnly()) {
    2496        1251 :           return WriteToReadOnlyProperty(it, value, should_throw);
    2497             :         }
    2498      487977 :         Handle<Object> accessors = it->GetAccessors();
    2499      732471 :         if (accessors->IsAccessorInfo() &&
    2500      608657 :             !it->HolderIsReceiverOrHiddenPrototype() &&
    2501             :             AccessorInfo::cast(*accessors)->is_special_data_property()) {
    2502         442 :           *found = false;
    2503             :           return Nothing<bool>();
    2504             :         }
    2505      487535 :         return SetPropertyWithAccessor(it, value, should_throw);
    2506             :       }
    2507             :       case LookupIterator::INTEGER_INDEXED_EXOTIC: {
    2508             :         // IntegerIndexedElementSet converts value to a Number/BigInt prior to
    2509             :         // the bounds check. The bounds check has already happened here, but
    2510             :         // perform the possibly effectful ToNumber (or ToBigInt) operation
    2511             :         // anyways.
    2512             :         auto holder = it->GetHolder<JSTypedArray>();
    2513             :         Handle<Object> throwaway_value;
    2514        6489 :         if (holder->type() == kExternalBigInt64Array ||
    2515        4326 :             holder->type() == kExternalBigUint64Array) {
    2516          36 :           ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2517             :               it->isolate(), throwaway_value,
    2518             :               BigInt::FromObject(it->isolate(), value), Nothing<bool>());
    2519             :         } else {
    2520        4290 :           ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2521             :               it->isolate(), throwaway_value,
    2522             :               Object::ToNumber(it->isolate(), value), Nothing<bool>());
    2523             :         }
    2524             : 
    2525             :         // FIXME: Throw a TypeError if the holder is detached here
    2526             :         // (IntegerIndexedElementSpec step 5).
    2527             : 
    2528             :         // TODO(verwaest): Per spec, we should return false here (steps 6-9
    2529             :         // in IntegerIndexedElementSpec), resulting in an exception being thrown
    2530             :         // on OOB accesses in strict code. Historically, v8 has not done made
    2531             :         // this change due to uncertainty about web compat. (v8:4901)
    2532             :         return Just(true);
    2533             :       }
    2534             : 
    2535             :       case LookupIterator::DATA:
    2536     4902186 :         if (it->IsReadOnly()) {
    2537       26864 :           return WriteToReadOnlyProperty(it, value, should_throw);
    2538             :         }
    2539     4875322 :         if (it->HolderIsReceiverOrHiddenPrototype()) {
    2540     4815923 :           return SetDataProperty(it, value);
    2541             :         }
    2542             :         V8_FALLTHROUGH;
    2543             :       case LookupIterator::TRANSITION:
    2544      555397 :         *found = false;
    2545             :         return Nothing<bool>();
    2546             :     }
    2547      273995 :     it->Next();
    2548             :   } while (it->IsFound());
    2549             : 
    2550      130317 :   *found = false;
    2551             :   return Nothing<bool>();
    2552             : }
    2553             : 
    2554    10878173 : Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
    2555             :                                 StoreOrigin store_origin,
    2556             :                                 Maybe<ShouldThrow> should_throw) {
    2557    10878173 :   if (it->IsFound()) {
    2558     6026064 :     bool found = true;
    2559             :     Maybe<bool> result =
    2560     6026064 :         SetPropertyInternal(it, value, should_throw, store_origin, &found);
    2561     6026058 :     if (found) return result;
    2562             :   }
    2563             : 
    2564             :   // If the receiver is the JSGlobalObject, the store was contextual. In case
    2565             :   // the property did not exist yet on the global object itself, we have to
    2566             :   // throw a reference error in strict mode.  In sloppy mode, we continue.
    2567     5586574 :   if (it->GetReceiver()->IsJSGlobalObject() &&
    2568       41361 :       (GetShouldThrow(it->isolate(), should_throw) ==
    2569             :        ShouldThrow::kThrowOnError)) {
    2570        1116 :     it->isolate()->Throw(*it->isolate()->factory()->NewReferenceError(
    2571        1116 :         MessageTemplate::kNotDefined, it->name()));
    2572             :     return Nothing<bool>();
    2573             :   }
    2574             : 
    2575     5544655 :   return AddDataProperty(it, value, NONE, should_throw, store_origin);
    2576             : }
    2577             : 
    2578       63986 : Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
    2579             :                                      StoreOrigin store_origin,
    2580             :                                      Maybe<ShouldThrow> should_throw) {
    2581             :   Isolate* isolate = it->isolate();
    2582             : 
    2583       63986 :   if (it->IsFound()) {
    2584       59722 :     bool found = true;
    2585             :     Maybe<bool> result =
    2586       59722 :         SetPropertyInternal(it, value, should_throw, store_origin, &found);
    2587       59722 :     if (found) return result;
    2588             :   }
    2589             : 
    2590        6460 :   it->UpdateProtector();
    2591             : 
    2592             :   // The property either doesn't exist on the holder or exists there as a data
    2593             :   // property.
    2594             : 
    2595             : 
    2596        6460 :   if (!it->GetReceiver()->IsJSReceiver()) {
    2597         729 :     return WriteToReadOnlyProperty(it, value, should_throw);
    2598             :   }
    2599             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    2600             : 
    2601             :   LookupIterator::Configuration c = LookupIterator::OWN;
    2602             :   LookupIterator own_lookup =
    2603             :       it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
    2604       11462 :                       : LookupIterator(isolate, receiver, it->name(), c);
    2605             : 
    2606        5803 :   for (; own_lookup.IsFound(); own_lookup.Next()) {
    2607        4367 :     switch (own_lookup.state()) {
    2608             :       case LookupIterator::ACCESS_CHECK:
    2609          41 :         if (!own_lookup.HasAccess()) {
    2610             :           return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value,
    2611           5 :                                                             should_throw);
    2612             :         }
    2613             :         break;
    2614             : 
    2615             :       case LookupIterator::ACCESSOR:
    2616        1962 :         if (own_lookup.GetAccessors()->IsAccessorInfo()) {
    2617           9 :           if (own_lookup.IsReadOnly()) {
    2618           0 :             return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
    2619             :           }
    2620             :           return Object::SetPropertyWithAccessor(&own_lookup, value,
    2621           9 :                                                  should_throw);
    2622             :         }
    2623             :         V8_FALLTHROUGH;
    2624             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    2625             :         return RedefineIncompatibleProperty(isolate, it->GetName(), value,
    2626        1944 :                                             should_throw);
    2627             : 
    2628             :       case LookupIterator::DATA: {
    2629         981 :         if (own_lookup.IsReadOnly()) {
    2630         297 :           return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
    2631             :         }
    2632         684 :         return SetDataProperty(&own_lookup, value);
    2633             :       }
    2634             : 
    2635             :       case LookupIterator::INTERCEPTOR:
    2636             :       case LookupIterator::JSPROXY: {
    2637             :         PropertyDescriptor desc;
    2638             :         Maybe<bool> owned =
    2639        2364 :             JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc);
    2640        2364 :         MAYBE_RETURN(owned, Nothing<bool>());
    2641        1914 :         if (!owned.FromJust()) {
    2642             :           return JSReceiver::CreateDataProperty(&own_lookup, value,
    2643        1014 :                                                 should_throw);
    2644             :         }
    2645        1800 :         if (PropertyDescriptor::IsAccessorDescriptor(&desc) ||
    2646             :             !desc.writable()) {
    2647             :           return RedefineIncompatibleProperty(isolate, it->GetName(), value,
    2648           0 :                                               should_throw);
    2649             :         }
    2650             : 
    2651             :         PropertyDescriptor value_desc;
    2652             :         value_desc.set_value(value);
    2653             :         return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
    2654        1800 :                                              &value_desc, should_throw);
    2655             :       }
    2656             : 
    2657             :       case LookupIterator::NOT_FOUND:
    2658             :       case LookupIterator::TRANSITION:
    2659           0 :         UNREACHABLE();
    2660             :     }
    2661             :   }
    2662             : 
    2663        1400 :   return AddDataProperty(&own_lookup, value, NONE, should_throw, store_origin);
    2664             : }
    2665             : 
    2666        5990 : Maybe<bool> Object::CannotCreateProperty(Isolate* isolate,
    2667             :                                          Handle<Object> receiver,
    2668             :                                          Handle<Object> name,
    2669             :                                          Handle<Object> value,
    2670             :                                          Maybe<ShouldThrow> should_throw) {
    2671        6224 :   RETURN_FAILURE(
    2672             :       isolate, GetShouldThrow(isolate, should_throw),
    2673             :       NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name,
    2674             :                    Object::TypeOf(isolate, receiver), receiver));
    2675             : }
    2676             : 
    2677       29141 : Maybe<bool> Object::WriteToReadOnlyProperty(
    2678             :     LookupIterator* it, Handle<Object> value,
    2679             :     Maybe<ShouldThrow> maybe_should_throw) {
    2680       29141 :   ShouldThrow should_throw = GetShouldThrow(it->isolate(), maybe_should_throw);
    2681       29141 :   if (it->IsFound() && !it->HolderIsReceiver()) {
    2682             :     // "Override mistake" attempted, record a use count to track this per
    2683             :     // v8:8175
    2684             :     v8::Isolate::UseCounterFeature feature =
    2685             :         should_throw == kThrowOnError
    2686             :             ? v8::Isolate::kAttemptOverrideReadOnlyOnPrototypeStrict
    2687       11489 :             : v8::Isolate::kAttemptOverrideReadOnlyOnPrototypeSloppy;
    2688       11489 :     it->isolate()->CountUsage(feature);
    2689             :   }
    2690             :   return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
    2691       58282 :                                  it->GetName(), value, should_throw);
    2692             : }
    2693             : 
    2694       29141 : Maybe<bool> Object::WriteToReadOnlyProperty(Isolate* isolate,
    2695             :                                             Handle<Object> receiver,
    2696             :                                             Handle<Object> name,
    2697             :                                             Handle<Object> value,
    2698             :                                             ShouldThrow should_throw) {
    2699       46727 :   RETURN_FAILURE(isolate, should_throw,
    2700             :                  NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
    2701             :                               Object::TypeOf(isolate, receiver), receiver));
    2702             : }
    2703             : 
    2704         981 : Maybe<bool> Object::RedefineIncompatibleProperty(
    2705             :     Isolate* isolate, Handle<Object> name, Handle<Object> value,
    2706             :     Maybe<ShouldThrow> should_throw) {
    2707        1215 :   RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
    2708             :                  NewTypeError(MessageTemplate::kRedefineDisallowed, name));
    2709             : }
    2710             : 
    2711     5341301 : Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) {
    2712             :   DCHECK_IMPLIES(it->GetReceiver()->IsJSProxy(),
    2713             :                  it->GetName()->IsPrivateName());
    2714             :   DCHECK_IMPLIES(!it->IsElement() && it->GetName()->IsPrivateName(),
    2715             :                  it->state() == LookupIterator::DATA);
    2716             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    2717             : 
    2718             :   // Store on the holder which may be hidden behind the receiver.
    2719             :   DCHECK(it->HolderIsReceiverOrHiddenPrototype());
    2720             : 
    2721     5341301 :   Handle<Object> to_assign = value;
    2722             :   // Convert the incoming value to a number for storing into typed arrays.
    2723    12529774 :   if (it->IsElement() && receiver->IsJSObject() &&
    2724     6264887 :       JSObject::cast(*receiver)->HasFixedTypedArrayElements()) {
    2725      702506 :     ElementsKind elements_kind = JSObject::cast(*receiver)->GetElementsKind();
    2726      702506 :     if (elements_kind == BIGINT64_ELEMENTS ||
    2727             :         elements_kind == BIGUINT64_ELEMENTS) {
    2728         134 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(it->isolate(), to_assign,
    2729             :                                        BigInt::FromObject(it->isolate(), value),
    2730             :                                        Nothing<bool>());
    2731             :       // We have to recheck the length. However, it can only change if the
    2732             :       // underlying buffer was detached, so just check that.
    2733          67 :       if (Handle<JSArrayBufferView>::cast(receiver)->WasDetached()) {
    2734             :         return Just(true);
    2735             :         // TODO(neis): According to the spec, this should throw a TypeError.
    2736             :       }
    2737      703492 :     } else if (!value->IsNumber() && !value->IsUndefined(it->isolate())) {
    2738        1746 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(it->isolate(), to_assign,
    2739             :                                        Object::ToNumber(it->isolate(), value),
    2740             :                                        Nothing<bool>());
    2741             :       // We have to recheck the length. However, it can only change if the
    2742             :       // underlying buffer was detached, so just check that.
    2743         873 :       if (Handle<JSArrayBufferView>::cast(receiver)->WasDetached()) {
    2744             :         return Just(true);
    2745             :         // TODO(neis): According to the spec, this should throw a TypeError.
    2746             :       }
    2747             :     }
    2748             :   }
    2749             : 
    2750             :   // Possibly migrate to the most up-to-date map that will be able to store
    2751             :   // |value| under it->name().
    2752     5341301 :   it->PrepareForDataProperty(to_assign);
    2753             : 
    2754             :   // Write the property value.
    2755     5341301 :   it->WriteDataValue(to_assign, false);
    2756             : 
    2757             : #if VERIFY_HEAP
    2758             :   if (FLAG_verify_heap) {
    2759             :     receiver->HeapObjectVerify(it->isolate());
    2760             :   }
    2761             : #endif
    2762             :   return Just(true);
    2763             : }
    2764             : 
    2765    37708352 : Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
    2766             :                                     PropertyAttributes attributes,
    2767             :                                     Maybe<ShouldThrow> should_throw,
    2768             :                                     StoreOrigin store_origin) {
    2769    37708352 :   if (!it->GetReceiver()->IsJSReceiver()) {
    2770             :     return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
    2771       11980 :                                 value, should_throw);
    2772             :   }
    2773             : 
    2774             :   // Private symbols should be installed on JSProxy using
    2775             :   // JSProxy::SetPrivateSymbol.
    2776    75404874 :   if (it->GetReceiver()->IsJSProxy() && it->GetName()->IsPrivate() &&
    2777    37702512 :       !it->GetName()->IsPrivateName()) {
    2778          45 :     RETURN_FAILURE(it->isolate(), GetShouldThrow(it->isolate(), should_throw),
    2779             :                    NewTypeError(MessageTemplate::kProxyPrivate));
    2780             :   }
    2781             : 
    2782             :   DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
    2783             : 
    2784    37702335 :   Handle<JSReceiver> receiver = it->GetStoreTarget<JSReceiver>();
    2785             :   DCHECK_IMPLIES(receiver->IsJSProxy(), it->GetName()->IsPrivateName());
    2786             :   DCHECK_IMPLIES(receiver->IsJSProxy(),
    2787             :                  it->state() == LookupIterator::NOT_FOUND);
    2788             : 
    2789             :   // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
    2790             :   // instead. If the prototype is Null, the proxy is detached.
    2791    37702337 :   if (receiver->IsJSGlobalProxy()) return Just(true);
    2792             : 
    2793             :   Isolate* isolate = it->isolate();
    2794             : 
    2795    37702337 :   if (it->ExtendingNonExtensible(receiver)) {
    2796      365117 :     RETURN_FAILURE(
    2797             :         isolate, GetShouldThrow(it->isolate(), should_throw),
    2798             :         NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName()));
    2799             :   }
    2800             : 
    2801    37608905 :   if (it->IsElement()) {
    2802     4995464 :     if (receiver->IsJSArray()) {
    2803             :       Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    2804     1652767 :       if (JSArray::WouldChangeReadOnlyLength(array, it->index())) {
    2805        1035 :         RETURN_FAILURE(isolate, GetShouldThrow(it->isolate(), should_throw),
    2806             :                        NewTypeError(MessageTemplate::kStrictReadOnlyProperty,
    2807             :                                     isolate->factory()->length_string(),
    2808             :                                     Object::TypeOf(isolate, array), array));
    2809             :       }
    2810             : 
    2811     4957464 :       if (FLAG_trace_external_array_abuse &&
    2812     1652488 :           array->HasFixedTypedArrayElements()) {
    2813           0 :         CheckArrayAbuse(array, "typed elements write", it->index(), true);
    2814             :       }
    2815             : 
    2816     1652488 :       if (FLAG_trace_js_array_abuse && !array->HasFixedTypedArrayElements()) {
    2817           0 :         CheckArrayAbuse(array, "elements write", it->index(), false);
    2818             :       }
    2819             :     }
    2820             : 
    2821             :     Handle<JSObject> receiver_obj = Handle<JSObject>::cast(receiver);
    2822     4995185 :     JSObject::AddDataElement(receiver_obj, it->index(), value, attributes);
    2823     4995185 :     JSObject::ValidateElements(*receiver_obj);
    2824             :     return Just(true);
    2825             :   } else {
    2826    32613441 :     it->UpdateProtector();
    2827             :     // Migrate to the most up-to-date map that will be able to store |value|
    2828             :     // under it->name() with |attributes|.
    2829             :     it->PrepareTransitionToDataProperty(receiver, value, attributes,
    2830    32613437 :                                         store_origin);
    2831             :     DCHECK_EQ(LookupIterator::TRANSITION, it->state());
    2832    32613399 :     it->ApplyTransitionToDataProperty(receiver);
    2833             : 
    2834             :     // Write the property value.
    2835    32613427 :     it->WriteDataValue(value, true);
    2836             : 
    2837             : #if VERIFY_HEAP
    2838             :     if (FLAG_verify_heap) {
    2839             :       receiver->HeapObjectVerify(isolate);
    2840             :     }
    2841             : #endif
    2842             :   }
    2843             : 
    2844             :   return Just(true);
    2845             : }
    2846             : 
    2847             : 
    2848             : template <class T>
    2849       53431 : static int AppendUniqueCallbacks(Isolate* isolate,
    2850             :                                  Handle<TemplateList> callbacks,
    2851             :                                  Handle<typename T::Array> array,
    2852             :                                  int valid_descriptors) {
    2853             :   int nof_callbacks = callbacks->length();
    2854             : 
    2855             :   // Fill in new callback descriptors.  Process the callbacks from
    2856             :   // back to front so that the last callback with a given name takes
    2857             :   // precedence over previously added callbacks with that name.
    2858      107123 :   for (int i = nof_callbacks - 1; i >= 0; i--) {
    2859             :     Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)), isolate);
    2860             :     Handle<Name> key(Name::cast(entry->name()), isolate);
    2861             :     DCHECK(key->IsUniqueName());
    2862             :     // Check if a descriptor with this name already exists before writing.
    2863       53692 :     if (!T::Contains(key, entry, valid_descriptors, array)) {
    2864             :       T::Insert(key, entry, valid_descriptors, array);
    2865       53680 :       valid_descriptors++;
    2866             :     }
    2867             :   }
    2868             : 
    2869       53431 :   return valid_descriptors;
    2870             : }
    2871             : 
    2872             : struct FixedArrayAppender {
    2873             :   typedef FixedArray Array;
    2874       53692 :   static bool Contains(Handle<Name> key,
    2875             :                        Handle<AccessorInfo> entry,
    2876             :                        int valid_descriptors,
    2877             :                        Handle<FixedArray> array) {
    2878       54670 :     for (int i = 0; i < valid_descriptors; i++) {
    2879         501 :       if (*key == AccessorInfo::cast(array->get(i))->name()) return true;
    2880             :     }
    2881             :     return false;
    2882             :   }
    2883             :   static void Insert(Handle<Name> key,
    2884             :                      Handle<AccessorInfo> entry,
    2885             :                      int valid_descriptors,
    2886             :                      Handle<FixedArray> array) {
    2887             :     DisallowHeapAllocation no_gc;
    2888      107360 :     array->set(valid_descriptors, *entry);
    2889             :   }
    2890             : };
    2891             : 
    2892       53431 : int AccessorInfo::AppendUnique(Isolate* isolate, Handle<Object> descriptors,
    2893             :                                Handle<FixedArray> array,
    2894             :                                int valid_descriptors) {
    2895       53431 :   Handle<TemplateList> callbacks = Handle<TemplateList>::cast(descriptors);
    2896             :   DCHECK_GE(array->length(), callbacks->length() + valid_descriptors);
    2897             :   return AppendUniqueCallbacks<FixedArrayAppender>(isolate, callbacks, array,
    2898       53431 :                                                    valid_descriptors);
    2899             : }
    2900             : 
    2901             : 
    2902             : 
    2903             : 
    2904             : 
    2905           5 : void JSProxy::Revoke(Handle<JSProxy> proxy) {
    2906             :   Isolate* isolate = proxy->GetIsolate();
    2907             :   // ES#sec-proxy-revocation-functions
    2908           5 :   if (!proxy->IsRevoked()) {
    2909             :     // 5. Set p.[[ProxyTarget]] to null.
    2910          10 :     proxy->set_target(ReadOnlyRoots(isolate).null_value());
    2911             :     // 6. Set p.[[ProxyHandler]] to null.
    2912          10 :     proxy->set_handler(ReadOnlyRoots(isolate).null_value());
    2913             :   }
    2914             :   DCHECK(proxy->IsRevoked());
    2915           5 : }
    2916             : 
    2917             : // static
    2918        1238 : Maybe<bool> JSProxy::IsArray(Handle<JSProxy> proxy) {
    2919             :   Isolate* isolate = proxy->GetIsolate();
    2920             :   Handle<JSReceiver> object = Handle<JSReceiver>::cast(proxy);
    2921     1844492 :   for (int i = 0; i < JSProxy::kMaxIterationLimit; i++) {
    2922             :     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
    2923      922856 :     if (proxy->IsRevoked()) {
    2924         216 :       isolate->Throw(*isolate->factory()->NewTypeError(
    2925             :           MessageTemplate::kProxyRevoked,
    2926         324 :           isolate->factory()->NewStringFromAsciiChecked("IsArray")));
    2927             :       return Nothing<bool>();
    2928             :     }
    2929             :     object = handle(JSReceiver::cast(proxy->target()), isolate);
    2930      922748 :     if (object->IsJSArray()) return Just(true);
    2931      922379 :     if (!object->IsJSProxy()) return Just(false);
    2932             :   }
    2933             : 
    2934             :   // Too deep recursion, throw a RangeError.
    2935           9 :   isolate->StackOverflow();
    2936             :   return Nothing<bool>();
    2937             : }
    2938             : 
    2939       53689 : Maybe<bool> JSProxy::HasProperty(Isolate* isolate, Handle<JSProxy> proxy,
    2940             :                                  Handle<Name> name) {
    2941             :   DCHECK(!name->IsPrivate());
    2942       53689 :   STACK_CHECK(isolate, Nothing<bool>());
    2943             :   // 1. (Assert)
    2944             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    2945             :   Handle<Object> handler(proxy->handler(), isolate);
    2946             :   // 3. If handler is null, throw a TypeError exception.
    2947             :   // 4. Assert: Type(handler) is Object.
    2948       53680 :   if (proxy->IsRevoked()) {
    2949           0 :     isolate->Throw(*isolate->factory()->NewTypeError(
    2950           0 :         MessageTemplate::kProxyRevoked, isolate->factory()->has_string()));
    2951             :     return Nothing<bool>();
    2952             :   }
    2953             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    2954             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    2955             :   // 6. Let trap be ? GetMethod(handler, "has").
    2956             :   Handle<Object> trap;
    2957      107360 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2958             :       isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler),
    2959             :                                        isolate->factory()->has_string()),
    2960             :       Nothing<bool>());
    2961             :   // 7. If trap is undefined, then
    2962       53672 :   if (trap->IsUndefined(isolate)) {
    2963             :     // 7a. Return target.[[HasProperty]](P).
    2964       44566 :     return JSReceiver::HasProperty(target, name);
    2965             :   }
    2966             :   // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, P»)).
    2967             :   Handle<Object> trap_result_obj;
    2968             :   Handle<Object> args[] = {target, name};
    2969       18212 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2970             :       isolate, trap_result_obj,
    2971             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    2972             :       Nothing<bool>());
    2973        8872 :   bool boolean_trap_result = trap_result_obj->BooleanValue(isolate);
    2974             :   // 9. If booleanTrapResult is false, then:
    2975        8872 :   if (!boolean_trap_result) {
    2976       11510 :     MAYBE_RETURN(JSProxy::CheckHasTrap(isolate, name, target), Nothing<bool>());
    2977             :   }
    2978             :   // 10. Return booleanTrapResult.
    2979             :   return Just(boolean_trap_result);
    2980             : }
    2981             : 
    2982        5778 : Maybe<bool> JSProxy::CheckHasTrap(Isolate* isolate, Handle<Name> name,
    2983             :                                   Handle<JSReceiver> target) {
    2984             :   // 9a. Let targetDesc be ? target.[[GetOwnProperty]](P).
    2985             :   PropertyDescriptor target_desc;
    2986             :   Maybe<bool> target_found =
    2987        5778 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    2988        5778 :   MAYBE_RETURN(target_found, Nothing<bool>());
    2989             :   // 9b. If targetDesc is not undefined, then:
    2990        5778 :   if (target_found.FromJust()) {
    2991             :     // 9b i. If targetDesc.[[Configurable]] is false, throw a TypeError
    2992             :     //       exception.
    2993         118 :     if (!target_desc.configurable()) {
    2994          66 :       isolate->Throw(*isolate->factory()->NewTypeError(
    2995          66 :           MessageTemplate::kProxyHasNonConfigurable, name));
    2996          84 :       return Nothing<bool>();
    2997             :     }
    2998             :     // 9b ii. Let extensibleTarget be ? IsExtensible(target).
    2999          85 :     Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    3000          85 :     MAYBE_RETURN(extensible_target, Nothing<bool>());
    3001             :     // 9b iii. If extensibleTarget is false, throw a TypeError exception.
    3002          85 :     if (!extensible_target.FromJust()) {
    3003         102 :       isolate->Throw(*isolate->factory()->NewTypeError(
    3004         102 :           MessageTemplate::kProxyHasNonExtensible, name));
    3005             :       return Nothing<bool>();
    3006             :     }
    3007             :   }
    3008             :   return Just(true);
    3009             : }
    3010             : 
    3011       56377 : Maybe<bool> JSProxy::SetProperty(Handle<JSProxy> proxy, Handle<Name> name,
    3012             :                                  Handle<Object> value, Handle<Object> receiver,
    3013             :                                  Maybe<ShouldThrow> should_throw) {
    3014             :   DCHECK(!name->IsPrivate());
    3015             :   Isolate* isolate = proxy->GetIsolate();
    3016       56377 :   STACK_CHECK(isolate, Nothing<bool>());
    3017             :   Factory* factory = isolate->factory();
    3018             :   Handle<String> trap_name = factory->set_string();
    3019             : 
    3020       56342 :   if (proxy->IsRevoked()) {
    3021             :     isolate->Throw(
    3022          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    3023             :     return Nothing<bool>();
    3024             :   }
    3025             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    3026             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    3027             : 
    3028             :   Handle<Object> trap;
    3029      112648 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3030             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    3031       56057 :   if (trap->IsUndefined(isolate)) {
    3032             :     LookupIterator it =
    3033       47724 :         LookupIterator::PropertyOrElement(isolate, receiver, name, target);
    3034             : 
    3035             :     return Object::SetSuperProperty(&it, value, StoreOrigin::kMaybeKeyed,
    3036       47724 :                                     should_throw);
    3037             :   }
    3038             : 
    3039             :   Handle<Object> trap_result;
    3040        8333 :   Handle<Object> args[] = {target, name, value, receiver};
    3041       16666 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3042             :       isolate, trap_result,
    3043             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    3044             :       Nothing<bool>());
    3045        2786 :   if (!trap_result->BooleanValue(isolate)) {
    3046         585 :     RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
    3047             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    3048             :                                 trap_name, name));
    3049             :   }
    3050             : 
    3051             :   MaybeHandle<Object> result =
    3052        2291 :       JSProxy::CheckGetSetTrapResult(isolate, name, target, value, kSet);
    3053             : 
    3054        2291 :   if (result.is_null()) {
    3055             :     return Nothing<bool>();
    3056             :   }
    3057             :   return Just(true);
    3058             : }
    3059             : 
    3060       28928 : Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy,
    3061             :                                              Handle<Name> name,
    3062             :                                              LanguageMode language_mode) {
    3063             :   DCHECK(!name->IsPrivate());
    3064             :   ShouldThrow should_throw =
    3065       28928 :       is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
    3066             :   Isolate* isolate = proxy->GetIsolate();
    3067       28928 :   STACK_CHECK(isolate, Nothing<bool>());
    3068             :   Factory* factory = isolate->factory();
    3069             :   Handle<String> trap_name = factory->deleteProperty_string();
    3070             : 
    3071       28918 :   if (proxy->IsRevoked()) {
    3072             :     isolate->Throw(
    3073          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    3074             :     return Nothing<bool>();
    3075             :   }
    3076             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    3077             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    3078             : 
    3079             :   Handle<Object> trap;
    3080       57800 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3081             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    3082       28765 :   if (trap->IsUndefined(isolate)) {
    3083       19701 :     return JSReceiver::DeletePropertyOrElement(target, name, language_mode);
    3084             :   }
    3085             : 
    3086             :   Handle<Object> trap_result;
    3087             :   Handle<Object> args[] = {target, name};
    3088       18128 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3089             :       isolate, trap_result,
    3090             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    3091             :       Nothing<bool>());
    3092        1809 :   if (!trap_result->BooleanValue(isolate)) {
    3093        1242 :     RETURN_FAILURE(isolate, should_throw,
    3094             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    3095             :                                 trap_name, name));
    3096             :   }
    3097             : 
    3098             :   // Enforce the invariant.
    3099             :   PropertyDescriptor target_desc;
    3100             :   Maybe<bool> owned =
    3101        1053 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    3102        1053 :   MAYBE_RETURN(owned, Nothing<bool>());
    3103        1593 :   if (owned.FromJust() && !target_desc.configurable()) {
    3104         720 :     isolate->Throw(*factory->NewTypeError(
    3105         720 :         MessageTemplate::kProxyDeletePropertyNonConfigurable, name));
    3106             :     return Nothing<bool>();
    3107             :   }
    3108             :   return Just(true);
    3109             : }
    3110             : 
    3111             : 
    3112             : // static
    3113          17 : MaybeHandle<JSProxy> JSProxy::New(Isolate* isolate, Handle<Object> target,
    3114             :                                   Handle<Object> handler) {
    3115          17 :   if (!target->IsJSReceiver()) {
    3116           0 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject),
    3117             :                     JSProxy);
    3118             :   }
    3119          17 :   if (target->IsJSProxy() && JSProxy::cast(*target)->IsRevoked()) {
    3120           0 :     THROW_NEW_ERROR(isolate,
    3121             :                     NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
    3122             :                     JSProxy);
    3123             :   }
    3124          17 :   if (!handler->IsJSReceiver()) {
    3125           0 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject),
    3126             :                     JSProxy);
    3127             :   }
    3128          17 :   if (handler->IsJSProxy() && JSProxy::cast(*handler)->IsRevoked()) {
    3129           0 :     THROW_NEW_ERROR(isolate,
    3130             :                     NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
    3131             :                     JSProxy);
    3132             :   }
    3133             :   return isolate->factory()->NewJSProxy(Handle<JSReceiver>::cast(target),
    3134          17 :                                         Handle<JSReceiver>::cast(handler));
    3135             : }
    3136             : 
    3137             : 
    3138             : // static
    3139          36 : MaybeHandle<NativeContext> JSProxy::GetFunctionRealm(Handle<JSProxy> proxy) {
    3140             :   DCHECK(proxy->map()->is_constructor());
    3141          36 :   if (proxy->IsRevoked()) {
    3142           0 :     THROW_NEW_ERROR(proxy->GetIsolate(),
    3143             :                     NewTypeError(MessageTemplate::kProxyRevoked),
    3144             :                     NativeContext);
    3145             :   }
    3146             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()),
    3147             :                             proxy->GetIsolate());
    3148          36 :   return JSReceiver::GetFunctionRealm(target);
    3149             : }
    3150             : 
    3151        2106 : Maybe<PropertyAttributes> JSProxy::GetPropertyAttributes(LookupIterator* it) {
    3152             :   PropertyDescriptor desc;
    3153             :   Maybe<bool> found = JSProxy::GetOwnPropertyDescriptor(
    3154        2106 :       it->isolate(), it->GetHolder<JSProxy>(), it->GetName(), &desc);
    3155        2106 :   MAYBE_RETURN(found, Nothing<PropertyAttributes>());
    3156        1809 :   if (!found.FromJust()) return Just(ABSENT);
    3157             :   return Just(desc.ToAttributes());
    3158             : }
    3159             : 
    3160             : // TODO(jkummerow): Consider unification with FastAsArrayLength() in
    3161             : // accessors.cc.
    3162       31997 : bool PropertyKeyToArrayLength(Handle<Object> value, uint32_t* length) {
    3163             :   DCHECK(value->IsNumber() || value->IsName());
    3164       63994 :   if (value->ToArrayLength(length)) return true;
    3165       57186 :   if (value->IsString()) return String::cast(*value)->AsArrayIndex(length);
    3166             :   return false;
    3167             : }
    3168             : 
    3169           0 : bool PropertyKeyToArrayIndex(Handle<Object> index_obj, uint32_t* output) {
    3170       31997 :   return PropertyKeyToArrayLength(index_obj, output) && *output != kMaxUInt32;
    3171             : }
    3172             : 
    3173             : // ES6 9.4.2.1
    3174             : // static
    3175       32360 : Maybe<bool> JSArray::DefineOwnProperty(Isolate* isolate, Handle<JSArray> o,
    3176             :                                        Handle<Object> name,
    3177             :                                        PropertyDescriptor* desc,
    3178             :                                        Maybe<ShouldThrow> should_throw) {
    3179             :   // 1. Assert: IsPropertyKey(P) is true. ("P" is |name|.)
    3180             :   // 2. If P is "length", then:
    3181             :   // TODO(jkummerow): Check if we need slow string comparison.
    3182       32360 :   if (*name == ReadOnlyRoots(isolate).length_string()) {
    3183             :     // 2a. Return ArraySetLength(A, Desc).
    3184         363 :     return ArraySetLength(isolate, o, desc, should_throw);
    3185             :   }
    3186             :   // 3. Else if P is an array index, then:
    3187       31997 :   uint32_t index = 0;
    3188       31997 :   if (PropertyKeyToArrayIndex(name, &index)) {
    3189             :     // 3a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    3190             :     PropertyDescriptor old_len_desc;
    3191             :     Maybe<bool> success = GetOwnPropertyDescriptor(
    3192       27178 :         isolate, o, isolate->factory()->length_string(), &old_len_desc);
    3193             :     // 3b. (Assert)
    3194             :     DCHECK(success.FromJust());
    3195             :     USE(success);
    3196             :     // 3c. Let oldLen be oldLenDesc.[[Value]].
    3197       27178 :     uint32_t old_len = 0;
    3198       54356 :     CHECK(old_len_desc.value()->ToArrayLength(&old_len));
    3199             :     // 3d. Let index be ToUint32(P).
    3200             :     // (Already done above.)
    3201             :     // 3e. (Assert)
    3202             :     // 3f. If index >= oldLen and oldLenDesc.[[Writable]] is false,
    3203             :     //     return false.
    3204       33446 :     if (index >= old_len && old_len_desc.has_writable() &&
    3205             :         !old_len_desc.writable()) {
    3206           0 :       RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
    3207             :                      NewTypeError(MessageTemplate::kDefineDisallowed, name));
    3208             :     }
    3209             :     // 3g. Let succeeded be OrdinaryDefineOwnProperty(A, P, Desc).
    3210             :     Maybe<bool> succeeded =
    3211       27178 :         OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
    3212             :     // 3h. Assert: succeeded is not an abrupt completion.
    3213             :     //     In our case, if should_throw == kThrowOnError, it can be!
    3214             :     // 3i. If succeeded is false, return false.
    3215       54270 :     if (succeeded.IsNothing() || !succeeded.FromJust()) return succeeded;
    3216             :     // 3j. If index >= oldLen, then:
    3217       27083 :     if (index >= old_len) {
    3218             :       // 3j i. Set oldLenDesc.[[Value]] to index + 1.
    3219        3134 :       old_len_desc.set_value(isolate->factory()->NewNumberFromUint(index + 1));
    3220             :       // 3j ii. Let succeeded be
    3221             :       //        OrdinaryDefineOwnProperty(A, "length", oldLenDesc).
    3222             :       succeeded = OrdinaryDefineOwnProperty(isolate, o,
    3223             :                                             isolate->factory()->length_string(),
    3224        3134 :                                             &old_len_desc, should_throw);
    3225             :       // 3j iii. Assert: succeeded is true.
    3226             :       DCHECK(succeeded.FromJust());
    3227             :       USE(succeeded);
    3228             :     }
    3229             :     // 3k. Return true.
    3230             :     return Just(true);
    3231             :   }
    3232             : 
    3233             :   // 4. Return OrdinaryDefineOwnProperty(A, P, Desc).
    3234        4819 :   return OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
    3235             : }
    3236             : 
    3237             : // Part of ES6 9.4.2.4 ArraySetLength.
    3238             : // static
    3239      470753 : bool JSArray::AnythingToArrayLength(Isolate* isolate,
    3240             :                                     Handle<Object> length_object,
    3241             :                                     uint32_t* output) {
    3242             :   // Fast path: check numbers and strings that can be converted directly
    3243             :   // and unobservably.
    3244      941506 :   if (length_object->ToArrayLength(output)) return true;
    3245      844804 :   if (length_object->IsString() &&
    3246      422411 :       Handle<String>::cast(length_object)->AsArrayIndex(output)) {
    3247             :     return true;
    3248             :   }
    3249             :   // Slow path: follow steps in ES6 9.4.2.4 "ArraySetLength".
    3250             :   // 3. Let newLen be ToUint32(Desc.[[Value]]).
    3251             :   Handle<Object> uint32_v;
    3252      844768 :   if (!Object::ToUint32(isolate, length_object).ToHandle(&uint32_v)) {
    3253             :     // 4. ReturnIfAbrupt(newLen).
    3254             :     return false;
    3255             :   }
    3256             :   // 5. Let numberLen be ToNumber(Desc.[[Value]]).
    3257             :   Handle<Object> number_v;
    3258      844750 :   if (!Object::ToNumber(isolate, length_object).ToHandle(&number_v)) {
    3259             :     // 6. ReturnIfAbrupt(newLen).
    3260             :     return false;
    3261             :   }
    3262             :   // 7. If newLen != numberLen, throw a RangeError exception.
    3263      422375 :   if (uint32_v->Number() != number_v->Number()) {
    3264             :     Handle<Object> exception =
    3265         153 :         isolate->factory()->NewRangeError(MessageTemplate::kInvalidArrayLength);
    3266         153 :     isolate->Throw(*exception);
    3267             :     return false;
    3268             :   }
    3269      844444 :   CHECK(uint32_v->ToArrayLength(output));
    3270             :   return true;
    3271             : }
    3272             : 
    3273             : // ES6 9.4.2.4
    3274             : // static
    3275         363 : Maybe<bool> JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a,
    3276             :                                     PropertyDescriptor* desc,
    3277             :                                     Maybe<ShouldThrow> should_throw) {
    3278             :   // 1. If the [[Value]] field of Desc is absent, then
    3279         363 :   if (!desc->has_value()) {
    3280             :     // 1a. Return OrdinaryDefineOwnProperty(A, "length", Desc).
    3281             :     return OrdinaryDefineOwnProperty(
    3282         282 :         isolate, a, isolate->factory()->length_string(), desc, should_throw);
    3283             :   }
    3284             :   // 2. Let newLenDesc be a copy of Desc.
    3285             :   // (Actual copying is not necessary.)
    3286             :   PropertyDescriptor* new_len_desc = desc;
    3287             :   // 3. - 7. Convert Desc.[[Value]] to newLen.
    3288          81 :   uint32_t new_len = 0;
    3289          81 :   if (!AnythingToArrayLength(isolate, desc->value(), &new_len)) {
    3290             :     DCHECK(isolate->has_pending_exception());
    3291             :     return Nothing<bool>();
    3292             :   }
    3293             :   // 8. Set newLenDesc.[[Value]] to newLen.
    3294             :   // (Done below, if needed.)
    3295             :   // 9. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    3296             :   PropertyDescriptor old_len_desc;
    3297             :   Maybe<bool> success = GetOwnPropertyDescriptor(
    3298          72 :       isolate, a, isolate->factory()->length_string(), &old_len_desc);
    3299             :   // 10. (Assert)
    3300             :   DCHECK(success.FromJust());
    3301             :   USE(success);
    3302             :   // 11. Let oldLen be oldLenDesc.[[Value]].
    3303          72 :   uint32_t old_len = 0;
    3304         144 :   CHECK(old_len_desc.value()->ToArrayLength(&old_len));
    3305             :   // 12. If newLen >= oldLen, then
    3306          72 :   if (new_len >= old_len) {
    3307             :     // 8. Set newLenDesc.[[Value]] to newLen.
    3308             :     // 12a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc).
    3309          63 :     new_len_desc->set_value(isolate->factory()->NewNumberFromUint(new_len));
    3310             :     return OrdinaryDefineOwnProperty(isolate, a,
    3311             :                                      isolate->factory()->length_string(),
    3312          63 :                                      new_len_desc, should_throw);
    3313             :   }
    3314             :   // 13. If oldLenDesc.[[Writable]] is false, return false.
    3315           9 :   if (!old_len_desc.writable()) {
    3316           0 :     RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
    3317             :                    NewTypeError(MessageTemplate::kRedefineDisallowed,
    3318             :                                 isolate->factory()->length_string()));
    3319             :   }
    3320             :   // 14. If newLenDesc.[[Writable]] is absent or has the value true,
    3321             :   // let newWritable be true.
    3322             :   bool new_writable = false;
    3323           9 :   if (!new_len_desc->has_writable() || new_len_desc->writable()) {
    3324             :     new_writable = true;
    3325             :   } else {
    3326             :     // 15. Else,
    3327             :     // 15a. Need to defer setting the [[Writable]] attribute to false in case
    3328             :     //      any elements cannot be deleted.
    3329             :     // 15b. Let newWritable be false. (It's initialized as "false" anyway.)
    3330             :     // 15c. Set newLenDesc.[[Writable]] to true.
    3331             :     // (Not needed.)
    3332             :   }
    3333             :   // Most of steps 16 through 19 is implemented by JSArray::SetLength.
    3334           9 :   JSArray::SetLength(a, new_len);
    3335             :   // Steps 19d-ii, 20.
    3336           9 :   if (!new_writable) {
    3337             :     PropertyDescriptor readonly;
    3338             :     readonly.set_writable(false);
    3339             :     Maybe<bool> success = OrdinaryDefineOwnProperty(
    3340             :         isolate, a, isolate->factory()->length_string(), &readonly,
    3341           0 :         should_throw);
    3342             :     DCHECK(success.FromJust());
    3343             :     USE(success);
    3344             :   }
    3345           9 :   uint32_t actual_new_len = 0;
    3346          18 :   CHECK(a->length()->ToArrayLength(&actual_new_len));
    3347             :   // Steps 19d-v, 21. Return false if there were non-deletable elements.
    3348           9 :   bool result = actual_new_len == new_len;
    3349           9 :   if (!result) {
    3350           9 :     RETURN_FAILURE(
    3351             :         isolate, GetShouldThrow(isolate, should_throw),
    3352             :         NewTypeError(MessageTemplate::kStrictDeleteProperty,
    3353             :                      isolate->factory()->NewNumberFromUint(actual_new_len - 1),
    3354             :                      a));
    3355             :   }
    3356             :   return Just(result);
    3357             : }
    3358             : 
    3359             : // ES6 9.5.6
    3360             : // static
    3361       55749 : Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy,
    3362             :                                        Handle<Object> key,
    3363             :                                        PropertyDescriptor* desc,
    3364             :                                        Maybe<ShouldThrow> should_throw) {
    3365       55749 :   STACK_CHECK(isolate, Nothing<bool>());
    3366       56028 :   if (key->IsSymbol() && Handle<Symbol>::cast(key)->IsPrivate()) {
    3367             :     DCHECK(!Handle<Symbol>::cast(key)->IsPrivateName());
    3368             :     return JSProxy::SetPrivateSymbol(isolate, proxy, Handle<Symbol>::cast(key),
    3369          18 :                                      desc, should_throw);
    3370             :   }
    3371             :   Handle<String> trap_name = isolate->factory()->defineProperty_string();
    3372             :   // 1. Assert: IsPropertyKey(P) is true.
    3373             :   DCHECK(key->IsName() || key->IsNumber());
    3374             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    3375             :   Handle<Object> handler(proxy->handler(), isolate);
    3376             :   // 3. If handler is null, throw a TypeError exception.
    3377             :   // 4. Assert: Type(handler) is Object.
    3378       55722 :   if (proxy->IsRevoked()) {
    3379          18 :     isolate->Throw(*isolate->factory()->NewTypeError(
    3380          18 :         MessageTemplate::kProxyRevoked, trap_name));
    3381             :     return Nothing<bool>();
    3382             :   }
    3383             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    3384             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    3385             :   // 6. Let trap be ? GetMethod(handler, "defineProperty").
    3386             :   Handle<Object> trap;
    3387      111426 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3388             :       isolate, trap,
    3389             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    3390             :       Nothing<bool>());
    3391             :   // 7. If trap is undefined, then:
    3392       55623 :   if (trap->IsUndefined(isolate)) {
    3393             :     // 7a. Return target.[[DefineOwnProperty]](P, Desc).
    3394             :     return JSReceiver::DefineOwnProperty(isolate, target, key, desc,
    3395       45778 :                                          should_throw);
    3396             :   }
    3397             :   // 8. Let descObj be FromPropertyDescriptor(Desc).
    3398        9845 :   Handle<Object> desc_obj = desc->ToObject(isolate);
    3399             :   // 9. Let booleanTrapResult be
    3400             :   //    ToBoolean(? Call(trap, handler, «target, P, descObj»)).
    3401             :   Handle<Name> property_name =
    3402             :       key->IsName()
    3403             :           ? Handle<Name>::cast(key)
    3404        9845 :           : Handle<Name>::cast(isolate->factory()->NumberToString(key));
    3405             :   // Do not leak private property names.
    3406             :   DCHECK(!property_name->IsPrivate());
    3407             :   Handle<Object> trap_result_obj;
    3408        9845 :   Handle<Object> args[] = {target, property_name, desc_obj};
    3409       19690 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3410             :       isolate, trap_result_obj,
    3411             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    3412             :       Nothing<bool>());
    3413             :   // 10. If booleanTrapResult is false, return false.
    3414        1323 :   if (!trap_result_obj->BooleanValue(isolate)) {
    3415          99 :     RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
    3416             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    3417             :                                 trap_name, property_name));
    3418             :   }
    3419             :   // 11. Let targetDesc be ? target.[[GetOwnProperty]](P).
    3420             :   PropertyDescriptor target_desc;
    3421             :   Maybe<bool> target_found =
    3422        1242 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, key, &target_desc);
    3423        1242 :   MAYBE_RETURN(target_found, Nothing<bool>());
    3424             :   // 12. Let extensibleTarget be ? IsExtensible(target).
    3425        1242 :   Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target);
    3426        1242 :   MAYBE_RETURN(maybe_extensible, Nothing<bool>());
    3427             :   bool extensible_target = maybe_extensible.FromJust();
    3428             :   // 13. If Desc has a [[Configurable]] field and if Desc.[[Configurable]]
    3429             :   //     is false, then:
    3430             :   // 13a. Let settingConfigFalse be true.
    3431             :   // 14. Else let settingConfigFalse be false.
    3432        1935 :   bool setting_config_false = desc->has_configurable() && !desc->configurable();
    3433             :   // 15. If targetDesc is undefined, then
    3434        1242 :   if (!target_found.FromJust()) {
    3435             :     // 15a. If extensibleTarget is false, throw a TypeError exception.
    3436         621 :     if (!extensible_target) {
    3437          18 :       isolate->Throw(*isolate->factory()->NewTypeError(
    3438          18 :           MessageTemplate::kProxyDefinePropertyNonExtensible, property_name));
    3439             :       return Nothing<bool>();
    3440             :     }
    3441             :     // 15b. If settingConfigFalse is true, throw a TypeError exception.
    3442         612 :     if (setting_config_false) {
    3443          18 :       isolate->Throw(*isolate->factory()->NewTypeError(
    3444          18 :           MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
    3445             :       return Nothing<bool>();
    3446             :     }
    3447             :   } else {
    3448             :     // 16. Else targetDesc is not undefined,
    3449             :     // 16a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc,
    3450             :     //      targetDesc) is false, throw a TypeError exception.
    3451             :     Maybe<bool> valid = IsCompatiblePropertyDescriptor(
    3452             :         isolate, extensible_target, desc, &target_desc, property_name,
    3453         621 :         Just(kDontThrow));
    3454         639 :     MAYBE_RETURN(valid, Nothing<bool>());
    3455         621 :     if (!valid.FromJust()) {
    3456          18 :       isolate->Throw(*isolate->factory()->NewTypeError(
    3457          18 :           MessageTemplate::kProxyDefinePropertyIncompatible, property_name));
    3458             :       return Nothing<bool>();
    3459             :     }
    3460             :     // 16b. If settingConfigFalse is true and targetDesc.[[Configurable]] is
    3461             :     //      true, throw a TypeError exception.
    3462         702 :     if (setting_config_false && target_desc.configurable()) {
    3463          18 :       isolate->Throw(*isolate->factory()->NewTypeError(
    3464          18 :           MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
    3465             :       return Nothing<bool>();
    3466             :     }
    3467             :   }
    3468             :   // 17. Return true.
    3469             :   return Just(true);
    3470             : }
    3471             : 
    3472             : // static
    3473          36 : Maybe<bool> JSProxy::SetPrivateSymbol(Isolate* isolate, Handle<JSProxy> proxy,
    3474             :                                       Handle<Symbol> private_name,
    3475             :                                       PropertyDescriptor* desc,
    3476             :                                       Maybe<ShouldThrow> should_throw) {
    3477             :   DCHECK(!private_name->IsPrivateName());
    3478             :   // Despite the generic name, this can only add private data properties.
    3479          54 :   if (!PropertyDescriptor::IsDataDescriptor(desc) ||
    3480             :       desc->ToAttributes() != DONT_ENUM) {
    3481          36 :     RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
    3482             :                    NewTypeError(MessageTemplate::kProxyPrivate));
    3483             :   }
    3484             :   DCHECK(proxy->map()->is_dictionary_map());
    3485             :   Handle<Object> value =
    3486             :       desc->has_value()
    3487             :           ? desc->value()
    3488          18 :           : Handle<Object>::cast(isolate->factory()->undefined_value());
    3489             : 
    3490             :   LookupIterator it(proxy, private_name, proxy);
    3491             : 
    3492          18 :   if (it.IsFound()) {
    3493             :     DCHECK_EQ(LookupIterator::DATA, it.state());
    3494             :     DCHECK_EQ(DONT_ENUM, it.property_attributes());
    3495           6 :     it.WriteDataValue(value, false);
    3496             :     return Just(true);
    3497             :   }
    3498             : 
    3499          24 :   Handle<NameDictionary> dict(proxy->property_dictionary(), isolate);
    3500             :   PropertyDetails details(kData, DONT_ENUM, PropertyCellType::kNoCell);
    3501             :   Handle<NameDictionary> result =
    3502          12 :       NameDictionary::Add(isolate, dict, private_name, value, details);
    3503          24 :   if (!dict.is_identical_to(result)) proxy->SetProperties(*result);
    3504             :   return Just(true);
    3505             : }
    3506             : 
    3507             : // ES6 9.5.5
    3508             : // static
    3509       35676 : Maybe<bool> JSProxy::GetOwnPropertyDescriptor(Isolate* isolate,
    3510             :                                               Handle<JSProxy> proxy,
    3511             :                                               Handle<Name> name,
    3512             :                                               PropertyDescriptor* desc) {
    3513             :   DCHECK(!name->IsPrivate());
    3514       35676 :   STACK_CHECK(isolate, Nothing<bool>());
    3515             : 
    3516             :   Handle<String> trap_name =
    3517             :       isolate->factory()->getOwnPropertyDescriptor_string();
    3518             :   // 1. (Assert)
    3519             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    3520             :   Handle<Object> handler(proxy->handler(), isolate);
    3521             :   // 3. If handler is null, throw a TypeError exception.
    3522             :   // 4. Assert: Type(handler) is Object.
    3523       35667 :   if (proxy->IsRevoked()) {
    3524          36 :     isolate->Throw(*isolate->factory()->NewTypeError(
    3525          36 :         MessageTemplate::kProxyRevoked, trap_name));
    3526             :     return Nothing<bool>();
    3527             :   }
    3528             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    3529             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    3530             :   // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor").
    3531             :   Handle<Object> trap;
    3532       71298 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3533             :       isolate, trap,
    3534             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    3535             :       Nothing<bool>());
    3536             :   // 7. If trap is undefined, then
    3537       35595 :   if (trap->IsUndefined(isolate)) {
    3538             :     // 7a. Return target.[[GetOwnProperty]](P).
    3539       23293 :     return JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, desc);
    3540             :   }
    3541             :   // 8. Let trapResultObj be ? Call(trap, handler, «target, P»).
    3542             :   Handle<Object> trap_result_obj;
    3543             :   Handle<Object> args[] = {target, name};
    3544       24604 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3545             :       isolate, trap_result_obj,
    3546             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    3547             :       Nothing<bool>());
    3548             :   // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a
    3549             :   //    TypeError exception.
    3550        5661 :   if (!trap_result_obj->IsJSReceiver() &&
    3551             :       !trap_result_obj->IsUndefined(isolate)) {
    3552          36 :     isolate->Throw(*isolate->factory()->NewTypeError(
    3553          36 :         MessageTemplate::kProxyGetOwnPropertyDescriptorInvalid, name));
    3554             :     return Nothing<bool>();
    3555             :   }
    3556             :   // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
    3557             :   PropertyDescriptor target_desc;
    3558             :   Maybe<bool> found =
    3559        4842 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    3560        4842 :   MAYBE_RETURN(found, Nothing<bool>());
    3561             :   // 11. If trapResultObj is undefined, then
    3562        4842 :   if (trap_result_obj->IsUndefined(isolate)) {
    3563             :     // 11a. If targetDesc is undefined, return undefined.
    3564         783 :     if (!found.FromJust()) return Just(false);
    3565             :     // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError
    3566             :     //      exception.
    3567          45 :     if (!target_desc.configurable()) {
    3568          54 :       isolate->Throw(*isolate->factory()->NewTypeError(
    3569          54 :           MessageTemplate::kProxyGetOwnPropertyDescriptorUndefined, name));
    3570             :       return Nothing<bool>();
    3571             :     }
    3572             :     // 11c. Let extensibleTarget be ? IsExtensible(target).
    3573          18 :     Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    3574          18 :     MAYBE_RETURN(extensible_target, Nothing<bool>());
    3575             :     // 11d. (Assert)
    3576             :     // 11e. If extensibleTarget is false, throw a TypeError exception.
    3577          18 :     if (!extensible_target.FromJust()) {
    3578           0 :       isolate->Throw(*isolate->factory()->NewTypeError(
    3579           0 :           MessageTemplate::kProxyGetOwnPropertyDescriptorNonExtensible, name));
    3580             :       return Nothing<bool>();
    3581             :     }
    3582             :     // 11f. Return undefined.
    3583             :     return Just(false);
    3584             :   }
    3585             :   // 12. Let extensibleTarget be ? IsExtensible(target).
    3586        4059 :   Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    3587        4059 :   MAYBE_RETURN(extensible_target, Nothing<bool>());
    3588             :   // 13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj).
    3589        4059 :   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj,
    3590             :                                                 desc)) {
    3591             :     DCHECK(isolate->has_pending_exception());
    3592             :     return Nothing<bool>();
    3593             :   }
    3594             :   // 14. Call CompletePropertyDescriptor(resultDesc).
    3595        3987 :   PropertyDescriptor::CompletePropertyDescriptor(isolate, desc);
    3596             :   // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget,
    3597             :   //     resultDesc, targetDesc).
    3598             :   Maybe<bool> valid = IsCompatiblePropertyDescriptor(
    3599             :       isolate, extensible_target.FromJust(), desc, &target_desc, name,
    3600        3987 :       Just(kDontThrow));
    3601        3987 :   MAYBE_RETURN(valid, Nothing<bool>());
    3602             :   // 16. If valid is false, throw a TypeError exception.
    3603        3987 :   if (!valid.FromJust()) {
    3604          36 :     isolate->Throw(*isolate->factory()->NewTypeError(
    3605          36 :         MessageTemplate::kProxyGetOwnPropertyDescriptorIncompatible, name));
    3606             :     return Nothing<bool>();
    3607             :   }
    3608             :   // 17. If resultDesc.[[Configurable]] is false, then
    3609        3969 :   if (!desc->configurable()) {
    3610             :     // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true:
    3611         513 :     if (target_desc.is_empty() || target_desc.configurable()) {
    3612             :       // 17a i. Throw a TypeError exception.
    3613          36 :       isolate->Throw(*isolate->factory()->NewTypeError(
    3614             :           MessageTemplate::kProxyGetOwnPropertyDescriptorNonConfigurable,
    3615          36 :           name));
    3616             :       return Nothing<bool>();
    3617             :     }
    3618             :   }
    3619             :   // 18. Return resultDesc.
    3620             :   return Just(true);
    3621             : }
    3622             : 
    3623       81828 : Maybe<bool> JSProxy::PreventExtensions(Handle<JSProxy> proxy,
    3624             :                                        ShouldThrow should_throw) {
    3625             :   Isolate* isolate = proxy->GetIsolate();
    3626       81828 :   STACK_CHECK(isolate, Nothing<bool>());
    3627             :   Factory* factory = isolate->factory();
    3628             :   Handle<String> trap_name = factory->preventExtensions_string();
    3629             : 
    3630       81819 :   if (proxy->IsRevoked()) {
    3631             :     isolate->Throw(
    3632          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    3633             :     return Nothing<bool>();
    3634             :   }
    3635             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    3636             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    3637             : 
    3638             :   Handle<Object> trap;
    3639      163602 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3640             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    3641       81783 :   if (trap->IsUndefined(isolate)) {
    3642       71380 :     return JSReceiver::PreventExtensions(target, should_throw);
    3643             :   }
    3644             : 
    3645             :   Handle<Object> trap_result;
    3646             :   Handle<Object> args[] = {target};
    3647       20806 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3648             :       isolate, trap_result,
    3649             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    3650             :       Nothing<bool>());
    3651          54 :   if (!trap_result->BooleanValue(isolate)) {
    3652          18 :     RETURN_FAILURE(
    3653             :         isolate, should_throw,
    3654             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
    3655             :   }
    3656             : 
    3657             :   // Enforce the invariant.
    3658          36 :   Maybe<bool> target_result = JSReceiver::IsExtensible(target);
    3659          36 :   MAYBE_RETURN(target_result, Nothing<bool>());
    3660          36 :   if (target_result.FromJust()) {
    3661          18 :     isolate->Throw(*factory->NewTypeError(
    3662          18 :         MessageTemplate::kProxyPreventExtensionsExtensible));
    3663             :     return Nothing<bool>();
    3664             :   }
    3665             :   return Just(true);
    3666             : }
    3667             : 
    3668       81801 : Maybe<bool> JSProxy::IsExtensible(Handle<JSProxy> proxy) {
    3669             :   Isolate* isolate = proxy->GetIsolate();
    3670       81801 :   STACK_CHECK(isolate, Nothing<bool>());
    3671             :   Factory* factory = isolate->factory();
    3672             :   Handle<String> trap_name = factory->isExtensible_string();
    3673             : 
    3674       81792 :   if (proxy->IsRevoked()) {
    3675             :     isolate->Throw(
    3676          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    3677             :     return Nothing<bool>();
    3678             :   }
    3679             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    3680             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    3681             : 
    3682             :   Handle<Object> trap;
    3683      163548 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3684             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    3685       81756 :   if (trap->IsUndefined(isolate)) {
    3686       70984 :     return JSReceiver::IsExtensible(target);
    3687             :   }
    3688             : 
    3689             :   Handle<Object> trap_result;
    3690             :   Handle<Object> args[] = {target};
    3691       21544 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    3692             :       isolate, trap_result,
    3693             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    3694             :       Nothing<bool>());
    3695             : 
    3696             :   // Enforce the invariant.
    3697         423 :   Maybe<bool> target_result = JSReceiver::IsExtensible(target);
    3698         423 :   MAYBE_RETURN(target_result, Nothing<bool>());
    3699         423 :   if (target_result.FromJust() != trap_result->BooleanValue(isolate)) {
    3700             :     isolate->Throw(
    3701          54 :         *factory->NewTypeError(MessageTemplate::kProxyIsExtensibleInconsistent,
    3702          81 :                                factory->ToBoolean(target_result.FromJust())));
    3703             :     return Nothing<bool>();
    3704             :   }
    3705         396 :   return target_result;
    3706             : }
    3707             : 
    3708    19814296 : Handle<DescriptorArray> DescriptorArray::CopyUpTo(Isolate* isolate,
    3709             :                                                   Handle<DescriptorArray> desc,
    3710             :                                                   int enumeration_index,
    3711             :                                                   int slack) {
    3712             :   return DescriptorArray::CopyUpToAddAttributes(isolate, desc,
    3713    19814296 :                                                 enumeration_index, NONE, slack);
    3714             : }
    3715             : 
    3716    19950459 : Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
    3717             :     Isolate* isolate, Handle<DescriptorArray> desc, int enumeration_index,
    3718             :     PropertyAttributes attributes, int slack) {
    3719    19950459 :   if (enumeration_index + slack == 0) {
    3720             :     return isolate->factory()->empty_descriptor_array();
    3721             :   }
    3722             : 
    3723             :   int size = enumeration_index;
    3724             : 
    3725             :   Handle<DescriptorArray> descriptors =
    3726             :       DescriptorArray::Allocate(isolate, size, slack);
    3727             : 
    3728    18433956 :   if (attributes != NONE) {
    3729      578008 :     for (int i = 0; i < size; ++i) {
    3730      223337 :       MaybeObject value_or_field_type = desc->GetValue(i);
    3731      223340 :       Name key = desc->GetKey(i);
    3732      223340 :       PropertyDetails details = desc->GetDetails(i);
    3733             :       // Bulk attribute changes never affect private properties.
    3734      223342 :       if (!key->IsPrivate()) {
    3735             :         int mask = DONT_DELETE | DONT_ENUM;
    3736             :         // READ_ONLY is an invalid attribute for JS setters/getters.
    3737             :         HeapObject heap_object;
    3738      447638 :         if (details.kind() != kAccessor ||
    3739             :             !(value_or_field_type->GetHeapObjectIfStrong(&heap_object) &&
    3740        1026 :               heap_object->IsAccessorPair())) {
    3741             :           mask |= READ_ONLY;
    3742             :         }
    3743             :         details = details.CopyAddAttributes(
    3744      223306 :             static_cast<PropertyAttributes>(attributes & mask));
    3745             :       }
    3746      223342 :       descriptors->Set(i, key, value_or_field_type, details);
    3747             :     }
    3748             :   } else {
    3749   261713250 :     for (int i = 0; i < size; ++i) {
    3750   121705256 :       descriptors->CopyFrom(i, *desc);
    3751             :     }
    3752             :   }
    3753             : 
    3754    18484878 :   if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort();
    3755             : 
    3756    18434014 :   return descriptors;
    3757             : }
    3758             : 
    3759             : // Create a new descriptor array with only enumerable, configurable, writeable
    3760             : // data properties, but identical field locations.
    3761         315 : Handle<DescriptorArray> DescriptorArray::CopyForFastObjectClone(
    3762             :     Isolate* isolate, Handle<DescriptorArray> src, int enumeration_index,
    3763             :     int slack) {
    3764         315 :   if (enumeration_index + slack == 0) {
    3765             :     return isolate->factory()->empty_descriptor_array();
    3766             :   }
    3767             : 
    3768             :   int size = enumeration_index;
    3769             :   Handle<DescriptorArray> descriptors =
    3770             :       DescriptorArray::Allocate(isolate, size, slack);
    3771             : 
    3772        1413 :   for (int i = 0; i < size; ++i) {
    3773         549 :     Name key = src->GetKey(i);
    3774         549 :     PropertyDetails details = src->GetDetails(i);
    3775             : 
    3776             :     DCHECK(!key->IsPrivateName());
    3777             :     DCHECK(details.IsEnumerable());
    3778             :     DCHECK_EQ(details.kind(), kData);
    3779             : 
    3780             :     // Ensure the ObjectClone property details are NONE, and that all source
    3781             :     // details did not contain DONT_ENUM.
    3782             :     PropertyDetails new_details(kData, NONE, details.location(),
    3783             :                                 details.constness(), details.representation(),
    3784             :                                 details.field_index());
    3785             :     // Do not propagate the field type of normal object fields from the
    3786             :     // original descriptors since FieldType changes don't create new maps.
    3787         549 :     MaybeObject type = src->GetValue(i);
    3788         549 :     if (details.location() == PropertyLocation::kField) {
    3789         549 :       type = MaybeObject::FromObject(FieldType::Any());
    3790             :     }
    3791         549 :     descriptors->Set(i, key, type, new_details);
    3792             :   }
    3793             : 
    3794         315 :   descriptors->Sort();
    3795             : 
    3796         315 :   return descriptors;
    3797             : }
    3798             : 
    3799        4815 : bool DescriptorArray::IsEqualUpTo(DescriptorArray desc, int nof_descriptors) {
    3800      137375 :   for (int i = 0; i < nof_descriptors; i++) {
    3801      198840 :     if (GetKey(i) != desc->GetKey(i) || GetValue(i) != desc->GetValue(i)) {
    3802             :       return false;
    3803             :     }
    3804       66280 :     PropertyDetails details = GetDetails(i);
    3805       66280 :     PropertyDetails other_details = desc->GetDetails(i);
    3806      132560 :     if (details.kind() != other_details.kind() ||
    3807      132560 :         details.location() != other_details.location() ||
    3808             :         !details.representation().Equals(other_details.representation())) {
    3809             :       return false;
    3810             :     }
    3811             :   }
    3812             :   return true;
    3813             : }
    3814             : 
    3815    10080873 : Handle<FixedArray> FixedArray::SetAndGrow(Isolate* isolate,
    3816             :                                           Handle<FixedArray> array, int index,
    3817             :                                           Handle<Object> value,
    3818             :                                           AllocationType allocation) {
    3819    10080873 :   if (index < array->length()) {
    3820     9541659 :     array->set(index, *value);
    3821     9541657 :     return array;
    3822             :   }
    3823             :   int capacity = array->length();
    3824             :   do {
    3825     1078428 :     capacity = JSObject::NewElementsCapacity(capacity);
    3826      539214 :   } while (capacity <= index);
    3827             :   Handle<FixedArray> new_array =
    3828      539214 :       isolate->factory()->NewUninitializedFixedArray(capacity, allocation);
    3829      539214 :   array->CopyTo(0, *new_array, 0, array->length());
    3830     1078428 :   new_array->FillWithHoles(array->length(), new_array->length());
    3831      539214 :   new_array->set(index, *value);
    3832      539214 :   return new_array;
    3833             : }
    3834             : 
    3835           0 : bool FixedArray::ContainsSortedNumbers() {
    3836           0 :   for (int i = 1; i < length(); ++i) {
    3837           0 :     Object a_obj = get(i - 1);
    3838             :     Object b_obj = get(i);
    3839           0 :     if (!a_obj->IsNumber() || !b_obj->IsNumber()) return false;
    3840             : 
    3841           0 :     uint32_t a = NumberToUint32(a_obj);
    3842           0 :     uint32_t b = NumberToUint32(b_obj);
    3843             : 
    3844           0 :     if (a > b) return false;
    3845             :   }
    3846             :   return true;
    3847             : }
    3848             : 
    3849      857093 : Handle<FixedArray> FixedArray::ShrinkOrEmpty(Isolate* isolate,
    3850             :                                              Handle<FixedArray> array,
    3851             :                                              int new_length) {
    3852      857093 :   if (new_length == 0) {
    3853             :     return array->GetReadOnlyRoots().empty_fixed_array_handle();
    3854             :   } else {
    3855      684825 :     array->Shrink(isolate, new_length);
    3856      684825 :     return array;
    3857             :   }
    3858             : }
    3859             : 
    3860     1996898 : void FixedArray::Shrink(Isolate* isolate, int new_length) {
    3861             :   DCHECK(0 < new_length && new_length <= length());
    3862     1996898 :   if (new_length < length()) {
    3863     2704596 :     isolate->heap()->RightTrimFixedArray(*this, length() - new_length);
    3864             :   }
    3865     1996898 : }
    3866             : 
    3867      556633 : void FixedArray::CopyTo(int pos, FixedArray dest, int dest_pos, int len) const {
    3868             :   DisallowHeapAllocation no_gc;
    3869             :   // Return early if len == 0 so that we don't try to read the write barrier off
    3870             :   // a canonical read-only empty fixed array.
    3871      556633 :   if (len == 0) return;
    3872             :   WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
    3873    16908069 :   for (int index = 0; index < len; index++) {
    3874    16358656 :     dest->set(dest_pos + index, get(pos + index), mode);
    3875             :   }
    3876             : }
    3877             : 
    3878             : 
    3879             : // static
    3880        1934 : Handle<ArrayList> ArrayList::Add(Isolate* isolate, Handle<ArrayList> array,
    3881             :                                  Handle<Object> obj) {
    3882        1934 :   int length = array->Length();
    3883        1934 :   array = EnsureSpace(isolate, array, length + 1);
    3884             :   // Check that GC didn't remove elements from the array.
    3885             :   DCHECK_EQ(array->Length(), length);
    3886             :   array->Set(length, *obj);
    3887             :   array->SetLength(length + 1);
    3888        1934 :   return array;
    3889             : }
    3890             : 
    3891             : // static
    3892           5 : Handle<ArrayList> ArrayList::Add(Isolate* isolate, Handle<ArrayList> array,
    3893             :                                  Handle<Object> obj1, Handle<Object> obj2) {
    3894           5 :   int length = array->Length();
    3895           5 :   array = EnsureSpace(isolate, array, length + 2);
    3896             :   // Check that GC didn't remove elements from the array.
    3897             :   DCHECK_EQ(array->Length(), length);
    3898             :   array->Set(length, *obj1);
    3899             :   array->Set(length + 1, *obj2);
    3900             :   array->SetLength(length + 2);
    3901           5 :   return array;
    3902             : }
    3903             : 
    3904             : // static
    3905         354 : Handle<ArrayList> ArrayList::New(Isolate* isolate, int size) {
    3906             :   Handle<FixedArray> fixed_array =
    3907         354 :       isolate->factory()->NewFixedArray(size + kFirstIndex);
    3908             :   fixed_array->set_map_no_write_barrier(
    3909             :       ReadOnlyRoots(isolate).array_list_map());
    3910             :   Handle<ArrayList> result = Handle<ArrayList>::cast(fixed_array);
    3911             :   result->SetLength(0);
    3912         354 :   return result;
    3913             : }
    3914             : 
    3915         422 : Handle<FixedArray> ArrayList::Elements(Isolate* isolate,
    3916             :                                        Handle<ArrayList> array) {
    3917         422 :   int length = array->Length();
    3918         422 :   Handle<FixedArray> result = isolate->factory()->NewFixedArray(length);
    3919             :   // Do not copy the first entry, i.e., the length.
    3920         422 :   array->CopyTo(kFirstIndex, *result, 0, length);
    3921         422 :   return result;
    3922             : }
    3923             : 
    3924             : namespace {
    3925             : 
    3926     9420061 : Handle<FixedArray> EnsureSpaceInFixedArray(Isolate* isolate,
    3927             :                                            Handle<FixedArray> array,
    3928             :                                            int length) {
    3929             :   int capacity = array->length();
    3930     9420061 :   if (capacity < length) {
    3931             :     int new_capacity = length;
    3932        5376 :     new_capacity = new_capacity + Max(new_capacity / 2, 2);
    3933        2688 :     int grow_by = new_capacity - capacity;
    3934        2688 :     array = isolate->factory()->CopyFixedArrayAndGrow(array, grow_by);
    3935             :   }
    3936     9420061 :   return array;
    3937             : }
    3938             : 
    3939             : }  // namespace
    3940             : 
    3941             : // static
    3942        1939 : Handle<ArrayList> ArrayList::EnsureSpace(Isolate* isolate,
    3943             :                                          Handle<ArrayList> array, int length) {
    3944             :   const bool empty = (array->length() == 0);
    3945             :   Handle<FixedArray> ret =
    3946        3878 :       EnsureSpaceInFixedArray(isolate, array, kFirstIndex + length);
    3947        1939 :   if (empty) {
    3948             :     ret->set_map_no_write_barrier(array->GetReadOnlyRoots().array_list_map());
    3949             : 
    3950             :     Handle<ArrayList>::cast(ret)->SetLength(0);
    3951             :   }
    3952        1939 :   return Handle<ArrayList>::cast(ret);
    3953             : }
    3954             : 
    3955             : // static
    3956    13719723 : Handle<WeakArrayList> WeakArrayList::AddToEnd(Isolate* isolate,
    3957             :                                               Handle<WeakArrayList> array,
    3958             :                                               const MaybeObjectHandle& value) {
    3959             :   int length = array->length();
    3960    13719723 :   array = EnsureSpace(isolate, array, length + 1);
    3961             :   // Reload length; GC might have removed elements from the array.
    3962             :   length = array->length();
    3963    27439474 :   array->Set(length, *value);
    3964    13719714 :   array->set_length(length + 1);
    3965    13719714 :   return array;
    3966             : }
    3967             : 
    3968      865972 : bool WeakArrayList::IsFull() { return length() == capacity(); }
    3969             : 
    3970             : // static
    3971    13853090 : Handle<WeakArrayList> WeakArrayList::EnsureSpace(Isolate* isolate,
    3972             :                                                  Handle<WeakArrayList> array,
    3973             :                                                  int length,
    3974             :                                                  AllocationType allocation) {
    3975             :   int capacity = array->capacity();
    3976    13853090 :   if (capacity < length) {
    3977             :     int new_capacity = length;
    3978     3074918 :     new_capacity = new_capacity + Max(new_capacity / 2, 2);
    3979     1537459 :     int grow_by = new_capacity - capacity;
    3980             :     array = isolate->factory()->CopyWeakArrayListAndGrow(array, grow_by,
    3981     1537459 :                                                          allocation);
    3982             :   }
    3983    13853085 :   return array;
    3984             : }
    3985             : 
    3986         422 : int WeakArrayList::CountLiveWeakReferences() const {
    3987             :   int live_weak_references = 0;
    3988      243090 :   for (int i = 0; i < length(); i++) {
    3989      121334 :     if (Get(i)->IsWeak()) {
    3990      120969 :       ++live_weak_references;
    3991             :     }
    3992             :   }
    3993         422 :   return live_weak_references;
    3994             : }
    3995             : 
    3996     3602822 : bool WeakArrayList::RemoveOne(const MaybeObjectHandle& value) {
    3997     3602822 :   if (length() == 0) return false;
    3998             :   // Optimize for the most recently added element to be removed again.
    3999             :   MaybeObject cleared_weak_ref =
    4000     3602824 :       HeapObjectReference::ClearedValue(GetIsolate());
    4001     3602824 :   int last_index = length() - 1;
    4002     3602864 :   for (int i = last_index; i >= 0; --i) {
    4003     7205682 :     if (Get(i) == *value) {
    4004             :       // Move the last element into the this slot (or no-op, if this is the
    4005             :       // last slot).
    4006     3602819 :       Set(i, Get(last_index));
    4007     3602817 :       Set(last_index, cleared_weak_ref);
    4008             :       set_length(last_index);
    4009     3602825 :       return true;
    4010             :     }
    4011             :   }
    4012             :   return false;
    4013             : }
    4014             : 
    4015             : // static
    4016      505109 : Handle<WeakArrayList> PrototypeUsers::Add(Isolate* isolate,
    4017             :                                           Handle<WeakArrayList> array,
    4018             :                                           Handle<Map> value,
    4019             :                                           int* assigned_index) {
    4020             :   int length = array->length();
    4021      505109 :   if (length == 0) {
    4022             :     // Uninitialized WeakArrayList; need to initialize empty_slot_index.
    4023      117782 :     array = WeakArrayList::EnsureSpace(isolate, array, kFirstIndex + 1);
    4024             :     set_empty_slot_index(*array, kNoEmptySlotsMarker);
    4025      235564 :     array->Set(kFirstIndex, HeapObjectReference::Weak(*value));
    4026             :     array->set_length(kFirstIndex + 1);
    4027      117782 :     if (assigned_index != nullptr) *assigned_index = kFirstIndex;
    4028      117782 :     return array;
    4029             :   }
    4030             : 
    4031             :   // If the array has unfilled space at the end, use it.
    4032      387327 :   if (!array->IsFull()) {
    4033      272535 :     array->Set(length, HeapObjectReference::Weak(*value));
    4034      272535 :     array->set_length(length + 1);
    4035      272535 :     if (assigned_index != nullptr) *assigned_index = length;
    4036      272535 :     return array;
    4037             :   }
    4038             : 
    4039             :   // If there are empty slots, use one of them.
    4040             :   int empty_slot = Smi::ToInt(empty_slot_index(*array));
    4041      114792 :   if (empty_slot != kNoEmptySlotsMarker) {
    4042             :     DCHECK_GE(empty_slot, kFirstIndex);
    4043       99335 :     CHECK_LT(empty_slot, array->length());
    4044             :     int next_empty_slot = array->Get(empty_slot).ToSmi().value();
    4045             : 
    4046      198670 :     array->Set(empty_slot, HeapObjectReference::Weak(*value));
    4047       99335 :     if (assigned_index != nullptr) *assigned_index = empty_slot;
    4048             : 
    4049             :     set_empty_slot_index(*array, next_empty_slot);
    4050       99335 :     return array;
    4051             :   } else {
    4052             :     DCHECK_EQ(empty_slot, kNoEmptySlotsMarker);
    4053             :   }
    4054             : 
    4055             :   // Array full and no empty slots. Grow the array.
    4056       15457 :   array = WeakArrayList::EnsureSpace(isolate, array, length + 1);
    4057       30914 :   array->Set(length, HeapObjectReference::Weak(*value));
    4058             :   array->set_length(length + 1);
    4059       15457 :   if (assigned_index != nullptr) *assigned_index = length;
    4060       15457 :   return array;
    4061             : }
    4062             : 
    4063          30 : WeakArrayList PrototypeUsers::Compact(Handle<WeakArrayList> array, Heap* heap,
    4064             :                                       CompactionCallback callback,
    4065             :                                       AllocationType allocation) {
    4066          30 :   if (array->length() == 0) {
    4067             :     return *array;
    4068             :   }
    4069          30 :   int new_length = kFirstIndex + array->CountLiveWeakReferences();
    4070          30 :   if (new_length == array->length()) {
    4071             :     return *array;
    4072             :   }
    4073             : 
    4074             :   Handle<WeakArrayList> new_array = WeakArrayList::EnsureSpace(
    4075             :       heap->isolate(),
    4076             :       handle(ReadOnlyRoots(heap).empty_weak_array_list(), heap->isolate()),
    4077           5 :       new_length, allocation);
    4078             :   // Allocation might have caused GC and turned some of the elements into
    4079             :   // cleared weak heap objects. Count the number of live objects again.
    4080             :   int copy_to = kFirstIndex;
    4081          35 :   for (int i = kFirstIndex; i < array->length(); i++) {
    4082             :     MaybeObject element = array->Get(i);
    4083          15 :     HeapObject value;
    4084          15 :     if (element->GetHeapObjectIfWeak(&value)) {
    4085           5 :       callback(value, i, copy_to);
    4086          10 :       new_array->Set(copy_to++, element);
    4087             :     } else {
    4088             :       DCHECK(element->IsCleared() || element->IsSmi());
    4089             :     }
    4090             :   }
    4091             :   new_array->set_length(copy_to);
    4092             :   set_empty_slot_index(*new_array, kNoEmptySlotsMarker);
    4093             :   return *new_array;
    4094             : }
    4095             : 
    4096     4257278 : Handle<RegExpMatchInfo> RegExpMatchInfo::ReserveCaptures(
    4097             :     Isolate* isolate, Handle<RegExpMatchInfo> match_info, int capture_count) {
    4098             :   DCHECK_GE(match_info->length(), kLastMatchOverhead);
    4099     4257278 :   const int required_length = kFirstCaptureIndex + capture_count;
    4100             :   return Handle<RegExpMatchInfo>::cast(
    4101     4257278 :       EnsureSpaceInFixedArray(isolate, match_info, required_length));
    4102             : }
    4103             : 
    4104             : // static
    4105     5004009 : Handle<FrameArray> FrameArray::AppendJSFrame(Handle<FrameArray> in,
    4106             :                                              Handle<Object> receiver,
    4107             :                                              Handle<JSFunction> function,
    4108             :                                              Handle<AbstractCode> code,
    4109             :                                              int offset, int flags,
    4110             :                                              Handle<FixedArray> parameters) {
    4111             :   const int frame_count = in->FrameCount();
    4112     5004009 :   const int new_length = LengthFor(frame_count + 1);
    4113             :   Handle<FrameArray> array =
    4114             :       EnsureSpace(function->GetIsolate(), in, new_length);
    4115    10008018 :   array->SetReceiver(frame_count, *receiver);
    4116    10008018 :   array->SetFunction(frame_count, *function);
    4117    10008018 :   array->SetCode(frame_count, *code);
    4118             :   array->SetOffset(frame_count, Smi::FromInt(offset));
    4119             :   array->SetFlags(frame_count, Smi::FromInt(flags));
    4120    10008018 :   array->SetParameters(frame_count, *parameters);
    4121             :   array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1));
    4122     5004009 :   return array;
    4123             : }
    4124             : 
    4125             : // static
    4126      156835 : Handle<FrameArray> FrameArray::AppendWasmFrame(
    4127             :     Handle<FrameArray> in, Handle<WasmInstanceObject> wasm_instance,
    4128             :     int wasm_function_index, wasm::WasmCode* code, int offset, int flags) {
    4129             :   Isolate* isolate = wasm_instance->GetIsolate();
    4130             :   const int frame_count = in->FrameCount();
    4131      156835 :   const int new_length = LengthFor(frame_count + 1);
    4132             :   Handle<FrameArray> array = EnsureSpace(isolate, in, new_length);
    4133             :   // The {code} will be {nullptr} for interpreted wasm frames.
    4134             :   Handle<Foreign> code_foreign =
    4135      156835 :       isolate->factory()->NewForeign(reinterpret_cast<Address>(code));
    4136      313670 :   array->SetWasmInstance(frame_count, *wasm_instance);
    4137             :   array->SetWasmFunctionIndex(frame_count, Smi::FromInt(wasm_function_index));
    4138      313670 :   array->SetWasmCodeObject(frame_count, *code_foreign);
    4139             :   array->SetOffset(frame_count, Smi::FromInt(offset));
    4140             :   array->SetFlags(frame_count, Smi::FromInt(flags));
    4141             :   array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1));
    4142      156835 :   return array;
    4143             : }
    4144             : 
    4145     1311087 : void FrameArray::ShrinkToFit(Isolate* isolate) {
    4146     1311087 :   Shrink(isolate, LengthFor(FrameCount()));
    4147     1311087 : }
    4148             : 
    4149             : // static
    4150           0 : Handle<FrameArray> FrameArray::EnsureSpace(Isolate* isolate,
    4151             :                                            Handle<FrameArray> array,
    4152             :                                            int length) {
    4153             :   return Handle<FrameArray>::cast(
    4154     5160844 :       EnsureSpaceInFixedArray(isolate, array, length));
    4155             : }
    4156             : 
    4157      464031 : Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
    4158             :                                                   int nof_descriptors,
    4159             :                                                   int slack,
    4160             :                                                   AllocationType allocation) {
    4161      464031 :   return nof_descriptors + slack == 0
    4162             :              ? isolate->factory()->empty_descriptor_array()
    4163             :              : isolate->factory()->NewDescriptorArray(nof_descriptors, slack,
    4164    37796751 :                                                       allocation);
    4165             : }
    4166             : 
    4167    18898368 : void DescriptorArray::Initialize(EnumCache enum_cache,
    4168             :                                  HeapObject undefined_value,
    4169             :                                  int nof_descriptors, int slack) {
    4170             :   DCHECK_GE(nof_descriptors, 0);
    4171             :   DCHECK_GE(slack, 0);
    4172             :   DCHECK_LE(nof_descriptors + slack, kMaxNumberOfDescriptors);
    4173    18898368 :   set_number_of_all_descriptors(nof_descriptors + slack);
    4174             :   set_number_of_descriptors(nof_descriptors);
    4175             :   set_raw_number_of_marked_descriptors(0);
    4176             :   set_filler16bits(0);
    4177    18898368 :   set_enum_cache(enum_cache);
    4178    18898365 :   MemsetTagged(GetDescriptorSlot(0), undefined_value,
    4179    18898365 :                number_of_all_descriptors() * kEntrySize);
    4180    18898370 : }
    4181             : 
    4182          43 : void DescriptorArray::ClearEnumCache() {
    4183          43 :   set_enum_cache(GetReadOnlyRoots().empty_enum_cache());
    4184          43 : }
    4185             : 
    4186      271497 : void DescriptorArray::Replace(int index, Descriptor* descriptor) {
    4187             :   descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index));
    4188      271498 :   Set(index, descriptor);
    4189      271497 : }
    4190             : 
    4191             : // static
    4192       48193 : void DescriptorArray::InitializeOrChangeEnumCache(
    4193             :     Handle<DescriptorArray> descriptors, Isolate* isolate,
    4194             :     Handle<FixedArray> keys, Handle<FixedArray> indices) {
    4195       48193 :   EnumCache enum_cache = descriptors->enum_cache();
    4196       48193 :   if (enum_cache == ReadOnlyRoots(isolate).empty_enum_cache()) {
    4197       94752 :     enum_cache = *isolate->factory()->NewEnumCache(keys, indices);
    4198       47376 :     descriptors->set_enum_cache(enum_cache);
    4199             :   } else {
    4200         817 :     enum_cache->set_keys(*keys);
    4201         817 :     enum_cache->set_indices(*indices);
    4202             :   }
    4203       48193 : }
    4204             : 
    4205   121705257 : void DescriptorArray::CopyFrom(int index, DescriptorArray src) {
    4206   121705257 :   PropertyDetails details = src->GetDetails(index);
    4207   121705290 :   Set(index, src->GetKey(index), src->GetValue(index), details);
    4208   121705308 : }
    4209             : 
    4210    14346908 : void DescriptorArray::Sort() {
    4211             :   // In-place heap sort.
    4212    14346908 :   int len = number_of_descriptors();
    4213             :   // Reset sorting since the descriptor array might contain invalid pointers.
    4214   107305541 :   for (int i = 0; i < len; ++i) SetSortedKey(i, i);
    4215             :   // Bottom-up max-heap construction.
    4216             :   // Index of the last node with children
    4217    14346932 :   const int max_parent_index = (len / 2) - 1;
    4218   101280658 :   for (int i = max_parent_index; i >= 0; --i) {
    4219             :     int parent_index = i;
    4220    43466863 :     const uint32_t parent_hash = GetSortedKey(i)->Hash();
    4221   106210518 :     while (parent_index <= max_parent_index) {
    4222    58380887 :       int child_index = 2 * parent_index + 1;
    4223    58380887 :       uint32_t child_hash = GetSortedKey(child_index)->Hash();
    4224    58380889 :       if (child_index + 1 < len) {
    4225    48342096 :         uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
    4226    48342087 :         if (right_child_hash > child_hash) {
    4227             :           child_index++;
    4228             :           child_hash = right_child_hash;
    4229             :         }
    4230             :       }
    4231    58380880 :       if (child_hash <= parent_hash) break;
    4232    31371836 :       SwapSortedKeys(parent_index, child_index);
    4233             :       // Now element at child_index could be < its children.
    4234             :       parent_index = child_index;  // parent_hash remains correct.
    4235             :     }
    4236             :   }
    4237             : 
    4238             :   // Extract elements and create sorted array.
    4239    92958230 :   for (int i = len - 1; i > 0; --i) {
    4240             :     // Put max element at the back of the array.
    4241    78611298 :     SwapSortedKeys(0, i);
    4242             :     // Shift down the new top element.
    4243             :     int parent_index = 0;
    4244    78611198 :     const uint32_t parent_hash = GetSortedKey(parent_index)->Hash();
    4245    78611517 :     const int max_parent_index = (i / 2) - 1;
    4246   329478553 :     while (parent_index <= max_parent_index) {
    4247   137472018 :       int child_index = parent_index * 2 + 1;
    4248   137472018 :       uint32_t child_hash = GetSortedKey(child_index)->Hash();
    4249   137471997 :       if (child_index + 1 < i) {
    4250   118063566 :         uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
    4251   118063623 :         if (right_child_hash > child_hash) {
    4252             :           child_index++;
    4253             :           child_hash = right_child_hash;
    4254             :         }
    4255             :       }
    4256   137472054 :       if (child_hash <= parent_hash) break;
    4257   125433773 :       SwapSortedKeys(parent_index, child_index);
    4258             :       parent_index = child_index;
    4259             :     }
    4260             :   }
    4261             :   DCHECK(IsSortedNoDuplicates());
    4262    14346932 : }
    4263             : 
    4264    37614677 : int16_t DescriptorArray::UpdateNumberOfMarkedDescriptors(
    4265             :     unsigned mark_compact_epoch, int16_t new_marked) {
    4266             :   STATIC_ASSERT(kMaxNumberOfDescriptors <=
    4267             :                 NumberOfMarkedDescriptors::kMaxNumberOfMarkedDescriptors);
    4268             :   int16_t old_raw_marked = raw_number_of_marked_descriptors();
    4269             :   int16_t old_marked =
    4270             :       NumberOfMarkedDescriptors::decode(mark_compact_epoch, old_raw_marked);
    4271             :   int16_t new_raw_marked =
    4272             :       NumberOfMarkedDescriptors::encode(mark_compact_epoch, new_marked);
    4273    37614689 :   while (old_marked < new_marked) {
    4274             :     int16_t actual_raw_marked = CompareAndSwapRawNumberOfMarkedDescriptors(
    4275             :         old_raw_marked, new_raw_marked);
    4276    23208484 :     if (actual_raw_marked == old_raw_marked) {
    4277             :       break;
    4278             :     }
    4279             :     old_raw_marked = actual_raw_marked;
    4280             :     old_marked =
    4281             :         NumberOfMarkedDescriptors::decode(mark_compact_epoch, old_raw_marked);
    4282             :   }
    4283    37614677 :   return old_marked;
    4284             : }
    4285             : 
    4286       15563 : Handle<AccessorPair> AccessorPair::Copy(Isolate* isolate,
    4287             :                                         Handle<AccessorPair> pair) {
    4288       15563 :   Handle<AccessorPair> copy = isolate->factory()->NewAccessorPair();
    4289       15563 :   copy->set_getter(pair->getter());
    4290       15563 :   copy->set_setter(pair->setter());
    4291       15563 :   return copy;
    4292             : }
    4293             : 
    4294       92557 : Handle<Object> AccessorPair::GetComponent(Isolate* isolate,
    4295             :                                           Handle<AccessorPair> accessor_pair,
    4296             :                                           AccessorComponent component) {
    4297       92557 :   Object accessor = accessor_pair->get(component);
    4298       92557 :   if (accessor->IsFunctionTemplateInfo()) {
    4299         178 :     return ApiNatives::InstantiateFunction(
    4300         178 :                handle(FunctionTemplateInfo::cast(accessor), isolate))
    4301          89 :         .ToHandleChecked();
    4302             :   }
    4303       92468 :   if (accessor->IsNull(isolate)) {
    4304        4461 :     return isolate->factory()->undefined_value();
    4305             :   }
    4306             :   return handle(accessor, isolate);
    4307             : }
    4308             : 
    4309             : #ifdef DEBUG
    4310             : bool DescriptorArray::IsEqualTo(DescriptorArray other) {
    4311             :   if (number_of_all_descriptors() != other->number_of_all_descriptors()) {
    4312             :     return false;
    4313             :   }
    4314             :   for (int i = 0; i < number_of_all_descriptors(); ++i) {
    4315             :     if (get(i) != other->get(i)) return false;
    4316             :   }
    4317             :   return true;
    4318             : }
    4319             : #endif
    4320             : 
    4321             : // static
    4322     1386052 : MaybeHandle<String> Name::ToFunctionName(Isolate* isolate, Handle<Name> name) {
    4323     1386052 :   if (name->IsString()) return Handle<String>::cast(name);
    4324             :   // ES6 section 9.2.11 SetFunctionName, step 4.
    4325             :   Handle<Object> description(Handle<Symbol>::cast(name)->name(), isolate);
    4326        5816 :   if (description->IsUndefined(isolate)) {
    4327          81 :     return isolate->factory()->empty_string();
    4328             :   }
    4329        5735 :   IncrementalStringBuilder builder(isolate);
    4330             :   builder.AppendCharacter('[');
    4331        5735 :   builder.AppendString(Handle<String>::cast(description));
    4332             :   builder.AppendCharacter(']');
    4333        5735 :   return builder.Finish();
    4334             : }
    4335             : 
    4336             : // static
    4337     1314080 : MaybeHandle<String> Name::ToFunctionName(Isolate* isolate, Handle<Name> name,
    4338             :                                          Handle<String> prefix) {
    4339             :   Handle<String> name_string;
    4340     2628168 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, name_string,
    4341             :                              ToFunctionName(isolate, name), String);
    4342     1314088 :   IncrementalStringBuilder builder(isolate);
    4343     1314087 :   builder.AppendString(prefix);
    4344             :   builder.AppendCharacter(' ');
    4345     1314093 :   builder.AppendString(name_string);
    4346     1314095 :   return builder.Finish();
    4347             : }
    4348             : 
    4349             : 
    4350       94928 : void Relocatable::PostGarbageCollectionProcessing(Isolate* isolate) {
    4351             :   Relocatable* current = isolate->relocatable_top();
    4352      157642 :   while (current != nullptr) {
    4353       31357 :     current->PostGarbageCollection();
    4354       31357 :     current = current->prev_;
    4355             :   }
    4356       94928 : }
    4357             : 
    4358             : 
    4359             : // Reserve space for statics needing saving and restoring.
    4360        1133 : int Relocatable::ArchiveSpacePerThread() {
    4361        1133 :   return sizeof(Relocatable*);  // NOLINT
    4362             : }
    4363             : 
    4364             : 
    4365             : // Archive statics that are thread-local.
    4366       32437 : char* Relocatable::ArchiveState(Isolate* isolate, char* to) {
    4367       32437 :   *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top();
    4368             :   isolate->set_relocatable_top(nullptr);
    4369       32437 :   return to + ArchiveSpacePerThread();
    4370             : }
    4371             : 
    4372             : 
    4373             : // Restore statics that are thread-local.
    4374       32437 : char* Relocatable::RestoreState(Isolate* isolate, char* from) {
    4375       32437 :   isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from));
    4376       32437 :   return from + ArchiveSpacePerThread();
    4377             : }
    4378             : 
    4379        5546 : char* Relocatable::Iterate(RootVisitor* v, char* thread_storage) {
    4380        5546 :   Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage);
    4381             :   Iterate(v, top);
    4382        5546 :   return thread_storage + ArchiveSpacePerThread();
    4383             : }
    4384             : 
    4385      276888 : void Relocatable::Iterate(Isolate* isolate, RootVisitor* v) {
    4386             :   Iterate(v, isolate->relocatable_top());
    4387      276888 : }
    4388             : 
    4389           0 : void Relocatable::Iterate(RootVisitor* v, Relocatable* top) {
    4390             :   Relocatable* current = top;
    4391      348124 :   while (current != nullptr) {
    4392       65690 :     current->IterateInstance(v);
    4393       65690 :     current = current->prev_;
    4394             :   }
    4395           0 : }
    4396             : 
    4397             : 
    4398             : 
    4399             : 
    4400             : 
    4401             : namespace {
    4402             : 
    4403             : template <typename sinkchar>
    4404      104292 : void WriteFixedArrayToFlat(FixedArray fixed_array, int length, String separator,
    4405             :                            sinkchar* sink, int sink_length) {
    4406             :   DisallowHeapAllocation no_allocation;
    4407      104292 :   CHECK_GT(length, 0);
    4408      104292 :   CHECK_LE(length, fixed_array->length());
    4409             : #ifdef DEBUG
    4410             :   sinkchar* sink_end = sink + sink_length;
    4411             : #endif
    4412             : 
    4413             :   const int separator_length = separator->length();
    4414             :   const bool use_one_byte_separator_fast_path =
    4415             :       separator_length == 1 && sizeof(sinkchar) == 1 &&
    4416      165068 :       StringShape(separator).IsSequentialOneByte();
    4417             :   uint8_t separator_one_char;
    4418      102802 :   if (use_one_byte_separator_fast_path) {
    4419      124532 :     CHECK(StringShape(separator).IsSequentialOneByte());
    4420       62266 :     CHECK_EQ(separator->length(), 1);
    4421       62266 :     separator_one_char =
    4422             :         SeqOneByteString::cast(separator)->GetChars(no_allocation)[0];
    4423             :   }
    4424             : 
    4425      104292 :   uint32_t num_separators = 0;
    4426    77658380 :   for (int i = 0; i < length; i++) {
    4427    38777044 :     Object element = fixed_array->get(i);
    4428             :     const bool element_is_separator_sequence = element->IsSmi();
    4429             : 
    4430             :     // If element is a Smi, it represents the number of separators to write.
    4431    38777044 :     if (V8_UNLIKELY(element_is_separator_sequence)) {
    4432        6593 :       CHECK(element->ToUint32(&num_separators));
    4433             :       // Verify that Smis (number of separators) only occur when necessary:
    4434             :       //   1) at the beginning
    4435             :       //   2) at the end
    4436             :       //   3) when the number of separators > 1
    4437             :       //     - It is assumed that consecutive Strings will have one separator,
    4438             :       //       so there is no need for a Smi.
    4439             :       DCHECK(i == 0 || i == length - 1 || num_separators > 1);
    4440             :     }
    4441             : 
    4442             :     // Write separator(s) if necessary.
    4443    38777044 :     if (num_separators > 0 && separator_length > 0) {
    4444             :       // TODO(pwong): Consider doubling strategy employed by runtime-strings.cc
    4445             :       //              WriteRepeatToFlat().
    4446             :       // Fast path for single character, single byte separators.
    4447    31001169 :       if (use_one_byte_separator_fast_path) {
    4448             :         DCHECK_LE(sink + num_separators, sink_end);
    4449    29388735 :         memset(sink, separator_one_char, num_separators);
    4450             :         DCHECK_EQ(separator_length, 1);
    4451    29388735 :         sink += num_separators;
    4452             :       } else {
    4453     4841352 :         for (uint32_t j = 0; j < num_separators; j++) {
    4454             :           DCHECK_LE(sink + separator_length, sink_end);
    4455     1614165 :           String::WriteToFlat(separator, sink, 0, separator_length);
    4456     1614165 :           sink += separator_length;
    4457             :         }
    4458             :       }
    4459             :     }
    4460             : 
    4461    38777044 :     if (V8_UNLIKELY(element_is_separator_sequence)) {
    4462        6593 :       num_separators = 0;
    4463             :     } else {
    4464             :       DCHECK(element->IsString());
    4465             :       String string = String::cast(element);
    4466             :       const int string_length = string->length();
    4467             : 
    4468             :       DCHECK(string_length == 0 || sink < sink_end);
    4469    38770451 :       String::WriteToFlat(string, sink, 0, string_length);
    4470    38770451 :       sink += string_length;
    4471             : 
    4472             :       // Next string element, needs at least one separator preceding it.
    4473    38770451 :       num_separators = 1;
    4474             :     }
    4475             :   }
    4476             : 
    4477             :   // Verify we have written to the end of the sink.
    4478             :   DCHECK_EQ(sink, sink_end);
    4479      104292 : }
    4480             : 
    4481             : }  // namespace
    4482             : 
    4483             : // static
    4484      104292 : Address JSArray::ArrayJoinConcatToSequentialString(Isolate* isolate,
    4485             :                                                    Address raw_fixed_array,
    4486             :                                                    intptr_t length,
    4487             :                                                    Address raw_separator,
    4488             :                                                    Address raw_dest) {
    4489             :   DisallowHeapAllocation no_allocation;
    4490      208584 :   DisallowJavascriptExecution no_js(isolate);
    4491      104292 :   FixedArray fixed_array = FixedArray::cast(Object(raw_fixed_array));
    4492      104292 :   String separator = String::cast(Object(raw_separator));
    4493             :   String dest = String::cast(Object(raw_dest));
    4494             :   DCHECK(fixed_array->IsFixedArray());
    4495             :   DCHECK(StringShape(dest).IsSequentialOneByte() ||
    4496             :          StringShape(dest).IsSequentialTwoByte());
    4497             : 
    4498      208584 :   if (StringShape(dest).IsSequentialOneByte()) {
    4499      102802 :     WriteFixedArrayToFlat(fixed_array, static_cast<int>(length), separator,
    4500             :                           SeqOneByteString::cast(dest)->GetChars(no_allocation),
    4501      102802 :                           dest->length());
    4502             :   } else {
    4503             :     DCHECK(StringShape(dest).IsSequentialTwoByte());
    4504        1490 :     WriteFixedArrayToFlat(fixed_array, static_cast<int>(length), separator,
    4505             :                           SeqTwoByteString::cast(dest)->GetChars(no_allocation),
    4506        1490 :                           dest->length());
    4507             :   }
    4508      104292 :   return dest->ptr();
    4509             : }
    4510             : 
    4511             : 
    4512             : 
    4513             : 
    4514     5357861 : uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
    4515             :   // For array indexes mix the length into the hash as an array index could
    4516             :   // be zero.
    4517             :   DCHECK_GT(length, 0);
    4518             :   DCHECK_LE(length, String::kMaxArrayIndexSize);
    4519             :   DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) <
    4520             :          (1 << String::kArrayIndexValueBits));
    4521             : 
    4522     5566068 :   value <<= String::ArrayIndexValueBits::kShift;
    4523     5566068 :   value |= length << String::ArrayIndexLengthBits::kShift;
    4524             : 
    4525             :   DCHECK_EQ(value & String::kIsNotArrayIndexMask, 0);
    4526             :   DCHECK_EQ(length <= String::kMaxCachedArrayIndexLength,
    4527             :             Name::ContainsCachedArrayIndex(value));
    4528     5357861 :   return value;
    4529             : }
    4530             : 
    4531             : 
    4532    93362813 : uint32_t StringHasher::GetHashField() {
    4533    93362813 :   if (length_ <= String::kMaxHashCalcLength) {
    4534    93295869 :     if (is_array_index_) {
    4535      411148 :       return MakeArrayIndexHash(array_index_, length_);
    4536             :     }
    4537   186180590 :     return (GetHashCore(raw_running_hash_) << String::kHashShift) |
    4538    93090295 :            String::kIsNotArrayIndexMask;
    4539             :   } else {
    4540       66944 :     return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask;
    4541             :   }
    4542             : }
    4543             : 
    4544    13466791 : uint32_t StringHasher::ComputeUtf8Hash(Vector<const char> chars, uint64_t seed,
    4545             :                                        int* utf16_length_out) {
    4546             :   int vector_length = chars.length();
    4547             :   // Handle some edge cases
    4548    13466791 :   if (vector_length <= 1) {
    4549             :     DCHECK(vector_length == 0 ||
    4550             :            static_cast<uint8_t>(chars.start()[0]) <=
    4551             :                unibrow::Utf8::kMaxOneByteChar);
    4552        2679 :     *utf16_length_out = vector_length;
    4553        2679 :     return HashSequentialString(chars.start(), vector_length, seed);
    4554             :   }
    4555             : 
    4556             :   // Start with a fake length which won't affect computation.
    4557             :   // It will be updated later.
    4558             :   StringHasher hasher(String::kMaxArrayIndexSize, seed);
    4559             :   DCHECK(hasher.is_array_index_);
    4560             : 
    4561             :   unibrow::Utf8Iterator it = unibrow::Utf8Iterator(chars);
    4562             :   int utf16_length = 0;
    4563             :   bool is_index = true;
    4564             : 
    4565   104044153 :   while (utf16_length < String::kMaxHashCalcLength && !it.Done()) {
    4566    90580056 :     utf16_length++;
    4567    90580056 :     uint16_t c = *it;
    4568    90580060 :     ++it;
    4569             :     hasher.AddCharacter(c);
    4570    90580050 :     if (is_index) is_index = hasher.UpdateIndex(c);
    4571             :   }
    4572             : 
    4573             :   // Now that hashing is done, we just need to calculate utf16_length
    4574    13464123 :   while (!it.Done()) {
    4575           0 :     ++it;
    4576           0 :     utf16_length++;
    4577             :   }
    4578             : 
    4579    13464123 :   *utf16_length_out = utf16_length;
    4580             :   // Must set length here so that hash computation is correct.
    4581    13464123 :   hasher.length_ = utf16_length;
    4582    13464123 :   return hasher.GetHashField();
    4583             : }
    4584             : 
    4585      110005 : void IteratingStringHasher::VisitConsString(ConsString cons_string) {
    4586             :   // Run small ConsStrings through ConsStringIterator.
    4587      110005 :   if (cons_string->length() < 64) {
    4588       65204 :     ConsStringIterator iter(cons_string);
    4589             :     int offset;
    4590      164752 :     for (String string = iter.Next(&offset); !string.is_null();
    4591             :          string = iter.Next(&offset)) {
    4592             :       DCHECK_EQ(0, offset);
    4593       99548 :       String::VisitFlat(this, string, 0);
    4594             :     }
    4595             :     return;
    4596             :   }
    4597             :   // Slow case.
    4598       44801 :   const int max_length = String::kMaxHashCalcLength;
    4599       89602 :   int length = std::min(cons_string->length(), max_length);
    4600       44801 :   if (cons_string->IsOneByteRepresentation()) {
    4601       44801 :     uint8_t* buffer = new uint8_t[length];
    4602       44801 :     String::WriteToFlat(cons_string, buffer, 0, length);
    4603       44801 :     AddCharacters(buffer, length);
    4604       44801 :     delete[] buffer;
    4605             :   } else {
    4606           0 :     uint16_t* buffer = new uint16_t[length];
    4607           0 :     String::WriteToFlat(cons_string, buffer, 0, length);
    4608           0 :     AddCharacters(buffer, length);
    4609           0 :     delete[] buffer;
    4610             :   }
    4611             : }
    4612             : 
    4613         222 : Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
    4614             :                                        Handle<Map> initial_map) {
    4615             :   // Replace all of the cached initial array maps in the native context with
    4616             :   // the appropriate transitioned elements kind maps.
    4617         222 :   Handle<Map> current_map = initial_map;
    4618             :   ElementsKind kind = current_map->elements_kind();
    4619             :   DCHECK_EQ(GetInitialFastElementsKind(), kind);
    4620             :   native_context->set(Context::ArrayMapIndex(kind), *current_map);
    4621        1332 :   for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
    4622        1332 :        i < kFastElementsKindCount; ++i) {
    4623             :     Handle<Map> new_map;
    4624        1110 :     ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
    4625        1110 :     Map maybe_elements_transition = current_map->ElementsTransitionMap();
    4626        1110 :     if (!maybe_elements_transition.is_null()) {
    4627             :       new_map = handle(maybe_elements_transition, native_context->GetIsolate());
    4628             :     } else {
    4629             :       new_map =
    4630             :           Map::CopyAsElementsKind(native_context->GetIsolate(), current_map,
    4631        2220 :                                   next_kind, INSERT_TRANSITION);
    4632             :     }
    4633             :     DCHECK_EQ(next_kind, new_map->elements_kind());
    4634             :     native_context->set(Context::ArrayMapIndex(next_kind), *new_map);
    4635             :     current_map = new_map;
    4636             :   }
    4637         222 :   return initial_map;
    4638             : }
    4639             : 
    4640             : STATIC_ASSERT(Oddball::kToNumberRawOffset == HeapNumber::kValueOffset);
    4641             : 
    4642         672 : void Oddball::Initialize(Isolate* isolate, Handle<Oddball> oddball,
    4643             :                          const char* to_string, Handle<Object> to_number,
    4644             :                          const char* type_of, byte kind) {
    4645             :   Handle<String> internalized_to_string =
    4646         672 :       isolate->factory()->InternalizeUtf8String(to_string);
    4647             :   Handle<String> internalized_type_of =
    4648         672 :       isolate->factory()->InternalizeUtf8String(type_of);
    4649         672 :   if (to_number->IsHeapNumber()) {
    4650             :     oddball->set_to_number_raw_as_bits(
    4651             :         Handle<HeapNumber>::cast(to_number)->value_as_bits());
    4652             :   } else {
    4653             :     oddball->set_to_number_raw(to_number->Number());
    4654             :   }
    4655         672 :   oddball->set_to_number(*to_number);
    4656         672 :   oddball->set_to_string(*internalized_to_string);
    4657         672 :   oddball->set_type_of(*internalized_type_of);
    4658             :   oddball->set_kind(kind);
    4659         672 : }
    4660             : 
    4661        2091 : int Script::GetEvalPosition() {
    4662             :   DisallowHeapAllocation no_gc;
    4663             :   DCHECK(compilation_type() == Script::COMPILATION_TYPE_EVAL);
    4664             :   int position = eval_from_position();
    4665        2091 :   if (position < 0) {
    4666             :     // Due to laziness, the position may not have been translated from code
    4667             :     // offset yet, which would be encoded as negative integer. In that case,
    4668             :     // translate and set the position.
    4669         780 :     if (!has_eval_from_shared()) {
    4670             :       position = 0;
    4671             :     } else {
    4672         780 :       SharedFunctionInfo shared = eval_from_shared();
    4673         780 :       position = shared->abstract_code()->SourcePosition(-position);
    4674             :     }
    4675             :     DCHECK_GE(position, 0);
    4676             :     set_eval_from_position(position);
    4677             :   }
    4678        2091 :   return position;
    4679             : }
    4680             : 
    4681     2580090 : void Script::InitLineEnds(Handle<Script> script) {
    4682             :   Isolate* isolate = script->GetIsolate();
    4683     2580090 :   if (!script->line_ends()->IsUndefined(isolate)) return;
    4684             :   DCHECK(script->type() != Script::TYPE_WASM ||
    4685             :          script->source_mapping_url()->IsString());
    4686             : 
    4687             :   Object src_obj = script->source();
    4688       46790 :   if (!src_obj->IsString()) {
    4689             :     DCHECK(src_obj->IsUndefined(isolate));
    4690          10 :     script->set_line_ends(ReadOnlyRoots(isolate).empty_fixed_array());
    4691             :   } else {
    4692             :     DCHECK(src_obj->IsString());
    4693             :     Handle<String> src(String::cast(src_obj), isolate);
    4694       46785 :     Handle<FixedArray> array = String::CalculateLineEnds(isolate, src, true);
    4695       93570 :     script->set_line_ends(*array);
    4696             :   }
    4697             : 
    4698             :   DCHECK(script->line_ends()->IsFixedArray());
    4699             : }
    4700             : 
    4701     2363615 : bool Script::GetPositionInfo(Handle<Script> script, int position,
    4702             :                              PositionInfo* info, OffsetFlag offset_flag) {
    4703             :   // For wasm, we do not create an artificial line_ends array, but do the
    4704             :   // translation directly.
    4705     2363615 :   if (script->type() != Script::TYPE_WASM) InitLineEnds(script);
    4706     2363616 :   return script->GetPositionInfo(position, info, offset_flag);
    4707             : }
    4708             : 
    4709    20867584 : bool Script::IsUserJavaScript() { return type() == Script::TYPE_NORMAL; }
    4710             : 
    4711         382 : bool Script::ContainsAsmModule() {
    4712             :   DisallowHeapAllocation no_gc;
    4713         382 :   SharedFunctionInfo::ScriptIterator iter(this->GetIsolate(), *this);
    4714       15330 :   for (SharedFunctionInfo info = iter.Next(); !info.is_null();
    4715             :        info = iter.Next()) {
    4716        7291 :     if (info->HasAsmWasmData()) return true;
    4717             :   }
    4718         374 :   return false;
    4719             : }
    4720             : 
    4721             : namespace {
    4722      269454 : bool GetPositionInfoSlow(const Script script, int position,
    4723             :                          Script::PositionInfo* info) {
    4724      269454 :   if (!script->source()->IsString()) return false;
    4725      269454 :   if (position < 0) position = 0;
    4726             : 
    4727             :   String source_string = String::cast(script->source());
    4728             :   int line = 0;
    4729             :   int line_start = 0;
    4730             :   int len = source_string->length();
    4731 11294870348 :   for (int pos = 0; pos <= len; ++pos) {
    4732 11295138760 :     if (pos == len || source_string->Get(pos) == '\n') {
    4733   180482023 :       if (position <= pos) {
    4734      269444 :         info->line = line;
    4735      269444 :         info->column = position - line_start;
    4736      269444 :         info->line_start = line_start;
    4737      269444 :         info->line_end = pos;
    4738      269444 :         return true;
    4739             :       }
    4740   180212579 :       line++;
    4741   180212579 :       line_start = pos + 1;
    4742             :     }
    4743             :   }
    4744             :   return false;
    4745             : }
    4746             : }  // namespace
    4747             : 
    4748             : #define SMI_VALUE(x) (Smi::ToInt(x))
    4749     5347175 : bool Script::GetPositionInfo(int position, PositionInfo* info,
    4750             :                              OffsetFlag offset_flag) const {
    4751             :   DisallowHeapAllocation no_allocation;
    4752             : 
    4753             :   // For wasm, we do not rely on the line_ends array, but do the translation
    4754             :   // directly.
    4755     5347175 :   if (type() == Script::TYPE_WASM) {
    4756             :     DCHECK_LE(0, position);
    4757        1480 :     return WasmModuleObject::cast(wasm_module_object())
    4758        1480 :         ->GetPositionInfo(static_cast<uint32_t>(position), info);
    4759             :   }
    4760             : 
    4761     5346435 :   if (line_ends()->IsUndefined()) {
    4762             :     // Slow mode: we do not have line_ends. We have to iterate through source.
    4763      269454 :     if (!GetPositionInfoSlow(*this, position, info)) return false;
    4764             :   } else {
    4765             :     DCHECK(line_ends()->IsFixedArray());
    4766             :     FixedArray ends = FixedArray::cast(line_ends());
    4767             : 
    4768             :     const int ends_len = ends->length();
    4769     5076981 :     if (ends_len == 0) return false;
    4770             : 
    4771             :     // Return early on invalid positions. Negative positions behave as if 0 was
    4772             :     // passed, and positions beyond the end of the script return as failure.
    4773     5076966 :     if (position < 0) {
    4774             :       position = 0;
    4775    10153902 :     } else if (position > SMI_VALUE(ends->get(ends_len - 1))) {
    4776             :       return false;
    4777             :     }
    4778             : 
    4779             :     // Determine line number by doing a binary search on the line ends array.
    4780     5071605 :     if (SMI_VALUE(ends->get(0)) >= position) {
    4781      261985 :       info->line = 0;
    4782      261985 :       info->line_start = 0;
    4783      261985 :       info->column = position;
    4784             :     } else {
    4785             :       int left = 0;
    4786     4809620 :       int right = ends_len - 1;
    4787             : 
    4788    44346032 :       while (right > 0) {
    4789             :         DCHECK_LE(left, right);
    4790    44346032 :         const int mid = (left + right) / 2;
    4791    44346032 :         if (position > SMI_VALUE(ends->get(mid))) {
    4792    20624924 :           left = mid + 1;
    4793    47442216 :         } else if (position <= SMI_VALUE(ends->get(mid - 1))) {
    4794             :           right = mid - 1;
    4795             :         } else {
    4796     4809620 :           info->line = mid;
    4797     4809620 :           break;
    4798             :         }
    4799             :       }
    4800             :       DCHECK(SMI_VALUE(ends->get(info->line)) >= position &&
    4801             :              SMI_VALUE(ends->get(info->line - 1)) < position);
    4802     9619240 :       info->line_start = SMI_VALUE(ends->get(info->line - 1)) + 1;
    4803     4809620 :       info->column = position - info->line_start;
    4804             :     }
    4805             : 
    4806             :     // Line end is position of the linebreak character.
    4807    10143209 :     info->line_end = SMI_VALUE(ends->get(info->line));
    4808     5071604 :     if (info->line_end > 0) {
    4809             :       DCHECK(source()->IsString());
    4810             :       String src = String::cast(source());
    4811    10141215 :       if (src->length() >= info->line_end &&
    4812     5070608 :           src->Get(info->line_end - 1) == '\r') {
    4813           0 :         info->line_end--;
    4814             :       }
    4815             :     }
    4816             :   }
    4817             : 
    4818             :   // Add offsets if requested.
    4819     5341047 :   if (offset_flag == WITH_OFFSET) {
    4820     5207948 :     if (info->line == 0) {
    4821      442503 :       info->column += column_offset();
    4822             :     }
    4823     5207948 :     info->line += line_offset();
    4824             :   }
    4825             : 
    4826             :   return true;
    4827             : }
    4828             : #undef SMI_VALUE
    4829             : 
    4830      851701 : int Script::GetColumnNumber(Handle<Script> script, int code_pos) {
    4831             :   PositionInfo info;
    4832      851701 :   GetPositionInfo(script, code_pos, &info, WITH_OFFSET);
    4833      851701 :   return info.column;
    4834             : }
    4835             : 
    4836      134726 : int Script::GetColumnNumber(int code_pos) const {
    4837             :   PositionInfo info;
    4838      134726 :   GetPositionInfo(code_pos, &info, WITH_OFFSET);
    4839      134726 :   return info.column;
    4840             : }
    4841             : 
    4842      856850 : int Script::GetLineNumber(Handle<Script> script, int code_pos) {
    4843             :   PositionInfo info;
    4844      856850 :   GetPositionInfo(script, code_pos, &info, WITH_OFFSET);
    4845      856850 :   return info.line;
    4846             : }
    4847             : 
    4848     2848487 : int Script::GetLineNumber(int code_pos) const {
    4849             :   PositionInfo info;
    4850     2848487 :   GetPositionInfo(code_pos, &info, WITH_OFFSET);
    4851     2848485 :   return info.line;
    4852             : }
    4853             : 
    4854       16969 : Object Script::GetNameOrSourceURL() {
    4855             :   // Keep in sync with ScriptNameOrSourceURL in messages.js.
    4856       16969 :   if (!source_url()->IsUndefined()) return source_url();
    4857             :   return name();
    4858             : }
    4859             : 
    4860     4112234 : MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
    4861             :     Isolate* isolate, const FunctionLiteral* fun) {
    4862     4112234 :   CHECK_NE(fun->function_literal_id(), kFunctionLiteralIdInvalid);
    4863             :   // If this check fails, the problem is most probably the function id
    4864             :   // renumbering done by AstFunctionLiteralIdReindexer; in particular, that
    4865             :   // AstTraversalVisitor doesn't recurse properly in the construct which
    4866             :   // triggers the mismatch.
    4867     4112234 :   CHECK_LT(fun->function_literal_id(), shared_function_infos()->length());
    4868             :   MaybeObject shared = shared_function_infos()->Get(fun->function_literal_id());
    4869             :   HeapObject heap_object;
    4870     8222617 :   if (!shared->GetHeapObject(&heap_object) ||
    4871             :       heap_object->IsUndefined(isolate)) {
    4872     2602739 :     return MaybeHandle<SharedFunctionInfo>();
    4873             :   }
    4874     1509499 :   return handle(SharedFunctionInfo::cast(heap_object), isolate);
    4875             : }
    4876             : 
    4877      135691 : Script::Iterator::Iterator(Isolate* isolate)
    4878      135691 :     : iterator_(isolate->heap()->script_list()) {}
    4879             : 
    4880     5197972 : Script Script::Iterator::Next() {
    4881     5197992 :   Object o = iterator_.Next();
    4882     5197992 :   if (o != Object()) {
    4883             :     return Script::cast(o);
    4884             :   }
    4885        4171 :   return Script();
    4886             : }
    4887             : 
    4888        3438 : uint32_t SharedFunctionInfo::Hash() {
    4889             :   // Hash SharedFunctionInfo based on its start position and script id. Note: we
    4890             :   // don't use the function's literal id since getting that is slow for compiled
    4891             :   // funcitons.
    4892        3438 :   int start_pos = StartPosition();
    4893       10314 :   int script_id = script()->IsScript() ? Script::cast(script())->id() : 0;
    4894        3438 :   return static_cast<uint32_t>(base::hash_combine(start_pos, script_id));
    4895             : }
    4896             : 
    4897    17684014 : Code SharedFunctionInfo::GetCode() const {
    4898             :   // ======
    4899             :   // NOTE: This chain of checks MUST be kept in sync with the equivalent CSA
    4900             :   // GetSharedFunctionInfoCode method in code-stub-assembler.cc.
    4901             :   // ======
    4902             : 
    4903             :   Isolate* isolate = GetIsolate();
    4904             :   Object data = function_data();
    4905    17684048 :   if (data->IsSmi()) {
    4906             :     // Holding a Smi means we are a builtin.
    4907             :     DCHECK(HasBuiltinId());
    4908     3434023 :     return isolate->builtins()->builtin(builtin_id());
    4909    14250030 :   } else if (data->IsBytecodeArray()) {
    4910             :     // Having a bytecode array means we are a compiled, interpreted function.
    4911             :     DCHECK(HasBytecodeArray());
    4912     6969659 :     return isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
    4913     7280371 :   } else if (data->IsAsmWasmData()) {
    4914             :     // Having AsmWasmData means we are an asm.js/wasm function.
    4915             :     DCHECK(HasAsmWasmData());
    4916        4489 :     return isolate->builtins()->builtin(Builtins::kInstantiateAsmJs);
    4917     7275882 :   } else if (data->IsUncompiledData()) {
    4918             :     // Having uncompiled data (with or without scope) means we need to compile.
    4919             :     DCHECK(HasUncompiledData());
    4920     3281329 :     return isolate->builtins()->builtin(Builtins::kCompileLazy);
    4921     3994553 :   } else if (data->IsFunctionTemplateInfo()) {
    4922             :     // Having a function template info means we are an API function.
    4923             :     DCHECK(IsApiFunction());
    4924     3752713 :     return isolate->builtins()->builtin(Builtins::kHandleApiCall);
    4925      241840 :   } else if (data->IsWasmExportedFunctionData()) {
    4926             :     // Having a WasmExportedFunctionData means the code is in there.
    4927             :     DCHECK(HasWasmExportedFunctionData());
    4928             :     return wasm_exported_function_data()->wrapper_code();
    4929          34 :   } else if (data->IsInterpreterData()) {
    4930          34 :     Code code = InterpreterTrampoline();
    4931             :     DCHECK(code->IsCode());
    4932             :     DCHECK(code->is_interpreter_trampoline_builtin());
    4933          34 :     return code;
    4934             :   }
    4935           0 :   UNREACHABLE();
    4936             : }
    4937             : 
    4938      544113 : WasmExportedFunctionData SharedFunctionInfo::wasm_exported_function_data()
    4939             :     const {
    4940             :   DCHECK(HasWasmExportedFunctionData());
    4941      544113 :   return WasmExportedFunctionData::cast(function_data());
    4942             : }
    4943             : 
    4944      122770 : SharedFunctionInfo::ScriptIterator::ScriptIterator(Isolate* isolate,
    4945             :                                                    Script script)
    4946             :     : ScriptIterator(isolate,
    4947      122770 :                      handle(script->shared_function_infos(), isolate)) {}
    4948             : 
    4949           0 : SharedFunctionInfo::ScriptIterator::ScriptIterator(
    4950             :     Isolate* isolate, Handle<WeakFixedArray> shared_function_infos)
    4951             :     : isolate_(isolate),
    4952             :       shared_function_infos_(shared_function_infos),
    4953      235855 :       index_(0) {}
    4954             : 
    4955     2183599 : SharedFunctionInfo SharedFunctionInfo::ScriptIterator::Next() {
    4956     6297310 :   while (index_ < shared_function_infos_->length()) {
    4957     3025947 :     MaybeObject raw = shared_function_infos_->Get(index_++);
    4958             :     HeapObject heap_object;
    4959     5686764 :     if (!raw->GetHeapObject(&heap_object) ||
    4960     2660817 :         heap_object->IsUndefined(isolate_)) {
    4961             :       continue;
    4962             :     }
    4963             :     return SharedFunctionInfo::cast(heap_object);
    4964             :   }
    4965      122708 :   return SharedFunctionInfo();
    4966             : }
    4967             : 
    4968          10 : void SharedFunctionInfo::ScriptIterator::Reset(Script script) {
    4969          20 :   shared_function_infos_ = handle(script->shared_function_infos(), isolate_);
    4970          10 :   index_ = 0;
    4971          10 : }
    4972             : 
    4973           5 : SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate)
    4974             :     : script_iterator_(isolate),
    4975             :       noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()),
    4976           5 :       sfi_iterator_(isolate, script_iterator_.Next()) {}
    4977             : 
    4978        3496 : SharedFunctionInfo SharedFunctionInfo::GlobalIterator::Next() {
    4979        3496 :   HeapObject next = noscript_sfi_iterator_.Next();
    4980        3496 :   if (!next.is_null()) return SharedFunctionInfo::cast(next);
    4981          10 :   for (;;) {
    4982          65 :     next = sfi_iterator_.Next();
    4983          65 :     if (!next.is_null()) return SharedFunctionInfo::cast(next);
    4984             :     Script next_script = script_iterator_.Next();
    4985          15 :     if (next_script.is_null()) return SharedFunctionInfo();
    4986          10 :     sfi_iterator_.Reset(next_script);
    4987             :   }
    4988             : }
    4989             : 
    4990     3602795 : void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
    4991             :                                    Handle<Object> script_object,
    4992             :                                    int function_literal_id,
    4993             :                                    bool reset_preparsed_scope_data) {
    4994     7205596 :   if (shared->script() == *script_object) return;
    4995             :   Isolate* isolate = shared->GetIsolate();
    4996             : 
    4997    10808394 :   if (reset_preparsed_scope_data &&
    4998     3603058 :       shared->HasUncompiledDataWithPreparseData()) {
    4999           0 :     shared->ClearPreparseData();
    5000             :   }
    5001             : 
    5002             :   // Add shared function info to new script's list. If a collection occurs,
    5003             :   // the shared function info may be temporarily in two lists.
    5004             :   // This is okay because the gc-time processing of these lists can tolerate
    5005             :   // duplicates.
    5006     3602798 :   if (script_object->IsScript()) {
    5007             :     DCHECK(!shared->script()->IsScript());
    5008             :     Handle<Script> script = Handle<Script>::cast(script_object);
    5009             :     Handle<WeakFixedArray> list =
    5010             :         handle(script->shared_function_infos(), isolate);
    5011             : #ifdef DEBUG
    5012             :     DCHECK_LT(function_literal_id, list->length());
    5013             :     MaybeObject maybe_object = list->Get(function_literal_id);
    5014             :     HeapObject heap_object;
    5015             :     if (maybe_object->GetHeapObjectIfWeak(&heap_object)) {
    5016             :       DCHECK_EQ(heap_object, *shared);
    5017             :     }
    5018             : #endif
    5019     7205600 :     list->Set(function_literal_id, HeapObjectReference::Weak(*shared));
    5020             : 
    5021             :     // Remove shared function info from root array.
    5022             :     WeakArrayList noscript_list =
    5023     3602802 :         isolate->heap()->noscript_shared_function_infos();
    5024     3602802 :     CHECK(noscript_list->RemoveOne(MaybeObjectHandle::Weak(shared)));
    5025             :   } else {
    5026             :     DCHECK(shared->script()->IsScript());
    5027             :     Handle<WeakArrayList> list =
    5028             :         isolate->factory()->noscript_shared_function_infos();
    5029             : 
    5030             : #ifdef DEBUG
    5031             :     if (FLAG_enable_slow_asserts) {
    5032             :       WeakArrayList::Iterator iterator(*list);
    5033             :       for (HeapObject next = iterator.Next(); !next.is_null();
    5034             :            next = iterator.Next()) {
    5035             :         DCHECK_NE(next, *shared);
    5036             :       }
    5037             :     }
    5038             : #endif  // DEBUG
    5039             : 
    5040             :     list =
    5041           0 :         WeakArrayList::AddToEnd(isolate, list, MaybeObjectHandle::Weak(shared));
    5042             : 
    5043             :     isolate->heap()->SetRootNoScriptSharedFunctionInfos(*list);
    5044             : 
    5045             :     // Remove shared function info from old script's list.
    5046           0 :     Script old_script = Script::cast(shared->script());
    5047             : 
    5048             :     // Due to liveedit, it might happen that the old_script doesn't know
    5049             :     // about the SharedFunctionInfo, so we have to guard against that.
    5050             :     Handle<WeakFixedArray> infos(old_script->shared_function_infos(), isolate);
    5051           0 :     if (function_literal_id < infos->length()) {
    5052             :       MaybeObject raw =
    5053             :           old_script->shared_function_infos()->Get(function_literal_id);
    5054             :       HeapObject heap_object;
    5055           0 :       if (raw->GetHeapObjectIfWeak(&heap_object) && heap_object == *shared) {
    5056           0 :         old_script->shared_function_infos()->Set(
    5057           0 :             function_literal_id, HeapObjectReference::Strong(
    5058           0 :                                      ReadOnlyRoots(isolate).undefined_value()));
    5059             :       }
    5060             :     }
    5061             :   }
    5062             : 
    5063             :   // Finally set new script.
    5064     3602810 :   shared->set_script(*script_object);
    5065             : }
    5066             : 
    5067     9037765 : bool SharedFunctionInfo::HasBreakInfo() const {
    5068     9037765 :   if (!HasDebugInfo()) return false;
    5069      477925 :   DebugInfo info = GetDebugInfo();
    5070      477925 :   bool has_break_info = info->HasBreakInfo();
    5071      477925 :   return has_break_info;
    5072             : }
    5073             : 
    5074       14669 : bool SharedFunctionInfo::BreakAtEntry() const {
    5075       14669 :   if (!HasDebugInfo()) return false;
    5076         470 :   DebugInfo info = GetDebugInfo();
    5077         470 :   bool break_at_entry = info->BreakAtEntry();
    5078         470 :   return break_at_entry;
    5079             : }
    5080             : 
    5081      206316 : bool SharedFunctionInfo::HasCoverageInfo() const {
    5082      206316 :   if (!HasDebugInfo()) return false;
    5083      192428 :   DebugInfo info = GetDebugInfo();
    5084      192428 :   bool has_coverage_info = info->HasCoverageInfo();
    5085      192428 :   return has_coverage_info;
    5086             : }
    5087             : 
    5088      179500 : CoverageInfo SharedFunctionInfo::GetCoverageInfo() const {
    5089             :   DCHECK(HasCoverageInfo());
    5090      179500 :   return CoverageInfo::cast(GetDebugInfo()->coverage_info());
    5091             : }
    5092             : 
    5093     7228520 : String SharedFunctionInfo::DebugName() {
    5094             :   DisallowHeapAllocation no_gc;
    5095     7228520 :   String function_name = Name();
    5096     7228536 :   if (function_name->length() > 0) return function_name;
    5097     1960690 :   return inferred_name();
    5098             : }
    5099             : 
    5100      943319 : bool SharedFunctionInfo::PassesFilter(const char* raw_filter) {
    5101      943319 :   Vector<const char> filter = CStrVector(raw_filter);
    5102      943319 :   std::unique_ptr<char[]> cstrname(DebugName()->ToCString());
    5103     1886652 :   return v8::internal::PassesFilter(CStrVector(cstrname.get()), filter);
    5104             : }
    5105             : 
    5106     6840206 : bool SharedFunctionInfo::HasSourceCode() const {
    5107             :   Isolate* isolate = GetIsolate();
    5108    20520618 :   return !script()->IsUndefined(isolate) &&
    5109    13680412 :          !Script::cast(script())->source()->IsUndefined(isolate);
    5110             : }
    5111             : 
    5112      109060 : void SharedFunctionInfo::DiscardCompiledMetadata(
    5113             :     Isolate* isolate,
    5114             :     std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
    5115             :         gc_notify_updated_slot) {
    5116             :   DisallowHeapAllocation no_gc;
    5117      109060 :   if (is_compiled()) {
    5118             :     HeapObject outer_scope_info;
    5119      109053 :     if (scope_info()->HasOuterScopeInfo()) {
    5120      103912 :       outer_scope_info = scope_info()->OuterScopeInfo();
    5121             :     } else {
    5122             :       outer_scope_info = ReadOnlyRoots(isolate).the_hole_value();
    5123             :     }
    5124             : 
    5125             :     // Raw setter to avoid validity checks, since we're performing the unusual
    5126             :     // task of decompiling.
    5127      109053 :     set_raw_outer_scope_info_or_feedback_metadata(outer_scope_info);
    5128             :     gc_notify_updated_slot(
    5129             :         *this,
    5130             :         RawField(SharedFunctionInfo::kOuterScopeInfoOrFeedbackMetadataOffset),
    5131             :         outer_scope_info);
    5132             :   } else {
    5133             :     DCHECK(outer_scope_info()->IsScopeInfo() ||
    5134             :            outer_scope_info()->IsTheHole());
    5135             :   }
    5136             : 
    5137             :   // TODO(rmcilroy): Possibly discard ScopeInfo here as well.
    5138      109060 : }
    5139             : 
    5140             : // static
    5141         218 : void SharedFunctionInfo::DiscardCompiled(
    5142             :     Isolate* isolate, Handle<SharedFunctionInfo> shared_info) {
    5143             :   DCHECK(shared_info->CanDiscardCompiled());
    5144             : 
    5145             :   Handle<String> inferred_name_val =
    5146         436 :       handle(shared_info->inferred_name(), isolate);
    5147         218 :   int start_position = shared_info->StartPosition();
    5148         218 :   int end_position = shared_info->EndPosition();
    5149         218 :   int function_literal_id = shared_info->FunctionLiteralId(isolate);
    5150             : 
    5151         436 :   shared_info->DiscardCompiledMetadata(isolate);
    5152             : 
    5153             :   // Replace compiled data with a new UncompiledData object.
    5154         218 :   if (shared_info->HasUncompiledDataWithPreparseData()) {
    5155             :     // If this is uncompiled data with a pre-parsed scope data, we can just
    5156             :     // clear out the scope data and keep the uncompiled data.
    5157           7 :     shared_info->ClearPreparseData();
    5158             :   } else {
    5159             :     // Create a new UncompiledData, without pre-parsed scope, and update the
    5160             :     // function data to point to it. Use the raw function data setter to avoid
    5161             :     // validity checks, since we're performing the unusual task of decompiling.
    5162             :     Handle<UncompiledData> data =
    5163             :         isolate->factory()->NewUncompiledDataWithoutPreparseData(
    5164             :             inferred_name_val, start_position, end_position,
    5165         211 :             function_literal_id);
    5166         422 :     shared_info->set_function_data(*data);
    5167             :   }
    5168         218 : }
    5169             : 
    5170             : // static
    5171         567 : Handle<Object> SharedFunctionInfo::GetSourceCode(
    5172             :     Handle<SharedFunctionInfo> shared) {
    5173             :   Isolate* isolate = shared->GetIsolate();
    5174         567 :   if (!shared->HasSourceCode()) return isolate->factory()->undefined_value();
    5175        1134 :   Handle<String> source(String::cast(Script::cast(shared->script())->source()),
    5176             :                         isolate);
    5177             :   return isolate->factory()->NewSubString(source, shared->StartPosition(),
    5178        1134 :                                           shared->EndPosition());
    5179             : }
    5180             : 
    5181             : // static
    5182      785278 : Handle<Object> SharedFunctionInfo::GetSourceCodeHarmony(
    5183             :     Handle<SharedFunctionInfo> shared) {
    5184             :   Isolate* isolate = shared->GetIsolate();
    5185      785278 :   if (!shared->HasSourceCode()) return isolate->factory()->undefined_value();
    5186             :   Handle<String> script_source(
    5187     1570556 :       String::cast(Script::cast(shared->script())->source()), isolate);
    5188     1570556 :   int start_pos = shared->function_token_position();
    5189             :   DCHECK_NE(start_pos, kNoSourcePosition);
    5190             :   Handle<String> source = isolate->factory()->NewSubString(
    5191      785278 :       script_source, start_pos, shared->EndPosition());
    5192      785278 :   if (!shared->is_wrapped()) return source;
    5193             : 
    5194             :   DCHECK(!shared->name_should_print_as_anonymous());
    5195          15 :   IncrementalStringBuilder builder(isolate);
    5196             :   builder.AppendCString("function ");
    5197          30 :   builder.AppendString(Handle<String>(shared->Name(), isolate));
    5198             :   builder.AppendCString("(");
    5199          30 :   Handle<FixedArray> args(Script::cast(shared->script())->wrapped_arguments(),
    5200             :                           isolate);
    5201             :   int argc = args->length();
    5202          25 :   for (int i = 0; i < argc; i++) {
    5203           5 :     if (i > 0) builder.AppendCString(", ");
    5204           5 :     builder.AppendString(Handle<String>(String::cast(args->get(i)), isolate));
    5205             :   }
    5206             :   builder.AppendCString(") {\n");
    5207          15 :   builder.AppendString(source);
    5208             :   builder.AppendCString("\n}");
    5209          30 :   return builder.Finish().ToHandleChecked();
    5210             : }
    5211             : 
    5212             : namespace {
    5213     7134564 : void TraceInlining(SharedFunctionInfo shared, const char* msg) {
    5214     7134564 :   if (FLAG_trace_turbo_inlining) {
    5215           0 :     StdoutStream os;
    5216           0 :     os << Brief(shared) << ": IsInlineable? " << msg << "\n";
    5217             :   }
    5218     7134564 : }
    5219             : }  // namespace
    5220             : 
    5221     7134562 : bool SharedFunctionInfo::IsInlineable() {
    5222    14269135 :   if (!script()->IsScript()) {
    5223     6108707 :     TraceInlining(*this, "false (no Script associated with it)");
    5224     6108708 :     return false;
    5225             :   }
    5226             : 
    5227     1025878 :   if (GetIsolate()->is_precise_binary_code_coverage() &&
    5228             :       !has_reported_binary_coverage()) {
    5229             :     // We may miss invocations if this function is inlined.
    5230           0 :     TraceInlining(*this, "false (requires precise binary coverage)");
    5231           0 :     return false;
    5232             :   }
    5233             : 
    5234     1025866 :   if (optimization_disabled()) {
    5235        1787 :     TraceInlining(*this, "false (optimization disabled)");
    5236        1787 :     return false;
    5237             :   }
    5238             : 
    5239             :   // Built-in functions are handled by the JSCallReducer.
    5240     1024077 :   if (HasBuiltinId()) {
    5241        1062 :     TraceInlining(*this, "false (is a builtin)");
    5242        1062 :     return false;
    5243             :   }
    5244             : 
    5245     1023015 :   if (!IsUserJavaScript()) {
    5246        1373 :     TraceInlining(*this, "false (is not user code)");
    5247        1369 :     return false;
    5248             :   }
    5249             : 
    5250             :   // If there is no bytecode array, it is either not compiled or it is compiled
    5251             :   // with WebAssembly for the asm.js pipeline. In either case we don't want to
    5252             :   // inline.
    5253     1021644 :   if (!HasBytecodeArray()) {
    5254      304433 :     TraceInlining(*this, "false (has no BytecodeArray)");
    5255      304433 :     return false;
    5256             :   }
    5257             : 
    5258     1434422 :   if (GetBytecodeArray()->length() > FLAG_max_inlined_bytecode_size) {
    5259        2173 :     TraceInlining(*this, "false (length > FLAG_max_inlined_bytecode_size)");
    5260        2173 :     return false;
    5261             :   }
    5262             : 
    5263      715038 :   if (HasBreakInfo()) {
    5264           6 :     TraceInlining(*this, "false (may contain break points)");
    5265           6 :     return false;
    5266             :   }
    5267             : 
    5268      715032 :   TraceInlining(*this, "true");
    5269      715032 :   return true;
    5270             : }
    5271             : 
    5272           0 : int SharedFunctionInfo::SourceSize() { return EndPosition() - StartPosition(); }
    5273             : 
    5274      113085 : int SharedFunctionInfo::FindIndexInScript(Isolate* isolate) const {
    5275             :   DisallowHeapAllocation no_gc;
    5276             : 
    5277      113085 :   Object script_obj = script();
    5278      113085 :   if (!script_obj->IsScript()) return kFunctionLiteralIdInvalid;
    5279             : 
    5280             :   WeakFixedArray shared_info_list =
    5281      113085 :       Script::cast(script_obj)->shared_function_infos();
    5282             :   SharedFunctionInfo::ScriptIterator iterator(
    5283             :       isolate,
    5284             :       Handle<WeakFixedArray>(reinterpret_cast<Address*>(&shared_info_list)));
    5285             : 
    5286      845243 :   for (SharedFunctionInfo shared = iterator.Next(); !shared.is_null();
    5287             :        shared = iterator.Next()) {
    5288      845243 :     if (shared == *this) {
    5289             :       return iterator.CurrentIndex();
    5290             :     }
    5291             :   }
    5292             : 
    5293             :   return kFunctionLiteralIdInvalid;
    5294             : }
    5295             : 
    5296             : 
    5297             : // Output the source code without any allocation in the heap.
    5298          24 : std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) {
    5299          24 :   const SharedFunctionInfo s = v.value;
    5300             :   // For some native functions there is no source.
    5301          24 :   if (!s->HasSourceCode()) return os << "<No Source>";
    5302             : 
    5303             :   // Get the source for the script which this function came from.
    5304             :   // Don't use String::cast because we don't want more assertion errors while
    5305             :   // we are already creating a stack dump.
    5306             :   String script_source =
    5307          48 :       String::unchecked_cast(Script::cast(s->script())->source());
    5308             : 
    5309          24 :   if (!script_source->LooksValid()) return os << "<Invalid Source>";
    5310             : 
    5311          24 :   if (!s->is_toplevel()) {
    5312          16 :     os << "function ";
    5313          16 :     String name = s->Name();
    5314          16 :     if (name->length() > 0) {
    5315          16 :       name->PrintUC16(os);
    5316             :     }
    5317             :   }
    5318             : 
    5319          24 :   int len = s->EndPosition() - s->StartPosition();
    5320          24 :   if (len <= v.max_length || v.max_length < 0) {
    5321           8 :     script_source->PrintUC16(os, s->StartPosition(), s->EndPosition());
    5322           8 :     return os;
    5323             :   } else {
    5324          16 :     script_source->PrintUC16(os, s->StartPosition(),
    5325          32 :                              s->StartPosition() + v.max_length);
    5326          16 :     return os << "...\n";
    5327             :   }
    5328             : }
    5329             : 
    5330             : 
    5331       20509 : void SharedFunctionInfo::DisableOptimization(BailoutReason reason) {
    5332             :   DCHECK_NE(reason, BailoutReason::kNoReason);
    5333             : 
    5334             :   set_flags(DisabledOptimizationReasonBits::update(flags(), reason));
    5335             :   // Code should be the lazy compilation stub or else interpreted.
    5336             :   DCHECK(abstract_code()->kind() == AbstractCode::INTERPRETED_FUNCTION ||
    5337             :          abstract_code()->kind() == AbstractCode::BUILTIN);
    5338       41018 :   PROFILE(GetIsolate(), CodeDisableOptEvent(abstract_code(), *this));
    5339       20509 :   if (FLAG_trace_opt) {
    5340           0 :     PrintF("[disabled optimization for ");
    5341           0 :     ShortPrint();
    5342           0 :     PrintF(", reason: %s]\n", GetBailoutReason(reason));
    5343             :   }
    5344       20509 : }
    5345             : 
    5346     3602666 : void SharedFunctionInfo::InitFromFunctionLiteral(
    5347             :     Handle<SharedFunctionInfo> shared_info, FunctionLiteral* lit,
    5348             :     bool is_toplevel) {
    5349             :   Isolate* isolate = shared_info->GetIsolate();
    5350             :   bool needs_position_info = true;
    5351             : 
    5352             :   // When adding fields here, make sure DeclarationScope::AnalyzePartially is
    5353             :   // updated accordingly.
    5354             :   shared_info->set_internal_formal_parameter_count(lit->parameter_count());
    5355     3602666 :   shared_info->SetFunctionTokenPosition(lit->function_token_position(),
    5356             :                                         lit->start_position());
    5357     3602668 :   if (shared_info->scope_info()->HasPositionInfo()) {
    5358           0 :     shared_info->scope_info()->SetPositionInfo(lit->start_position(),
    5359           0 :                                                lit->end_position());
    5360             :     needs_position_info = false;
    5361             :   }
    5362     7205340 :   shared_info->set_is_declaration(lit->is_declaration());
    5363     7205338 :   shared_info->set_is_named_expression(lit->is_named_expression());
    5364     7205340 :   shared_info->set_is_anonymous_expression(lit->is_anonymous_expression());
    5365     7205344 :   shared_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
    5366     7205350 :   shared_info->set_language_mode(lit->language_mode());
    5367     7205360 :   shared_info->set_is_wrapped(lit->is_wrapped());
    5368             :   //  shared_info->set_kind(lit->kind());
    5369             :   // FunctionKind must have already been set.
    5370             :   DCHECK(lit->kind() == shared_info->kind());
    5371     7205350 :   shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject());
    5372             :   DCHECK_IMPLIES(lit->requires_instance_members_initializer(),
    5373             :                  IsClassConstructor(lit->kind()));
    5374    10808009 :   shared_info->set_requires_instance_members_initializer(
    5375     3602669 :       lit->requires_instance_members_initializer());
    5376             : 
    5377     7205342 :   shared_info->set_is_toplevel(is_toplevel);
    5378             :   DCHECK(shared_info->outer_scope_info()->IsTheHole());
    5379     3602673 :   if (!is_toplevel) {
    5380     2602736 :     Scope* outer_scope = lit->scope()->GetOuterScopeWithContext();
    5381     2602737 :     if (outer_scope) {
    5382     4422450 :       shared_info->set_outer_scope_info(*outer_scope->scope_info());
    5383             :     }
    5384             :   }
    5385             : 
    5386             :   // For lazy parsed functions, the following flags will be inaccurate since we
    5387             :   // don't have the information yet. They're set later in
    5388             :   // SetSharedFunctionFlagsFromLiteral (compiler.cc), when the function is
    5389             :   // really parsed and compiled.
    5390     3602674 :   if (lit->ShouldEagerCompile()) {
    5391             :     shared_info->set_length(lit->function_length());
    5392     3015844 :     shared_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
    5393             :     shared_info->SetExpectedNofPropertiesFromEstimate(lit);
    5394     4523769 :     shared_info->set_is_safe_to_skip_arguments_adaptor(
    5395     3015844 :         lit->SafeToSkipArgumentsAdaptor());
    5396             :     DCHECK_NULL(lit->produced_preparse_data());
    5397             :     // If we're about to eager compile, we'll have the function literal
    5398             :     // available, so there's no need to wastefully allocate an uncompiled data.
    5399             :     // TODO(leszeks): This should be explicitly passed as a parameter, rather
    5400             :     // than relying on a property of the literal.
    5401             :     needs_position_info = false;
    5402             :   } else {
    5403             :     // Set an invalid length for lazy functions. This way we can set the correct
    5404             :     // value after compiling, but avoid overwriting values set manually by the
    5405             :     // bootstrapper.
    5406             :     shared_info->set_length(SharedFunctionInfo::kInvalidLength);
    5407     2094754 :     shared_info->set_is_safe_to_skip_arguments_adaptor(false);
    5408             :     ProducedPreparseData* scope_data = lit->produced_preparse_data();
    5409     2094754 :     if (scope_data != nullptr) {
    5410             :       Handle<PreparseData> preparse_data =
    5411      118956 :           scope_data->Serialize(shared_info->GetIsolate());
    5412             :       Handle<UncompiledData> data =
    5413             :           isolate->factory()->NewUncompiledDataWithPreparseData(
    5414             :               lit->inferred_name(), lit->start_position(), lit->end_position(),
    5415       59478 :               lit->function_literal_id(), preparse_data);
    5416      118956 :       shared_info->set_uncompiled_data(*data);
    5417             :       needs_position_info = false;
    5418             :     }
    5419             :   }
    5420     3602677 :   if (needs_position_info) {
    5421             :     Handle<UncompiledData> data =
    5422             :         isolate->factory()->NewUncompiledDataWithoutPreparseData(
    5423             :             lit->inferred_name(), lit->start_position(), lit->end_position(),
    5424     2035276 :             lit->function_literal_id());
    5425     4070551 :     shared_info->set_uncompiled_data(*data);
    5426             :   }
    5427     3602677 : }
    5428             : 
    5429     2075262 : void SharedFunctionInfo::SetExpectedNofPropertiesFromEstimate(
    5430             :     FunctionLiteral* literal) {
    5431     3583183 :   int estimate = literal->expected_property_count();
    5432             : 
    5433             :   // If no properties are added in the constructor, they are more likely
    5434             :   // to be added later.
    5435     3583183 :   if (estimate == 0) estimate = 2;
    5436             : 
    5437             :   // Limit actual estimate to fit in a 8 bit field, we will never allocate
    5438             :   // more than this in any case.
    5439             :   STATIC_ASSERT(JSObject::kMaxInObjectProperties <= kMaxUInt8);
    5440     3583183 :   estimate = std::min(estimate, kMaxUInt8);
    5441             : 
    5442             :   set_expected_nof_properties(estimate);
    5443     2075262 : }
    5444             : 
    5445        1137 : void SharedFunctionInfo::SetFunctionTokenPosition(int function_token_position,
    5446             :                                                   int start_position) {
    5447             :   int offset;
    5448     3603805 :   if (function_token_position == kNoSourcePosition) {
    5449             :     offset = 0;
    5450             :   } else {
    5451     2579350 :     offset = start_position - function_token_position;
    5452             :   }
    5453             : 
    5454     3603805 :   if (offset > kMaximumFunctionTokenOffset) {
    5455             :     offset = kFunctionTokenOutOfRange;
    5456             :   }
    5457             :   set_raw_function_token_offset(offset);
    5458        1137 : }
    5459             : 
    5460    10279189 : int SharedFunctionInfo::StartPosition() const {
    5461             :   Object maybe_scope_info = name_or_scope_info();
    5462    10279189 :   if (maybe_scope_info->IsScopeInfo()) {
    5463     6371492 :     ScopeInfo info = ScopeInfo::cast(maybe_scope_info);
    5464     6371492 :     if (info->HasPositionInfo()) {
    5465     6371492 :       return info->StartPosition();
    5466             :     }
    5467     3907697 :   } else if (HasUncompiledData()) {
    5468             :     // Works with or without scope.
    5469             :     return uncompiled_data()->start_position();
    5470     2010592 :   } else if (IsApiFunction() || HasBuiltinId()) {
    5471             :     DCHECK_IMPLIES(HasBuiltinId(), builtin_id() != Builtins::kCompileLazy);
    5472             :     return 0;
    5473             :   }
    5474             :   return kNoSourcePosition;
    5475             : }
    5476             : 
    5477     2400389 : int SharedFunctionInfo::EndPosition() const {
    5478             :   Object maybe_scope_info = name_or_scope_info();
    5479     2400389 :   if (maybe_scope_info->IsScopeInfo()) {
    5480      579969 :     ScopeInfo info = ScopeInfo::cast(maybe_scope_info);
    5481      579969 :     if (info->HasPositionInfo()) {
    5482      579969 :       return info->EndPosition();
    5483             :     }
    5484     1820420 :   } else if (HasUncompiledData()) {
    5485             :     // Works with or without scope.
    5486             :     return uncompiled_data()->end_position();
    5487           0 :   } else if (IsApiFunction() || HasBuiltinId()) {
    5488             :     DCHECK_IMPLIES(HasBuiltinId(), builtin_id() != Builtins::kCompileLazy);
    5489             :     return 0;
    5490             :   }
    5491             :   return kNoSourcePosition;
    5492             : }
    5493             : 
    5494      719045 : int SharedFunctionInfo::FunctionLiteralId(Isolate* isolate) const {
    5495             :   // Fast path for the common case when the SFI is uncompiled and so the
    5496             :   // function literal id is already in the uncompiled data.
    5497     1329297 :   if (HasUncompiledData() && uncompiled_data()->has_function_literal_id()) {
    5498             :     int id = uncompiled_data()->function_literal_id();
    5499             :     // Make sure the id is what we should have found with the slow path.
    5500             :     DCHECK_EQ(id, FindIndexInScript(isolate));
    5501      605961 :     return id;
    5502             :   }
    5503             : 
    5504             :   // Otherwise, search for the function in the SFI's script's function list,
    5505             :   // and return its index in that list.
    5506      113085 :   return FindIndexInScript(isolate);
    5507             : }
    5508             : 
    5509        1137 : void SharedFunctionInfo::SetPosition(int start_position, int end_position) {
    5510             :   Object maybe_scope_info = name_or_scope_info();
    5511        1137 :   if (maybe_scope_info->IsScopeInfo()) {
    5512        1067 :     ScopeInfo info = ScopeInfo::cast(maybe_scope_info);
    5513        1067 :     if (info->HasPositionInfo()) {
    5514        1067 :       info->SetPositionInfo(start_position, end_position);
    5515             :     }
    5516          70 :   } else if (HasUncompiledData()) {
    5517          70 :     if (HasUncompiledDataWithPreparseData()) {
    5518             :       // Clear out preparsed scope data, since the position setter invalidates
    5519             :       // any scope data.
    5520          14 :       ClearPreparseData();
    5521             :     }
    5522             :     uncompiled_data()->set_start_position(start_position);
    5523             :     uncompiled_data()->set_end_position(end_position);
    5524             :   } else {
    5525           0 :     UNREACHABLE();
    5526             :   }
    5527        1137 : }
    5528             : 
    5529             : // static
    5530       23810 : void SharedFunctionInfo::EnsureSourcePositionsAvailable(
    5531             :     Isolate* isolate, Handle<SharedFunctionInfo> shared_info) {
    5532       47640 :   if (FLAG_enable_lazy_source_positions && shared_info->HasBytecodeArray() &&
    5533       23820 :       !shared_info->GetBytecodeArray()->HasSourcePositionTable()) {
    5534           5 :     Compiler::CollectSourcePositions(isolate, shared_info);
    5535             :   }
    5536       23810 : }
    5537             : 
    5538           0 : bool BytecodeArray::IsBytecodeEqual(const BytecodeArray other) const {
    5539           0 :   if (length() != other->length()) return false;
    5540             : 
    5541           0 :   for (int i = 0; i < length(); ++i) {
    5542           0 :     if (get(i) != other->get(i)) return false;
    5543             :   }
    5544             : 
    5545             :   return true;
    5546             : }
    5547             : 
    5548             : // static
    5549        4534 : void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) {
    5550             :   DCHECK_GE(capacity, 0);
    5551             :   array->GetIsolate()->factory()->NewJSArrayStorage(
    5552        4534 :       array, length, capacity, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
    5553        4534 : }
    5554             : 
    5555      475354 : void JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) {
    5556             :   // We should never end in here with a pixel or external array.
    5557             :   DCHECK(array->AllowsSetLength());
    5558      475354 :   if (array->SetLengthWouldNormalize(new_length)) {
    5559         446 :     JSObject::NormalizeElements(array);
    5560             :   }
    5561      475354 :   array->GetElementsAccessor()->SetLength(array, new_length);
    5562      475354 : }
    5563             : 
    5564             : // ES6: 9.5.2 [[SetPrototypeOf]] (V)
    5565             : // static
    5566       72666 : Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value,
    5567             :                                   bool from_javascript,
    5568             :                                   ShouldThrow should_throw) {
    5569             :   Isolate* isolate = proxy->GetIsolate();
    5570       72666 :   STACK_CHECK(isolate, Nothing<bool>());
    5571             :   Handle<Name> trap_name = isolate->factory()->setPrototypeOf_string();
    5572             :   // 1. Assert: Either Type(V) is Object or Type(V) is Null.
    5573             :   DCHECK(value->IsJSReceiver() || value->IsNull(isolate));
    5574             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    5575             :   Handle<Object> handler(proxy->handler(), isolate);
    5576             :   // 3. If handler is null, throw a TypeError exception.
    5577             :   // 4. Assert: Type(handler) is Object.
    5578       72649 :   if (proxy->IsRevoked()) {
    5579          18 :     isolate->Throw(*isolate->factory()->NewTypeError(
    5580          18 :         MessageTemplate::kProxyRevoked, trap_name));
    5581             :     return Nothing<bool>();
    5582             :   }
    5583             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot.
    5584             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    5585             :   // 6. Let trap be ? GetMethod(handler, "getPrototypeOf").
    5586             :   Handle<Object> trap;
    5587      145280 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5588             :       isolate, trap,
    5589             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    5590             :       Nothing<bool>());
    5591             :   // 7. If trap is undefined, then return target.[[SetPrototypeOf]]().
    5592       72640 :   if (trap->IsUndefined(isolate)) {
    5593             :     return JSReceiver::SetPrototype(target, value, from_javascript,
    5594       63217 :                                     should_throw);
    5595             :   }
    5596             :   // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, V»)).
    5597        9423 :   Handle<Object> argv[] = {target, value};
    5598             :   Handle<Object> trap_result;
    5599       18846 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5600             :       isolate, trap_result,
    5601             :       Execution::Call(isolate, trap, handler, arraysize(argv), argv),
    5602             :       Nothing<bool>());
    5603          90 :   bool bool_trap_result = trap_result->BooleanValue(isolate);
    5604             :   // 9. If booleanTrapResult is false, return false.
    5605          90 :   if (!bool_trap_result) {
    5606          90 :     RETURN_FAILURE(
    5607             :         isolate, should_throw,
    5608             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
    5609             :   }
    5610             :   // 10. Let extensibleTarget be ? IsExtensible(target).
    5611          54 :   Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
    5612          54 :   if (is_extensible.IsNothing()) return Nothing<bool>();
    5613             :   // 11. If extensibleTarget is true, return true.
    5614          54 :   if (is_extensible.FromJust()) {
    5615          27 :     if (bool_trap_result) return Just(true);
    5616           0 :     RETURN_FAILURE(
    5617             :         isolate, should_throw,
    5618             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
    5619             :   }
    5620             :   // 12. Let targetProto be ? target.[[GetPrototypeOf]]().
    5621             :   Handle<Object> target_proto;
    5622          54 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_proto,
    5623             :                                    JSReceiver::GetPrototype(isolate, target),
    5624             :                                    Nothing<bool>());
    5625             :   // 13. If SameValue(V, targetProto) is false, throw a TypeError exception.
    5626          36 :   if (bool_trap_result && !value->SameValue(*target_proto)) {
    5627          18 :     isolate->Throw(*isolate->factory()->NewTypeError(
    5628          18 :         MessageTemplate::kProxySetPrototypeOfNonExtensible));
    5629             :     return Nothing<bool>();
    5630             :   }
    5631             :   // 14. Return true.
    5632             :   return Just(true);
    5633             : }
    5634             : 
    5635             : 
    5636             : 
    5637             : 
    5638             : 
    5639      475354 : bool JSArray::SetLengthWouldNormalize(uint32_t new_length) {
    5640      950708 :   if (!HasFastElements()) return false;
    5641      467673 :   uint32_t capacity = static_cast<uint32_t>(elements()->length());
    5642             :   uint32_t new_capacity;
    5643      468128 :   return JSArray::SetLengthWouldNormalize(GetHeap(), new_length) &&
    5644         455 :          ShouldConvertToSlowElements(*this, capacity, new_length - 1,
    5645             :                                      &new_capacity);
    5646             : }
    5647             : 
    5648             : 
    5649             : const double AllocationSite::kPretenureRatio = 0.85;
    5650             : 
    5651             : 
    5652           0 : void AllocationSite::ResetPretenureDecision() {
    5653             :   set_pretenure_decision(kUndecided);
    5654             :   set_memento_found_count(0);
    5655             :   set_memento_create_count(0);
    5656           0 : }
    5657             : 
    5658       23673 : AllocationType AllocationSite::GetAllocationType() const {
    5659             :   PretenureDecision mode = pretenure_decision();
    5660             :   // Zombie objects "decide" to be untenured.
    5661       23673 :   return mode == kTenure ? AllocationType::kOld : AllocationType::kYoung;
    5662             : }
    5663             : 
    5664           0 : bool AllocationSite::IsNested() {
    5665             :   DCHECK(FLAG_trace_track_allocation_sites);
    5666             :   Object current = boilerplate()->GetHeap()->allocation_sites_list();
    5667           0 :   while (current->IsAllocationSite()) {
    5668             :     AllocationSite current_site = AllocationSite::cast(current);
    5669           0 :     if (current_site->nested_site() == *this) {
    5670             :       return true;
    5671             :     }
    5672             :     current = current_site->weak_next();
    5673             :   }
    5674             :   return false;
    5675             : }
    5676             : 
    5677             : 
    5678        4872 : bool AllocationSite::ShouldTrack(ElementsKind from, ElementsKind to) {
    5679        7616 :   return IsSmiElementsKind(from) &&
    5680        7616 :          IsMoreGeneralElementsKindTransition(from, to);
    5681             : }
    5682             : 
    5683           0 : const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) {
    5684           0 :   switch (decision) {
    5685             :     case kUndecided: return "undecided";
    5686           0 :     case kDontTenure: return "don't tenure";
    5687           0 :     case kMaybeTenure: return "maybe tenure";
    5688           0 :     case kTenure: return "tenure";
    5689           0 :     case kZombie: return "zombie";
    5690           0 :     default: UNREACHABLE();
    5691             :   }
    5692             :   return nullptr;
    5693             : }
    5694             : 
    5695             : 
    5696             : 
    5697     3608314 : bool JSArray::HasReadOnlyLength(Handle<JSArray> array) {
    5698             :   Map map = array->map();
    5699             :   // Fast path: "length" is the first fast property of arrays. Since it's not
    5700             :   // configurable, it's guaranteed to be the first in the descriptor array.
    5701     3608314 :   if (!map->is_dictionary_map()) {
    5702             :     DCHECK(map->instance_descriptors()->GetKey(0) ==
    5703             :            array->GetReadOnlyRoots().length_string());
    5704             :     return map->instance_descriptors()->GetDetails(0).IsReadOnly();
    5705             :   }
    5706             : 
    5707             :   Isolate* isolate = array->GetIsolate();
    5708             :   LookupIterator it(array, isolate->factory()->length_string(), array,
    5709             :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
    5710         560 :   CHECK_EQ(LookupIterator::ACCESSOR, it.state());
    5711         560 :   return it.IsReadOnly();
    5712             : }
    5713             : 
    5714             : 
    5715     1652767 : bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
    5716             :                                         uint32_t index) {
    5717     1652767 :   uint32_t length = 0;
    5718     3305534 :   CHECK(array->length()->ToArrayLength(&length));
    5719     1652767 :   if (length <= index) return HasReadOnlyLength(array);
    5720             :   return false;
    5721             : }
    5722             : 
    5723             : 
    5724             : 
    5725             : // Certain compilers request function template instantiation when they
    5726             : // see the definition of the other template functions in the
    5727             : // class. This requires us to have the template functions put
    5728             : // together, so even though this function belongs in objects-debug.cc,
    5729             : // we keep it here instead to satisfy certain compilers.
    5730             : #ifdef OBJECT_PRINT
    5731             : template <typename Derived, typename Shape>
    5732             : void Dictionary<Derived, Shape>::Print(std::ostream& os) {
    5733             :   DisallowHeapAllocation no_gc;
    5734             :   ReadOnlyRoots roots = this->GetReadOnlyRoots();
    5735             :   Derived dictionary = Derived::cast(*this);
    5736             :   int capacity = dictionary->Capacity();
    5737             :   for (int i = 0; i < capacity; i++) {
    5738             :     Object k = dictionary->KeyAt(i);
    5739             :     if (!dictionary->ToKey(roots, i, &k)) continue;
    5740             :     os << "\n   ";
    5741             :     if (k->IsString()) {
    5742             :       String::cast(k)->StringPrint(os);
    5743             :     } else {
    5744             :       os << Brief(k);
    5745             :     }
    5746             :     os << ": " << Brief(dictionary->ValueAt(i)) << " ";
    5747             :     dictionary->DetailsAt(i).PrintAsSlowTo(os);
    5748             :   }
    5749             : }
    5750             : template <typename Derived, typename Shape>
    5751             : void Dictionary<Derived, Shape>::Print() {
    5752             :   StdoutStream os;
    5753             :   Print(os);
    5754             :   os << std::endl;
    5755             : }
    5756             : #endif
    5757             : 
    5758             : 
    5759             : 
    5760        5412 : int FixedArrayBase::GetMaxLengthForNewSpaceAllocation(ElementsKind kind) {
    5761             :   return ((kMaxRegularHeapObjectSize - FixedArrayBase::kHeaderSize) >>
    5762        5412 :           ElementsKindToShiftSize(kind));
    5763             : }
    5764             : 
    5765      506679 : bool FixedArrayBase::IsCowArray() const {
    5766      506679 :   return map() == GetReadOnlyRoots().fixed_cow_array_map();
    5767             : }
    5768             : 
    5769             : 
    5770        1859 : const char* Symbol::PrivateSymbolToName() const {
    5771             :   ReadOnlyRoots roots = GetReadOnlyRoots();
    5772             : #define SYMBOL_CHECK_AND_PRINT(_, name) \
    5773             :   if (*this == roots.name()) return #name;
    5774       28304 :   PRIVATE_SYMBOL_LIST_GENERATOR(SYMBOL_CHECK_AND_PRINT, /* not used */)
    5775             : #undef SYMBOL_CHECK_AND_PRINT
    5776         150 :   return "UNKNOWN";
    5777             : }
    5778             : 
    5779             : 
    5780        4276 : void Symbol::SymbolShortPrint(std::ostream& os) {
    5781        4276 :   os << "<Symbol:";
    5782        4276 :   if (!name()->IsUndefined()) {
    5783        2417 :     os << " ";
    5784             :     HeapStringAllocator allocator;
    5785             :     StringStream accumulator(&allocator);
    5786        2417 :     String::cast(name())->StringShortPrint(&accumulator, false);
    5787        7251 :     os << accumulator.ToCString().get();
    5788             :   } else {
    5789        3718 :     os << " (" << PrivateSymbolToName() << ")";
    5790             :   }
    5791        4276 :   os << ">";
    5792        4276 : }
    5793             : 
    5794             : 
    5795             : // StringSharedKeys are used as keys in the eval cache.
    5796     8641229 : class StringSharedKey : public HashTableKey {
    5797             :  public:
    5798             :   // This tuple unambiguously identifies calls to eval() or
    5799             :   // CreateDynamicFunction() (such as through the Function() constructor).
    5800             :   // * source is the string passed into eval(). For dynamic functions, this is
    5801             :   //   the effective source for the function, some of which is implicitly
    5802             :   //   generated.
    5803             :   // * shared is the shared function info for the function containing the call
    5804             :   //   to eval(). for dynamic functions, shared is the native context closure.
    5805             :   // * When positive, position is the position in the source where eval is
    5806             :   //   called. When negative, position is the negation of the position in the
    5807             :   //   dynamic function's effective source where the ')' ends the parameters.
    5808     5117194 :   StringSharedKey(Handle<String> source, Handle<SharedFunctionInfo> shared,
    5809             :                   LanguageMode language_mode, int position)
    5810             :       : HashTableKey(CompilationCacheShape::StringSharedHash(
    5811             :             *source, *shared, language_mode, position)),
    5812             :         source_(source),
    5813             :         shared_(shared),
    5814             :         language_mode_(language_mode),
    5815    10234388 :         position_(position) {}
    5816             : 
    5817     6277123 :   bool IsMatch(Object other) override {
    5818             :     DisallowHeapAllocation no_allocation;
    5819     6277123 :     if (!other->IsFixedArray()) {
    5820             :       DCHECK(other->IsNumber());
    5821     1964387 :       uint32_t other_hash = static_cast<uint32_t>(other->Number());
    5822     1964387 :       return Hash() == other_hash;
    5823             :     }
    5824             :     FixedArray other_array = FixedArray::cast(other);
    5825             :     SharedFunctionInfo shared = SharedFunctionInfo::cast(other_array->get(0));
    5826     4312736 :     if (shared != *shared_) return false;
    5827             :     int language_unchecked = Smi::ToInt(other_array->get(2));
    5828             :     DCHECK(is_valid_language_mode(language_unchecked));
    5829     4139055 :     LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
    5830     4139055 :     if (language_mode != language_mode_) return false;
    5831             :     int position = Smi::ToInt(other_array->get(3));
    5832     4125836 :     if (position != position_) return false;
    5833     4125615 :     String source = String::cast(other_array->get(1));
    5834     4125615 :     return source->Equals(*source_);
    5835             :   }
    5836             : 
    5837     1322886 :   Handle<Object> AsHandle(Isolate* isolate) {
    5838     1322886 :     Handle<FixedArray> array = isolate->factory()->NewFixedArray(4);
    5839     2645772 :     array->set(0, *shared_);
    5840     2645772 :     array->set(1, *source_);
    5841     1322886 :     array->set(2, Smi::FromEnum(language_mode_));
    5842     1322886 :     array->set(3, Smi::FromInt(position_));
    5843     1322886 :     array->set_map(ReadOnlyRoots(isolate).fixed_cow_array_map());
    5844     1322886 :     return array;
    5845             :   }
    5846             : 
    5847             :  private:
    5848             :   Handle<String> source_;
    5849             :   Handle<SharedFunctionInfo> shared_;
    5850             :   LanguageMode language_mode_;
    5851             :   int position_;
    5852             : };
    5853             : 
    5854      175640 : v8::Promise::PromiseState JSPromise::status() const {
    5855      216286 :   int value = flags() & kStatusMask;
    5856             :   DCHECK(value == 0 || value == 1 || value == 2);
    5857      216286 :   return static_cast<v8::Promise::PromiseState>(value);
    5858             : }
    5859             : 
    5860       40646 : void JSPromise::set_status(Promise::PromiseState status) {
    5861       40646 :   int value = flags() & ~kStatusMask;
    5862       40646 :   set_flags(value | status);
    5863       40646 : }
    5864             : 
    5865             : // static
    5866          40 : const char* JSPromise::Status(v8::Promise::PromiseState status) {
    5867          40 :   switch (status) {
    5868             :     case v8::Promise::kFulfilled:
    5869             :       return "resolved";
    5870             :     case v8::Promise::kPending:
    5871          15 :       return "pending";
    5872             :     case v8::Promise::kRejected:
    5873           5 :       return "rejected";
    5874             :   }
    5875           0 :   UNREACHABLE();
    5876             : }
    5877             : 
    5878       20438 : int JSPromise::async_task_id() const {
    5879       40876 :   return AsyncTaskIdField::decode(flags());
    5880             : }
    5881             : 
    5882        6368 : void JSPromise::set_async_task_id(int id) {
    5883       12736 :   set_flags(AsyncTaskIdField::update(flags(), id));
    5884        6368 : }
    5885             : 
    5886             : // static
    5887       28921 : Handle<Object> JSPromise::Fulfill(Handle<JSPromise> promise,
    5888             :                                   Handle<Object> value) {
    5889             :   Isolate* const isolate = promise->GetIsolate();
    5890             : 
    5891             :   // 1. Assert: The value of promise.[[PromiseState]] is "pending".
    5892       28921 :   CHECK_EQ(Promise::kPending, promise->status());
    5893             : 
    5894             :   // 2. Let reactions be promise.[[PromiseFulfillReactions]].
    5895             :   Handle<Object> reactions(promise->reactions(), isolate);
    5896             : 
    5897             :   // 3. Set promise.[[PromiseResult]] to value.
    5898             :   // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
    5899             :   // 5. Set promise.[[PromiseRejectReactions]] to undefined.
    5900       28921 :   promise->set_reactions_or_result(*value);
    5901             : 
    5902             :   // 6. Set promise.[[PromiseState]] to "fulfilled".
    5903       28921 :   promise->set_status(Promise::kFulfilled);
    5904             : 
    5905             :   // 7. Return TriggerPromiseReactions(reactions, value).
    5906             :   return TriggerPromiseReactions(isolate, reactions, value,
    5907       28921 :                                  PromiseReaction::kFulfill);
    5908             : }
    5909             : 
    5910             : // static
    5911       11725 : Handle<Object> JSPromise::Reject(Handle<JSPromise> promise,
    5912             :                                  Handle<Object> reason, bool debug_event) {
    5913             :   Isolate* const isolate = promise->GetIsolate();
    5914             : 
    5915       20052 :   if (debug_event) isolate->debug()->OnPromiseReject(promise, reason);
    5916       11725 :   isolate->RunPromiseHook(PromiseHookType::kResolve, promise,
    5917       11725 :                           isolate->factory()->undefined_value());
    5918             : 
    5919             :   // 1. Assert: The value of promise.[[PromiseState]] is "pending".
    5920       11725 :   CHECK_EQ(Promise::kPending, promise->status());
    5921             : 
    5922             :   // 2. Let reactions be promise.[[PromiseRejectReactions]].
    5923             :   Handle<Object> reactions(promise->reactions(), isolate);
    5924             : 
    5925             :   // 3. Set promise.[[PromiseResult]] to reason.
    5926             :   // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
    5927             :   // 5. Set promise.[[PromiseRejectReactions]] to undefined.
    5928       11725 :   promise->set_reactions_or_result(*reason);
    5929             : 
    5930             :   // 6. Set promise.[[PromiseState]] to "rejected".
    5931       11725 :   promise->set_status(Promise::kRejected);
    5932             : 
    5933             :   // 7. If promise.[[PromiseIsHandled]] is false, perform
    5934             :   //    HostPromiseRejectionTracker(promise, "reject").
    5935       11725 :   if (!promise->has_handler()) {
    5936        9212 :     isolate->ReportPromiseReject(promise, reason, kPromiseRejectWithNoHandler);
    5937             :   }
    5938             : 
    5939             :   // 8. Return TriggerPromiseReactions(reactions, reason).
    5940             :   return TriggerPromiseReactions(isolate, reactions, reason,
    5941       11725 :                                  PromiseReaction::kReject);
    5942             : }
    5943             : 
    5944             : // static
    5945       30570 : MaybeHandle<Object> JSPromise::Resolve(Handle<JSPromise> promise,
    5946             :                                        Handle<Object> resolution) {
    5947             :   Isolate* const isolate = promise->GetIsolate();
    5948             : 
    5949       30570 :   isolate->RunPromiseHook(PromiseHookType::kResolve, promise,
    5950       30570 :                           isolate->factory()->undefined_value());
    5951             : 
    5952             :   // 6. If SameValue(resolution, promise) is true, then
    5953       30570 :   if (promise.is_identical_to(resolution)) {
    5954             :     // a. Let selfResolutionError be a newly created TypeError object.
    5955             :     Handle<Object> self_resolution_error = isolate->factory()->NewTypeError(
    5956          50 :         MessageTemplate::kPromiseCyclic, resolution);
    5957             :     // b. Return RejectPromise(promise, selfResolutionError).
    5958          50 :     return Reject(promise, self_resolution_error);
    5959             :   }
    5960             : 
    5961             :   // 7. If Type(resolution) is not Object, then
    5962       30520 :   if (!resolution->IsJSReceiver()) {
    5963             :     // a. Return FulfillPromise(promise, resolution).
    5964       26930 :     return Fulfill(promise, resolution);
    5965             :   }
    5966             : 
    5967             :   // 8. Let then be Get(resolution, "then").
    5968             :   MaybeHandle<Object> then;
    5969        3590 :   if (isolate->IsPromiseThenLookupChainIntact(
    5970             :           Handle<JSReceiver>::cast(resolution))) {
    5971             :     // We can skip the "then" lookup on {resolution} if its [[Prototype]]
    5972             :     // is the (initial) Promise.prototype and the Promise#then protector
    5973             :     // is intact, as that guards the lookup path for the "then" property
    5974             :     // on JSPromise instances which have the (initial) %PromisePrototype%.
    5975        1530 :     then = isolate->promise_then();
    5976             :   } else {
    5977             :     then =
    5978             :         JSReceiver::GetProperty(isolate, Handle<JSReceiver>::cast(resolution),
    5979        2060 :                                 isolate->factory()->then_string());
    5980             :   }
    5981             : 
    5982             :   // 9. If then is an abrupt completion, then
    5983             :   Handle<Object> then_action;
    5984        3590 :   if (!then.ToHandle(&then_action)) {
    5985             :     // a. Return RejectPromise(promise, then.[[Value]]).
    5986             :     Handle<Object> reason(isolate->pending_exception(), isolate);
    5987             :     isolate->clear_pending_exception();
    5988          64 :     return Reject(promise, reason, false);
    5989             :   }
    5990             : 
    5991             :   // 10. Let thenAction be then.[[Value]].
    5992             :   // 11. If IsCallable(thenAction) is false, then
    5993        3526 :   if (!then_action->IsCallable()) {
    5994             :     // a. Return FulfillPromise(promise, resolution).
    5995        1991 :     return Fulfill(promise, resolution);
    5996             :   }
    5997             : 
    5998             :   // 12. Perform EnqueueJob("PromiseJobs", PromiseResolveThenableJob,
    5999             :   //                        «promise, resolution, thenAction»).
    6000             :   Handle<PromiseResolveThenableJobTask> task =
    6001             :       isolate->factory()->NewPromiseResolveThenableJobTask(
    6002             :           promise, Handle<JSReceiver>::cast(then_action),
    6003        3070 :           Handle<JSReceiver>::cast(resolution), isolate->native_context());
    6004        2890 :   if (isolate->debug()->is_active() && resolution->IsJSPromise()) {
    6005             :     // Mark the dependency of the new {promise} on the {resolution}.
    6006        2710 :     Object::SetProperty(isolate, resolution,
    6007             :                         isolate->factory()->promise_handled_by_symbol(),
    6008        1355 :                         promise)
    6009             :         .Check();
    6010             :   }
    6011        3070 :   isolate->native_context()->microtask_queue()->EnqueueMicrotask(*task);
    6012             : 
    6013             :   // 13. Return undefined.
    6014        1535 :   return isolate->factory()->undefined_value();
    6015             : }
    6016             : 
    6017             : // static
    6018       40646 : Handle<Object> JSPromise::TriggerPromiseReactions(Isolate* isolate,
    6019             :                                                   Handle<Object> reactions,
    6020             :                                                   Handle<Object> argument,
    6021             :                                                   PromiseReaction::Type type) {
    6022       48690 :   CHECK(reactions->IsSmi() || reactions->IsPromiseReaction());
    6023             : 
    6024             :   // We need to reverse the {reactions} here, since we record them
    6025             :   // on the JSPromise in the reverse order.
    6026             :   {
    6027             :     DisallowHeapAllocation no_gc;
    6028             :     Object current = *reactions;
    6029             :     Object reversed = Smi::kZero;
    6030       57782 :     while (!current->IsSmi()) {
    6031             :       Object next = PromiseReaction::cast(current)->next();
    6032        8568 :       PromiseReaction::cast(current)->set_next(reversed);
    6033             :       reversed = current;
    6034             :       current = next;
    6035             :     }
    6036             :     reactions = handle(reversed, isolate);
    6037             :   }
    6038             : 
    6039             :   // Morph the {reactions} into PromiseReactionJobTasks
    6040             :   // and push them onto the microtask queue.
    6041       57782 :   while (!reactions->IsSmi()) {
    6042             :     Handle<HeapObject> task = Handle<HeapObject>::cast(reactions);
    6043             :     Handle<PromiseReaction> reaction = Handle<PromiseReaction>::cast(task);
    6044             :     reactions = handle(reaction->next(), isolate);
    6045             : 
    6046             :     Handle<NativeContext> handler_context;
    6047             : 
    6048             :     STATIC_ASSERT(static_cast<int>(PromiseReaction::kSize) ==
    6049             :                   static_cast<int>(PromiseReactionJobTask::kSize));
    6050        8568 :     if (type == PromiseReaction::kFulfill) {
    6051             :       Handle<HeapObject> handler = handle(reaction->fulfill_handler(), isolate);
    6052        6035 :       if (handler->IsJSReceiver()) {
    6053        8982 :         JSReceiver::GetContextForMicrotask(Handle<JSReceiver>::cast(handler))
    6054             :             .ToHandle(&handler_context);
    6055             :       }
    6056        6035 :       if (handler_context.is_null())
    6057        1544 :         handler_context = isolate->native_context();
    6058             : 
    6059       12070 :       task->synchronized_set_map(
    6060        6035 :           ReadOnlyRoots(isolate).promise_fulfill_reaction_job_task_map());
    6061       12070 :       Handle<PromiseFulfillReactionJobTask>::cast(task)->set_argument(
    6062        6035 :           *argument);
    6063       18105 :       Handle<PromiseFulfillReactionJobTask>::cast(task)->set_context(
    6064        6035 :           *handler_context);
    6065             :       STATIC_ASSERT(
    6066             :           static_cast<int>(PromiseReaction::kFulfillHandlerOffset) ==
    6067             :           static_cast<int>(PromiseFulfillReactionJobTask::kHandlerOffset));
    6068             :       STATIC_ASSERT(
    6069             :           static_cast<int>(PromiseReaction::kPromiseOrCapabilityOffset) ==
    6070             :           static_cast<int>(
    6071             :               PromiseFulfillReactionJobTask::kPromiseOrCapabilityOffset));
    6072             :     } else {
    6073             :       DisallowHeapAllocation no_gc;
    6074             :       Handle<HeapObject> handler = handle(reaction->reject_handler(), isolate);
    6075        2533 :       if (handler->IsJSReceiver()) {
    6076        3872 :         JSReceiver::GetContextForMicrotask(Handle<JSReceiver>::cast(handler))
    6077             :             .ToHandle(&handler_context);
    6078             :       }
    6079        2533 :       if (handler_context.is_null())
    6080         597 :         handler_context = isolate->native_context();
    6081        5066 :       task->synchronized_set_map(
    6082        2533 :           ReadOnlyRoots(isolate).promise_reject_reaction_job_task_map());
    6083        2533 :       Handle<PromiseRejectReactionJobTask>::cast(task)->set_argument(*argument);
    6084        7599 :       Handle<PromiseRejectReactionJobTask>::cast(task)->set_context(
    6085        2533 :           *handler_context);
    6086        2533 :       Handle<PromiseRejectReactionJobTask>::cast(task)->set_handler(*handler);
    6087             :       STATIC_ASSERT(
    6088             :           static_cast<int>(PromiseReaction::kPromiseOrCapabilityOffset) ==
    6089             :           static_cast<int>(
    6090             :               PromiseRejectReactionJobTask::kPromiseOrCapabilityOffset));
    6091             :     }
    6092             : 
    6093       17136 :     handler_context->microtask_queue()->EnqueueMicrotask(
    6094        8568 :         *Handle<PromiseReactionJobTask>::cast(task));
    6095             :   }
    6096             : 
    6097       40646 :   return isolate->factory()->undefined_value();
    6098             : }
    6099             : 
    6100             : namespace {
    6101             : 
    6102             : constexpr JSRegExp::Flag kCharFlagValues[] = {
    6103             :     JSRegExp::kGlobal,      // g
    6104             :     JSRegExp::kInvalid,     // h
    6105             :     JSRegExp::kIgnoreCase,  // i
    6106             :     JSRegExp::kInvalid,     // j
    6107             :     JSRegExp::kInvalid,     // k
    6108             :     JSRegExp::kInvalid,     // l
    6109             :     JSRegExp::kMultiline,   // m
    6110             :     JSRegExp::kInvalid,     // n
    6111             :     JSRegExp::kInvalid,     // o
    6112             :     JSRegExp::kInvalid,     // p
    6113             :     JSRegExp::kInvalid,     // q
    6114             :     JSRegExp::kInvalid,     // r
    6115             :     JSRegExp::kDotAll,      // s
    6116             :     JSRegExp::kInvalid,     // t
    6117             :     JSRegExp::kUnicode,     // u
    6118             :     JSRegExp::kInvalid,     // v
    6119             :     JSRegExp::kInvalid,     // w
    6120             :     JSRegExp::kInvalid,     // x
    6121             :     JSRegExp::kSticky,      // y
    6122             : };
    6123             : 
    6124             : constexpr JSRegExp::Flag CharToFlag(uc16 flag_char) {
    6125       75710 :   return (flag_char < 'g' || flag_char > 'y')
    6126             :              ? JSRegExp::kInvalid
    6127       75710 :              : kCharFlagValues[flag_char - 'g'];
    6128             : }
    6129             : 
    6130      378286 : JSRegExp::Flags RegExpFlagsFromString(Isolate* isolate, Handle<String> flags,
    6131             :                                       bool* success) {
    6132             :   STATIC_ASSERT(CharToFlag('g') == JSRegExp::kGlobal);
    6133             :   STATIC_ASSERT(CharToFlag('i') == JSRegExp::kIgnoreCase);
    6134             :   STATIC_ASSERT(CharToFlag('m') == JSRegExp::kMultiline);
    6135             :   STATIC_ASSERT(CharToFlag('s') == JSRegExp::kDotAll);
    6136             :   STATIC_ASSERT(CharToFlag('u') == JSRegExp::kUnicode);
    6137             :   STATIC_ASSERT(CharToFlag('y') == JSRegExp::kSticky);
    6138             : 
    6139             :   int length = flags->length();
    6140      378286 :   if (length == 0) {
    6141      303783 :     *success = true;
    6142      303783 :     return JSRegExp::kNone;
    6143             :   }
    6144             :   // A longer flags string cannot be valid.
    6145       74503 :   if (length > JSRegExp::FlagCount()) return JSRegExp::Flags(0);
    6146             :   // Initialize {value} to {kInvalid} to allow 2-in-1 duplicate/invalid check.
    6147             :   JSRegExp::Flags value = JSRegExp::kInvalid;
    6148       74503 :   if (flags->IsSeqOneByteString()) {
    6149             :     DisallowHeapAllocation no_gc;
    6150             :     SeqOneByteString seq_flags = SeqOneByteString::cast(*flags);
    6151      225635 :     for (int i = 0; i < length; i++) {
    6152             :       JSRegExp::Flag flag = CharToFlag(seq_flags.SeqOneByteStringGet(i));
    6153             :       // Duplicate or invalid flag.
    6154       75710 :       if (value & flag) return JSRegExp::Flags(0);
    6155             :       value |= flag;
    6156             :     }
    6157             :   } else {
    6158           0 :     flags = String::Flatten(isolate, flags);
    6159             :     DisallowHeapAllocation no_gc;
    6160           0 :     String::FlatContent flags_content = flags->GetFlatContent(no_gc);
    6161           0 :     for (int i = 0; i < length; i++) {
    6162             :       JSRegExp::Flag flag = CharToFlag(flags_content.Get(i));
    6163             :       // Duplicate or invalid flag.
    6164           0 :       if (value & flag) return JSRegExp::Flags(0);
    6165             :       value |= flag;
    6166             :     }
    6167             :   }
    6168       74359 :   *success = true;
    6169             :   // Drop the initially set {kInvalid} bit.
    6170             :   value ^= JSRegExp::kInvalid;
    6171       74359 :   return value;
    6172             : }
    6173             : 
    6174             : }  // namespace
    6175             : 
    6176             : 
    6177             : // static
    6178       81948 : MaybeHandle<JSRegExp> JSRegExp::New(Isolate* isolate, Handle<String> pattern,
    6179             :                                     Flags flags) {
    6180       81948 :   Handle<JSFunction> constructor = isolate->regexp_function();
    6181             :   Handle<JSRegExp> regexp =
    6182       81948 :       Handle<JSRegExp>::cast(isolate->factory()->NewJSObject(constructor));
    6183             : 
    6184       81948 :   return JSRegExp::Initialize(regexp, pattern, flags);
    6185             : }
    6186             : 
    6187             : 
    6188             : // static
    6189       18598 : Handle<JSRegExp> JSRegExp::Copy(Handle<JSRegExp> regexp) {
    6190             :   Isolate* const isolate = regexp->GetIsolate();
    6191       18598 :   return Handle<JSRegExp>::cast(isolate->factory()->CopyJSObject(regexp));
    6192             : }
    6193             : 
    6194             : namespace {
    6195             : 
    6196             : template <typename Char>
    6197      460090 : int CountRequiredEscapes(Handle<String> source) {
    6198             :   DisallowHeapAllocation no_gc;
    6199             :   int escapes = 0;
    6200      920180 :   Vector<const Char> src = source->GetCharVector<Char>(no_gc);
    6201  4852049654 :   for (int i = 0; i < src.length(); i++) {
    6202  4851589564 :     const Char c = src[i];
    6203  2425794782 :     if (c == '\\') {
    6204             :       // Escape. Skip next character;
    6205      131095 :       i++;
    6206  2425663687 :     } else if (c == '/') {
    6207             :       // Not escaped forward-slash needs escape.
    6208        1397 :       escapes++;
    6209  2425662290 :     } else if (c == '\n') {
    6210         925 :       escapes++;
    6211  2425661365 :     } else if (c == '\r') {
    6212          36 :       escapes++;
    6213      445825 :     } else if (static_cast<int>(c) == 0x2028) {
    6214          20 :       escapes += std::strlen("\\u2028") - 1;
    6215      445805 :     } else if (static_cast<int>(c) == 0x2029) {
    6216          20 :       escapes += std::strlen("\\u2029") - 1;
    6217             :     } else {
    6218             :       DCHECK(!unibrow::IsLineTerminator(static_cast<unibrow::uchar>(c)));
    6219             :     }
    6220             :   }
    6221      460090 :   return escapes;
    6222             : }
    6223             : 
    6224             : template <typename Char>
    6225             : void WriteStringToCharVector(Vector<Char> v, int* d, const char* string) {
    6226             :   int s = 0;
    6227        5325 :   while (string[s] != '\0') v[(*d)++] = string[s++];
    6228             : }
    6229             : 
    6230             : template <typename Char, typename StringType>
    6231        1527 : Handle<StringType> WriteEscapedRegExpSource(Handle<String> source,
    6232             :                                             Handle<StringType> result) {
    6233             :   DisallowHeapAllocation no_gc;
    6234        3054 :   Vector<const Char> src = source->GetCharVector<Char>(no_gc);
    6235             :   Vector<Char> dst(result->GetChars(no_gc), result->length());
    6236             :   int s = 0;
    6237             :   int d = 0;
    6238             :   // TODO(v8:1982): Fully implement
    6239             :   // https://tc39.github.io/ecma262/#sec-escaperegexppattern
    6240       32232 :   while (s < src.length()) {
    6241       61410 :     if (src[s] == '\\') {
    6242             :       // Escape. Copy this and next character.
    6243        3606 :       dst[d++] = src[s++];
    6244        1803 :       if (s == src.length()) break;
    6245       28902 :     } else if (src[s] == '/') {
    6246             :       // Not escaped forward-slash needs escape.
    6247        2794 :       dst[d++] = '\\';
    6248       27505 :     } else if (src[s] == '\n') {
    6249             :       WriteStringToCharVector(dst, &d, "\\n");
    6250         925 :       s++;
    6251         925 :       continue;
    6252       26580 :     } else if (src[s] == '\r') {
    6253             :       WriteStringToCharVector(dst, &d, "\\r");
    6254          36 :       s++;
    6255          36 :       continue;
    6256          51 :     } else if (static_cast<int>(src[s]) == 0x2028) {
    6257             :       WriteStringToCharVector(dst, &d, "\\u2028");
    6258          20 :       s++;
    6259          20 :       continue;
    6260          31 :     } else if (static_cast<int>(src[s]) == 0x2029) {
    6261             :       WriteStringToCharVector(dst, &d, "\\u2029");
    6262          20 :       s++;
    6263          20 :       continue;
    6264             :     }
    6265       89112 :     dst[d++] = src[s++];
    6266             :   }
    6267             :   DCHECK_EQ(result->length(), d);
    6268        1527 :   return result;
    6269             : }
    6270             : 
    6271      460090 : MaybeHandle<String> EscapeRegExpSource(Isolate* isolate,
    6272             :                                        Handle<String> source) {
    6273             :   DCHECK(source->IsFlat());
    6274      460090 :   if (source->length() == 0) return isolate->factory()->query_colon_string();
    6275      460090 :   bool one_byte = String::IsOneByteRepresentationUnderneath(*source);
    6276             :   int escapes = one_byte ? CountRequiredEscapes<uint8_t>(source)
    6277      460090 :                          : CountRequiredEscapes<uc16>(source);
    6278      460090 :   if (escapes == 0) return source;
    6279        1527 :   int length = source->length() + escapes;
    6280        1527 :   if (one_byte) {
    6281             :     Handle<SeqOneByteString> result;
    6282        2976 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
    6283             :                                isolate->factory()->NewRawOneByteString(length),
    6284             :                                String);
    6285        1488 :     return WriteEscapedRegExpSource<uint8_t>(source, result);
    6286             :   } else {
    6287             :     Handle<SeqTwoByteString> result;
    6288          78 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
    6289             :                                isolate->factory()->NewRawTwoByteString(length),
    6290             :                                String);
    6291          39 :     return WriteEscapedRegExpSource<uc16>(source, result);
    6292             :   }
    6293             : }
    6294             : 
    6295             : }  // namespace
    6296             : 
    6297             : // static
    6298      378286 : MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
    6299             :                                            Handle<String> source,
    6300             :                                            Handle<String> flags_string) {
    6301             :   Isolate* isolate = regexp->GetIsolate();
    6302      378286 :   bool success = false;
    6303      378286 :   Flags flags = RegExpFlagsFromString(isolate, flags_string, &success);
    6304      378286 :   if (!success) {
    6305         288 :     THROW_NEW_ERROR(
    6306             :         isolate,
    6307             :         NewSyntaxError(MessageTemplate::kInvalidRegExpFlags, flags_string),
    6308             :         JSRegExp);
    6309             :   }
    6310      378142 :   return Initialize(regexp, source, flags);
    6311             : }
    6312             : 
    6313             : 
    6314             : // static
    6315      460090 : MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
    6316             :                                            Handle<String> source, Flags flags) {
    6317             :   Isolate* isolate = regexp->GetIsolate();
    6318             :   Factory* factory = isolate->factory();
    6319             :   // If source is the empty string we set it to "(?:)" instead as
    6320             :   // suggested by ECMA-262, 5th, section 15.10.4.1.
    6321      460090 :   if (source->length() == 0) source = factory->query_colon_string();
    6322             : 
    6323      460090 :   source = String::Flatten(isolate, source);
    6324             : 
    6325             :   Handle<String> escaped_source;
    6326      920180 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, escaped_source,
    6327             :                              EscapeRegExpSource(isolate, source), JSRegExp);
    6328             : 
    6329      920180 :   RETURN_ON_EXCEPTION(
    6330             :       isolate, RegExpImpl::Compile(isolate, regexp, source, flags), JSRegExp);
    6331             : 
    6332      914518 :   regexp->set_source(*escaped_source);
    6333      914518 :   regexp->set_flags(Smi::FromInt(flags));
    6334             : 
    6335      457259 :   Map map = regexp->map();
    6336      457259 :   Object constructor = map->GetConstructor();
    6337      914518 :   if (constructor->IsJSFunction() &&
    6338             :       JSFunction::cast(constructor)->initial_map() == map) {
    6339             :     // If we still have the original map, set in-object properties directly.
    6340      913982 :     regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, Smi::kZero,
    6341      456991 :                                   SKIP_WRITE_BARRIER);
    6342             :   } else {
    6343             :     // Map has changed, so use generic, but slower, method.
    6344         536 :     RETURN_ON_EXCEPTION(
    6345             :         isolate,
    6346             :         Object::SetProperty(isolate, regexp, factory->lastIndex_string(),
    6347             :                             Handle<Smi>(Smi::zero(), isolate)),
    6348             :         JSRegExp);
    6349             :   }
    6350             : 
    6351      457259 :   return regexp;
    6352             : }
    6353             : 
    6354             : 
    6355             : // RegExpKey carries the source and flags of a regular expression as key.
    6356      723374 : class RegExpKey : public HashTableKey {
    6357             :  public:
    6358             :   RegExpKey(Handle<String> string, JSRegExp::Flags flags)
    6359             :       : HashTableKey(
    6360             :             CompilationCacheShape::RegExpHash(*string, Smi::FromInt(flags))),
    6361             :         string_(string),
    6362      723374 :         flags_(Smi::FromInt(flags)) {}
    6363             : 
    6364             :   // Rather than storing the key in the hash table, a pointer to the
    6365             :   // stored value is stored where the key should be.  IsMatch then
    6366             :   // compares the search key to the found object, rather than comparing
    6367             :   // a key to a key.
    6368      618939 :   bool IsMatch(Object obj) override {
    6369             :     FixedArray val = FixedArray::cast(obj);
    6370     1237878 :     return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex)))
    6371     1433709 :         && (flags_ == val->get(JSRegExp::kFlagsIndex));
    6372             :   }
    6373             : 
    6374             :   Handle<String> string_;
    6375             :   Smi flags_;
    6376             : };
    6377             : 
    6378       40692 : Handle<String> OneByteStringKey::AsHandle(Isolate* isolate) {
    6379       40692 :   return isolate->factory()->NewOneByteInternalizedString(string_, HashField());
    6380             : }
    6381             : 
    6382          40 : Handle<String> TwoByteStringKey::AsHandle(Isolate* isolate) {
    6383          40 :   return isolate->factory()->NewTwoByteInternalizedString(string_, HashField());
    6384             : }
    6385             : 
    6386      481445 : Handle<String> SeqOneByteSubStringKey::AsHandle(Isolate* isolate) {
    6387             :   return isolate->factory()->NewOneByteInternalizedSubString(
    6388      481445 :       string_, from_, length_, HashField());
    6389             : }
    6390             : 
    6391     1654109 : bool SeqOneByteSubStringKey::IsMatch(Object string) {
    6392             :   DisallowHeapAllocation no_gc;
    6393     3308218 :   Vector<const uint8_t> chars(string_->GetChars(no_gc) + from_, length_);
    6394     1654109 :   return String::cast(string)->IsOneByteEqualTo(chars);
    6395             : }
    6396             : 
    6397             : // InternalizedStringKey carries a string/internalized-string object as key.
    6398    10527794 : class InternalizedStringKey : public StringTableKey {
    6399             :  public:
    6400    10527786 :   explicit InternalizedStringKey(Handle<String> string)
    6401    10527786 :       : StringTableKey(0), string_(string) {
    6402             :     DCHECK(!string->IsInternalizedString());
    6403             :     DCHECK(string->IsFlat());
    6404             :     // Make sure hash_field is computed.
    6405    10527786 :     string->Hash();
    6406             :     set_hash_field(string->hash_field());
    6407    10527798 :   }
    6408             : 
    6409    14551024 :   bool IsMatch(Object string) override {
    6410    14551024 :     return string_->SlowEquals(String::cast(string));
    6411             :   }
    6412             : 
    6413     4754126 :   Handle<String> AsHandle(Isolate* isolate) override {
    6414             :     // Internalize the string if possible.
    6415             :     MaybeHandle<Map> maybe_map =
    6416     4754126 :         isolate->factory()->InternalizedStringMapForString(string_);
    6417             :     Handle<Map> map;
    6418     4754129 :     if (maybe_map.ToHandle(&map)) {
    6419             :       string_->set_map_no_write_barrier(*map);
    6420             :       DCHECK(string_->IsInternalizedString());
    6421       57449 :       return string_;
    6422             :     }
    6423     4696680 :     if (FLAG_thin_strings) {
    6424             :       // External strings get special treatment, to avoid copying their
    6425             :       // contents.
    6426     4696680 :       if (string_->IsExternalOneByteString()) {
    6427             :         return isolate->factory()
    6428           5 :             ->InternalizeExternalString<ExternalOneByteString>(string_);
    6429     4696675 :       } else if (string_->IsExternalTwoByteString()) {
    6430             :         return isolate->factory()
    6431           0 :             ->InternalizeExternalString<ExternalTwoByteString>(string_);
    6432             :       }
    6433             :     }
    6434             :     // Otherwise allocate a new internalized string.
    6435             :     return isolate->factory()->NewInternalizedStringImpl(
    6436     4696674 :         string_, string_->length(), string_->hash_field());
    6437             :   }
    6438             : 
    6439             :  private:
    6440             :   Handle<String> string_;
    6441             : };
    6442             : 
    6443             : template <typename Derived, typename Shape>
    6444       73379 : void HashTable<Derived, Shape>::IteratePrefix(ObjectVisitor* v) {
    6445             :   BodyDescriptorBase::IteratePointers(*this, 0, kElementsStartOffset, v);
    6446       73379 : }
    6447             : 
    6448             : template <typename Derived, typename Shape>
    6449       73955 : void HashTable<Derived, Shape>::IterateElements(ObjectVisitor* v) {
    6450             :   BodyDescriptorBase::IteratePointers(*this, kElementsStartOffset,
    6451             :                                       SizeFor(length()), v);
    6452       73955 : }
    6453             : 
    6454             : template <typename Derived, typename Shape>
    6455     1458307 : Handle<Derived> HashTable<Derived, Shape>::New(
    6456             :     Isolate* isolate, int at_least_space_for, AllocationType allocation,
    6457             :     MinimumCapacity capacity_option) {
    6458             :   DCHECK_LE(0, at_least_space_for);
    6459             :   DCHECK_IMPLIES(capacity_option == USE_CUSTOM_MINIMUM_CAPACITY,
    6460             :                  base::bits::IsPowerOfTwo(at_least_space_for));
    6461             : 
    6462             :   int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
    6463             :                      ? at_least_space_for
    6464     1458307 :                      : ComputeCapacity(at_least_space_for);
    6465     1458307 :   if (capacity > HashTable::kMaxCapacity) {
    6466           0 :     isolate->heap()->FatalProcessOutOfMemory("invalid table size");
    6467             :   }
    6468     1458307 :   return NewInternal(isolate, capacity, allocation);
    6469             : }
    6470             : 
    6471             : template <typename Derived, typename Shape>
    6472     1458307 : Handle<Derived> HashTable<Derived, Shape>::NewInternal(
    6473             :     Isolate* isolate, int capacity, AllocationType allocation) {
    6474             :   Factory* factory = isolate->factory();
    6475             :   int length = EntryToIndex(capacity);
    6476             :   RootIndex map_root_index = Shape::GetMapRootIndex();
    6477             :   Handle<FixedArray> array =
    6478     1458307 :       factory->NewFixedArrayWithMap(map_root_index, length, allocation);
    6479             :   Handle<Derived> table = Handle<Derived>::cast(array);
    6480             : 
    6481             :   table->SetNumberOfElements(0);
    6482             :   table->SetNumberOfDeletedElements(0);
    6483             :   table->SetCapacity(capacity);
    6484     1458307 :   return table;
    6485             : }
    6486             : 
    6487             : template <typename Derived, typename Shape>
    6488      237421 : void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots, Derived new_table) {
    6489             :   DisallowHeapAllocation no_gc;
    6490             :   WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc);
    6491             : 
    6492             :   DCHECK_LT(NumberOfElements(), new_table->Capacity());
    6493             : 
    6494             :   // Copy prefix to new array.
    6495     1122371 :   for (int i = kPrefixStartIndex; i < kElementsStartIndex; i++) {
    6496      447498 :     new_table->set(i, get(i), mode);
    6497             :   }
    6498             : 
    6499             :   // Rehash the elements.
    6500             :   int capacity = this->Capacity();
    6501    84778437 :   for (int i = 0; i < capacity; i++) {
    6502    43200960 :     uint32_t from_index = EntryToIndex(i);
    6503             :     Object k = this->get(from_index);
    6504    43200960 :     if (!Shape::IsLive(roots, k)) continue;
    6505     7179149 :     uint32_t hash = Shape::HashForObject(roots, k);
    6506             :     uint32_t insertion_index =
    6507    50813180 :         EntryToIndex(new_table->FindInsertionEntry(hash));
    6508   107303916 :     for (int j = 0; j < Shape::kEntrySize; j++) {
    6509    81897326 :       new_table->set(insertion_index + j, get(from_index + j), mode);
    6510             :     }
    6511             :   }
    6512             :   new_table->SetNumberOfElements(NumberOfElements());
    6513             :   new_table->SetNumberOfDeletedElements(0);
    6514      237421 : }
    6515             : 
    6516             : template <typename Derived, typename Shape>
    6517   477285908 : uint32_t HashTable<Derived, Shape>::EntryForProbe(ReadOnlyRoots roots, Object k,
    6518             :                                                   int probe,
    6519             :                                                   uint32_t expected) {
    6520    31281154 :   uint32_t hash = Shape::HashForObject(roots, k);
    6521   477287621 :   uint32_t capacity = this->Capacity();
    6522             :   uint32_t entry = FirstProbe(hash, capacity);
    6523   724940911 :   for (int i = 1; i < probe; i++) {
    6524   455233310 :     if (entry == expected) return expected;
    6525   123826645 :     entry = NextProbe(entry, i, capacity);
    6526             :   }
    6527             :   return entry;
    6528             : }
    6529             : 
    6530             : template <typename Derived, typename Shape>
    6531    58234970 : void HashTable<Derived, Shape>::Swap(uint32_t entry1, uint32_t entry2,
    6532             :                                      WriteBarrierMode mode) {
    6533    58234970 :   int index1 = EntryToIndex(entry1);
    6534    58234970 :   int index2 = EntryToIndex(entry2);
    6535    58234970 :   Object temp[Shape::kEntrySize];
    6536   174708412 :   for (int j = 0; j < Shape::kEntrySize; j++) {
    6537   116473618 :     temp[j] = get(index1 + j);
    6538             :   }
    6539   174708432 :   for (int j = 0; j < Shape::kEntrySize; j++) {
    6540   116473298 :     set(index1 + j, get(index2 + j), mode);
    6541             :   }
    6542   174708227 :   for (int j = 0; j < Shape::kEntrySize; j++) {
    6543    58236820 :     set(index2 + j, temp[j], mode);
    6544             :   }
    6545    58234725 : }
    6546             : 
    6547             : template <typename Derived, typename Shape>
    6548      365053 : void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots) {
    6549             :   DisallowHeapAllocation no_gc;
    6550             :   WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
    6551      367973 :   uint32_t capacity = Capacity();
    6552             :   bool done = false;
    6553     2568399 :   for (int probe = 1; !done; probe++) {
    6554             :     // All elements at entries given by one of the first _probe_ probes
    6555             :     // are placed correctly. Other elements might need to be moved.
    6556             :     done = true;
    6557  2103951335 :     for (uint32_t current = 0; current < capacity; current++) {
    6558  1051426823 :       Object current_key = KeyAt(current);
    6559  1097969585 :       if (!Shape::IsLive(roots, current_key)) continue;
    6560   439349471 :       uint32_t target = EntryForProbe(roots, current_key, probe, current);
    6561   439350329 :       if (current == target) continue;
    6562    81888050 :       Object target_key = KeyAt(target);
    6563   119827392 :       if (!Shape::IsLive(roots, target_key) ||
    6564    37939576 :           EntryForProbe(roots, target_key, probe, target) != target) {
    6565             :         // Put the current element into the correct position.
    6566    58234885 :         Swap(current, target, mode);
    6567             :         // The other element will be processed on the next iteration.
    6568    58234721 :         current--;
    6569             :       } else {
    6570             :         // The place for the current element is occupied. Leave the element
    6571             :         // for the next probe.
    6572             :         done = false;
    6573             :       }
    6574             :     }
    6575             :   }
    6576             :   // Wipe deleted entries.
    6577             :   Object the_hole = roots.the_hole_value();
    6578      365449 :   Object undefined = roots.undefined_value();
    6579   367846685 :   for (uint32_t current = 0; current < capacity; current++) {
    6580   367481780 :     if (KeyAt(current) == the_hole) {
    6581     1163476 :       set(EntryToIndex(current) + kEntryKeyIndex, undefined);
    6582             :     }
    6583             :   }
    6584             :   SetNumberOfDeletedElements(0);
    6585      365056 : }
    6586             : 
    6587             : template <typename Derived, typename Shape>
    6588    32321936 : Handle<Derived> HashTable<Derived, Shape>::EnsureCapacity(
    6589             :     Isolate* isolate, Handle<Derived> table, int n, AllocationType allocation) {
    6590    32321936 :   if (table->HasSufficientCapacityToAdd(n)) return table;
    6591             : 
    6592             :   int capacity = table->Capacity();
    6593      236929 :   int new_nof = table->NumberOfElements() + n;
    6594             : 
    6595             :   const int kMinCapacityForPretenure = 256;
    6596             :   bool should_pretenure = allocation == AllocationType::kOld ||
    6597             :                           ((capacity > kMinCapacityForPretenure) &&
    6598      245550 :                            !Heap::InYoungGeneration(*table));
    6599      236929 :   Handle<Derived> new_table = HashTable::New(
    6600             :       isolate, new_nof,
    6601      236929 :       should_pretenure ? AllocationType::kOld : AllocationType::kYoung);
    6602             : 
    6603      236929 :   table->Rehash(ReadOnlyRoots(isolate), *new_table);
    6604      236929 :   return new_table;
    6605             : }
    6606             : 
    6607             : template bool
    6608             : HashTable<NameDictionary, NameDictionaryShape>::HasSufficientCapacityToAdd(int);
    6609             : 
    6610             : template <typename Derived, typename Shape>
    6611    32355843 : bool HashTable<Derived, Shape>::HasSufficientCapacityToAdd(
    6612             :     int number_of_additional_elements) {
    6613             :   int capacity = Capacity();
    6614    32355841 :   int nof = NumberOfElements() + number_of_additional_elements;
    6615             :   int nod = NumberOfDeletedElements();
    6616             :   // Return true if:
    6617             :   //   50% is still free after adding number_of_additional_elements elements and
    6618             :   //   at most 50% of the free elements are deleted elements.
    6619    32355843 :   if ((nof < capacity) && ((nod <= (capacity - nof) >> 1))) {
    6620    32293138 :     int needed_free = nof >> 1;
    6621    32293138 :     if (nof + needed_free <= capacity) return true;
    6622             :   }
    6623      237421 :   return false;
    6624             : }
    6625             : 
    6626             : template <typename Derived, typename Shape>
    6627       78485 : Handle<Derived> HashTable<Derived, Shape>::Shrink(Isolate* isolate,
    6628             :                                                   Handle<Derived> table,
    6629             :                                                   int additionalCapacity) {
    6630             :   int capacity = table->Capacity();
    6631             :   int nof = table->NumberOfElements();
    6632             : 
    6633             :   // Shrink to fit the number of elements if only a quarter of the
    6634             :   // capacity is filled with elements.
    6635       78485 :   if (nof > (capacity >> 2)) return table;
    6636             :   // Allocate a new dictionary with room for at least the current number of
    6637             :   // elements + {additionalCapacity}. The allocation method will make sure that
    6638             :   // there is extra room in the dictionary for additions. Don't go lower than
    6639             :   // room for {kMinShrinkCapacity} elements.
    6640       59970 :   int at_least_room_for = nof + additionalCapacity;
    6641             :   int new_capacity = ComputeCapacity(at_least_room_for);
    6642       59970 :   if (new_capacity < Derived::kMinShrinkCapacity) return table;
    6643         492 :   if (new_capacity == capacity) return table;
    6644             : 
    6645             :   const int kMinCapacityForPretenure = 256;
    6646             :   bool pretenure = (at_least_room_for > kMinCapacityForPretenure) &&
    6647         714 :                    !Heap::InYoungGeneration(*table);
    6648             :   Handle<Derived> new_table =
    6649         492 :       HashTable::New(isolate, new_capacity,
    6650             :                      pretenure ? AllocationType::kOld : AllocationType::kYoung,
    6651         492 :                      USE_CUSTOM_MINIMUM_CAPACITY);
    6652             : 
    6653         492 :   table->Rehash(ReadOnlyRoots(isolate), *new_table);
    6654         492 :   return new_table;
    6655             : }
    6656             : 
    6657             : template <typename Derived, typename Shape>
    6658    57732945 : uint32_t HashTable<Derived, Shape>::FindInsertionEntry(uint32_t hash) {
    6659    57732950 :   uint32_t capacity = Capacity();
    6660             :   uint32_t entry = FirstProbe(hash, capacity);
    6661             :   uint32_t count = 1;
    6662             :   // EnsureCapacity will guarantee the hash table is never full.
    6663             :   ReadOnlyRoots roots = GetReadOnlyRoots();
    6664    84632820 :   while (true) {
    6665   284731531 :     if (!Shape::IsLive(roots, KeyAt(entry))) break;
    6666    84632820 :     entry = NextProbe(entry, count++, capacity);
    6667             :   }
    6668    57732941 :   return entry;
    6669             : }
    6670             : 
    6671             : 
    6672             : // This class is used for looking up two character strings in the string table.
    6673             : // If we don't have a hit we don't want to waste much time so we unroll the
    6674             : // string hash calculation loop here for speed.  Doesn't work if the two
    6675             : // characters form a decimal integer, since such strings have a different hash
    6676             : // algorithm.
    6677     1705986 : class TwoCharHashTableKey : public StringTableKey {
    6678             :  public:
    6679             :   TwoCharHashTableKey(uint16_t c1, uint16_t c2, uint64_t seed)
    6680     3411972 :       : StringTableKey(ComputeHashField(c1, c2, seed)), c1_(c1), c2_(c2) {}
    6681             : 
    6682     2377245 :   bool IsMatch(Object o) override {
    6683             :     String other = String::cast(o);
    6684     2377245 :     if (other->length() != 2) return false;
    6685       92241 :     if (other->Get(0) != c1_) return false;
    6686       14323 :     return other->Get(1) == c2_;
    6687             :   }
    6688             : 
    6689           0 :   Handle<String> AsHandle(Isolate* isolate) override {
    6690             :     // The TwoCharHashTableKey is only used for looking in the string
    6691             :     // table, not for adding to it.
    6692           0 :     UNREACHABLE();
    6693             :   }
    6694             : 
    6695             :  private:
    6696     1705986 :   uint32_t ComputeHashField(uint16_t c1, uint16_t c2, uint64_t seed) {
    6697             :     // Char 1.
    6698     1705986 :     uint32_t hash = static_cast<uint32_t>(seed);
    6699     1705986 :     hash += c1;
    6700     1705986 :     hash += hash << 10;
    6701     1705986 :     hash ^= hash >> 6;
    6702             :     // Char 2.
    6703     1705986 :     hash += c2;
    6704     1705986 :     hash += hash << 10;
    6705     1705986 :     hash ^= hash >> 6;
    6706             :     // GetHash.
    6707     1705986 :     hash += hash << 3;
    6708     1705986 :     hash ^= hash >> 11;
    6709     1705986 :     hash += hash << 15;
    6710     1705986 :     if ((hash & String::kHashBitMask) == 0) hash = StringHasher::kZeroHash;
    6711     1705986 :     hash = (hash << String::kHashShift) | String::kIsNotArrayIndexMask;
    6712             : #ifdef DEBUG
    6713             :     // If this assert fails then we failed to reproduce the two-character
    6714             :     // version of the string hashing algorithm above.  One reason could be
    6715             :     // that we were passed two digits as characters, since the hash
    6716             :     // algorithm is different in that case.
    6717             :     uint16_t chars[2] = {c1, c2};
    6718             :     uint32_t check_hash = StringHasher::HashSequentialString(chars, 2, seed);
    6719             :     DCHECK_EQ(hash, check_hash);
    6720             : #endif
    6721     1705986 :     return hash;
    6722             :   }
    6723             : 
    6724             :   uint16_t c1_;
    6725             :   uint16_t c2_;
    6726             : };
    6727             : 
    6728     1705986 : MaybeHandle<String> StringTable::LookupTwoCharsStringIfExists(
    6729             :     Isolate* isolate,
    6730             :     uint16_t c1,
    6731             :     uint16_t c2) {
    6732             :   TwoCharHashTableKey key(c1, c2, HashSeed(isolate));
    6733             :   Handle<StringTable> string_table = isolate->factory()->string_table();
    6734     1705986 :   int entry = string_table->FindEntry(isolate, &key);
    6735     1705986 :   if (entry == kNotFound) return MaybeHandle<String>();
    6736             : 
    6737             :   Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
    6738             :   DCHECK(StringShape(*result).IsInternalized());
    6739             :   DCHECK_EQ(result->Hash(), key.Hash());
    6740       13394 :   return result;
    6741             : }
    6742             : 
    6743         209 : void StringTable::EnsureCapacityForDeserialization(Isolate* isolate,
    6744             :                                                    int expected) {
    6745             :   Handle<StringTable> table = isolate->factory()->string_table();
    6746             :   // We need a key instance for the virtual hash function.
    6747         209 :   table = StringTable::EnsureCapacity(isolate, table, expected);
    6748             :   isolate->heap()->SetRootStringTable(*table);
    6749         209 : }
    6750             : 
    6751             : namespace {
    6752             : 
    6753             : template <class StringClass>
    6754          14 : void MigrateExternalStringResource(Isolate* isolate, String from, String to) {
    6755          14 :   StringClass cast_from = StringClass::cast(from);
    6756          14 :   StringClass cast_to = StringClass::cast(to);
    6757             :   const typename StringClass::Resource* to_resource = cast_to->resource();
    6758          14 :   if (to_resource == nullptr) {
    6759             :     // |to| is a just-created internalized copy of |from|. Migrate the resource.
    6760           5 :     cast_to->SetResource(isolate, cast_from->resource());
    6761             :     // Zap |from|'s resource pointer to reflect the fact that |from| has
    6762             :     // relinquished ownership of its resource.
    6763          10 :     isolate->heap()->UpdateExternalString(
    6764          10 :         from, ExternalString::cast(from)->ExternalPayloadSize(), 0);
    6765           5 :     cast_from->SetResource(isolate, nullptr);
    6766           9 :   } else if (to_resource != cast_from->resource()) {
    6767             :     // |to| already existed and has its own resource. Finalize |from|.
    6768           9 :     isolate->heap()->FinalizeExternalString(from);
    6769             :   }
    6770          14 : }
    6771             : 
    6772    22775910 : void MakeStringThin(String string, String internalized, Isolate* isolate) {
    6773             :   DCHECK_NE(string, internalized);
    6774             :   DCHECK(internalized->IsInternalizedString());
    6775             : 
    6776    22775917 :   if (string->IsExternalString()) {
    6777          14 :     if (internalized->IsExternalOneByteString()) {
    6778             :       MigrateExternalStringResource<ExternalOneByteString>(isolate, string,
    6779          14 :                                                            internalized);
    6780           0 :     } else if (internalized->IsExternalTwoByteString()) {
    6781             :       MigrateExternalStringResource<ExternalTwoByteString>(isolate, string,
    6782           0 :                                                            internalized);
    6783             :     } else {
    6784             :       // If the external string is duped into an existing non-external
    6785             :       // internalized string, free its resource (it's about to be rewritten
    6786             :       // into a ThinString below).
    6787           0 :       isolate->heap()->FinalizeExternalString(string);
    6788             :     }
    6789             :   }
    6790             : 
    6791             :   DisallowHeapAllocation no_gc;
    6792    22775917 :   int old_size = string->Size();
    6793    22775916 :   isolate->heap()->NotifyObjectLayoutChange(string, old_size, no_gc);
    6794    22775919 :   bool one_byte = internalized->IsOneByteRepresentation();
    6795             :   Handle<Map> map = one_byte ? isolate->factory()->thin_one_byte_string_map()
    6796    22775919 :                              : isolate->factory()->thin_string_map();
    6797             :   DCHECK_GE(old_size, ThinString::kSize);
    6798    22775919 :   string->synchronized_set_map(*map);
    6799    22775919 :   ThinString thin = ThinString::cast(string);
    6800    22775919 :   thin->set_actual(internalized);
    6801    22775919 :   Address thin_end = thin->address() + ThinString::kSize;
    6802    22775919 :   int size_delta = old_size - ThinString::kSize;
    6803    22775919 :   if (size_delta != 0) {
    6804             :     Heap* heap = isolate->heap();
    6805     9715992 :     heap->CreateFillerObjectAt(thin_end, size_delta, ClearRecordedSlots::kNo);
    6806             :   }
    6807    22775915 : }
    6808             : 
    6809             : }  // namespace
    6810             : 
    6811             : // static
    6812    11453862 : Handle<String> StringTable::LookupString(Isolate* isolate,
    6813             :                                          Handle<String> string) {
    6814    11453862 :   string = String::Flatten(isolate, string);
    6815    11453860 :   if (string->IsInternalizedString()) return string;
    6816             : 
    6817    10527792 :   InternalizedStringKey key(string);
    6818    10527799 :   Handle<String> result = LookupKey(isolate, &key);
    6819             : 
    6820    10527793 :   if (FLAG_thin_strings) {
    6821    10527793 :     if (!string->IsInternalizedString()) {
    6822    10470350 :       MakeStringThin(*string, *result, isolate);
    6823             :     }
    6824             :   } else {  // !FLAG_thin_strings
    6825           0 :     if (string->IsConsString()) {
    6826             :       Handle<ConsString> cons = Handle<ConsString>::cast(string);
    6827           0 :       cons->set_first(isolate, *result);
    6828           0 :       cons->set_second(isolate, ReadOnlyRoots(isolate).empty_string());
    6829           0 :     } else if (string->IsSlicedString()) {
    6830             :       STATIC_ASSERT(static_cast<int>(ConsString::kSize) ==
    6831             :                     static_cast<int>(SlicedString::kSize));
    6832             :       DisallowHeapAllocation no_gc;
    6833           0 :       bool one_byte = result->IsOneByteRepresentation();
    6834             :       Handle<Map> map = one_byte
    6835             :                             ? isolate->factory()->cons_one_byte_string_map()
    6836           0 :                             : isolate->factory()->cons_string_map();
    6837           0 :       string->set_map(*map);
    6838             :       Handle<ConsString> cons = Handle<ConsString>::cast(string);
    6839           0 :       cons->set_first(isolate, *result);
    6840           0 :       cons->set_second(isolate, ReadOnlyRoots(isolate).empty_string());
    6841             :     }
    6842             :   }
    6843    10527794 :   return result;
    6844             : }
    6845             : 
    6846             : // static
    6847    50764653 : Handle<String> StringTable::LookupKey(Isolate* isolate, StringTableKey* key) {
    6848             :   Handle<StringTable> table = isolate->factory()->string_table();
    6849    50764653 :   int entry = table->FindEntry(isolate, key);
    6850             : 
    6851             :   // String already in table.
    6852    50764747 :   if (entry != kNotFound) {
    6853             :     return handle(String::cast(table->KeyAt(entry)), isolate);
    6854             :   }
    6855             : 
    6856    14605635 :   table = StringTable::CautiousShrink(isolate, table);
    6857             :   // Adding new string. Grow table if needed.
    6858    14605635 :   table = StringTable::EnsureCapacity(isolate, table, 1);
    6859             :   isolate->heap()->SetRootStringTable(*table);
    6860             : 
    6861    14605634 :   return AddKeyNoResize(isolate, key);
    6862             : }
    6863             : 
    6864    14610273 : Handle<String> StringTable::AddKeyNoResize(Isolate* isolate,
    6865             :                                            StringTableKey* key) {
    6866             :   Handle<StringTable> table = isolate->factory()->string_table();
    6867             :   DCHECK(table->HasSufficientCapacityToAdd(1));
    6868             :   // Create string object.
    6869    14610273 :   Handle<String> string = key->AsHandle(isolate);
    6870             :   // There must be no attempts to internalize strings that could throw
    6871             :   // InvalidStringLength error.
    6872    14610258 :   CHECK(!string.is_null());
    6873             :   DCHECK(string->HasHashCode());
    6874             :   DCHECK_EQ(table->FindEntry(isolate, key), kNotFound);
    6875             : 
    6876             :   // Add the new string and return it along with the string table.
    6877    14610258 :   int entry = table->FindInsertionEntry(key->Hash());
    6878    29220514 :   table->set(EntryToIndex(entry), *string);
    6879    14610259 :   table->ElementAdded();
    6880             : 
    6881    14610261 :   return Handle<String>::cast(string);
    6882             : }
    6883             : 
    6884    14605633 : Handle<StringTable> StringTable::CautiousShrink(Isolate* isolate,
    6885             :                                                 Handle<StringTable> table) {
    6886             :   // Only shrink if the table is very empty to avoid performance penalty.
    6887             :   int capacity = table->Capacity();
    6888             :   int nof = table->NumberOfElements();
    6889    14605637 :   if (capacity <= StringTable::kMinCapacity) return table;
    6890     7385086 :   if (nof > (capacity / kMaxEmptyFactor)) return table;
    6891             :   // Keep capacity for at least half of the current nof elements.
    6892       30892 :   int slack_capacity = nof >> 2;
    6893       30892 :   return Shrink(isolate, table, slack_capacity);
    6894             : }
    6895             : 
    6896             : namespace {
    6897             : 
    6898             : class StringTableNoAllocateKey : public StringTableKey {
    6899             :  public:
    6900    12691712 :   StringTableNoAllocateKey(String string, uint64_t seed)
    6901    12691712 :       : StringTableKey(0), string_(string) {
    6902    12691712 :     StringShape shape(string);
    6903    12691712 :     one_byte_ = shape.encoding_tag() == kOneByteStringTag;
    6904             :     DCHECK(!shape.IsInternalized());
    6905             :     DCHECK(!shape.IsThin());
    6906             :     int length = string->length();
    6907    12691712 :     if (shape.IsCons() && length <= String::kMaxHashCalcLength) {
    6908      287754 :       special_flattening_ = true;
    6909             :       uint32_t hash_field = 0;
    6910      287754 :       if (one_byte_) {
    6911      287754 :         if (V8_LIKELY(length <=
    6912             :                       static_cast<int>(arraysize(one_byte_buffer_)))) {
    6913      287754 :           one_byte_content_ = one_byte_buffer_;
    6914             :         } else {
    6915           0 :           one_byte_content_ = new uint8_t[length];
    6916             :         }
    6917      287754 :         String::WriteToFlat(string, one_byte_content_, 0, length);
    6918             :         hash_field =
    6919      287754 :             StringHasher::HashSequentialString(one_byte_content_, length, seed);
    6920             :       } else {
    6921           0 :         if (V8_LIKELY(length <=
    6922             :                       static_cast<int>(arraysize(two_byte_buffer_)))) {
    6923           0 :           two_byte_content_ = two_byte_buffer_;
    6924             :         } else {
    6925           0 :           two_byte_content_ = new uint16_t[length];
    6926             :         }
    6927           0 :         String::WriteToFlat(string, two_byte_content_, 0, length);
    6928             :         hash_field =
    6929           0 :             StringHasher::HashSequentialString(two_byte_content_, length, seed);
    6930             :       }
    6931             :       string->set_hash_field(hash_field);
    6932             :     } else {
    6933    12403958 :       special_flattening_ = false;
    6934    12403958 :       one_byte_content_ = nullptr;
    6935    12403958 :       string->Hash();
    6936             :     }
    6937             : 
    6938             :     DCHECK(string->HasHashCode());
    6939             :     set_hash_field(string->hash_field());
    6940    12691712 :   }
    6941             : 
    6942    25383424 :   ~StringTableNoAllocateKey() override {
    6943    12691712 :     if (one_byte_) {
    6944    11950727 :       if (one_byte_content_ != one_byte_buffer_) delete[] one_byte_content_;
    6945             :     } else {
    6946      740985 :       if (two_byte_content_ != two_byte_buffer_) delete[] two_byte_content_;
    6947             :     }
    6948    12691712 :   }
    6949             : 
    6950    21888247 :   bool IsMatch(Object otherstring) override {
    6951    21888247 :     String other = String::cast(otherstring);
    6952             :     DCHECK(other->IsInternalizedString());
    6953             :     DCHECK(other->IsFlat());
    6954    21888247 :     if (Hash() != other->Hash()) return false;
    6955             :     int len = string_->length();
    6956    12305018 :     if (len != other->length()) return false;
    6957             : 
    6958             :     DisallowHeapAllocation no_gc;
    6959    12305018 :     if (!special_flattening_) {
    6960    24337170 :       if (string_->Get(0) != other->Get(0)) return false;
    6961    12168585 :       if (string_->IsFlat()) {
    6962    12168582 :         StringShape shape1(string_);
    6963    12168582 :         StringShape shape2(other);
    6964    23614472 :         if (shape1.encoding_tag() == kOneByteStringTag &&
    6965             :             shape2.encoding_tag() == kOneByteStringTag) {
    6966    11445890 :           String::FlatContent flat1 = string_->GetFlatContent(no_gc);
    6967    11445890 :           String::FlatContent flat2 = other->GetFlatContent(no_gc);
    6968             :           return CompareRawStringContents(flat1.ToOneByteVector().start(),
    6969             :                                           flat2.ToOneByteVector().start(), len);
    6970             :         }
    6971     1445384 :         if (shape1.encoding_tag() == kTwoByteStringTag &&
    6972             :             shape2.encoding_tag() == kTwoByteStringTag) {
    6973      722692 :           String::FlatContent flat1 = string_->GetFlatContent(no_gc);
    6974      722692 :           String::FlatContent flat2 = other->GetFlatContent(no_gc);
    6975             :           return CompareRawStringContents(flat1.ToUC16Vector().start(),
    6976             :                                           flat2.ToUC16Vector().start(), len);
    6977             :         }
    6978             :       }
    6979             :       StringComparator comparator;
    6980           3 :       return comparator.Equals(string_, other);
    6981             :     }
    6982             : 
    6983      136433 :     String::FlatContent flat_content = other->GetFlatContent(no_gc);
    6984      136433 :     if (one_byte_) {
    6985      136433 :       if (flat_content.IsOneByte()) {
    6986             :         return CompareRawStringContents(
    6987      136433 :             one_byte_content_, flat_content.ToOneByteVector().start(), len);
    6988             :       } else {
    6989             :         DCHECK(flat_content.IsTwoByte());
    6990           0 :         for (int i = 0; i < len; i++) {
    6991           0 :           if (flat_content.Get(i) != one_byte_content_[i]) return false;
    6992             :         }
    6993             :         return true;
    6994             :       }
    6995             :     } else {
    6996           0 :       if (flat_content.IsTwoByte()) {
    6997             :         return CompareRawStringContents(
    6998           0 :             two_byte_content_, flat_content.ToUC16Vector().start(), len);
    6999             :       } else {
    7000             :         DCHECK(flat_content.IsOneByte());
    7001           0 :         for (int i = 0; i < len; i++) {
    7002           0 :           if (flat_content.Get(i) != two_byte_content_[i]) return false;
    7003             :         }
    7004             :         return true;
    7005             :       }
    7006             :     }
    7007             :   }
    7008             : 
    7009           0 :   V8_WARN_UNUSED_RESULT Handle<String> AsHandle(Isolate* isolate) override {
    7010           0 :     UNREACHABLE();
    7011             :   }
    7012             : 
    7013             :  private:
    7014             :   String string_;
    7015             :   bool one_byte_;
    7016             :   bool special_flattening_;
    7017             :   union {
    7018             :     uint8_t* one_byte_content_;
    7019             :     uint16_t* two_byte_content_;
    7020             :   };
    7021             :   union {
    7022             :     uint8_t one_byte_buffer_[256];
    7023             :     uint16_t two_byte_buffer_[128];
    7024             :   };
    7025             : };
    7026             : 
    7027             : }  // namespace
    7028             : 
    7029             : // static
    7030    12691712 : Address StringTable::LookupStringIfExists_NoAllocate(Isolate* isolate,
    7031             :                                                      Address raw_string) {
    7032             :   DisallowHeapAllocation no_gc;
    7033             :   String string = String::cast(Object(raw_string));
    7034             :   Heap* heap = isolate->heap();
    7035    12691712 :   StringTable table = heap->string_table();
    7036             : 
    7037    25383424 :   StringTableNoAllocateKey key(string, HashSeed(isolate));
    7038             : 
    7039             :   // String could be an array index.
    7040             :   uint32_t hash = string->hash_field();
    7041             : 
    7042             :   // Valid array indices are >= 0, so they cannot be mixed up with any of
    7043             :   // the result sentinels, which are negative.
    7044             :   STATIC_ASSERT(
    7045             :       !String::ArrayIndexValueBits::is_valid(ResultSentinel::kUnsupported));
    7046             :   STATIC_ASSERT(
    7047             :       !String::ArrayIndexValueBits::is_valid(ResultSentinel::kNotFound));
    7048             : 
    7049    12691712 :   if (Name::ContainsCachedArrayIndex(hash)) {
    7050          70 :     return Smi::FromInt(String::ArrayIndexValueBits::decode(hash)).ptr();
    7051             :   }
    7052    12691642 :   if ((hash & Name::kIsNotArrayIndexMask) == 0) {
    7053             :     // It is an indexed, but it's not cached.
    7054             :     return Smi::FromInt(ResultSentinel::kUnsupported).ptr();
    7055             :   }
    7056             : 
    7057             :   DCHECK(!string->IsInternalizedString());
    7058    25383136 :   int entry = table->FindEntry(ReadOnlyRoots(isolate), &key, key.Hash());
    7059    12691568 :   if (entry != kNotFound) {
    7060             :     String internalized = String::cast(table->KeyAt(entry));
    7061    12305018 :     if (FLAG_thin_strings) {
    7062    12305018 :       MakeStringThin(string, internalized, isolate);
    7063             :     }
    7064             :     return internalized.ptr();
    7065             :   }
    7066             :   // A string that's not an array index, and not in the string table,
    7067             :   // cannot have been used as a property name before.
    7068             :   return Smi::FromInt(ResultSentinel::kNotFound).ptr();
    7069             : }
    7070             : 
    7071        5195 : String StringTable::ForwardStringIfExists(Isolate* isolate, StringTableKey* key,
    7072             :                                           String string) {
    7073             :   Handle<StringTable> table = isolate->factory()->string_table();
    7074        5195 :   int entry = table->FindEntry(isolate, key);
    7075        5195 :   if (entry == kNotFound) return String();
    7076             : 
    7077             :   String canonical = String::cast(table->KeyAt(entry));
    7078         553 :   if (canonical != string) MakeStringThin(string, canonical, isolate);
    7079         553 :   return canonical;
    7080             : }
    7081             : 
    7082       12560 : Handle<StringSet> StringSet::New(Isolate* isolate) {
    7083       12560 :   return HashTable::New(isolate, 0);
    7084             : }
    7085             : 
    7086       16549 : Handle<StringSet> StringSet::Add(Isolate* isolate, Handle<StringSet> stringset,
    7087             :                                  Handle<String> name) {
    7088       33098 :   if (!stringset->Has(isolate, name)) {
    7089       11655 :     stringset = EnsureCapacity(isolate, stringset, 1);
    7090             :     uint32_t hash = ShapeT::Hash(isolate, *name);
    7091       11655 :     int entry = stringset->FindInsertionEntry(hash);
    7092       23310 :     stringset->set(EntryToIndex(entry), *name);
    7093       11655 :     stringset->ElementAdded();
    7094             :   }
    7095       16549 :   return stringset;
    7096             : }
    7097             : 
    7098        5101 : bool StringSet::Has(Isolate* isolate, Handle<String> name) {
    7099       21650 :   return FindEntry(isolate, *name) != kNotFound;
    7100             : }
    7101             : 
    7102      107938 : Handle<ObjectHashSet> ObjectHashSet::Add(Isolate* isolate,
    7103             :                                          Handle<ObjectHashSet> set,
    7104             :                                          Handle<Object> key) {
    7105      215876 :   int32_t hash = key->GetOrCreateHash(isolate)->value();
    7106      215876 :   if (!set->Has(isolate, key, hash)) {
    7107      106302 :     set = EnsureCapacity(isolate, set, 1);
    7108      212604 :     int entry = set->FindInsertionEntry(hash);
    7109      106302 :     set->set(EntryToIndex(entry), *key);
    7110      106302 :     set->ElementAdded();
    7111             :   }
    7112      107938 :   return set;
    7113             : }
    7114             : 
    7115             : namespace {
    7116             : 
    7117             : const int kLiteralEntryLength = 2;
    7118             : const int kLiteralInitialLength = 2;
    7119             : const int kLiteralContextOffset = 0;
    7120             : const int kLiteralLiteralsOffset = 1;
    7121             : 
    7122     2979090 : int SearchLiteralsMapEntry(CompilationCacheTable cache, int cache_entry,
    7123             :                            Context native_context) {
    7124             :   DisallowHeapAllocation no_gc;
    7125             :   DCHECK(native_context->IsNativeContext());
    7126             :   Object obj = cache->get(cache_entry);
    7127             : 
    7128             :   // Check that there's no confusion between FixedArray and WeakFixedArray (the
    7129             :   // object used to be a FixedArray here).
    7130             :   DCHECK(!obj->IsFixedArray());
    7131     2979090 :   if (obj->IsWeakFixedArray()) {
    7132             :     WeakFixedArray literals_map = WeakFixedArray::cast(obj);
    7133             :     int length = literals_map->length();
    7134     7069223 :     for (int i = 0; i < length; i += kLiteralEntryLength) {
    7135             :       DCHECK(literals_map->Get(i + kLiteralContextOffset)->IsWeakOrCleared());
    7136     6335309 :       if (literals_map->Get(i + kLiteralContextOffset) ==
    7137             :           HeapObjectReference::Weak(native_context)) {
    7138             :         return i;
    7139             :       }
    7140             :     }
    7141             :   }
    7142             :   return -1;
    7143             : }
    7144             : 
    7145      560487 : void AddToFeedbackCellsMap(Handle<CompilationCacheTable> cache, int cache_entry,
    7146             :                            Handle<Context> native_context,
    7147             :                            Handle<FeedbackCell> feedback_cell) {
    7148             :   Isolate* isolate = native_context->GetIsolate();
    7149             :   DCHECK(native_context->IsNativeContext());
    7150             :   STATIC_ASSERT(kLiteralEntryLength == 2);
    7151             :   Handle<WeakFixedArray> new_literals_map;
    7152             :   int entry;
    7153             : 
    7154             :   Object obj = cache->get(cache_entry);
    7155             : 
    7156             :   // Check that there's no confusion between FixedArray and WeakFixedArray (the
    7157             :   // object used to be a FixedArray here).
    7158             :   DCHECK(!obj->IsFixedArray());
    7159      937946 :   if (!obj->IsWeakFixedArray() || WeakFixedArray::cast(obj)->length() == 0) {
    7160             :     new_literals_map = isolate->factory()->NewWeakFixedArray(
    7161      183028 :         kLiteralInitialLength, AllocationType::kOld);
    7162             :     entry = 0;
    7163             :   } else {
    7164             :     Handle<WeakFixedArray> old_literals_map(WeakFixedArray::cast(obj), isolate);
    7165      377459 :     entry = SearchLiteralsMapEntry(*cache, cache_entry, *native_context);
    7166      377459 :     if (entry >= 0) {
    7167             :       // Just set the code of the entry.
    7168       20442 :       old_literals_map->Set(entry + kLiteralLiteralsOffset,
    7169       20442 :                             HeapObjectReference::Weak(*feedback_cell));
    7170             :       return;
    7171             :     }
    7172             : 
    7173             :     // Can we reuse an entry?
    7174             :     DCHECK_LT(entry, 0);
    7175             :     int length = old_literals_map->length();
    7176     1124135 :     for (int i = 0; i < length; i += kLiteralEntryLength) {
    7177      757830 :       if (old_literals_map->Get(i + kLiteralContextOffset)->IsCleared()) {
    7178             :         new_literals_map = old_literals_map;
    7179             :         entry = i;
    7180             :         break;
    7181             :       }
    7182             :     }
    7183             : 
    7184      370645 :     if (entry < 0) {
    7185             :       // Copy old optimized code map and append one new entry.
    7186             :       new_literals_map = isolate->factory()->CopyWeakFixedArrayAndGrow(
    7187      366305 :           old_literals_map, kLiteralEntryLength, AllocationType::kOld);
    7188             :       entry = old_literals_map->length();
    7189             :     }
    7190             :   }
    7191             : 
    7192     1107346 :   new_literals_map->Set(entry + kLiteralContextOffset,
    7193     1661019 :                         HeapObjectReference::Weak(*native_context));
    7194     1661019 :   new_literals_map->Set(entry + kLiteralLiteralsOffset,
    7195     1661019 :                         HeapObjectReference::Weak(*feedback_cell));
    7196             : 
    7197             : #ifdef DEBUG
    7198             :   for (int i = 0; i < new_literals_map->length(); i += kLiteralEntryLength) {
    7199             :     MaybeObject object = new_literals_map->Get(i + kLiteralContextOffset);
    7200             :     DCHECK(object->IsCleared() ||
    7201             :            object->GetHeapObjectAssumeWeak()->IsNativeContext());
    7202             :     object = new_literals_map->Get(i + kLiteralLiteralsOffset);
    7203             :     DCHECK(object->IsCleared() ||
    7204             :            object->GetHeapObjectAssumeWeak()->IsFeedbackCell());
    7205             :   }
    7206             : #endif
    7207             : 
    7208             :   Object old_literals_map = cache->get(cache_entry);
    7209      553673 :   if (old_literals_map != *new_literals_map) {
    7210     1098666 :     cache->set(cache_entry, *new_literals_map);
    7211             :   }
    7212             : }
    7213             : 
    7214     2601631 : FeedbackCell SearchLiteralsMap(CompilationCacheTable cache, int cache_entry,
    7215             :                                Context native_context) {
    7216             :   FeedbackCell result;
    7217     2601631 :   int entry = SearchLiteralsMapEntry(cache, cache_entry, native_context);
    7218     2601631 :   if (entry >= 0) {
    7219             :     WeakFixedArray literals_map = WeakFixedArray::cast(cache->get(cache_entry));
    7220             :     DCHECK_LE(entry + kLiteralEntryLength, literals_map->length());
    7221             :     MaybeObject object = literals_map->Get(entry + kLiteralLiteralsOffset);
    7222             : 
    7223     2238362 :     if (!object->IsCleared()) {
    7224             :       result = FeedbackCell::cast(object->GetHeapObjectAssumeWeak());
    7225             :     }
    7226             :   }
    7227             :   DCHECK(result.is_null() || result->IsFeedbackCell());
    7228     2601631 :   return result;
    7229             : }
    7230             : 
    7231             : }  // namespace
    7232             : 
    7233      270273 : MaybeHandle<SharedFunctionInfo> CompilationCacheTable::LookupScript(
    7234             :     Handle<CompilationCacheTable> table, Handle<String> src,
    7235             :     Handle<Context> native_context, LanguageMode language_mode) {
    7236             :   // We use the empty function SFI as part of the key. Although the
    7237             :   // empty_function is native context dependent, the SFI is de-duped on
    7238             :   // snapshot builds by the PartialSnapshotCache, and so this does not prevent
    7239             :   // reuse of scripts in the compilation cache across native contexts.
    7240      540546 :   Handle<SharedFunctionInfo> shared(native_context->empty_function()->shared(),
    7241             :                                     native_context->GetIsolate());
    7242             :   Isolate* isolate = native_context->GetIsolate();
    7243      270273 :   src = String::Flatten(isolate, src);
    7244      270273 :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
    7245      270273 :   int entry = table->FindEntry(isolate, &key);
    7246      270273 :   if (entry == kNotFound) return MaybeHandle<SharedFunctionInfo>();
    7247             :   int index = EntryToIndex(entry);
    7248      130503 :   if (!table->get(index)->IsFixedArray()) {
    7249           0 :     return MaybeHandle<SharedFunctionInfo>();
    7250             :   }
    7251      130503 :   Object obj = table->get(index + 1);
    7252      130503 :   if (obj->IsSharedFunctionInfo()) {
    7253      130503 :     return handle(SharedFunctionInfo::cast(obj), native_context->GetIsolate());
    7254             :   }
    7255           0 :   return MaybeHandle<SharedFunctionInfo>();
    7256             : }
    7257             : 
    7258     3524035 : InfoCellPair CompilationCacheTable::LookupEval(
    7259             :     Handle<CompilationCacheTable> table, Handle<String> src,
    7260             :     Handle<SharedFunctionInfo> outer_info, Handle<Context> native_context,
    7261             :     LanguageMode language_mode, int position) {
    7262             :   InfoCellPair empty_result;
    7263             :   Isolate* isolate = native_context->GetIsolate();
    7264     3524035 :   src = String::Flatten(isolate, src);
    7265     3524035 :   StringSharedKey key(src, outer_info, language_mode, position);
    7266     3524035 :   int entry = table->FindEntry(isolate, &key);
    7267     3524035 :   if (entry == kNotFound) return empty_result;
    7268             :   int index = EntryToIndex(entry);
    7269     2782392 :   if (!table->get(index)->IsFixedArray()) return empty_result;
    7270     2601631 :   Object obj = table->get(EntryToIndex(entry) + 1);
    7271     2601631 :   if (obj->IsSharedFunctionInfo()) {
    7272             :     FeedbackCell feedback_cell =
    7273     5203262 :         SearchLiteralsMap(*table, EntryToIndex(entry) + 2, *native_context);
    7274             :     return InfoCellPair(SharedFunctionInfo::cast(obj), feedback_cell);
    7275             :   }
    7276           0 :   return empty_result;
    7277             : }
    7278             : 
    7279      723374 : Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src,
    7280             :                                                    JSRegExp::Flags flags) {
    7281             :   Isolate* isolate = GetIsolate();
    7282             :   DisallowHeapAllocation no_allocation;
    7283             :   RegExpKey key(src, flags);
    7284      723374 :   int entry = FindEntry(isolate, &key);
    7285     1250949 :   if (entry == kNotFound) return isolate->factory()->undefined_value();
    7286      391598 :   return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
    7287             : }
    7288             : 
    7289      138074 : Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
    7290             :     Handle<CompilationCacheTable> cache, Handle<String> src,
    7291             :     Handle<Context> native_context, LanguageMode language_mode,
    7292             :     Handle<SharedFunctionInfo> value) {
    7293             :   Isolate* isolate = native_context->GetIsolate();
    7294             :   // We use the empty function SFI as part of the key. Although the
    7295             :   // empty_function is native context dependent, the SFI is de-duped on
    7296             :   // snapshot builds by the PartialSnapshotCache, and so this does not prevent
    7297             :   // reuse of scripts in the compilation cache across native contexts.
    7298      276148 :   Handle<SharedFunctionInfo> shared(native_context->empty_function()->shared(),
    7299             :                                     isolate);
    7300      138074 :   src = String::Flatten(isolate, src);
    7301      138074 :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
    7302      138074 :   Handle<Object> k = key.AsHandle(isolate);
    7303      138074 :   cache = EnsureCapacity(isolate, cache, 1);
    7304      138074 :   int entry = cache->FindInsertionEntry(key.Hash());
    7305      138074 :   cache->set(EntryToIndex(entry), *k);
    7306      276148 :   cache->set(EntryToIndex(entry) + 1, *value);
    7307      138074 :   cache->ElementAdded();
    7308      276148 :   return cache;
    7309             : }
    7310             : 
    7311     1184812 : Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
    7312             :     Handle<CompilationCacheTable> cache, Handle<String> src,
    7313             :     Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
    7314             :     Handle<Context> native_context, Handle<FeedbackCell> feedback_cell,
    7315             :     int position) {
    7316             :   Isolate* isolate = native_context->GetIsolate();
    7317     1184812 :   src = String::Flatten(isolate, src);
    7318     1184812 :   StringSharedKey key(src, outer_info, value->language_mode(), position);
    7319             :   {
    7320     1184812 :     Handle<Object> k = key.AsHandle(isolate);
    7321     1184812 :     int entry = cache->FindEntry(isolate, &key);
    7322     1184812 :     if (entry != kNotFound) {
    7323      560487 :       cache->set(EntryToIndex(entry), *k);
    7324     1120974 :       cache->set(EntryToIndex(entry) + 1, *value);
    7325             :       // AddToFeedbackCellsMap may allocate a new sub-array to live in the
    7326             :       // entry, but it won't change the cache array. Therefore EntryToIndex
    7327             :       // and entry remains correct.
    7328      560487 :       AddToFeedbackCellsMap(cache, EntryToIndex(entry) + 2, native_context,
    7329      560487 :                             feedback_cell);
    7330      560487 :       return cache;
    7331             :     }
    7332             :   }
    7333             : 
    7334      624325 :   cache = EnsureCapacity(isolate, cache, 1);
    7335      624325 :   int entry = cache->FindInsertionEntry(key.Hash());
    7336             :   Handle<Object> k =
    7337      624325 :       isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
    7338      624325 :   cache->set(EntryToIndex(entry), *k);
    7339             :   cache->set(EntryToIndex(entry) + 1, Smi::FromInt(kHashGenerations));
    7340      624325 :   cache->ElementAdded();
    7341      624325 :   return cache;
    7342             : }
    7343             : 
    7344      261725 : Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
    7345             :     Isolate* isolate, Handle<CompilationCacheTable> cache, Handle<String> src,
    7346             :     JSRegExp::Flags flags, Handle<FixedArray> value) {
    7347             :   RegExpKey key(src, flags);
    7348      261725 :   cache = EnsureCapacity(isolate, cache, 1);
    7349      261725 :   int entry = cache->FindInsertionEntry(key.Hash());
    7350             :   // We store the value in the key slot, and compare the search key
    7351             :   // to the stored value with a custon IsMatch function during lookups.
    7352      523450 :   cache->set(EntryToIndex(entry), *value);
    7353      523450 :   cache->set(EntryToIndex(entry) + 1, *value);
    7354      261725 :   cache->ElementAdded();
    7355      261725 :   return cache;
    7356             : }
    7357             : 
    7358             : 
    7359       63827 : void CompilationCacheTable::Age() {
    7360             :   DisallowHeapAllocation no_allocation;
    7361             :   Object the_hole_value = GetReadOnlyRoots().the_hole_value();
    7362    10640179 :   for (int entry = 0, size = Capacity(); entry < size; entry++) {
    7363             :     int entry_index = EntryToIndex(entry);
    7364    10576352 :     int value_index = entry_index + 1;
    7365             : 
    7366    10576352 :     if (get(entry_index)->IsNumber()) {
    7367             :       Smi count = Smi::cast(get(value_index));
    7368      905498 :       count = Smi::FromInt(count->value() - 1);
    7369      905498 :       if (count->value() == 0) {
    7370             :         NoWriteBarrierSet(*this, entry_index, the_hole_value);
    7371             :         NoWriteBarrierSet(*this, value_index, the_hole_value);
    7372       66982 :         ElementRemoved();
    7373             :       } else {
    7374             :         NoWriteBarrierSet(*this, value_index, count);
    7375             :       }
    7376     9670854 :     } else if (get(entry_index)->IsFixedArray()) {
    7377      433659 :       SharedFunctionInfo info = SharedFunctionInfo::cast(get(value_index));
    7378      433659 :       if (info->IsInterpreted() && info->GetBytecodeArray()->IsOld()) {
    7379      144627 :         for (int i = 0; i < kEntrySize; i++) {
    7380       61983 :           NoWriteBarrierSet(*this, entry_index + i, the_hole_value);
    7381             :         }
    7382       20661 :         ElementRemoved();
    7383             :       }
    7384             :     }
    7385             :   }
    7386       63827 : }
    7387             : 
    7388         804 : void CompilationCacheTable::Remove(Object value) {
    7389             :   DisallowHeapAllocation no_allocation;
    7390             :   Object the_hole_value = GetReadOnlyRoots().the_hole_value();
    7391      103716 :   for (int entry = 0, size = Capacity(); entry < size; entry++) {
    7392             :     int entry_index = EntryToIndex(entry);
    7393      102912 :     int value_index = entry_index + 1;
    7394      102912 :     if (get(value_index) == value) {
    7395         994 :       for (int i = 0; i < kEntrySize; i++) {
    7396         426 :         NoWriteBarrierSet(*this, entry_index + i, the_hole_value);
    7397             :       }
    7398         142 :       ElementRemoved();
    7399             :     }
    7400             :   }
    7401         804 :   return;
    7402             : }
    7403             : 
    7404             : template <typename Derived, typename Shape>
    7405      776584 : Handle<Derived> BaseNameDictionary<Derived, Shape>::New(
    7406             :     Isolate* isolate, int at_least_space_for, AllocationType allocation,
    7407             :     MinimumCapacity capacity_option) {
    7408             :   DCHECK_LE(0, at_least_space_for);
    7409             :   Handle<Derived> dict = Dictionary<Derived, Shape>::New(
    7410      776584 :       isolate, at_least_space_for, allocation, capacity_option);
    7411             :   dict->SetHash(PropertyArray::kNoHashSentinel);
    7412             :   dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
    7413      776584 :   return dict;
    7414             : }
    7415             : 
    7416             : template <typename Derived, typename Shape>
    7417    12698685 : Handle<Derived> BaseNameDictionary<Derived, Shape>::EnsureCapacity(
    7418             :     Isolate* isolate, Handle<Derived> dictionary, int n) {
    7419             :   // Check whether there are enough enumeration indices to add n elements.
    7420    25397370 :   if (!PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) {
    7421             :     // If not, we generate new indices for the properties.
    7422             :     int length = dictionary->NumberOfElements();
    7423             : 
    7424           0 :     Handle<FixedArray> iteration_order = IterationIndices(isolate, dictionary);
    7425             :     DCHECK_EQ(length, iteration_order->length());
    7426             : 
    7427             :     // Iterate over the dictionary using the enumeration order and update
    7428             :     // the dictionary with new enumeration indices.
    7429           0 :     for (int i = 0; i < length; i++) {
    7430             :       int index = Smi::ToInt(iteration_order->get(i));
    7431             :       DCHECK(dictionary->IsKey(dictionary->GetReadOnlyRoots(),
    7432             :                                dictionary->KeyAt(index)));
    7433             : 
    7434           0 :       int enum_index = PropertyDetails::kInitialIndex + i;
    7435             : 
    7436           0 :       PropertyDetails details = dictionary->DetailsAt(index);
    7437           0 :       PropertyDetails new_details = details.set_index(enum_index);
    7438           0 :       dictionary->DetailsAtPut(isolate, index, new_details);
    7439             :     }
    7440             : 
    7441             :     // Set the next enumeration index.
    7442           0 :     dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex +
    7443             :                                         length);
    7444             :   }
    7445    12698685 :   return HashTable<Derived, Shape>::EnsureCapacity(isolate, dictionary, n);
    7446             : }
    7447             : 
    7448             : template <typename Derived, typename Shape>
    7449       47194 : Handle<Derived> Dictionary<Derived, Shape>::DeleteEntry(
    7450             :     Isolate* isolate, Handle<Derived> dictionary, int entry) {
    7451             :   DCHECK(Shape::kEntrySize != 3 ||
    7452             :          dictionary->DetailsAt(entry).IsConfigurable());
    7453       47194 :   dictionary->ClearEntry(isolate, entry);
    7454       47194 :   dictionary->ElementRemoved();
    7455       47194 :   return Shrink(isolate, dictionary);
    7456             : }
    7457             : 
    7458             : template <typename Derived, typename Shape>
    7459      480100 : Handle<Derived> Dictionary<Derived, Shape>::AtPut(Isolate* isolate,
    7460             :                                                   Handle<Derived> dictionary,
    7461             :                                                   Key key, Handle<Object> value,
    7462             :                                                   PropertyDetails details) {
    7463      480100 :   int entry = dictionary->FindEntry(isolate, key);
    7464             : 
    7465             :   // If the entry is present set the value;
    7466      480100 :   if (entry == Dictionary::kNotFound) {
    7467      477707 :     return Derived::Add(isolate, dictionary, key, value, details);
    7468             :   }
    7469             : 
    7470             :   // We don't need to copy over the enumeration index.
    7471        4786 :   dictionary->ValueAtPut(entry, *value);
    7472           0 :   if (Shape::kEntrySize == 3) dictionary->DetailsAtPut(isolate, entry, details);
    7473        2393 :   return dictionary;
    7474             : }
    7475             : 
    7476             : template <typename Derived, typename Shape>
    7477             : Handle<Derived>
    7478     4478625 : BaseNameDictionary<Derived, Shape>::AddNoUpdateNextEnumerationIndex(
    7479             :     Isolate* isolate, Handle<Derived> dictionary, Key key, Handle<Object> value,
    7480             :     PropertyDetails details, int* entry_out) {
    7481             :   // Insert element at empty or deleted entry
    7482             :   return Dictionary<Derived, Shape>::Add(isolate, dictionary, key, value,
    7483    12698676 :                                          details, entry_out);
    7484             : }
    7485             : 
    7486             : // GCC workaround: Explicitly instantiate template method for NameDictionary
    7487             : // to avoid "undefined reference" issues during linking.
    7488             : template Handle<NameDictionary>
    7489             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::
    7490             :     AddNoUpdateNextEnumerationIndex(Isolate* isolate, Handle<NameDictionary>,
    7491             :                                     Handle<Name>, Handle<Object>,
    7492             :                                     PropertyDetails, int*);
    7493             : 
    7494             : template <typename Derived, typename Shape>
    7495    12662949 : Handle<Derived> BaseNameDictionary<Derived, Shape>::Add(
    7496             :     Isolate* isolate, Handle<Derived> dictionary, Key key, Handle<Object> value,
    7497             :     PropertyDetails details, int* entry_out) {
    7498             :   // Insert element at empty or deleted entry
    7499             :   DCHECK_EQ(0, details.dictionary_index());
    7500             :   // Assign an enumeration index to the property and update
    7501             :   // SetNextEnumerationIndex.
    7502             :   int index = dictionary->NextEnumerationIndex();
    7503             :   details = details.set_index(index);
    7504     4442898 :   dictionary = AddNoUpdateNextEnumerationIndex(isolate, dictionary, key, value,
    7505             :                                                details, entry_out);
    7506             :   // Update enumeration index here in order to avoid potential modification of
    7507             :   // the canonical empty dictionary which lives in read only space.
    7508    12662958 :   dictionary->SetNextEnumerationIndex(index + 1);
    7509    12662958 :   return dictionary;
    7510             : }
    7511             : 
    7512             : template <typename Derived, typename Shape>
    7513    16540102 : Handle<Derived> Dictionary<Derived, Shape>::Add(Isolate* isolate,
    7514             :                                                 Handle<Derived> dictionary,
    7515             :                                                 Key key, Handle<Object> value,
    7516             :                                                 PropertyDetails details,
    7517             :                                                 int* entry_out) {
    7518             :   uint32_t hash = Shape::Hash(isolate, key);
    7519             :   // Valdate key is absent.
    7520             :   SLOW_DCHECK((dictionary->FindEntry(isolate, key) == Dictionary::kNotFound));
    7521             :   // Check whether the dictionary should be extended.
    7522    16540103 :   dictionary = Derived::EnsureCapacity(isolate, dictionary, 1);
    7523             : 
    7524             :   // Compute the key object.
    7525             :   Handle<Object> k = Shape::AsHandle(isolate, key);
    7526             : 
    7527    16540107 :   uint32_t entry = dictionary->FindInsertionEntry(hash);
    7528    41300284 :   dictionary->SetEntry(isolate, entry, *k, *value, details);
    7529             :   DCHECK(dictionary->KeyAt(entry)->IsNumber() ||
    7530             :          Shape::Unwrap(dictionary->KeyAt(entry))->IsUniqueName());
    7531    16540109 :   dictionary->ElementAdded();
    7532    16540103 :   if (entry_out) *entry_out = entry;
    7533    16540103 :   return dictionary;
    7534             : }
    7535             : 
    7536             : // static
    7537       74166 : Handle<SimpleNumberDictionary> SimpleNumberDictionary::Set(
    7538             :     Isolate* isolate, Handle<SimpleNumberDictionary> dictionary, uint32_t key,
    7539             :     Handle<Object> value) {
    7540       74166 :   return AtPut(isolate, dictionary, key, value, PropertyDetails::Empty());
    7541             : }
    7542             : 
    7543           0 : bool NumberDictionary::HasComplexElements() {
    7544           0 :   if (!requires_slow_elements()) return false;
    7545           0 :   ReadOnlyRoots roots = GetReadOnlyRoots();
    7546             :   int capacity = this->Capacity();
    7547           0 :   for (int i = 0; i < capacity; i++) {
    7548           0 :     Object k;
    7549           0 :     if (!this->ToKey(roots, i, &k)) continue;
    7550             :     PropertyDetails details = this->DetailsAt(i);
    7551           0 :     if (details.kind() == kAccessor) return true;
    7552             :     PropertyAttributes attr = details.attributes();
    7553           0 :     if (attr & ALL_ATTRIBUTES_MASK) return true;
    7554             :   }
    7555             :   return false;
    7556             : }
    7557             : 
    7558     1480899 : void NumberDictionary::UpdateMaxNumberKey(uint32_t key,
    7559             :                                           Handle<JSObject> dictionary_holder) {
    7560             :   DisallowHeapAllocation no_allocation;
    7561             :   // If the dictionary requires slow elements an element has already
    7562             :   // been added at a high index.
    7563     1480899 :   if (requires_slow_elements()) return;
    7564             :   // Check if this index is high enough that we should require slow
    7565             :   // elements.
    7566     1435077 :   if (key > kRequiresSlowElementsLimit) {
    7567        1705 :     if (!dictionary_holder.is_null()) {
    7568        1453 :       dictionary_holder->RequireSlowElements(*this);
    7569             :     }
    7570             :     set_requires_slow_elements();
    7571             :     return;
    7572             :   }
    7573             :   // Update max key value.
    7574             :   Object max_index_object = get(kMaxNumberKeyIndex);
    7575     1433372 :   if (!max_index_object->IsSmi() || max_number_key() < key) {
    7576     1146229 :     FixedArray::set(kMaxNumberKeyIndex,
    7577     1146229 :                     Smi::FromInt(key << kRequiresSlowElementsTagSize));
    7578             :   }
    7579             : }
    7580             : 
    7581      405934 : Handle<NumberDictionary> NumberDictionary::Set(
    7582             :     Isolate* isolate, Handle<NumberDictionary> dictionary, uint32_t key,
    7583             :     Handle<Object> value, Handle<JSObject> dictionary_holder,
    7584             :     PropertyDetails details) {
    7585      405934 :   dictionary->UpdateMaxNumberKey(key, dictionary_holder);
    7586      405934 :   return AtPut(isolate, dictionary, key, value, details);
    7587             : }
    7588             : 
    7589          36 : void NumberDictionary::CopyValuesTo(FixedArray elements) {
    7590          36 :   ReadOnlyRoots roots = GetReadOnlyRoots();
    7591             :   int pos = 0;
    7592             :   int capacity = this->Capacity();
    7593             :   DisallowHeapAllocation no_gc;
    7594             :   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
    7595        1188 :   for (int i = 0; i < capacity; i++) {
    7596         576 :     Object k;
    7597         576 :     if (this->ToKey(roots, i, &k)) {
    7598         270 :       elements->set(pos++, this->ValueAt(i), mode);
    7599             :     }
    7600             :   }
    7601             :   DCHECK_EQ(pos, elements->length());
    7602          36 : }
    7603             : 
    7604             : template <typename Derived, typename Shape>
    7605       43133 : int Dictionary<Derived, Shape>::NumberOfEnumerableProperties() {
    7606       43133 :   ReadOnlyRoots roots = this->GetReadOnlyRoots();
    7607             :   int capacity = this->Capacity();
    7608             :   int result = 0;
    7609    29133749 :   for (int i = 0; i < capacity; i++) {
    7610    14545308 :     Object k;
    7611    22122628 :     if (!this->ToKey(roots, i, &k)) continue;
    7612     7004490 :     if (k->FilterKey(ENUMERABLE_STRINGS)) continue;
    7613     6967412 :     PropertyDetails details = this->DetailsAt(i);
    7614             :     PropertyAttributes attr = details.attributes();
    7615     6967988 :     if ((attr & ONLY_ENUMERABLE) == 0) result++;
    7616             :   }
    7617       43133 :   return result;
    7618             : }
    7619             : 
    7620             : 
    7621             : template <typename Dictionary>
    7622             : struct EnumIndexComparator {
    7623             :   explicit EnumIndexComparator(Dictionary dict) : dict(dict) {}
    7624   122752139 :   bool operator()(Tagged_t a, Tagged_t b) {
    7625   122752139 :     PropertyDetails da(dict->DetailsAt(Smi(static_cast<Address>(a)).value()));
    7626   122752153 :     PropertyDetails db(dict->DetailsAt(Smi(static_cast<Address>(b)).value()));
    7627   122752157 :     return da.dictionary_index() < db.dictionary_index();
    7628             :   }
    7629             :   Dictionary dict;
    7630             : };
    7631             : 
    7632             : template <typename Derived, typename Shape>
    7633       42917 : void BaseNameDictionary<Derived, Shape>::CopyEnumKeysTo(
    7634             :     Isolate* isolate, Handle<Derived> dictionary, Handle<FixedArray> storage,
    7635             :     KeyCollectionMode mode, KeyAccumulator* accumulator) {
    7636             :   DCHECK_IMPLIES(mode != KeyCollectionMode::kOwnOnly, accumulator != nullptr);
    7637             :   int length = storage->length();
    7638             :   int capacity = dictionary->Capacity();
    7639             :   int properties = 0;
    7640             :   ReadOnlyRoots roots(isolate);
    7641    29035791 :   for (int i = 0; i < capacity; i++) {
    7642    14538885 :     Object key;
    7643    24248326 :     if (!dictionary->ToKey(roots, i, &key)) continue;
    7644             :     bool is_shadowing_key = false;
    7645     7003150 :     if (key->IsSymbol()) continue;
    7646     6966693 :     PropertyDetails details = dictionary->DetailsAt(i);
    7647     6966693 :     if (details.IsDontEnum()) {
    7648     2137249 :       if (mode == KeyCollectionMode::kIncludePrototypes) {
    7649             :         is_shadowing_key = true;
    7650             :       } else {
    7651             :         continue;
    7652             :       }
    7653             :     }
    7654     4832710 :     if (is_shadowing_key) {
    7655        3266 :       accumulator->AddShadowingKey(key);
    7656        3266 :       continue;
    7657             :     } else {
    7658             :       storage->set(properties, Smi::FromInt(i));
    7659             :     }
    7660     4829444 :     properties++;
    7661     4829444 :     if (mode == KeyCollectionMode::kOwnOnly && properties == length) break;
    7662             :   }
    7663             : 
    7664       42917 :   CHECK_EQ(length, properties);
    7665             :   DisallowHeapAllocation no_gc;
    7666       42917 :   Derived raw_dictionary = *dictionary;
    7667       42917 :   FixedArray raw_storage = *storage;
    7668             :   EnumIndexComparator<Derived> cmp(raw_dictionary);
    7669             :   // Use AtomicSlot wrapper to ensure that std::sort uses atomic load and
    7670             :   // store operations that are safe for concurrent marking.
    7671             :   AtomicSlot start(storage->GetFirstElementAddress());
    7672             :   std::sort(start, start + length, cmp);
    7673     9701805 :   for (int i = 0; i < length; i++) {
    7674             :     int index = Smi::ToInt(raw_storage->get(i));
    7675     4829444 :     raw_storage->set(i, raw_dictionary->NameAt(index));
    7676             :   }
    7677       42917 : }
    7678             : 
    7679             : template <typename Derived, typename Shape>
    7680      427053 : Handle<FixedArray> BaseNameDictionary<Derived, Shape>::IterationIndices(
    7681             :     Isolate* isolate, Handle<Derived> dictionary) {
    7682             :   int capacity = dictionary->Capacity();
    7683             :   int length = dictionary->NumberOfElements();
    7684      427053 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
    7685             :   ReadOnlyRoots roots(isolate);
    7686             :   int array_size = 0;
    7687             :   {
    7688             :     DisallowHeapAllocation no_gc;
    7689      427054 :     Derived raw_dictionary = *dictionary;
    7690    31816806 :     for (int i = 0; i < capacity; i++) {
    7691    15694877 :       Object k;
    7692    24717621 :       if (!raw_dictionary->ToKey(roots, i, &k)) continue;
    7693     6672132 :       array->set(array_size++, Smi::FromInt(i));
    7694             :     }
    7695             : 
    7696             :     DCHECK_EQ(array_size, length);
    7697             : 
    7698             :     EnumIndexComparator<Derived> cmp(raw_dictionary);
    7699             :     // Use AtomicSlot wrapper to ensure that std::sort uses atomic load and
    7700             :     // store operations that are safe for concurrent marking.
    7701             :     AtomicSlot start(array->GetFirstElementAddress());
    7702             :     std::sort(start, start + array_size, cmp);
    7703             :   }
    7704      427053 :   return FixedArray::ShrinkOrEmpty(isolate, array, array_size);
    7705             : }
    7706             : 
    7707             : template <typename Derived, typename Shape>
    7708       41398 : void BaseNameDictionary<Derived, Shape>::CollectKeysTo(
    7709             :     Handle<Derived> dictionary, KeyAccumulator* keys) {
    7710             :   Isolate* isolate = keys->isolate();
    7711             :   ReadOnlyRoots roots(isolate);
    7712             :   int capacity = dictionary->Capacity();
    7713             :   Handle<FixedArray> array =
    7714       41398 :       isolate->factory()->NewFixedArray(dictionary->NumberOfElements());
    7715             :   int array_size = 0;
    7716             :   PropertyFilter filter = keys->filter();
    7717             :   {
    7718             :     DisallowHeapAllocation no_gc;
    7719       41398 :     Derived raw_dictionary = *dictionary;
    7720    22390220 :     for (int i = 0; i < capacity; i++) {
    7721    11174411 :       Object k;
    7722    19436892 :       if (!raw_dictionary->ToKey(roots, i, &k)) continue;
    7723     5226179 :       if (k->FilterKey(filter)) continue;
    7724     2912887 :       PropertyDetails details = raw_dictionary->DetailsAt(i);
    7725     2912887 :       if ((details.attributes() & filter) != 0) {
    7726         588 :         keys->AddShadowingKey(k);
    7727         588 :         continue;
    7728             :       }
    7729     2912299 :       if (filter & ONLY_ALL_CAN_READ) {
    7730         754 :         if (details.kind() != kAccessor) continue;
    7731          26 :         Object accessors = raw_dictionary->ValueAt(i);
    7732          26 :         if (!accessors->IsAccessorInfo()) continue;
    7733          26 :         if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
    7734             :       }
    7735     2911930 :       array->set(array_size++, Smi::FromInt(i));
    7736             :     }
    7737             : 
    7738             :     EnumIndexComparator<Derived> cmp(raw_dictionary);
    7739             :     // Use AtomicSlot wrapper to ensure that std::sort uses atomic load and
    7740             :     // store operations that are safe for concurrent marking.
    7741             :     AtomicSlot start(array->GetFirstElementAddress());
    7742             :     std::sort(start, start + array_size, cmp);
    7743             :   }
    7744             : 
    7745             :   bool has_seen_symbol = false;
    7746     5865258 :   for (int i = 0; i < array_size; i++) {
    7747             :     int index = Smi::ToInt(array->get(i));
    7748     2968508 :     Object key = dictionary->NameAt(index);
    7749     2911930 :     if (key->IsSymbol()) {
    7750             :       has_seen_symbol = true;
    7751             :       continue;
    7752             :     }
    7753     2893681 :     keys->AddKey(key, DO_NOT_CONVERT);
    7754             :   }
    7755       41398 :   if (has_seen_symbol) {
    7756     4626471 :     for (int i = 0; i < array_size; i++) {
    7757             :       int index = Smi::ToInt(array->get(i));
    7758     2304725 :       Object key = dictionary->NameAt(index);
    7759     2304161 :       if (!key->IsSymbol()) continue;
    7760       18249 :       keys->AddKey(key, DO_NOT_CONVERT);
    7761             :     }
    7762             :   }
    7763       41398 : }
    7764             : 
    7765             : // Backwards lookup (slow).
    7766             : template <typename Derived, typename Shape>
    7767          57 : Object Dictionary<Derived, Shape>::SlowReverseLookup(Object value) {
    7768          57 :   Derived dictionary = Derived::cast(*this);
    7769             :   ReadOnlyRoots roots = dictionary->GetReadOnlyRoots();
    7770             :   int capacity = dictionary->Capacity();
    7771       29241 :   for (int i = 0; i < capacity; i++) {
    7772       14592 :     Object k;
    7773       21256 :     if (!dictionary->ToKey(roots, i, &k)) continue;
    7774        7928 :     Object e = dictionary->ValueAt(i);
    7775        7928 :     if (e == value) return k;
    7776             :   }
    7777          57 :   return roots.undefined_value();
    7778             : }
    7779             : 
    7780             : template <typename Derived, typename Shape>
    7781         352 : void ObjectHashTableBase<Derived, Shape>::FillEntriesWithHoles(
    7782             :     Handle<Derived> table) {
    7783             :   int length = table->length();
    7784       97936 :   for (int i = Derived::EntryToIndex(0); i < length; i++) {
    7785       48792 :     table->set_the_hole(i);
    7786             :   }
    7787         352 : }
    7788             : 
    7789             : template <typename Derived, typename Shape>
    7790       42495 : Object ObjectHashTableBase<Derived, Shape>::Lookup(ReadOnlyRoots roots,
    7791             :                                                    Handle<Object> key,
    7792             :                                                    int32_t hash) {
    7793             :   DisallowHeapAllocation no_gc;
    7794             :   DCHECK(this->IsKey(roots, *key));
    7795             : 
    7796       42495 :   int entry = this->FindEntry(roots, key, hash);
    7797       44621 :   if (entry == kNotFound) return roots.the_hole_value();
    7798       40369 :   return this->get(Derived::EntryToIndex(entry) + 1);
    7799             : }
    7800             : 
    7801             : template <typename Derived, typename Shape>
    7802       37601 : Object ObjectHashTableBase<Derived, Shape>::Lookup(Handle<Object> key) {
    7803             :   DisallowHeapAllocation no_gc;
    7804             : 
    7805             :   ReadOnlyRoots roots = this->GetReadOnlyRoots();
    7806             :   DCHECK(this->IsKey(roots, *key));
    7807             : 
    7808             :   // If the object does not have an identity hash, it was never used as a key.
    7809       37601 :   Object hash = key->GetHash();
    7810       37601 :   if (hash->IsUndefined(roots)) {
    7811         668 :     return roots.the_hole_value();
    7812             :   }
    7813       36933 :   return Lookup(roots, key, Smi::ToInt(hash));
    7814             : }
    7815             : 
    7816             : template <typename Derived, typename Shape>
    7817        5540 : Object ObjectHashTableBase<Derived, Shape>::Lookup(Handle<Object> key,
    7818             :                                                    int32_t hash) {
    7819        5540 :   return Lookup(this->GetReadOnlyRoots(), key, hash);
    7820             : }
    7821             : 
    7822             : template <typename Derived, typename Shape>
    7823         269 : Object ObjectHashTableBase<Derived, Shape>::ValueAt(int entry) {
    7824         269 :   return this->get(EntryToValueIndex(entry));
    7825             : }
    7826             : 
    7827             : template <typename Derived, typename Shape>
    7828       32794 : Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Handle<Derived> table,
    7829             :                                                          Handle<Object> key,
    7830             :                                                          Handle<Object> value) {
    7831             :   Isolate* isolate = Heap::FromWritableHeapObject(*table)->isolate();
    7832             :   DCHECK(table->IsKey(ReadOnlyRoots(isolate), *key));
    7833             :   DCHECK(!value->IsTheHole(ReadOnlyRoots(isolate)));
    7834             : 
    7835             :   // Make sure the key object has an identity hash code.
    7836       65588 :   int32_t hash = key->GetOrCreateHash(isolate)->value();
    7837             : 
    7838             :   return ObjectHashTableBase<Derived, Shape>::Put(isolate, table, key, value,
    7839       32794 :                                                   hash);
    7840             : }
    7841             : 
    7842             : template <typename Derived, typename Shape>
    7843       36542 : Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Isolate* isolate,
    7844             :                                                          Handle<Derived> table,
    7845             :                                                          Handle<Object> key,
    7846             :                                                          Handle<Object> value,
    7847             :                                                          int32_t hash) {
    7848             :   ReadOnlyRoots roots(isolate);
    7849             :   DCHECK(table->IsKey(roots, *key));
    7850             :   DCHECK(!value->IsTheHole(roots));
    7851             : 
    7852       36542 :   int entry = table->FindEntry(roots, key, hash);
    7853             : 
    7854             :   // Key is already in table, just overwrite value.
    7855       36542 :   if (entry != kNotFound) {
    7856        5270 :     table->set(Derived::EntryToIndex(entry) + 1, *value);
    7857        2635 :     return table;
    7858             :   }
    7859             : 
    7860             :   // Rehash if more than 33% of the entries are deleted entries.
    7861             :   // TODO(jochen): Consider to shrink the fixed array in place.
    7862       67814 :   if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) {
    7863           5 :     table->Rehash(roots);
    7864             :   }
    7865             :   // If we're out of luck, we didn't get a GC recently, and so rehashing
    7866             :   // isn't enough to avoid a crash.
    7867       33907 :   if (!table->HasSufficientCapacityToAdd(1)) {
    7868         492 :     int nof = table->NumberOfElements() + 1;
    7869         492 :     int capacity = ObjectHashTable::ComputeCapacity(nof * 2);
    7870         492 :     if (capacity > ObjectHashTable::kMaxCapacity) {
    7871           0 :       for (size_t i = 0; i < 2; ++i) {
    7872           0 :         isolate->heap()->CollectAllGarbage(
    7873             :             Heap::kNoGCFlags, GarbageCollectionReason::kFullHashtable);
    7874             :       }
    7875           0 :       table->Rehash(roots);
    7876             :     }
    7877             :   }
    7878             : 
    7879             :   // Check whether the hash table should be extended.
    7880       33907 :   table = Derived::EnsureCapacity(isolate, table, 1);
    7881      101721 :   table->AddEntry(table->FindInsertionEntry(hash), *key, *value);
    7882       33907 :   return table;
    7883             : }
    7884             : 
    7885             : template <typename Derived, typename Shape>
    7886         184 : Handle<Derived> ObjectHashTableBase<Derived, Shape>::Remove(
    7887             :     Isolate* isolate, Handle<Derived> table, Handle<Object> key,
    7888             :     bool* was_present) {
    7889             :   DCHECK(table->IsKey(table->GetReadOnlyRoots(), *key));
    7890             : 
    7891         184 :   Object hash = key->GetHash();
    7892         184 :   if (hash->IsUndefined()) {
    7893           0 :     *was_present = false;
    7894           0 :     return table;
    7895             :   }
    7896             : 
    7897         184 :   return Remove(isolate, table, key, was_present, Smi::ToInt(hash));
    7898             : }
    7899             : 
    7900             : template <typename Derived, typename Shape>
    7901         184 : Handle<Derived> ObjectHashTableBase<Derived, Shape>::Remove(
    7902             :     Isolate* isolate, Handle<Derived> table, Handle<Object> key,
    7903             :     bool* was_present, int32_t hash) {
    7904         184 :   ReadOnlyRoots roots = table->GetReadOnlyRoots();
    7905             :   DCHECK(table->IsKey(roots, *key));
    7906             : 
    7907         184 :   int entry = table->FindEntry(roots, key, hash);
    7908         184 :   if (entry == kNotFound) {
    7909          46 :     *was_present = false;
    7910          46 :     return table;
    7911             :   }
    7912             : 
    7913         138 :   *was_present = true;
    7914         138 :   table->RemoveEntry(entry);
    7915         138 :   return Derived::Shrink(isolate, table);
    7916             : }
    7917             : 
    7918             : template <typename Derived, typename Shape>
    7919       33907 : void ObjectHashTableBase<Derived, Shape>::AddEntry(int entry, Object key,
    7920             :                                                    Object value) {
    7921       33907 :   this->set(Derived::EntryToIndex(entry), key);
    7922       33907 :   this->set(Derived::EntryToIndex(entry) + 1, value);
    7923       33907 :   this->ElementAdded();
    7924       33907 : }
    7925             : 
    7926             : template <typename Derived, typename Shape>
    7927         242 : void ObjectHashTableBase<Derived, Shape>::RemoveEntry(int entry) {
    7928         242 :   this->set_the_hole(Derived::EntryToIndex(entry));
    7929         242 :   this->set_the_hole(Derived::EntryToIndex(entry) + 1);
    7930         242 :   this->ElementRemoved();
    7931         242 : }
    7932             : 
    7933             : 
    7934       79706 : void JSSet::Initialize(Handle<JSSet> set, Isolate* isolate) {
    7935       79706 :   Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
    7936      159412 :   set->set_table(*table);
    7937       79706 : }
    7938             : 
    7939          42 : void JSSet::Clear(Isolate* isolate, Handle<JSSet> set) {
    7940             :   Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()), isolate);
    7941          42 :   table = OrderedHashSet::Clear(isolate, table);
    7942          84 :   set->set_table(*table);
    7943          42 : }
    7944             : 
    7945             : 
    7946          13 : void JSMap::Initialize(Handle<JSMap> map, Isolate* isolate) {
    7947          13 :   Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
    7948          26 :   map->set_table(*table);
    7949          13 : }
    7950             : 
    7951         212 : void JSMap::Clear(Isolate* isolate, Handle<JSMap> map) {
    7952             :   Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()), isolate);
    7953         212 :   table = OrderedHashMap::Clear(isolate, table);
    7954         424 :   map->set_table(*table);
    7955         212 : }
    7956             : 
    7957             : 
    7958       50099 : void JSWeakCollection::Initialize(Handle<JSWeakCollection> weak_collection,
    7959             :                                   Isolate* isolate) {
    7960       50099 :   Handle<EphemeronHashTable> table = EphemeronHashTable::New(isolate, 0);
    7961      100198 :   weak_collection->set_table(*table);
    7962       50099 : }
    7963             : 
    7964             : 
    7965         982 : void JSWeakCollection::Set(Handle<JSWeakCollection> weak_collection,
    7966             :                            Handle<Object> key, Handle<Object> value,
    7967             :                            int32_t hash) {
    7968             :   DCHECK(key->IsJSReceiver() || key->IsSymbol());
    7969             :   Handle<EphemeronHashTable> table(
    7970             :       EphemeronHashTable::cast(weak_collection->table()),
    7971             :       weak_collection->GetIsolate());
    7972             :   DCHECK(table->IsKey(weak_collection->GetReadOnlyRoots(), *key));
    7973             :   Handle<EphemeronHashTable> new_table = EphemeronHashTable::Put(
    7974         982 :       weak_collection->GetIsolate(), table, key, value, hash);
    7975        1964 :   weak_collection->set_table(*new_table);
    7976         982 :   if (*table != *new_table) {
    7977             :     // Zap the old table since we didn't record slots for its elements.
    7978         352 :     EphemeronHashTable::FillEntriesWithHoles(table);
    7979             :   }
    7980         982 : }
    7981             : 
    7982             : 
    7983           0 : bool JSWeakCollection::Delete(Handle<JSWeakCollection> weak_collection,
    7984             :                               Handle<Object> key, int32_t hash) {
    7985             :   DCHECK(key->IsJSReceiver() || key->IsSymbol());
    7986             :   Handle<EphemeronHashTable> table(
    7987             :       EphemeronHashTable::cast(weak_collection->table()),
    7988             :       weak_collection->GetIsolate());
    7989             :   DCHECK(table->IsKey(weak_collection->GetReadOnlyRoots(), *key));
    7990           0 :   bool was_present = false;
    7991             :   Handle<EphemeronHashTable> new_table = EphemeronHashTable::Remove(
    7992           0 :       weak_collection->GetIsolate(), table, key, &was_present, hash);
    7993           0 :   weak_collection->set_table(*new_table);
    7994           0 :   if (*table != *new_table) {
    7995             :     // Zap the old table since we didn't record slots for its elements.
    7996           0 :     EphemeronHashTable::FillEntriesWithHoles(table);
    7997             :   }
    7998           0 :   return was_present;
    7999             : }
    8000             : 
    8001          98 : Handle<JSArray> JSWeakCollection::GetEntries(Handle<JSWeakCollection> holder,
    8002             :                                              int max_entries) {
    8003             :   Isolate* isolate = holder->GetIsolate();
    8004             :   Handle<EphemeronHashTable> table(EphemeronHashTable::cast(holder->table()),
    8005             :                                    isolate);
    8006          98 :   if (max_entries == 0 || max_entries > table->NumberOfElements()) {
    8007             :     max_entries = table->NumberOfElements();
    8008             :   }
    8009          98 :   int values_per_entry = holder->IsJSWeakMap() ? 2 : 1;
    8010             :   Handle<FixedArray> entries =
    8011          98 :       isolate->factory()->NewFixedArray(max_entries * values_per_entry);
    8012             :   // Recompute max_values because GC could have removed elements from the table.
    8013          98 :   if (max_entries > table->NumberOfElements()) {
    8014             :     max_entries = table->NumberOfElements();
    8015             :   }
    8016             : 
    8017             :   {
    8018             :     DisallowHeapAllocation no_gc;
    8019             :     ReadOnlyRoots roots = ReadOnlyRoots(isolate);
    8020             :     int count = 0;
    8021         318 :     for (int i = 0;
    8022         318 :          count / values_per_entry < max_entries && i < table->Capacity(); i++) {
    8023         110 :       Object key;
    8024         110 :       if (table->ToKey(roots, i, &key)) {
    8025         100 :         entries->set(count++, key);
    8026          50 :         if (values_per_entry > 1) {
    8027          25 :           Object value = table->Lookup(handle(key, isolate));
    8028          50 :           entries->set(count++, value);
    8029             :         }
    8030             :       }
    8031             :     }
    8032             :     DCHECK_EQ(max_entries * values_per_entry, count);
    8033             :   }
    8034          98 :   return isolate->factory()->NewJSArrayWithElements(entries);
    8035             : }
    8036             : 
    8037             : 
    8038       20008 : Handle<PropertyCell> PropertyCell::InvalidateEntry(
    8039             :     Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry) {
    8040             :   // Swap with a copy.
    8041             :   Handle<PropertyCell> cell(dictionary->CellAt(entry), isolate);
    8042             :   Handle<Name> name(cell->name(), isolate);
    8043       20008 :   Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell(name);
    8044       20008 :   new_cell->set_value(cell->value());
    8045       40016 :   dictionary->ValueAtPut(entry, *new_cell);
    8046             :   bool is_the_hole = cell->value()->IsTheHole(isolate);
    8047             :   // Cell is officially mutable henceforth.
    8048             :   PropertyDetails details = cell->property_details();
    8049             :   details = details.set_cell_type(is_the_hole ? PropertyCellType::kUninitialized
    8050       20008 :                                               : PropertyCellType::kMutable);
    8051       40016 :   new_cell->set_property_details(details);
    8052             :   // Old cell is ready for invalidation.
    8053       20008 :   if (is_the_hole) {
    8054       16594 :     cell->set_value(ReadOnlyRoots(isolate).undefined_value());
    8055             :   } else {
    8056       23422 :     cell->set_value(ReadOnlyRoots(isolate).the_hole_value());
    8057             :   }
    8058             :   details = details.set_cell_type(PropertyCellType::kInvalidated);
    8059       40016 :   cell->set_property_details(details);
    8060       40016 :   cell->dependent_code()->DeoptimizeDependentCodeGroup(
    8061       20008 :       isolate, DependentCode::kPropertyCellChangedGroup);
    8062       20008 :   return new_cell;
    8063             : }
    8064             : 
    8065             : 
    8066           0 : PropertyCellConstantType PropertyCell::GetConstantType() {
    8067           0 :   if (value()->IsSmi()) return PropertyCellConstantType::kSmi;
    8068           0 :   return PropertyCellConstantType::kStableMap;
    8069             : }
    8070             : 
    8071             : 
    8072      913659 : static bool RemainsConstantType(Handle<PropertyCell> cell,
    8073             :                                 Handle<Object> value) {
    8074             :   // TODO(dcarney): double->smi and smi->double transition from kConstant
    8075     1644977 :   if (cell->value()->IsSmi() && value->IsSmi()) {
    8076             :     return true;
    8077      366354 :   } else if (cell->value()->IsHeapObject() && value->IsHeapObject()) {
    8078             :     return HeapObject::cast(cell->value())->map() ==
    8079      354453 :                HeapObject::cast(*value)->map() &&
    8080             :            HeapObject::cast(*value)->map()->is_stable();
    8081             :   }
    8082             :   return false;
    8083             : }
    8084             : 
    8085    12853705 : PropertyCellType PropertyCell::UpdatedType(Isolate* isolate,
    8086             :                                            Handle<PropertyCell> cell,
    8087             :                                            Handle<Object> value,
    8088             :                                            PropertyDetails details) {
    8089             :   PropertyCellType type = details.cell_type();
    8090             :   DCHECK(!value->IsTheHole(isolate));
    8091    12853705 :   if (cell->value()->IsTheHole(isolate)) {
    8092     8229861 :     switch (type) {
    8093             :       // Only allow a cell to transition once into constant state.
    8094             :       case PropertyCellType::kUninitialized:
    8095     8229861 :         if (value->IsUndefined(isolate)) return PropertyCellType::kUndefined;
    8096     6502046 :         return PropertyCellType::kConstant;
    8097             :       case PropertyCellType::kInvalidated:
    8098             :         return PropertyCellType::kMutable;
    8099             :       default:
    8100           0 :         UNREACHABLE();
    8101             :     }
    8102             :   }
    8103     4623844 :   switch (type) {
    8104             :     case PropertyCellType::kUndefined:
    8105             :       return PropertyCellType::kConstant;
    8106             :     case PropertyCellType::kConstant:
    8107     1641907 :       if (*value == cell->value()) return PropertyCellType::kConstant;
    8108             :       V8_FALLTHROUGH;
    8109             :     case PropertyCellType::kConstantType:
    8110      913659 :       if (RemainsConstantType(cell, value)) {
    8111             :         return PropertyCellType::kConstantType;
    8112             :       }
    8113             :       V8_FALLTHROUGH;
    8114             :     case PropertyCellType::kMutable:
    8115             :       return PropertyCellType::kMutable;
    8116             :   }
    8117           0 :   UNREACHABLE();
    8118             : }
    8119             : 
    8120     4631660 : Handle<PropertyCell> PropertyCell::PrepareForValue(
    8121             :     Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry,
    8122             :     Handle<Object> value, PropertyDetails details) {
    8123             :   DCHECK(!value->IsTheHole(isolate));
    8124             :   Handle<PropertyCell> cell(dictionary->CellAt(entry), isolate);
    8125             :   const PropertyDetails original_details = cell->property_details();
    8126             :   // Data accesses could be cached in ics or optimized code.
    8127             :   bool invalidate =
    8128    13886292 :       (original_details.kind() == kData && details.kind() == kAccessor) ||
    8129     4623577 :       (!original_details.IsReadOnly() && details.IsReadOnly());
    8130             :   int index;
    8131             :   PropertyCellType old_type = original_details.cell_type();
    8132             :   // Preserve the enumeration index unless the property was deleted or never
    8133             :   // initialized.
    8134     4631660 :   if (cell->value()->IsTheHole(isolate)) {
    8135             :     index = dictionary->NextEnumerationIndex();
    8136        7816 :     dictionary->SetNextEnumerationIndex(index + 1);
    8137             :   } else {
    8138             :     index = original_details.dictionary_index();
    8139             :   }
    8140             :   DCHECK_LT(0, index);
    8141             :   details = details.set_index(index);
    8142             : 
    8143             :   PropertyCellType new_type =
    8144     4631660 :       UpdatedType(isolate, cell, value, original_details);
    8145     4631660 :   if (invalidate) {
    8146        8143 :     cell = PropertyCell::InvalidateEntry(isolate, dictionary, entry);
    8147             :   }
    8148             : 
    8149             :   // Install new property details.
    8150             :   details = details.set_cell_type(new_type);
    8151     9263320 :   cell->set_property_details(details);
    8152             : 
    8153     4631660 :   if (new_type == PropertyCellType::kConstant ||
    8154             :       new_type == PropertyCellType::kConstantType) {
    8155             :     // Store the value now to ensure that the cell contains the constant or
    8156             :     // type information. Otherwise subsequent store operation will turn
    8157             :     // the cell to mutable.
    8158     4097602 :     cell->set_value(*value);
    8159             :   }
    8160             : 
    8161             :   // Deopt when transitioning from a constant type.
    8162     7616305 :   if (!invalidate && (old_type != new_type ||
    8163             :                       original_details.IsReadOnly() != details.IsReadOnly())) {
    8164     3277762 :     cell->dependent_code()->DeoptimizeDependentCodeGroup(
    8165     1638881 :         isolate, DependentCode::kPropertyCellChangedGroup);
    8166             :   }
    8167     4631660 :   return cell;
    8168             : }
    8169             : 
    8170             : 
    8171             : // static
    8172        4856 : void PropertyCell::SetValueWithInvalidation(Isolate* isolate,
    8173             :                                             Handle<PropertyCell> cell,
    8174             :                                             Handle<Object> new_value) {
    8175        4856 :   if (cell->value() != *new_value) {
    8176        4856 :     cell->set_value(*new_value);
    8177        9712 :     cell->dependent_code()->DeoptimizeDependentCodeGroup(
    8178        4856 :         isolate, DependentCode::kPropertyCellChangedGroup);
    8179             :   }
    8180        4856 : }
    8181             : 
    8182        1430 : int JSGeneratorObject::source_position() const {
    8183        1430 :   CHECK(is_suspended());
    8184             :   DCHECK(function()->shared()->HasBytecodeArray());
    8185             :   DCHECK(function()->shared()->GetBytecodeArray()->HasSourcePositionTable());
    8186             : 
    8187             :   int code_offset = Smi::ToInt(input_or_debug_pos());
    8188             : 
    8189             :   // The stored bytecode offset is relative to a different base than what
    8190             :   // is used in the source position table, hence the subtraction.
    8191        1430 :   code_offset -= BytecodeArray::kHeaderSize - kHeapObjectTag;
    8192             :   AbstractCode code =
    8193        1430 :       AbstractCode::cast(function()->shared()->GetBytecodeArray());
    8194        1430 :   return code->SourcePosition(code_offset);
    8195             : }
    8196             : 
    8197             : // static
    8198        4709 : AccessCheckInfo AccessCheckInfo::Get(Isolate* isolate,
    8199             :                                      Handle<JSObject> receiver) {
    8200             :   DisallowHeapAllocation no_gc;
    8201             :   DCHECK(receiver->map()->is_access_check_needed());
    8202        4709 :   Object maybe_constructor = receiver->map()->GetConstructor();
    8203        4709 :   if (maybe_constructor->IsFunctionTemplateInfo()) {
    8204             :     Object data_obj =
    8205         145 :         FunctionTemplateInfo::cast(maybe_constructor)->GetAccessCheckInfo();
    8206         145 :     if (data_obj->IsUndefined(isolate)) return AccessCheckInfo();
    8207             :     return AccessCheckInfo::cast(data_obj);
    8208             :   }
    8209             :   // Might happen for a detached context.
    8210        4564 :   if (!maybe_constructor->IsJSFunction()) return AccessCheckInfo();
    8211             :   JSFunction constructor = JSFunction::cast(maybe_constructor);
    8212             :   // Might happen for the debug context.
    8213        4539 :   if (!constructor->shared()->IsApiFunction()) return AccessCheckInfo();
    8214             : 
    8215             :   Object data_obj =
    8216        4121 :       constructor->shared()->get_api_func_data()->GetAccessCheckInfo();
    8217        4121 :   if (data_obj->IsUndefined(isolate)) return AccessCheckInfo();
    8218             : 
    8219             :   return AccessCheckInfo::cast(data_obj);
    8220             : }
    8221             : 
    8222             : 
    8223      356861 : MaybeHandle<Name> FunctionTemplateInfo::TryGetCachedPropertyName(
    8224             :     Isolate* isolate, Handle<Object> getter) {
    8225      356861 :   if (getter->IsFunctionTemplateInfo()) {
    8226             :     Handle<FunctionTemplateInfo> fti =
    8227             :         Handle<FunctionTemplateInfo>::cast(getter);
    8228             :     // Check if the accessor uses a cached property.
    8229      102477 :     if (!fti->cached_property_name()->IsTheHole(isolate)) {
    8230          84 :       return handle(Name::cast(fti->cached_property_name()), isolate);
    8231             :     }
    8232             :   }
    8233      356777 :   return MaybeHandle<Name>();
    8234             : }
    8235             : 
    8236     4344114 : Address Smi::LexicographicCompare(Isolate* isolate, Smi x, Smi y) {
    8237             :   DisallowHeapAllocation no_allocation;
    8238     8688228 :   DisallowJavascriptExecution no_js(isolate);
    8239             : 
    8240             :   int x_value = Smi::ToInt(x);
    8241             :   int y_value = Smi::ToInt(y);
    8242             : 
    8243             :   // If the integers are equal so are the string representations.
    8244     4344114 :   if (x_value == y_value) return Smi::FromInt(0).ptr();
    8245             : 
    8246             :   // If one of the integers is zero the normal integer order is the
    8247             :   // same as the lexicographic order of the string representations.
    8248     4340172 :   if (x_value == 0 || y_value == 0) {
    8249        7613 :     return Smi::FromInt(x_value < y_value ? -1 : 1).ptr();
    8250             :   }
    8251             : 
    8252             :   // If only one of the integers is negative the negative number is
    8253             :   // smallest because the char code of '-' is less than the char code
    8254             :   // of any digit.  Otherwise, we make both values positive.
    8255             : 
    8256             :   // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
    8257             :   // architectures using 32-bit Smis.
    8258     4332559 :   uint32_t x_scaled = x_value;
    8259     4332559 :   uint32_t y_scaled = y_value;
    8260     4332559 :   if (x_value < 0) {
    8261     1258586 :     if (y_value >= 0) {
    8262             :       return Smi::FromInt(-1).ptr();
    8263             :     } else {
    8264      628440 :       y_scaled = base::NegateWithWraparound(y_value);
    8265             :     }
    8266      628440 :     x_scaled = base::NegateWithWraparound(x_value);
    8267     3073973 :   } else if (y_value < 0) {
    8268             :     return Smi::FromInt(1).ptr();
    8269             :   }
    8270             : 
    8271             :   // clang-format off
    8272             :   static const uint32_t kPowersOf10[] = {
    8273             :       1,                 10,                100,         1000,
    8274             :       10 * 1000,         100 * 1000,        1000 * 1000, 10 * 1000 * 1000,
    8275             :       100 * 1000 * 1000, 1000 * 1000 * 1000};
    8276             :   // clang-format on
    8277             : 
    8278             :   // If the integers have the same number of decimal digits they can be
    8279             :   // compared directly as the numeric order is the same as the
    8280             :   // lexicographic order.  If one integer has fewer digits, it is scaled
    8281             :   // by some power of 10 to have the same number of digits as the longer
    8282             :   // integer.  If the scaled integers are equal it means the shorter
    8283             :   // integer comes first in the lexicographic order.
    8284             : 
    8285             :   // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
    8286     3072279 :   int x_log2 = 31 - base::bits::CountLeadingZeros(x_scaled);
    8287     3072279 :   int x_log10 = ((x_log2 + 1) * 1233) >> 12;
    8288     3072279 :   x_log10 -= x_scaled < kPowersOf10[x_log10];
    8289             : 
    8290     3072279 :   int y_log2 = 31 - base::bits::CountLeadingZeros(y_scaled);
    8291     3072279 :   int y_log10 = ((y_log2 + 1) * 1233) >> 12;
    8292     3072279 :   y_log10 -= y_scaled < kPowersOf10[y_log10];
    8293             : 
    8294             :   int tie = 0;
    8295             : 
    8296     3072279 :   if (x_log10 < y_log10) {
    8297             :     // X has fewer digits.  We would like to simply scale up X but that
    8298             :     // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
    8299             :     // be scaled up to 9_000_000_000. So we scale up by the next
    8300             :     // smallest power and scale down Y to drop one digit. It is OK to
    8301             :     // drop one digit from the longer integer since the final digit is
    8302             :     // past the length of the shorter integer.
    8303      556860 :     x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
    8304      556860 :     y_scaled /= 10;
    8305             :     tie = -1;
    8306     2515419 :   } else if (y_log10 < x_log10) {
    8307     1419213 :     y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
    8308     1419213 :     x_scaled /= 10;
    8309             :     tie = 1;
    8310             :   }
    8311             : 
    8312     3072279 :   if (x_scaled < y_scaled) return Smi::FromInt(-1).ptr();
    8313     1879161 :   if (x_scaled > y_scaled) return Smi::FromInt(1).ptr();
    8314             :   return Smi::FromInt(tie).ptr();
    8315             : }
    8316             : 
    8317             : // Force instantiation of template instances class.
    8318             : // Please note this list is compiler dependent.
    8319             : // Keep this at the end of this file
    8320             : 
    8321             : template class HashTable<StringTable, StringTableShape>;
    8322             : 
    8323             : template class HashTable<CompilationCacheTable, CompilationCacheShape>;
    8324             : 
    8325             : template class HashTable<ObjectHashTable, ObjectHashTableShape>;
    8326             : 
    8327             : template class HashTable<EphemeronHashTable, EphemeronHashTableShape>;
    8328             : 
    8329             : template class ObjectHashTableBase<ObjectHashTable, ObjectHashTableShape>;
    8330             : 
    8331             : template class ObjectHashTableBase<EphemeronHashTable, EphemeronHashTableShape>;
    8332             : 
    8333             : template class Dictionary<NameDictionary, NameDictionaryShape>;
    8334             : 
    8335             : template class Dictionary<GlobalDictionary, GlobalDictionaryShape>;
    8336             : 
    8337             : template class EXPORT_TEMPLATE_DEFINE(
    8338             :     V8_EXPORT_PRIVATE) HashTable<NumberDictionary, NumberDictionaryShape>;
    8339             : 
    8340             : template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
    8341             :     Dictionary<NumberDictionary, NumberDictionaryShape>;
    8342             : 
    8343             : template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
    8344             :     HashTable<SimpleNumberDictionary, SimpleNumberDictionaryShape>;
    8345             : 
    8346             : template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
    8347             :     Dictionary<SimpleNumberDictionary, SimpleNumberDictionaryShape>;
    8348             : 
    8349             : template Handle<NameDictionary>
    8350             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::New(
    8351             :     Isolate*, int n, AllocationType allocation,
    8352             :     MinimumCapacity capacity_option);
    8353             : 
    8354             : template Handle<GlobalDictionary>
    8355             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::New(
    8356             :     Isolate*, int n, AllocationType allocation,
    8357             :     MinimumCapacity capacity_option);
    8358             : 
    8359             : template Handle<NameDictionary>
    8360             : HashTable<NameDictionary, NameDictionaryShape>::New(Isolate*, int,
    8361             :                                                     AllocationType,
    8362             :                                                     MinimumCapacity);
    8363             : 
    8364             : template Handle<ObjectHashSet>
    8365             : HashTable<ObjectHashSet, ObjectHashSetShape>::New(Isolate*, int n,
    8366             :                                                   AllocationType,
    8367             :                                                   MinimumCapacity);
    8368             : 
    8369             : template Handle<NameDictionary>
    8370             : HashTable<NameDictionary, NameDictionaryShape>::Shrink(Isolate* isolate,
    8371             :                                                        Handle<NameDictionary>,
    8372             :                                                        int additionalCapacity);
    8373             : 
    8374             : template Handle<NameDictionary>
    8375             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::Add(
    8376             :     Isolate* isolate, Handle<NameDictionary>, Handle<Name>, Handle<Object>,
    8377             :     PropertyDetails, int*);
    8378             : 
    8379             : template Handle<GlobalDictionary>
    8380             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::Add(
    8381             :     Isolate* isolate, Handle<GlobalDictionary>, Handle<Name>, Handle<Object>,
    8382             :     PropertyDetails, int*);
    8383             : 
    8384             : template void HashTable<GlobalDictionary, GlobalDictionaryShape>::Rehash(
    8385             :     ReadOnlyRoots roots);
    8386             : 
    8387             : template Handle<NameDictionary>
    8388             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::EnsureCapacity(
    8389             :     Isolate* isolate, Handle<NameDictionary>, int);
    8390             : 
    8391             : template void
    8392             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::CopyEnumKeysTo(
    8393             :     Isolate* isolate, Handle<GlobalDictionary> dictionary,
    8394             :     Handle<FixedArray> storage, KeyCollectionMode mode,
    8395             :     KeyAccumulator* accumulator);
    8396             : 
    8397             : template void
    8398             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::CopyEnumKeysTo(
    8399             :     Isolate* isolate, Handle<NameDictionary> dictionary,
    8400             :     Handle<FixedArray> storage, KeyCollectionMode mode,
    8401             :     KeyAccumulator* accumulator);
    8402             : 
    8403             : template Handle<FixedArray>
    8404             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::IterationIndices(
    8405             :     Isolate* isolate, Handle<GlobalDictionary> dictionary);
    8406             : template void
    8407             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::CollectKeysTo(
    8408             :     Handle<GlobalDictionary> dictionary, KeyAccumulator* keys);
    8409             : 
    8410             : template Handle<FixedArray>
    8411             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::IterationIndices(
    8412             :     Isolate* isolate, Handle<NameDictionary> dictionary);
    8413             : template void
    8414             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::CollectKeysTo(
    8415             :     Handle<NameDictionary> dictionary, KeyAccumulator* keys);
    8416             : 
    8417         252 : void JSFinalizationGroup::Cleanup(
    8418             :     Handle<JSFinalizationGroup> finalization_group, Isolate* isolate) {
    8419             :   // It's possible that the cleared_cells list is empty, since
    8420             :   // FinalizationGroup.unregister() removed all its elements before this task
    8421             :   // ran. In that case, don't call the cleanup function.
    8422         252 :   if (!finalization_group->cleared_cells()->IsUndefined(isolate)) {
    8423             :     // Construct the iterator.
    8424             :     Handle<JSFinalizationGroupCleanupIterator> iterator;
    8425             :     {
    8426             :       Handle<Map> cleanup_iterator_map(
    8427         378 :           isolate->native_context()
    8428         378 :               ->js_finalization_group_cleanup_iterator_map(),
    8429         189 :           isolate);
    8430             :       iterator = Handle<JSFinalizationGroupCleanupIterator>::cast(
    8431             :           isolate->factory()->NewJSObjectFromMap(
    8432             :               cleanup_iterator_map, AllocationType::kYoung,
    8433         189 :               Handle<AllocationSite>::null()));
    8434         189 :       iterator->set_finalization_group(*finalization_group);
    8435             :     }
    8436             :     Handle<Object> cleanup(finalization_group->cleanup(), isolate);
    8437             : 
    8438         378 :     v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
    8439             :     v8::Local<v8::Value> result;
    8440         189 :     MaybeHandle<Object> exception;
    8441             :     Handle<Object> args[] = {iterator};
    8442         189 :     bool has_pending_exception = !ToLocal<Value>(
    8443             :         Execution::TryCall(
    8444             :             isolate, cleanup,
    8445             :             handle(ReadOnlyRoots(isolate).undefined_value(), isolate), 1, args,
    8446             :             Execution::MessageHandling::kReport, &exception),
    8447             :         &result);
    8448             :     // TODO(marja): (spec): What if there's an exception?
    8449             :     USE(has_pending_exception);
    8450             : 
    8451             :     // TODO(marja): (spec): Should the iterator be invalidated after the
    8452             :     // function returns?
    8453             :   }
    8454         252 : }
    8455             : 
    8456       79273 : MaybeHandle<FixedArray> JSReceiver::GetPrivateEntries(
    8457             :     Isolate* isolate, Handle<JSReceiver> receiver) {
    8458             :   PropertyFilter key_filter = static_cast<PropertyFilter>(PRIVATE_NAMES_ONLY);
    8459             : 
    8460             :   Handle<FixedArray> keys;
    8461      158546 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8462             :       isolate, keys,
    8463             :       KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly, key_filter,
    8464             :                               GetKeysConversion::kConvertToString),
    8465             :       MaybeHandle<FixedArray>());
    8466             : 
    8467             :   Handle<FixedArray> entries =
    8468       79273 :       isolate->factory()->NewFixedArray(keys->length() * 2);
    8469             :   int length = 0;
    8470             : 
    8471       79463 :   for (int i = 0; i < keys->length(); ++i) {
    8472             :     Handle<Object> obj_key = handle(keys->get(i), isolate);
    8473             :     Handle<Symbol> key(Symbol::cast(*obj_key), isolate);
    8474          95 :     CHECK(key->is_private_name());
    8475             :     Handle<Object> value;
    8476         190 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8477             :         isolate, value, Object::GetProperty(isolate, receiver, key),
    8478             :         MaybeHandle<FixedArray>());
    8479             : 
    8480         190 :     entries->set(length++, *key);
    8481         190 :     entries->set(length++, *value);
    8482             :   }
    8483             :   DCHECK_EQ(length, entries->length());
    8484       79273 :   return FixedArray::ShrinkOrEmpty(isolate, entries, length);
    8485             : }
    8486             : 
    8487             : }  // namespace internal
    8488      120216 : }  // namespace v8

Generated by: LCOV version 1.10