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

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

Generated by: LCOV version 1.10