LCOV - code coverage report
Current view: top level - src - objects.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2751 3175 86.6 %
Date: 2019-04-19 Functions: 429 515 83.3 %

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

Generated by: LCOV version 1.10