LCOV - code coverage report
Current view: top level - src - objects.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2906 3311 87.8 %
Date: 2019-02-19 Functions: 429 506 84.8 %

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

Generated by: LCOV version 1.10