LCOV - code coverage report
Current view: top level - src - objects.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 6464 7279 88.8 %
Date: 2019-01-20 Functions: 782 882 88.7 %

          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 <iomanip>
      10             : #include <memory>
      11             : #include <sstream>
      12             : #include <vector>
      13             : 
      14             : #include "src/objects-inl.h"
      15             : 
      16             : #include "src/accessors.h"
      17             : #include "src/allocation-site-scopes.h"
      18             : #include "src/api-arguments-inl.h"
      19             : #include "src/api-natives.h"
      20             : #include "src/api.h"
      21             : #include "src/arguments.h"
      22             : #include "src/assembler-inl.h"
      23             : #include "src/ast/ast.h"
      24             : #include "src/ast/scopes.h"
      25             : #include "src/base/bits.h"
      26             : #include "src/base/utils/random-number-generator.h"
      27             : #include "src/bootstrapper.h"
      28             : #include "src/builtins/builtins.h"
      29             : #include "src/compiler.h"
      30             : #include "src/counters-inl.h"
      31             : #include "src/counters.h"
      32             : #include "src/date.h"
      33             : #include "src/debug/debug.h"
      34             : #include "src/deoptimizer.h"
      35             : #include "src/elements.h"
      36             : #include "src/execution.h"
      37             : #include "src/field-index-inl.h"
      38             : #include "src/field-index.h"
      39             : #include "src/field-type.h"
      40             : #include "src/frames-inl.h"
      41             : #include "src/globals.h"
      42             : #include "src/ic/ic.h"
      43             : #include "src/identity-map.h"
      44             : #include "src/interpreter/bytecode-array-iterator.h"
      45             : #include "src/interpreter/bytecode-decoder.h"
      46             : #include "src/interpreter/interpreter.h"
      47             : #include "src/isolate-inl.h"
      48             : #include "src/keys.h"
      49             : #include "src/log.h"
      50             : #include "src/lookup-inl.h"
      51             : #include "src/map-updater.h"
      52             : #include "src/message-template.h"
      53             : #include "src/microtask-queue.h"
      54             : #include "src/objects-body-descriptors-inl.h"
      55             : #include "src/objects/api-callbacks.h"
      56             : #include "src/objects/arguments-inl.h"
      57             : #include "src/objects/bigint.h"
      58             : #include "src/objects/cell-inl.h"
      59             : #include "src/objects/code-inl.h"
      60             : #include "src/objects/compilation-cache-inl.h"
      61             : #include "src/objects/debug-objects-inl.h"
      62             : #include "src/objects/foreign.h"
      63             : #include "src/objects/frame-array-inl.h"
      64             : #include "src/objects/hash-table-inl.h"
      65             : #include "src/objects/js-array-inl.h"
      66             : #ifdef V8_INTL_SUPPORT
      67             : #include "src/objects/js-break-iterator.h"
      68             : #include "src/objects/js-collator.h"
      69             : #endif  // V8_INTL_SUPPORT
      70             : #include "src/objects/js-collection-inl.h"
      71             : #ifdef V8_INTL_SUPPORT
      72             : #include "src/objects/js-date-time-format.h"
      73             : #endif  // V8_INTL_SUPPORT
      74             : #include "src/objects/js-generator-inl.h"
      75             : #ifdef V8_INTL_SUPPORT
      76             : #include "src/objects/js-list-format.h"
      77             : #include "src/objects/js-locale.h"
      78             : #include "src/objects/js-number-format.h"
      79             : #include "src/objects/js-plural-rules.h"
      80             : #endif  // V8_INTL_SUPPORT
      81             : #include "src/objects/js-regexp-inl.h"
      82             : #include "src/objects/js-regexp-string-iterator.h"
      83             : #ifdef V8_INTL_SUPPORT
      84             : #include "src/objects/js-relative-time-format.h"
      85             : #include "src/objects/js-segment-iterator.h"
      86             : #include "src/objects/js-segmenter.h"
      87             : #endif  // V8_INTL_SUPPORT
      88             : #include "src/code-comments.h"
      89             : #include "src/objects/js-weak-refs-inl.h"
      90             : #include "src/objects/literal-objects-inl.h"
      91             : #include "src/objects/map.h"
      92             : #include "src/objects/microtask-inl.h"
      93             : #include "src/objects/module-inl.h"
      94             : #include "src/objects/promise-inl.h"
      95             : #include "src/objects/slots-atomic-inl.h"
      96             : #include "src/objects/stack-frame-info-inl.h"
      97             : #include "src/objects/struct-inl.h"
      98             : #include "src/parsing/preparse-data.h"
      99             : #include "src/property-descriptor.h"
     100             : #include "src/prototype.h"
     101             : #include "src/regexp/jsregexp.h"
     102             : #include "src/safepoint-table.h"
     103             : #include "src/snapshot/code-serializer.h"
     104             : #include "src/snapshot/snapshot.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/unicode-decoder.h"
     110             : #include "src/unicode-inl.h"
     111             : #include "src/utils-inl.h"
     112             : #include "src/wasm/wasm-engine.h"
     113             : #include "src/wasm/wasm-objects.h"
     114             : #include "src/zone/zone.h"
     115             : 
     116             : #ifdef ENABLE_DISASSEMBLER
     117             : #include "src/disasm.h"
     118             : #include "src/disassembler.h"
     119             : #include "src/eh-frame.h"
     120             : #endif
     121             : 
     122             : namespace v8 {
     123             : namespace internal {
     124             : 
     125     4428077 : bool ComparisonResultToBool(Operation op, ComparisonResult result) {
     126     4428077 :   switch (op) {
     127             :     case Operation::kLessThan:
     128       17879 :       return result == ComparisonResult::kLessThan;
     129             :     case Operation::kLessThanOrEqual:
     130     3124720 :       return result == ComparisonResult::kLessThan ||
     131     3124720 :              result == ComparisonResult::kEqual;
     132             :     case Operation::kGreaterThan:
     133         981 :       return result == ComparisonResult::kGreaterThan;
     134             :     case Operation::kGreaterThanOrEqual:
     135     1284497 :       return result == ComparisonResult::kGreaterThan ||
     136     1284497 :              result == ComparisonResult::kEqual;
     137             :     default:
     138             :       break;
     139             :   }
     140           0 :   UNREACHABLE();
     141             : }
     142             : 
     143       40179 : std::ostream& operator<<(std::ostream& os, InstanceType instance_type) {
     144       40179 :   switch (instance_type) {
     145             : #define WRITE_TYPE(TYPE) \
     146             :   case TYPE:             \
     147             :     return os << #TYPE;
     148          17 :     INSTANCE_TYPE_LIST(WRITE_TYPE)
     149             : #undef WRITE_TYPE
     150             :   }
     151           0 :   UNREACHABLE();
     152             : }
     153             : 
     154     7576041 : Handle<FieldType> Object::OptimalType(Isolate* isolate,
     155             :                                       Representation representation) {
     156     7576041 :   if (representation.IsNone()) return FieldType::None(isolate);
     157     7353517 :   if (FLAG_track_field_types) {
     158    10401923 :     if (representation.IsHeapObject() && IsHeapObject()) {
     159             :       // We can track only JavaScript objects with stable maps.
     160             :       Handle<Map> map(HeapObject::cast(*this)->map(), isolate);
     161     5798840 :       if (map->is_stable() && map->IsJSReceiverMap()) {
     162      781992 :         return FieldType::Class(map, isolate);
     163             :       }
     164             :     }
     165             :   }
     166     6571525 :   return FieldType::Any(isolate);
     167             : }
     168             : 
     169        7076 : MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
     170             :                                          Handle<Object> object,
     171             :                                          Handle<Context> native_context,
     172             :                                          const char* method_name) {
     173       14152 :   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
     174             :   Handle<JSFunction> constructor;
     175       14152 :   if (object->IsSmi()) {
     176        1056 :     constructor = handle(native_context->number_function(), isolate);
     177             :   } else {
     178             :     int constructor_function_index =
     179       13096 :         Handle<HeapObject>::cast(object)->map()->GetConstructorFunctionIndex();
     180        6548 :     if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
     181        1698 :       if (method_name != nullptr) {
     182         900 :         THROW_NEW_ERROR(
     183             :             isolate,
     184             :             NewTypeError(
     185             :                 MessageTemplate::kCalledOnNullOrUndefined,
     186             :                 isolate->factory()->NewStringFromAsciiChecked(method_name)),
     187             :             JSReceiver);
     188             :       }
     189        1248 :       THROW_NEW_ERROR(isolate,
     190             :                       NewTypeError(MessageTemplate::kUndefinedOrNullToObject),
     191             :                       JSReceiver);
     192             :     }
     193             :     constructor = handle(
     194             :         JSFunction::cast(native_context->get(constructor_function_index)),
     195        9700 :         isolate);
     196             :   }
     197        5378 :   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
     198       10756 :   Handle<JSValue>::cast(result)->set_value(*object);
     199        5378 :   return result;
     200             : }
     201             : 
     202             : // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
     203             : // static
     204         180 : MaybeHandle<JSReceiver> Object::ConvertReceiver(Isolate* isolate,
     205             :                                                 Handle<Object> object) {
     206         360 :   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
     207         360 :   if (object->IsNullOrUndefined(isolate)) {
     208           6 :     return isolate->global_proxy();
     209             :   }
     210         174 :   return Object::ToObject(isolate, object);
     211             : }
     212             : 
     213             : // static
     214     3240113 : MaybeHandle<Object> Object::ConvertToNumberOrNumeric(Isolate* isolate,
     215             :                                                      Handle<Object> input,
     216             :                                                      Conversion mode) {
     217             :   while (true) {
     218     6491366 :     if (input->IsNumber()) {
     219      106919 :       return input;
     220             :     }
     221     6277528 :     if (input->IsString()) {
     222        3542 :       return String::ToNumber(isolate, Handle<String>::cast(input));
     223             :     }
     224     6270444 :     if (input->IsOddball()) {
     225     3124697 :       return Oddball::ToNumber(isolate, Handle<Oddball>::cast(input));
     226             :     }
     227       21050 :     if (input->IsSymbol()) {
     228        3767 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber),
     229             :                       Object);
     230             :     }
     231       13516 :     if (input->IsBigInt()) {
     232         582 :       if (mode == Conversion::kToNumeric) return input;
     233             :       DCHECK_EQ(mode, Conversion::kToNumber);
     234         582 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kBigIntToNumber),
     235             :                       Object);
     236             :     }
     237       12352 :     ASSIGN_RETURN_ON_EXCEPTION(
     238             :         isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
     239             :                                                 ToPrimitiveHint::kNumber),
     240             :         Object);
     241             :   }
     242             : }
     243             : 
     244             : // static
     245      107089 : MaybeHandle<Object> Object::ConvertToInteger(Isolate* isolate,
     246             :                                              Handle<Object> input) {
     247      214178 :   ASSIGN_RETURN_ON_EXCEPTION(
     248             :       isolate, input,
     249             :       ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber), Object);
     250      213728 :   if (input->IsSmi()) return input;
     251      105415 :   return isolate->factory()->NewNumber(DoubleToInteger(input->Number()));
     252             : }
     253             : 
     254             : // static
     255        1466 : MaybeHandle<Object> Object::ConvertToInt32(Isolate* isolate,
     256             :                                            Handle<Object> input) {
     257        2932 :   ASSIGN_RETURN_ON_EXCEPTION(
     258             :       isolate, input,
     259             :       ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber), Object);
     260        2908 :   if (input->IsSmi()) return input;
     261        1246 :   return isolate->factory()->NewNumberFromInt(DoubleToInt32(input->Number()));
     262             : }
     263             : 
     264             : // static
     265      436857 : MaybeHandle<Object> Object::ConvertToUint32(Isolate* isolate,
     266             :                                             Handle<Object> input) {
     267      873714 :   ASSIGN_RETURN_ON_EXCEPTION(
     268             :       isolate, input,
     269             :       ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber), Object);
     270     1310361 :   if (input->IsSmi()) return handle(Smi::cast(*input)->ToUint32Smi(), isolate);
     271         294 :   return isolate->factory()->NewNumberFromUint(DoubleToUint32(input->Number()));
     272             : }
     273             : 
     274             : // static
     275       78286 : MaybeHandle<Name> Object::ConvertToName(Isolate* isolate,
     276             :                                         Handle<Object> input) {
     277      156572 :   ASSIGN_RETURN_ON_EXCEPTION(
     278             :       isolate, input, Object::ToPrimitive(input, ToPrimitiveHint::kString),
     279             :       Name);
     280      156100 :   if (input->IsName()) return Handle<Name>::cast(input);
     281       72385 :   return ToString(isolate, input);
     282             : }
     283             : 
     284             : // ES6 7.1.14
     285             : // static
     286         486 : MaybeHandle<Object> Object::ConvertToPropertyKey(Isolate* isolate,
     287             :                                                  Handle<Object> value) {
     288             :   // 1. Let key be ToPrimitive(argument, hint String).
     289             :   MaybeHandle<Object> maybe_key =
     290         486 :       Object::ToPrimitive(value, ToPrimitiveHint::kString);
     291             :   // 2. ReturnIfAbrupt(key).
     292             :   Handle<Object> key;
     293         486 :   if (!maybe_key.ToHandle(&key)) return key;
     294             :   // 3. If Type(key) is Symbol, then return key.
     295         972 :   if (key->IsSymbol()) return key;
     296             :   // 4. Return ToString(key).
     297             :   // Extending spec'ed behavior, we'd be happy to return an element index.
     298         972 :   if (key->IsSmi()) return key;
     299         972 :   if (key->IsHeapNumber()) {
     300             :     uint32_t uint_value;
     301          45 :     if (value->ToArrayLength(&uint_value) &&
     302           9 :         uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) {
     303           0 :       return handle(Smi::FromInt(static_cast<int>(uint_value)), isolate);
     304             :     }
     305             :   }
     306         486 :   return Object::ToString(isolate, key);
     307             : }
     308             : 
     309             : // static
     310     8280172 : MaybeHandle<String> Object::ConvertToString(Isolate* isolate,
     311             :                                             Handle<Object> input) {
     312             :   while (true) {
     313    16927940 :     if (input->IsOddball()) {
     314     8084493 :       return handle(Handle<Oddball>::cast(input)->to_string(), isolate);
     315             :     }
     316    11538278 :     if (input->IsNumber()) {
     317      264458 :       return isolate->factory()->NumberToString(input);
     318             :     }
     319    11009362 :     if (input->IsSymbol()) {
     320        2078 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToString),
     321             :                       String);
     322             :     }
     323    11005206 :     if (input->IsBigInt()) {
     324        8842 :       return BigInt::ToString(isolate, Handle<BigInt>::cast(input));
     325             :     }
     326    10987522 :     ASSIGN_RETURN_ON_EXCEPTION(
     327             :         isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
     328             :                                                 ToPrimitiveHint::kString),
     329             :         String);
     330             :     // The previous isString() check happened in Object::ToString and thus we
     331             :     // put it at the end of the loop in this helper.
     332    10970224 :     if (input->IsString()) {
     333     5301314 :       return Handle<String>::cast(input);
     334             :     }
     335             :   }
     336             : }
     337             : 
     338             : namespace {
     339             : 
     340       31084 : bool IsErrorObject(Isolate* isolate, Handle<Object> object) {
     341       62168 :   if (!object->IsJSReceiver()) return false;
     342             :   Handle<Symbol> symbol = isolate->factory()->stack_trace_symbol();
     343       62168 :   return JSReceiver::HasOwnProperty(Handle<JSReceiver>::cast(object), symbol)
     344       62168 :       .FromMaybe(false);
     345             : }
     346             : 
     347       27634 : Handle<String> AsStringOrEmpty(Isolate* isolate, Handle<Object> object) {
     348       55268 :   return object->IsString() ? Handle<String>::cast(object)
     349       55268 :                             : isolate->factory()->empty_string();
     350             : }
     351             : 
     352        4833 : Handle<String> NoSideEffectsErrorToString(Isolate* isolate,
     353             :                                           Handle<Object> input) {
     354        4833 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
     355             : 
     356             :   Handle<Name> name_key = isolate->factory()->name_string();
     357        4833 :   Handle<Object> name = JSReceiver::GetDataProperty(receiver, name_key);
     358        4833 :   Handle<String> name_str = AsStringOrEmpty(isolate, name);
     359             : 
     360             :   Handle<Name> msg_key = isolate->factory()->message_string();
     361        4833 :   Handle<Object> msg = JSReceiver::GetDataProperty(receiver, msg_key);
     362        4833 :   Handle<String> msg_str = AsStringOrEmpty(isolate, msg);
     363             : 
     364        4833 :   if (name_str->length() == 0) return msg_str;
     365        4815 :   if (msg_str->length() == 0) return name_str;
     366             : 
     367        4653 :   IncrementalStringBuilder builder(isolate);
     368        4653 :   builder.AppendString(name_str);
     369             :   builder.AppendCString(": ");
     370        4653 :   builder.AppendString(msg_str);
     371             : 
     372        9306 :   return builder.Finish().ToHandleChecked();
     373             : }
     374             : 
     375             : }  // namespace
     376             : 
     377             : // static
     378     3486854 : Handle<String> Object::NoSideEffectsToString(Isolate* isolate,
     379             :                                              Handle<Object> input) {
     380     3486854 :   DisallowJavascriptExecution no_js(isolate);
     381             : 
     382    17765368 :   if (input->IsString() || input->IsNumber() || input->IsOddball()) {
     383     6906858 :     return Object::ToString(isolate, input).ToHandleChecked();
     384       66850 :   } else if (input->IsBigInt()) {
     385             :     MaybeHandle<String> maybe_string =
     386          14 :         BigInt::ToString(isolate, Handle<BigInt>::cast(input), 10, kDontThrow);
     387             :     Handle<String> result;
     388          14 :     if (maybe_string.ToHandle(&result)) return result;
     389             :     // BigInt-to-String conversion can fail on 32-bit platforms where
     390             :     // String::kMaxLength is too small to fit this BigInt.
     391             :     return isolate->factory()->NewStringFromStaticChars(
     392           0 :         "<a very large BigInt>");
     393       66822 :   } else if (input->IsFunction()) {
     394             :     // -- F u n c t i o n
     395             :     Handle<String> fun_str;
     396        1044 :     if (input->IsJSBoundFunction()) {
     397           0 :       fun_str = JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(input));
     398             :     } else {
     399             :       DCHECK(input->IsJSFunction());
     400         522 :       fun_str = JSFunction::ToString(Handle<JSFunction>::cast(input));
     401             :     }
     402             : 
     403         522 :     if (fun_str->length() > 128) {
     404           9 :       IncrementalStringBuilder builder(isolate);
     405           9 :       builder.AppendString(isolate->factory()->NewSubString(fun_str, 0, 111));
     406             :       builder.AppendCString("...<omitted>...");
     407             :       builder.AppendString(isolate->factory()->NewSubString(
     408           9 :           fun_str, fun_str->length() - 2, fun_str->length()));
     409             : 
     410          18 :       return builder.Finish().ToHandleChecked();
     411             :     }
     412         513 :     return fun_str;
     413       65778 :   } else if (input->IsSymbol()) {
     414             :     // -- S y m b o l
     415        1805 :     Handle<Symbol> symbol = Handle<Symbol>::cast(input);
     416             : 
     417        1805 :     IncrementalStringBuilder builder(isolate);
     418             :     builder.AppendCString("Symbol(");
     419        3610 :     if (symbol->name()->IsString()) {
     420        2530 :       builder.AppendString(handle(String::cast(symbol->name()), isolate));
     421             :     }
     422             :     builder.AppendCharacter(')');
     423             : 
     424        3610 :     return builder.Finish().ToHandleChecked();
     425       62168 :   } else if (input->IsJSReceiver()) {
     426             :     // -- J S R e c e i v e r
     427       31084 :     Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
     428             :     Handle<Object> to_string = JSReceiver::GetDataProperty(
     429       31084 :         receiver, isolate->factory()->toString_string());
     430             : 
     431       93252 :     if (IsErrorObject(isolate, input) ||
     432       83604 :         *to_string == *isolate->error_to_string()) {
     433             :       // When internally formatting error objects, use a side-effects-free
     434             :       // version of Error.prototype.toString independent of the actually
     435             :       // installed toString method.
     436       26894 :       return NoSideEffectsErrorToString(isolate, input);
     437       52502 :     } else if (*to_string == *isolate->object_to_string()) {
     438             :       Handle<Object> ctor = JSReceiver::GetDataProperty(
     439       18193 :           receiver, isolate->factory()->constructor_string());
     440       36386 :       if (ctor->IsFunction()) {
     441             :         Handle<String> ctor_name;
     442       35936 :         if (ctor->IsJSBoundFunction()) {
     443             :           ctor_name = JSBoundFunction::GetName(
     444           0 :                           isolate, Handle<JSBoundFunction>::cast(ctor))
     445           0 :                           .ToHandleChecked();
     446       35936 :         } else if (ctor->IsJSFunction()) {
     447             :           Handle<Object> ctor_name_obj =
     448       17968 :               JSFunction::GetName(isolate, Handle<JSFunction>::cast(ctor));
     449       17968 :           ctor_name = AsStringOrEmpty(isolate, ctor_name_obj);
     450             :         }
     451             : 
     452       17968 :         if (ctor_name->length() != 0) {
     453       17228 :           IncrementalStringBuilder builder(isolate);
     454             :           builder.AppendCString("#<");
     455       17228 :           builder.AppendString(ctor_name);
     456             :           builder.AppendCString(">");
     457             : 
     458       34456 :           return builder.Finish().ToHandleChecked();
     459             :         }
     460             :       }
     461             :     }
     462             :   }
     463             : 
     464             :   // At this point, input is either none of the above or a JSReceiver.
     465             : 
     466             :   Handle<JSReceiver> receiver;
     467       18046 :   if (input->IsJSReceiver()) {
     468        9023 :     receiver = Handle<JSReceiver>::cast(input);
     469             :   } else {
     470             :     // This is the only case where Object::ToObject throws.
     471             :     DCHECK(!input->IsSmi());
     472             :     int constructor_function_index =
     473           0 :         Handle<HeapObject>::cast(input)->map()->GetConstructorFunctionIndex();
     474           0 :     if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
     475           0 :       return isolate->factory()->NewStringFromAsciiChecked("[object Unknown]");
     476             :     }
     477             : 
     478           0 :     receiver = Object::ToObject(isolate, input, isolate->native_context())
     479           0 :                    .ToHandleChecked();
     480             :   }
     481             : 
     482       18046 :   Handle<String> builtin_tag = handle(receiver->class_name(), isolate);
     483             :   Handle<Object> tag_obj = JSReceiver::GetDataProperty(
     484        9023 :       receiver, isolate->factory()->to_string_tag_symbol());
     485             :   Handle<String> tag =
     486       18046 :       tag_obj->IsString() ? Handle<String>::cast(tag_obj) : builtin_tag;
     487             : 
     488        9023 :   IncrementalStringBuilder builder(isolate);
     489             :   builder.AppendCString("[object ");
     490        9023 :   builder.AppendString(tag);
     491             :   builder.AppendCString("]");
     492             : 
     493       18046 :   return builder.Finish().ToHandleChecked();
     494             : }
     495             : 
     496             : // static
     497        2322 : MaybeHandle<Object> Object::ConvertToLength(Isolate* isolate,
     498             :                                             Handle<Object> input) {
     499        4644 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(isolate, input), Object);
     500        4302 :   if (input->IsSmi()) {
     501        1647 :     int value = std::max(Smi::ToInt(*input), 0);
     502         549 :     return handle(Smi::FromInt(value), isolate);
     503             :   }
     504        1602 :   double len = DoubleToInteger(input->Number());
     505        1602 :   if (len <= 0.0) {
     506        1179 :     return handle(Smi::kZero, isolate);
     507         423 :   } else if (len >= kMaxSafeInteger) {
     508             :     len = kMaxSafeInteger;
     509             :   }
     510         423 :   return isolate->factory()->NewNumber(len);
     511             : }
     512             : 
     513             : // static
     514        1293 : MaybeHandle<Object> Object::ConvertToIndex(Isolate* isolate,
     515             :                                            Handle<Object> input,
     516             :                                            MessageTemplate error_index) {
     517        3411 :   if (input->IsUndefined(isolate)) return handle(Smi::kZero, isolate);
     518         936 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(isolate, input), Object);
     519        1012 :   if (input->IsSmi() && Smi::ToInt(*input) >= 0) return input;
     520         396 :   double len = DoubleToInteger(input->Number()) + 0.0;
     521         396 :   auto js_len = isolate->factory()->NewNumber(len);
     522         396 :   if (len < 0.0 || len > kMaxSafeInteger) {
     523         108 :     THROW_NEW_ERROR(isolate, NewRangeError(error_index, js_len), Object);
     524             :   }
     525         288 :   return js_len;
     526             : }
     527             : 
     528    89990686 : bool Object::BooleanValue(Isolate* isolate) {
     529    89990740 :   if (IsSmi()) return Smi::ToInt(*this) != 0;
     530             :   DCHECK(IsHeapObject());
     531    91265280 :   if (IsBoolean()) return IsTrue(isolate);
     532    88705334 :   if (IsNullOrUndefined(isolate)) return false;
     533    87723282 :   if (IsUndetectable()) return false;  // Undetectable object is false.
     534    95222760 :   if (IsString()) return String::cast(*this)->length() != 0;
     535    80685558 :   if (IsHeapNumber()) return DoubleToBoolean(HeapNumber::cast(*this)->value());
     536    79766547 :   if (IsBigInt()) return BigInt::cast(*this)->ToBoolean();
     537             :   return true;
     538             : }
     539             : 
     540             : namespace {
     541             : 
     542             : // TODO(bmeurer): Maybe we should introduce a marker interface Number,
     543             : // where we put all these methods at some point?
     544             : ComparisonResult NumberCompare(double x, double y) {
     545         660 :   if (std::isnan(x) || std::isnan(y)) {
     546             :     return ComparisonResult::kUndefined;
     547         480 :   } else if (x < y) {
     548             :     return ComparisonResult::kLessThan;
     549         260 :   } else if (x > y) {
     550             :     return ComparisonResult::kGreaterThan;
     551             :   } else {
     552             :     return ComparisonResult::kEqual;
     553             :   }
     554             : }
     555             : 
     556             : bool NumberEquals(double x, double y) {
     557             :   // Must check explicitly for NaN's on Windows, but -0 works fine.
     558       11421 :   if (std::isnan(x)) return false;
     559       11329 :   if (std::isnan(y)) return false;
     560       11262 :   return x == y;
     561             : }
     562             : 
     563       11421 : bool NumberEquals(const Object x, const Object y) {
     564       22842 :   return NumberEquals(x->Number(), y->Number());
     565             : }
     566             : 
     567        4227 : bool NumberEquals(Handle<Object> x, Handle<Object> y) {
     568        4227 :   return NumberEquals(*x, *y);
     569             : }
     570             : 
     571             : ComparisonResult Reverse(ComparisonResult result) {
     572         153 :   if (result == ComparisonResult::kLessThan) {
     573             :     return ComparisonResult::kGreaterThan;
     574             :   }
     575         135 :   if (result == ComparisonResult::kGreaterThan) {
     576             :     return ComparisonResult::kLessThan;
     577             :   }
     578             :   return result;
     579             : }
     580             : 
     581             : }  // anonymous namespace
     582             : 
     583             : // static
     584        1069 : Maybe<ComparisonResult> Object::Compare(Isolate* isolate, Handle<Object> x,
     585             :                                         Handle<Object> y) {
     586             :   // ES6 section 7.2.11 Abstract Relational Comparison step 3 and 4.
     587        4276 :   if (!Object::ToPrimitive(x, ToPrimitiveHint::kNumber).ToHandle(&x) ||
     588        2138 :       !Object::ToPrimitive(y, ToPrimitiveHint::kNumber).ToHandle(&y)) {
     589             :     return Nothing<ComparisonResult>();
     590             :   }
     591        2544 :   if (x->IsString() && y->IsString()) {
     592             :     // ES6 section 7.2.11 Abstract Relational Comparison step 5.
     593             :     return Just(String::Compare(isolate, Handle<String>::cast(x),
     594          40 :                                 Handle<String>::cast(y)));
     595             :   }
     596        2472 :   if (x->IsBigInt() && y->IsString()) {
     597             :     return Just(BigInt::CompareToString(isolate, Handle<BigInt>::cast(x),
     598          63 :                                         Handle<String>::cast(y)));
     599             :   }
     600        2258 :   if (x->IsString() && y->IsBigInt()) {
     601             :     return Just(Reverse(BigInt::CompareToString(
     602          63 :         isolate, Handle<BigInt>::cast(y), Handle<String>::cast(x))));
     603             :   }
     604             :   // ES6 section 7.2.11 Abstract Relational Comparison step 6.
     605        3603 :   if (!Object::ToNumeric(isolate, x).ToHandle(&x) ||
     606        1797 :       !Object::ToNumeric(isolate, y).ToHandle(&y)) {
     607             :     return Nothing<ComparisonResult>();
     608             :   }
     609             : 
     610        1770 :   bool x_is_number = x->IsNumber();
     611        1770 :   bool y_is_number = y->IsNumber();
     612         885 :   if (x_is_number && y_is_number) {
     613        1980 :     return Just(NumberCompare(x->Number(), y->Number()));
     614         225 :   } else if (!x_is_number && !y_is_number) {
     615             :     return Just(BigInt::CompareToBigInt(Handle<BigInt>::cast(x),
     616          45 :                                         Handle<BigInt>::cast(y)));
     617         180 :   } else if (x_is_number) {
     618          90 :     return Just(Reverse(BigInt::CompareToNumber(Handle<BigInt>::cast(y), x)));
     619             :   } else {
     620          90 :     return Just(BigInt::CompareToNumber(Handle<BigInt>::cast(x), y));
     621             :   }
     622             : }
     623             : 
     624             : 
     625             : // static
     626      169241 : Maybe<bool> Object::Equals(Isolate* isolate, Handle<Object> x,
     627             :                            Handle<Object> y) {
     628             :   // This is the generic version of Abstract Equality Comparison. Must be in
     629             :   // sync with CodeStubAssembler::Equal.
     630             :   while (true) {
     631      338638 :     if (x->IsNumber()) {
     632        9100 :       if (y->IsNumber()) {
     633        4092 :         return Just(NumberEquals(x, y));
     634         916 :       } else if (y->IsBoolean()) {
     635           0 :         return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
     636         916 :       } else if (y->IsString()) {
     637             :         return Just(NumberEquals(
     638          80 :             x, String::ToNumber(isolate, Handle<String>::cast(y))));
     639         756 :       } else if (y->IsBigInt()) {
     640         378 :         return Just(BigInt::EqualToNumber(Handle<BigInt>::cast(y), x));
     641           0 :       } else if (y->IsJSReceiver()) {
     642           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     643           0 :                  .ToHandle(&y)) {
     644             :           return Nothing<bool>();
     645             :         }
     646             :       } else {
     647             :         return Just(false);
     648             :       }
     649      329538 :     } else if (x->IsString()) {
     650      286232 :       if (y->IsString()) {
     651             :         return Just(String::Equals(isolate, Handle<String>::cast(x),
     652      142899 :                                    Handle<String>::cast(y)));
     653         434 :       } else if (y->IsNumber()) {
     654          55 :         x = String::ToNumber(isolate, Handle<String>::cast(x));
     655          55 :         return Just(NumberEquals(x, y));
     656         324 :       } else if (y->IsBoolean()) {
     657           0 :         x = String::ToNumber(isolate, Handle<String>::cast(x));
     658           0 :         return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
     659         324 :       } else if (y->IsBigInt()) {
     660             :         return Just(BigInt::EqualToString(isolate, Handle<BigInt>::cast(y),
     661         162 :                                           Handle<String>::cast(x)));
     662           0 :       } else if (y->IsJSReceiver()) {
     663           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     664           0 :                  .ToHandle(&y)) {
     665             :           return Nothing<bool>();
     666             :         }
     667             :       } else {
     668             :         return Just(false);
     669             :       }
     670       43306 :     } else if (x->IsBoolean()) {
     671        1632 :       if (y->IsOddball()) {
     672             :         return Just(x.is_identical_to(y));
     673         432 :       } else if (y->IsNumber()) {
     674           0 :         return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
     675         432 :       } else if (y->IsString()) {
     676           0 :         y = String::ToNumber(isolate, Handle<String>::cast(y));
     677           0 :         return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
     678         432 :       } else if (y->IsBigInt()) {
     679         216 :         x = Oddball::ToNumber(isolate, Handle<Oddball>::cast(x));
     680         216 :         return Just(BigInt::EqualToNumber(Handle<BigInt>::cast(y), x));
     681           0 :       } else if (y->IsJSReceiver()) {
     682           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     683           0 :                  .ToHandle(&y)) {
     684             :           return Nothing<bool>();
     685             :         }
     686           0 :         x = Oddball::ToNumber(isolate, Handle<Oddball>::cast(x));
     687             :       } else {
     688             :         return Just(false);
     689             :       }
     690       41674 :     } else if (x->IsSymbol()) {
     691         180 :       if (y->IsSymbol()) {
     692             :         return Just(x.is_identical_to(y));
     693          72 :       } else if (y->IsJSReceiver()) {
     694           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     695           0 :                  .ToHandle(&y)) {
     696             :           return Nothing<bool>();
     697             :         }
     698             :       } else {
     699             :         return Just(false);
     700             :       }
     701       41494 :     } else if (x->IsBigInt()) {
     702         954 :       if (y->IsBigInt()) {
     703          81 :         return Just(BigInt::EqualToBigInt(BigInt::cast(*x), BigInt::cast(*y)));
     704             :       }
     705         396 :       return Equals(isolate, y, x);
     706       40540 :     } else if (x->IsJSReceiver()) {
     707       40336 :       if (y->IsJSReceiver()) {
     708             :         return Just(x.is_identical_to(y));
     709         156 :       } else if (y->IsUndetectable()) {
     710           0 :         return Just(x->IsUndetectable());
     711         156 :       } else if (y->IsBoolean()) {
     712           0 :         y = Oddball::ToNumber(isolate, Handle<Oddball>::cast(y));
     713         156 :       } else if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x))
     714         156 :                       .ToHandle(&x)) {
     715             :         return Nothing<bool>();
     716             :       }
     717             :     } else {
     718         510 :       return Just(x->IsUndetectable() && y->IsUndetectable());
     719             :     }
     720             :   }
     721             : }
     722             : 
     723       10337 : bool Object::StrictEquals(Object that) {
     724       10337 :   if (this->IsNumber()) {
     725        7751 :     if (!that->IsNumber()) return false;
     726        7194 :     return NumberEquals(*this, that);
     727        2586 :   } else if (this->IsString()) {
     728        1337 :     if (!that->IsString()) return false;
     729        1272 :     return String::cast(*this)->Equals(String::cast(that));
     730        1249 :   } else if (this->IsBigInt()) {
     731          90 :     if (!that->IsBigInt()) return false;
     732          72 :     return BigInt::EqualToBigInt(BigInt::cast(*this), BigInt::cast(that));
     733             :   }
     734        1159 :   return *this == that;
     735             : }
     736             : 
     737             : // static
     738       12779 : Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
     739       25558 :   if (object->IsNumber()) return isolate->factory()->number_string();
     740       24902 :   if (object->IsOddball())
     741        3144 :     return handle(Oddball::cast(*object)->type_of(), isolate);
     742       21758 :   if (object->IsUndetectable()) {
     743             :     return isolate->factory()->undefined_string();
     744             :   }
     745       21758 :   if (object->IsString()) return isolate->factory()->string_string();
     746       21280 :   if (object->IsSymbol()) return isolate->factory()->symbol_string();
     747       21180 :   if (object->IsBigInt()) return isolate->factory()->bigint_string();
     748       21144 :   if (object->IsCallable()) return isolate->factory()->function_string();
     749             :   return isolate->factory()->object_string();
     750             : }
     751             : 
     752             : 
     753             : // static
     754          40 : MaybeHandle<Object> Object::Add(Isolate* isolate, Handle<Object> lhs,
     755             :                                 Handle<Object> rhs) {
     756         140 :   if (lhs->IsNumber() && rhs->IsNumber()) {
     757          60 :     return isolate->factory()->NewNumber(lhs->Number() + rhs->Number());
     758          20 :   } else if (lhs->IsString() && rhs->IsString()) {
     759             :     return isolate->factory()->NewConsString(Handle<String>::cast(lhs),
     760           0 :                                              Handle<String>::cast(rhs));
     761             :   }
     762          20 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToPrimitive(lhs), Object);
     763          20 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToPrimitive(rhs), Object);
     764          40 :   if (lhs->IsString() || rhs->IsString()) {
     765           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToString(isolate, rhs),
     766             :                                Object);
     767           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToString(isolate, lhs),
     768             :                                Object);
     769             :     return isolate->factory()->NewConsString(Handle<String>::cast(lhs),
     770           0 :                                              Handle<String>::cast(rhs));
     771             :   }
     772          20 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(isolate, rhs),
     773             :                              Object);
     774          20 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(isolate, lhs),
     775             :                              Object);
     776          20 :   return isolate->factory()->NewNumber(lhs->Number() + rhs->Number());
     777             : }
     778             : 
     779             : 
     780             : // static
     781      107560 : MaybeHandle<Object> Object::OrdinaryHasInstance(Isolate* isolate,
     782             :                                                 Handle<Object> callable,
     783             :                                                 Handle<Object> object) {
     784             :   // The {callable} must have a [[Call]] internal method.
     785      215155 :   if (!callable->IsCallable()) return isolate->factory()->false_value();
     786             : 
     787             :   // Check if {callable} is a bound function, and if so retrieve its
     788             :   // [[BoundTargetFunction]] and use that instead of {callable}.
     789      215050 :   if (callable->IsJSBoundFunction()) {
     790             :     Handle<Object> bound_callable(
     791         876 :         Handle<JSBoundFunction>::cast(callable)->bound_target_function(),
     792         584 :         isolate);
     793         292 :     return Object::InstanceOf(isolate, object, bound_callable);
     794             :   }
     795             : 
     796             :   // If {object} is not a receiver, return false.
     797      221754 :   if (!object->IsJSReceiver()) return isolate->factory()->false_value();
     798             : 
     799             :   // Get the "prototype" of {callable}; raise an error if it's not a receiver.
     800             :   Handle<Object> prototype;
     801      199890 :   ASSIGN_RETURN_ON_EXCEPTION(
     802             :       isolate, prototype,
     803             :       Object::GetProperty(isolate, callable,
     804             :                           isolate->factory()->prototype_string()),
     805             :       Object);
     806      199890 :   if (!prototype->IsJSReceiver()) {
     807       99603 :     THROW_NEW_ERROR(
     808             :         isolate,
     809             :         NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype),
     810             :         Object);
     811             :   }
     812             : 
     813             :   // Return whether or not {prototype} is in the prototype chain of {object}.
     814             :   Maybe<bool> result = JSReceiver::HasInPrototypeChain(
     815         342 :       isolate, Handle<JSReceiver>::cast(object), prototype);
     816         342 :   if (result.IsNothing()) return MaybeHandle<Object>();
     817         342 :   return isolate->factory()->ToBoolean(result.FromJust());
     818             : }
     819             : 
     820             : // static
     821        8924 : MaybeHandle<Object> Object::InstanceOf(Isolate* isolate, Handle<Object> object,
     822             :                                        Handle<Object> callable) {
     823             :   // The {callable} must be a receiver.
     824       17848 :   if (!callable->IsJSReceiver()) {
     825           0 :     THROW_NEW_ERROR(isolate,
     826             :                     NewTypeError(MessageTemplate::kNonObjectInInstanceOfCheck),
     827             :                     Object);
     828             :   }
     829             : 
     830             :   // Lookup the @@hasInstance method on {callable}.
     831             :   Handle<Object> inst_of_handler;
     832       17848 :   ASSIGN_RETURN_ON_EXCEPTION(
     833             :       isolate, inst_of_handler,
     834             :       Object::GetMethod(Handle<JSReceiver>::cast(callable),
     835             :                         isolate->factory()->has_instance_symbol()),
     836             :       Object);
     837       17848 :   if (!inst_of_handler->IsUndefined(isolate)) {
     838             :     // Call the {inst_of_handler} on the {callable}.
     839             :     Handle<Object> result;
     840       17836 :     ASSIGN_RETURN_ON_EXCEPTION(
     841             :         isolate, result,
     842             :         Execution::Call(isolate, inst_of_handler, callable, 1, &object),
     843             :         Object);
     844        8912 :     return isolate->factory()->ToBoolean(result->BooleanValue(isolate));
     845             :   }
     846             : 
     847             :   // The {callable} must have a [[Call]] internal method.
     848          12 :   if (!callable->IsCallable()) {
     849           6 :     THROW_NEW_ERROR(
     850             :         isolate, NewTypeError(MessageTemplate::kNonCallableInInstanceOfCheck),
     851             :         Object);
     852             :   }
     853             : 
     854             :   // Fall back to OrdinaryHasInstance with {callable} and {object}.
     855             :   Handle<Object> result;
     856           0 :   ASSIGN_RETURN_ON_EXCEPTION(
     857             :       isolate, result, Object::OrdinaryHasInstance(isolate, callable, object),
     858             :       Object);
     859           0 :   return result;
     860             : }
     861             : 
     862             : // static
     863    10771302 : MaybeHandle<Object> Object::GetMethod(Handle<JSReceiver> receiver,
     864             :                                       Handle<Name> name) {
     865             :   Handle<Object> func;
     866             :   Isolate* isolate = receiver->GetIsolate();
     867    21542604 :   ASSIGN_RETURN_ON_EXCEPTION(
     868             :       isolate, func, JSReceiver::GetProperty(isolate, receiver, name), Object);
     869    21495876 :   if (func->IsNullOrUndefined(isolate)) {
     870     9696416 :     return isolate->factory()->undefined_value();
     871             :   }
     872     2103044 :   if (!func->IsCallable()) {
     873         234 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kPropertyNotFunction,
     874             :                                           func, name, receiver),
     875             :                     Object);
     876             :   }
     877     1051288 :   return func;
     878             : }
     879             : 
     880             : namespace {
     881             : 
     882       17699 : MaybeHandle<FixedArray> CreateListFromArrayLikeFastPath(
     883             :     Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
     884       17699 :   if (element_types == ElementTypes::kAll) {
     885       33076 :     if (object->IsJSArray()) {
     886         395 :       Handle<JSArray> array = Handle<JSArray>::cast(object);
     887             :       uint32_t length;
     888        1185 :       if (!array->HasArrayPrototype(isolate) ||
     889        2190 :           !array->length()->ToUint32(&length) || !array->HasFastElements() ||
     890         610 :           !JSObject::PrototypeHasNoElements(isolate, *array)) {
     891         279 :         return MaybeHandle<FixedArray>();
     892             :       }
     893         232 :       return array->GetElementsAccessor()->CreateListFromArrayLike(
     894         232 :           isolate, array, length);
     895       32286 :     } else if (object->IsJSTypedArray()) {
     896         657 :       Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(object);
     897             :       size_t length = array->length_value();
     898         657 :       if (array->WasDetached() ||
     899             :           length > static_cast<size_t>(FixedArray::kMaxLength)) {
     900           0 :         return MaybeHandle<FixedArray>();
     901             :       }
     902        1314 :       return array->GetElementsAccessor()->CreateListFromArrayLike(
     903        1314 :           isolate, array, static_cast<uint32_t>(length));
     904             :     }
     905             :   }
     906       16647 :   return MaybeHandle<FixedArray>();
     907             : }
     908             : 
     909             : }  // namespace
     910             : 
     911             : // static
     912       17699 : MaybeHandle<FixedArray> Object::CreateListFromArrayLike(
     913             :     Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
     914             :   // Fast-path for JSArray and JSTypedArray.
     915             :   MaybeHandle<FixedArray> fast_result =
     916       17699 :       CreateListFromArrayLikeFastPath(isolate, object, element_types);
     917       17699 :   if (!fast_result.is_null()) return fast_result;
     918             :   // 1. ReturnIfAbrupt(object).
     919             :   // 2. (default elementTypes -- not applicable.)
     920             :   // 3. If Type(obj) is not Object, throw a TypeError exception.
     921       33852 :   if (!object->IsJSReceiver()) {
     922         918 :     THROW_NEW_ERROR(isolate,
     923             :                     NewTypeError(MessageTemplate::kCalledOnNonObject,
     924             :                                  isolate->factory()->NewStringFromAsciiChecked(
     925             :                                      "CreateListFromArrayLike")),
     926             :                     FixedArray);
     927             :   }
     928             : 
     929             :   // 4. Let len be ? ToLength(? Get(obj, "length")).
     930       16467 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
     931             :   Handle<Object> raw_length_number;
     932       32934 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, raw_length_number,
     933             :                              Object::GetLengthFromArrayLike(isolate, receiver),
     934             :                              FixedArray);
     935             :   uint32_t len;
     936       32853 :   if (!raw_length_number->ToUint32(&len) ||
     937       16422 :       len > static_cast<uint32_t>(FixedArray::kMaxLength)) {
     938          27 :     THROW_NEW_ERROR(isolate,
     939             :                     NewRangeError(MessageTemplate::kInvalidArrayLength),
     940             :                     FixedArray);
     941             :   }
     942             :   // 5. Let list be an empty List.
     943       16404 :   Handle<FixedArray> list = isolate->factory()->NewFixedArray(len);
     944             :   // 6. Let index be 0.
     945             :   // 7. Repeat while index < len:
     946    40159821 :   for (uint32_t index = 0; index < len; ++index) {
     947             :     // 7a. Let indexName be ToString(index).
     948             :     // 7b. Let next be ? Get(obj, indexName).
     949             :     Handle<Object> next;
     950    80286978 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, next,
     951             :                                JSReceiver::GetElement(isolate, receiver, index),
     952             :                                FixedArray);
     953    40143453 :     switch (element_types) {
     954             :       case ElementTypes::kAll:
     955             :         // Nothing to do.
     956             :         break;
     957             :       case ElementTypes::kStringAndSymbol: {
     958             :         // 7c. If Type(next) is not an element of elementTypes, throw a
     959             :         //     TypeError exception.
     960        6048 :         if (!next->IsName()) {
     961          36 :           THROW_NEW_ERROR(isolate,
     962             :                           NewTypeError(MessageTemplate::kNotPropertyName, next),
     963             :                           FixedArray);
     964             :         }
     965             :         // 7d. Append next as the last element of list.
     966             :         // Internalize on the fly so we can use pointer identity later.
     967        2988 :         next = isolate->factory()->InternalizeName(Handle<Name>::cast(next));
     968        2988 :         break;
     969             :       }
     970             :     }
     971    80286834 :     list->set(index, *next);
     972             :     // 7e. Set index to index + 1. (See loop header.)
     973             :   }
     974             :   // 8. Return list.
     975       16332 :   return list;
     976             : }
     977             : 
     978             : 
     979             : // static
     980       55078 : MaybeHandle<Object> Object::GetLengthFromArrayLike(Isolate* isolate,
     981             :                                                    Handle<JSReceiver> object) {
     982             :   Handle<Object> val;
     983             :   Handle<Name> key = isolate->factory()->length_string();
     984      110156 :   ASSIGN_RETURN_ON_EXCEPTION(
     985             :       isolate, val, JSReceiver::GetProperty(isolate, object, key), Object);
     986       54979 :   return Object::ToLength(isolate, val);
     987             : }
     988             : 
     989             : // static
     990    10349419 : Maybe<bool> JSReceiver::HasProperty(LookupIterator* it) {
     991    10325592 :   for (; it->IsFound(); it->Next()) {
     992     1614448 :     switch (it->state()) {
     993             :       case LookupIterator::NOT_FOUND:
     994             :       case LookupIterator::TRANSITION:
     995           0 :         UNREACHABLE();
     996             :       case LookupIterator::JSPROXY:
     997             :         return JSProxy::HasProperty(it->isolate(), it->GetHolder<JSProxy>(),
     998      105806 :                                     it->GetName());
     999             :       case LookupIterator::INTERCEPTOR: {
    1000             :         Maybe<PropertyAttributes> result =
    1001         226 :             JSObject::GetPropertyAttributesWithInterceptor(it);
    1002         300 :         if (result.IsNothing()) return Nothing<bool>();
    1003         220 :         if (result.FromJust() != ABSENT) return Just(true);
    1004         152 :         break;
    1005             :       }
    1006             :       case LookupIterator::ACCESS_CHECK: {
    1007       28964 :         if (it->HasAccess()) break;
    1008             :         Maybe<PropertyAttributes> result =
    1009          40 :             JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
    1010          80 :         if (result.IsNothing()) return Nothing<bool>();
    1011           0 :         return Just(result.FromJust() != ABSENT);
    1012             :       }
    1013             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1014             :         // TypedArray out-of-bounds access.
    1015             :         return Just(false);
    1016             :       case LookupIterator::ACCESSOR:
    1017             :       case LookupIterator::DATA:
    1018             :         return Just(true);
    1019             :     }
    1020             :   }
    1021             :   return Just(false);
    1022             : }
    1023             : 
    1024             : // static
    1025      421660 : Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object,
    1026             :                                        Handle<Name> name) {
    1027      843320 :   if (object->IsJSModuleNamespace()) {
    1028             :     PropertyDescriptor desc;
    1029             :     return JSReceiver::GetOwnPropertyDescriptor(object->GetIsolate(), object,
    1030         171 :                                                 name, &desc);
    1031             :   }
    1032             : 
    1033      842978 :   if (object->IsJSObject()) {  // Shortcut.
    1034             :     LookupIterator it = LookupIterator::PropertyOrElement(
    1035      420100 :         object->GetIsolate(), object, name, object, LookupIterator::OWN);
    1036      420100 :     return HasProperty(&it);
    1037             :   }
    1038             : 
    1039             :   Maybe<PropertyAttributes> attributes =
    1040        1389 :       JSReceiver::GetOwnPropertyAttributes(object, name);
    1041        1389 :   MAYBE_RETURN(attributes, Nothing<bool>());
    1042        1299 :   return Just(attributes.FromJust() != ABSENT);
    1043             : }
    1044             : 
    1045             : // static
    1046   114983596 : MaybeHandle<Object> Object::GetProperty(LookupIterator* it,
    1047             :                                         OnNonExistent on_non_existent) {
    1048    93562750 :   for (; it->IsFound(); it->Next()) {
    1049    24751250 :     switch (it->state()) {
    1050             :       case LookupIterator::NOT_FOUND:
    1051             :       case LookupIterator::TRANSITION:
    1052           0 :         UNREACHABLE();
    1053             :       case LookupIterator::JSPROXY: {
    1054             :         bool was_found;
    1055             :         Handle<Object> receiver = it->GetReceiver();
    1056             :         // In case of global IC, the receiver is the global object. Replace by
    1057             :         // the global proxy.
    1058      335572 :         if (receiver->IsJSGlobalObject()) {
    1059             :           receiver = handle(JSGlobalObject::cast(*receiver)->global_proxy(),
    1060         200 :                             it->isolate());
    1061             :         }
    1062             :         MaybeHandle<Object> result =
    1063             :             JSProxy::GetProperty(it->isolate(), it->GetHolder<JSProxy>(),
    1064      335572 :                                  it->GetName(), receiver, &was_found);
    1065      167786 :         if (!was_found) it->NotFound();
    1066      167786 :         return result;
    1067             :       }
    1068             :       case LookupIterator::INTERCEPTOR: {
    1069             :         bool done;
    1070             :         Handle<Object> result;
    1071      228166 :         ASSIGN_RETURN_ON_EXCEPTION(
    1072             :             it->isolate(), result,
    1073             :             JSObject::GetPropertyWithInterceptor(it, &done), Object);
    1074      114065 :         if (done) return result;
    1075      110871 :         break;
    1076             :       }
    1077             :       case LookupIterator::ACCESS_CHECK:
    1078      670249 :         if (it->HasAccess()) break;
    1079        1169 :         return JSObject::GetPropertyWithFailedAccessCheck(it);
    1080             :       case LookupIterator::ACCESSOR:
    1081      918600 :         return GetPropertyWithAccessor(it);
    1082             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1083        2782 :         return it->isolate()->factory()->undefined_value();
    1084             :       case LookupIterator::DATA:
    1085    22877752 :         return it->GetDataValue();
    1086             :     }
    1087             :   }
    1088             : 
    1089    22030127 :   if (on_non_existent == OnNonExistent::kThrowReferenceError) {
    1090          35 :     THROW_NEW_ERROR(it->isolate(),
    1091             :                     NewReferenceError(MessageTemplate::kNotDefined, it->name()),
    1092             :                     Object);
    1093             :   }
    1094    22030092 :   return it->isolate()->factory()->undefined_value();
    1095             : }
    1096             : 
    1097             : 
    1098             : // static
    1099      167786 : MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate,
    1100             :                                          Handle<JSProxy> proxy,
    1101             :                                          Handle<Name> name,
    1102             :                                          Handle<Object> receiver,
    1103             :                                          bool* was_found) {
    1104      167786 :   *was_found = true;
    1105             : 
    1106             :   DCHECK(!name->IsPrivate());
    1107      167786 :   STACK_CHECK(isolate, MaybeHandle<Object>());
    1108             :   Handle<Name> trap_name = isolate->factory()->get_string();
    1109             :   // 1. Assert: IsPropertyKey(P) is true.
    1110             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    1111      335230 :   Handle<Object> handler(proxy->handler(), isolate);
    1112             :   // 3. If handler is null, throw a TypeError exception.
    1113             :   // 4. Assert: Type(handler) is Object.
    1114      335230 :   if (proxy->IsRevoked()) {
    1115          36 :     THROW_NEW_ERROR(isolate,
    1116             :                     NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
    1117             :                     Object);
    1118             :   }
    1119             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    1120      335158 :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    1121             :   // 6. Let trap be ? GetMethod(handler, "get").
    1122             :   Handle<Object> trap;
    1123      335158 :   ASSIGN_RETURN_ON_EXCEPTION(
    1124             :       isolate, trap,
    1125             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), Object);
    1126             :   // 7. If trap is undefined, then
    1127      289178 :   if (trap->IsUndefined(isolate)) {
    1128             :     // 7.a Return target.[[Get]](P, Receiver).
    1129             :     LookupIterator it =
    1130      112408 :         LookupIterator::PropertyOrElement(isolate, receiver, name, target);
    1131      112408 :     MaybeHandle<Object> result = Object::GetProperty(&it);
    1132      224816 :     *was_found = it.IsFound();
    1133      112408 :     return result;
    1134             :   }
    1135             :   // 8. Let trapResult be ? Call(trap, handler, «target, P, Receiver»).
    1136             :   Handle<Object> trap_result;
    1137       32181 :   Handle<Object> args[] = {target, name, receiver};
    1138       64362 :   ASSIGN_RETURN_ON_EXCEPTION(
    1139             :       isolate, trap_result,
    1140             :       Execution::Call(isolate, trap, handler, arraysize(args), args), Object);
    1141             : 
    1142             :   MaybeHandle<Object> result =
    1143       25012 :       JSProxy::CheckGetSetTrapResult(isolate, name, target, trap_result, kGet);
    1144       25012 :   if (result.is_null()) {
    1145          45 :     return result;
    1146             :   }
    1147             : 
    1148             :   // 11. Return trap_result
    1149       24967 :   return trap_result;
    1150             : }
    1151             : 
    1152             : // static
    1153       27397 : MaybeHandle<Object> JSProxy::CheckGetSetTrapResult(Isolate* isolate,
    1154             :                                                    Handle<Name> name,
    1155             :                                                    Handle<JSReceiver> target,
    1156             :                                                    Handle<Object> trap_result,
    1157             :                                                    AccessKind access_kind) {
    1158             :   // 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
    1159             :   PropertyDescriptor target_desc;
    1160             :   Maybe<bool> target_found =
    1161       27397 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    1162       27397 :   MAYBE_RETURN_NULL(target_found);
    1163             :   // 10. If targetDesc is not undefined, then
    1164       27388 :   if (target_found.FromJust()) {
    1165             :     // 10.a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is
    1166             :     //       false and targetDesc.[[Writable]] is false, then
    1167             :     // 10.a.i. If SameValue(trapResult, targetDesc.[[Value]]) is false,
    1168             :     //        throw a TypeError exception.
    1169        7965 :     bool inconsistent = PropertyDescriptor::IsDataDescriptor(&target_desc) &&
    1170        2430 :                         !target_desc.configurable() &&
    1171        9999 :                         !target_desc.writable() &&
    1172        9999 :                         !trap_result->SameValue(*target_desc.value());
    1173        8343 :     if (inconsistent) {
    1174         234 :       if (access_kind == kGet) {
    1175          54 :         THROW_NEW_ERROR(
    1176             :             isolate,
    1177             :             NewTypeError(MessageTemplate::kProxyGetNonConfigurableData, name,
    1178             :                          target_desc.value(), trap_result),
    1179             :             Object);
    1180             :       } else {
    1181             :         isolate->Throw(*isolate->factory()->NewTypeError(
    1182         360 :             MessageTemplate::kProxySetFrozenData, name));
    1183         180 :         return MaybeHandle<Object>();
    1184             :       }
    1185             :     }
    1186             :     // 10.b. If IsAccessorDescriptor(targetDesc) and targetDesc.[[Configurable]]
    1187             :     //       is false and targetDesc.[[Get]] is undefined, then
    1188             :     // 10.b.i. If trapResult is not undefined, throw a TypeError exception.
    1189        8109 :     if (access_kind == kGet) {
    1190           0 :       inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
    1191           0 :                      !target_desc.configurable() &&
    1192       13446 :                      target_desc.get()->IsUndefined(isolate) &&
    1193        6723 :                      !trap_result->IsUndefined(isolate);
    1194             :     } else {
    1195         378 :       inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
    1196        1575 :                      !target_desc.configurable() &&
    1197        1575 :                      target_desc.set()->IsUndefined(isolate);
    1198             :     }
    1199        8109 :     if (inconsistent) {
    1200         189 :       if (access_kind == kGet) {
    1201           0 :         THROW_NEW_ERROR(
    1202             :             isolate,
    1203             :             NewTypeError(MessageTemplate::kProxyGetNonConfigurableAccessor,
    1204             :                          name, trap_result),
    1205             :             Object);
    1206             :       } else {
    1207             :         isolate->Throw(*isolate->factory()->NewTypeError(
    1208         378 :             MessageTemplate::kProxySetFrozenAccessor, name));
    1209         189 :         return MaybeHandle<Object>();
    1210             :       }
    1211             :     }
    1212             :   }
    1213       26965 :   return isolate->factory()->undefined_value();
    1214             : }
    1215             : 
    1216             : 
    1217     9847588 : Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) {
    1218     9270916 :   for (; it->IsFound(); it->Next()) {
    1219     4582145 :     switch (it->state()) {
    1220             :       case LookupIterator::INTERCEPTOR:
    1221             :       case LookupIterator::NOT_FOUND:
    1222             :       case LookupIterator::TRANSITION:
    1223           0 :         UNREACHABLE();
    1224             :       case LookupIterator::ACCESS_CHECK:
    1225             :         // Support calling this method without an active context, but refuse
    1226             :         // access to access-checked objects in that case.
    1227      596643 :         if (!it->isolate()->context().is_null() && it->HasAccess()) continue;
    1228             :         V8_FALLTHROUGH;
    1229             :       case LookupIterator::JSPROXY:
    1230             :         it->NotFound();
    1231        3006 :         return it->isolate()->factory()->undefined_value();
    1232             :       case LookupIterator::ACCESSOR:
    1233             :         // TODO(verwaest): For now this doesn't call into AccessorInfo, since
    1234             :         // clients don't need it. Update once relevant.
    1235             :         it->NotFound();
    1236      519529 :         return it->isolate()->factory()->undefined_value();
    1237             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1238           0 :         return it->isolate()->factory()->undefined_value();
    1239             :       case LookupIterator::DATA:
    1240     3463791 :         return it->GetDataValue();
    1241             :     }
    1242             :   }
    1243       53313 :   return it->isolate()->factory()->undefined_value();
    1244             : }
    1245             : 
    1246             : 
    1247     7079606 : bool Object::ToInt32(int32_t* value) {
    1248     7079610 :   if (IsSmi()) {
    1249     7079439 :     *value = Smi::ToInt(*this);
    1250     7079439 :     return true;
    1251             :   }
    1252         171 :   if (IsHeapNumber()) {
    1253             :     double num = HeapNumber::cast(*this)->value();
    1254             :     // Check range before conversion to avoid undefined behavior.
    1255         135 :     if (num >= kMinInt && num <= kMaxInt && FastI2D(FastD2I(num)) == num) {
    1256           0 :       *value = FastD2I(num);
    1257           0 :       return true;
    1258             :     }
    1259             :   }
    1260             :   return false;
    1261             : }
    1262             : 
    1263             : // static constexpr object declarations need a definition to make the
    1264             : // compiler happy.
    1265             : constexpr Object Smi::kZero;
    1266             : constexpr Object SharedFunctionInfo::kNoSharedNameSentinel;
    1267             : 
    1268     3837926 : Handle<SharedFunctionInfo> FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(
    1269             :     Isolate* isolate, Handle<FunctionTemplateInfo> info,
    1270             :     MaybeHandle<Name> maybe_name) {
    1271     3837926 :   Object current_info = info->shared_function_info();
    1272     3837925 :   if (current_info->IsSharedFunctionInfo()) {
    1273             :     return handle(SharedFunctionInfo::cast(current_info), isolate);
    1274             :   }
    1275             :   Handle<Name> name;
    1276             :   Handle<String> name_string;
    1277    10946224 :   if (maybe_name.ToHandle(&name) && name->IsString()) {
    1278     3608634 :     name_string = Handle<String>::cast(name);
    1279      240628 :   } else if (info->class_name()->IsString()) {
    1280         468 :     name_string = handle(String::cast(info->class_name()), isolate);
    1281             :   } else {
    1282             :     name_string = isolate->factory()->empty_string();
    1283             :   }
    1284             :   FunctionKind function_kind;
    1285     3728948 :   if (info->remove_prototype()) {
    1286             :     function_kind = kConciseMethod;
    1287             :   } else {
    1288             :     function_kind = kNormalFunction;
    1289             :   }
    1290             :   Handle<SharedFunctionInfo> result =
    1291             :       isolate->factory()->NewSharedFunctionInfoForApiFunction(name_string, info,
    1292     7457894 :                                                               function_kind);
    1293             : 
    1294             :   result->set_length(info->length());
    1295             :   result->DontAdaptArguments();
    1296             :   DCHECK(result->IsApiFunction());
    1297             : 
    1298     7457898 :   info->set_shared_function_info(*result);
    1299     3728951 :   return result;
    1300             : }
    1301             : 
    1302       17779 : bool FunctionTemplateInfo::IsTemplateFor(Map map) {
    1303             :   // There is a constraint on the object; check.
    1304       17779 :   if (!map->IsJSObjectMap()) return false;
    1305             :   // Fetch the constructor function of the object.
    1306       17779 :   Object cons_obj = map->GetConstructor();
    1307       17779 :   Object type;
    1308       17779 :   if (cons_obj->IsJSFunction()) {
    1309       17765 :     JSFunction fun = JSFunction::cast(cons_obj);
    1310       35530 :     type = fun->shared()->function_data();
    1311          14 :   } else if (cons_obj->IsFunctionTemplateInfo()) {
    1312          14 :     type = FunctionTemplateInfo::cast(cons_obj);
    1313             :   } else {
    1314             :     return false;
    1315             :   }
    1316             :   // Iterate through the chain of inheriting function templates to
    1317             :   // see if the required one occurs.
    1318       18850 :   while (type->IsFunctionTemplateInfo()) {
    1319       11521 :     if (type == *this) return true;
    1320        1071 :     type = FunctionTemplateInfo::cast(type)->GetParentTemplate();
    1321             :   }
    1322             :   // Didn't find the required type in the inheritance chain.
    1323             :   return false;
    1324             : }
    1325             : 
    1326             : // static
    1327      620119 : FunctionTemplateRareData FunctionTemplateInfo::AllocateFunctionTemplateRareData(
    1328             :     Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info) {
    1329             :   DCHECK(function_template_info->rare_data()->IsUndefined(isolate));
    1330             :   Handle<Struct> struct_obj =
    1331      620119 :       isolate->factory()->NewStruct(FUNCTION_TEMPLATE_RARE_DATA_TYPE, TENURED);
    1332             :   Handle<FunctionTemplateRareData> rare_data =
    1333      620119 :       i::Handle<FunctionTemplateRareData>::cast(struct_obj);
    1334     1240238 :   function_template_info->set_rare_data(*rare_data);
    1335      620119 :   return *rare_data;
    1336             : }
    1337             : 
    1338             : // static
    1339      365846 : Handle<TemplateList> TemplateList::New(Isolate* isolate, int size) {
    1340             :   Handle<FixedArray> list =
    1341      365846 :       isolate->factory()->NewFixedArray(kLengthIndex + size);
    1342      365846 :   list->set(kLengthIndex, Smi::kZero);
    1343      365846 :   return Handle<TemplateList>::cast(list);
    1344             : }
    1345             : 
    1346             : // static
    1347     5952417 : Handle<TemplateList> TemplateList::Add(Isolate* isolate,
    1348             :                                        Handle<TemplateList> list,
    1349             :                                        Handle<i::Object> value) {
    1350             :   STATIC_ASSERT(kFirstElementIndex == 1);
    1351     5952417 :   int index = list->length() + 1;
    1352     5952417 :   Handle<i::FixedArray> fixed_array = Handle<FixedArray>::cast(list);
    1353     5952417 :   fixed_array = FixedArray::SetAndGrow(isolate, fixed_array, index, value);
    1354             :   fixed_array->set(kLengthIndex, Smi::FromInt(index));
    1355     5952417 :   return Handle<TemplateList>::cast(fixed_array);
    1356             : }
    1357             : 
    1358             : // static
    1359     2729088 : MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
    1360             :                                     Handle<JSReceiver> new_target,
    1361             :                                     Handle<AllocationSite> site) {
    1362             :   // If called through new, new.target can be:
    1363             :   // - a subclass of constructor,
    1364             :   // - a proxy wrapper around constructor, or
    1365             :   // - the constructor itself.
    1366             :   // If called through Reflect.construct, it's guaranteed to be a constructor.
    1367             :   Isolate* const isolate = constructor->GetIsolate();
    1368             :   DCHECK(constructor->IsConstructor());
    1369             :   DCHECK(new_target->IsConstructor());
    1370             :   DCHECK(!constructor->has_initial_map() ||
    1371             :          constructor->initial_map()->instance_type() != JS_FUNCTION_TYPE);
    1372             : 
    1373             :   Handle<Map> initial_map;
    1374     5458232 :   ASSIGN_RETURN_ON_EXCEPTION(
    1375             :       isolate, initial_map,
    1376             :       JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject);
    1377             :   Handle<JSObject> result =
    1378     2729040 :       isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site);
    1379     2729037 :   if (initial_map->is_dictionary_map()) {
    1380             :     Handle<NameDictionary> dictionary =
    1381           0 :         NameDictionary::New(isolate, NameDictionary::kInitialCapacity);
    1382           0 :     result->SetProperties(*dictionary);
    1383             :   }
    1384     2729037 :   isolate->counters()->constructed_objects()->Increment();
    1385     2729039 :   isolate->counters()->constructed_objects_runtime()->Increment();
    1386     2729038 :   return result;
    1387             : }
    1388             : 
    1389             : // 9.1.12 ObjectCreate ( proto [ , internalSlotsList ] )
    1390             : // Notice: This is NOT 19.1.2.2 Object.create ( O, Properties )
    1391      119997 : MaybeHandle<JSObject> JSObject::ObjectCreate(Isolate* isolate,
    1392             :                                              Handle<Object> prototype) {
    1393             :   // Generate the map with the specified {prototype} based on the Object
    1394             :   // function's initial map from the current native context.
    1395             :   // TODO(bmeurer): Use a dedicated cache for Object.create; think about
    1396             :   // slack tracking for Object.create.
    1397             :   Handle<Map> map =
    1398      119997 :       Map::GetObjectCreateMap(isolate, Handle<HeapObject>::cast(prototype));
    1399             : 
    1400             :   // Actually allocate the object.
    1401             :   Handle<JSObject> object;
    1402      119997 :   if (map->is_dictionary_map()) {
    1403         366 :     object = isolate->factory()->NewSlowJSObjectFromMap(map);
    1404             :   } else {
    1405      119631 :     object = isolate->factory()->NewJSObjectFromMap(map);
    1406             :   }
    1407      119997 :   return object;
    1408             : }
    1409             : 
    1410     5918908 : void JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
    1411             :   DCHECK(object->HasSmiOrObjectElements() ||
    1412             :          object->HasFastStringWrapperElements());
    1413    11837818 :   FixedArray raw_elems = FixedArray::cast(object->elements());
    1414             :   Heap* heap = object->GetHeap();
    1415    11823218 :   if (raw_elems->map() != ReadOnlyRoots(heap).fixed_cow_array_map()) return;
    1416             :   Isolate* isolate = heap->isolate();
    1417             :   Handle<FixedArray> elems(raw_elems, isolate);
    1418             :   Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap(
    1419       14596 :       elems, isolate->factory()->fixed_array_map());
    1420       29192 :   object->set_elements(*writable_elems);
    1421       14596 :   isolate->counters()->cow_arrays_converted()->Increment();
    1422             : }
    1423             : 
    1424     5859622 : int JSObject::GetHeaderSize(InstanceType type,
    1425             :                             bool function_has_prototype_slot) {
    1426     5859622 :   switch (type) {
    1427             :     case JS_OBJECT_TYPE:
    1428             :     case JS_API_OBJECT_TYPE:
    1429             :     case JS_SPECIAL_API_OBJECT_TYPE:
    1430             :       return JSObject::kHeaderSize;
    1431             :     case JS_GENERATOR_OBJECT_TYPE:
    1432        7263 :       return JSGeneratorObject::kSize;
    1433             :     case JS_ASYNC_FUNCTION_OBJECT_TYPE:
    1434           0 :       return JSAsyncFunctionObject::kSize;
    1435             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
    1436        1375 :       return JSAsyncGeneratorObject::kSize;
    1437             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
    1438           0 :       return JSAsyncFromSyncIterator::kSize;
    1439             :     case JS_GLOBAL_PROXY_TYPE:
    1440       54454 :       return JSGlobalProxy::kSize;
    1441             :     case JS_GLOBAL_OBJECT_TYPE:
    1442       55066 :       return JSGlobalObject::kSize;
    1443             :     case JS_BOUND_FUNCTION_TYPE:
    1444         838 :       return JSBoundFunction::kSize;
    1445             :     case JS_FUNCTION_TYPE:
    1446      469341 :       return JSFunction::GetHeaderSize(function_has_prototype_slot);
    1447             :     case JS_VALUE_TYPE:
    1448        6335 :       return JSValue::kSize;
    1449             :     case JS_DATE_TYPE:
    1450        1034 :       return JSDate::kSize;
    1451             :     case JS_ARRAY_TYPE:
    1452       61371 :       return JSArray::kSize;
    1453             :     case JS_ARRAY_BUFFER_TYPE:
    1454      904640 :       return JSArrayBuffer::kHeaderSize;
    1455             :     case JS_ARRAY_ITERATOR_TYPE:
    1456         189 :       return JSArrayIterator::kSize;
    1457             :     case JS_TYPED_ARRAY_TYPE:
    1458       11237 :       return JSTypedArray::kHeaderSize;
    1459             :     case JS_DATA_VIEW_TYPE:
    1460        8285 :       return JSDataView::kHeaderSize;
    1461             :     case JS_SET_TYPE:
    1462        1527 :       return JSSet::kSize;
    1463             :     case JS_MAP_TYPE:
    1464        1608 :       return JSMap::kSize;
    1465             :     case JS_SET_KEY_VALUE_ITERATOR_TYPE:
    1466             :     case JS_SET_VALUE_ITERATOR_TYPE:
    1467          63 :       return JSSetIterator::kSize;
    1468             :     case JS_MAP_KEY_ITERATOR_TYPE:
    1469             :     case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
    1470             :     case JS_MAP_VALUE_ITERATOR_TYPE:
    1471          45 :       return JSMapIterator::kSize;
    1472             :     case JS_WEAK_CELL_TYPE:
    1473           0 :       return JSWeakCell::kSize;
    1474             :     case JS_WEAK_REF_TYPE:
    1475           0 :       return JSWeakRef::kSize;
    1476             :     case JS_WEAK_FACTORY_TYPE:
    1477           0 :       return JSWeakFactory::kSize;
    1478             :     case JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE:
    1479           0 :       return JSWeakFactoryCleanupIterator::kSize;
    1480             :     case JS_WEAK_MAP_TYPE:
    1481        1344 :       return JSWeakMap::kSize;
    1482             :     case JS_WEAK_SET_TYPE:
    1483        1419 :       return JSWeakSet::kSize;
    1484             :     case JS_PROMISE_TYPE:
    1485         461 :       return JSPromise::kSize;
    1486             :     case JS_REGEXP_TYPE:
    1487        1352 :       return JSRegExp::kSize;
    1488             :     case JS_REGEXP_STRING_ITERATOR_TYPE:
    1489           0 :       return JSRegExpStringIterator::kSize;
    1490             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    1491             :       return JSObject::kHeaderSize;
    1492             :     case JS_MESSAGE_OBJECT_TYPE:
    1493           0 :       return JSMessageObject::kSize;
    1494             :     case JS_ARGUMENTS_TYPE:
    1495             :       return JSObject::kHeaderSize;
    1496             :     case JS_ERROR_TYPE:
    1497             :       return JSObject::kHeaderSize;
    1498             :     case JS_STRING_ITERATOR_TYPE:
    1499           0 :       return JSStringIterator::kSize;
    1500             :     case JS_MODULE_NAMESPACE_TYPE:
    1501         116 :       return JSModuleNamespace::kHeaderSize;
    1502             : #ifdef V8_INTL_SUPPORT
    1503             :     case JS_INTL_V8_BREAK_ITERATOR_TYPE:
    1504          18 :       return JSV8BreakIterator::kSize;
    1505             :     case JS_INTL_COLLATOR_TYPE:
    1506           0 :       return JSCollator::kSize;
    1507             :     case JS_INTL_DATE_TIME_FORMAT_TYPE:
    1508           0 :       return JSDateTimeFormat::kSize;
    1509             :     case JS_INTL_LIST_FORMAT_TYPE:
    1510          18 :       return JSListFormat::kSize;
    1511             :     case JS_INTL_LOCALE_TYPE:
    1512           0 :       return JSLocale::kSize;
    1513             :     case JS_INTL_NUMBER_FORMAT_TYPE:
    1514           0 :       return JSNumberFormat::kSize;
    1515             :     case JS_INTL_PLURAL_RULES_TYPE:
    1516           0 :       return JSPluralRules::kSize;
    1517             :     case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
    1518          18 :       return JSRelativeTimeFormat::kSize;
    1519             :     case JS_INTL_SEGMENT_ITERATOR_TYPE:
    1520           0 :       return JSSegmentIterator::kSize;
    1521             :     case JS_INTL_SEGMENTER_TYPE:
    1522          18 :       return JSSegmenter::kSize;
    1523             : #endif  // V8_INTL_SUPPORT
    1524             :     case WASM_GLOBAL_TYPE:
    1525           0 :       return WasmGlobalObject::kSize;
    1526             :     case WASM_INSTANCE_TYPE:
    1527           0 :       return WasmInstanceObject::kSize;
    1528             :     case WASM_MEMORY_TYPE:
    1529           0 :       return WasmMemoryObject::kSize;
    1530             :     case WASM_MODULE_TYPE:
    1531           0 :       return WasmModuleObject::kSize;
    1532             :     case WASM_TABLE_TYPE:
    1533           0 :       return WasmTableObject::kSize;
    1534             :     case WASM_EXCEPTION_TYPE:
    1535           0 :       return WasmExceptionObject::kSize;
    1536             :     default:
    1537           0 :       UNREACHABLE();
    1538             :   }
    1539             : }
    1540             : 
    1541             : // ES6 9.5.1
    1542             : // static
    1543     3716688 : MaybeHandle<Object> JSProxy::GetPrototype(Handle<JSProxy> proxy) {
    1544             :   Isolate* isolate = proxy->GetIsolate();
    1545             :   Handle<String> trap_name = isolate->factory()->getPrototypeOf_string();
    1546             : 
    1547     3716688 :   STACK_CHECK(isolate, MaybeHandle<Object>());
    1548             : 
    1549             :   // 1. Let handler be the value of the [[ProxyHandler]] internal slot.
    1550             :   // 2. If handler is null, throw a TypeError exception.
    1551             :   // 3. Assert: Type(handler) is Object.
    1552             :   // 4. Let target be the value of the [[ProxyTarget]] internal slot.
    1553     7433358 :   if (proxy->IsRevoked()) {
    1554          18 :     THROW_NEW_ERROR(isolate,
    1555             :                     NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
    1556             :                     Object);
    1557             :   }
    1558     7433322 :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    1559     7433322 :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    1560             : 
    1561             :   // 5. Let trap be ? GetMethod(handler, "getPrototypeOf").
    1562             :   Handle<Object> trap;
    1563     7433322 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, trap,
    1564             :                              Object::GetMethod(handler, trap_name), Object);
    1565             :   // 6. If trap is undefined, then return target.[[GetPrototypeOf]]().
    1566     7433322 :   if (trap->IsUndefined(isolate)) {
    1567     2794683 :     return JSReceiver::GetPrototype(isolate, target);
    1568             :   }
    1569             :   // 7. Let handlerProto be ? Call(trap, handler, «target»).
    1570             :   Handle<Object> argv[] = {target};
    1571             :   Handle<Object> handler_proto;
    1572     1843956 :   ASSIGN_RETURN_ON_EXCEPTION(
    1573             :       isolate, handler_proto,
    1574             :       Execution::Call(isolate, trap, handler, arraysize(argv), argv), Object);
    1575             :   // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError.
    1576     1843812 :   if (!(handler_proto->IsJSReceiver() || handler_proto->IsNull(isolate))) {
    1577           9 :     THROW_NEW_ERROR(isolate,
    1578             :                     NewTypeError(MessageTemplate::kProxyGetPrototypeOfInvalid),
    1579             :                     Object);
    1580             :   }
    1581             :   // 9. Let extensibleTarget be ? IsExtensible(target).
    1582      921870 :   Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
    1583      921870 :   MAYBE_RETURN_NULL(is_extensible);
    1584             :   // 10. If extensibleTarget is true, return handlerProto.
    1585      921870 :   if (is_extensible.FromJust()) return handler_proto;
    1586             :   // 11. Let targetProto be ? target.[[GetPrototypeOf]]().
    1587             :   Handle<Object> target_proto;
    1588           0 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, target_proto,
    1589             :                              JSReceiver::GetPrototype(isolate, target), Object);
    1590             :   // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError.
    1591           0 :   if (!handler_proto->SameValue(*target_proto)) {
    1592           0 :     THROW_NEW_ERROR(
    1593             :         isolate,
    1594             :         NewTypeError(MessageTemplate::kProxyGetPrototypeOfNonExtensible),
    1595             :         Object);
    1596             :   }
    1597             :   // 13. Return handlerProto.
    1598           0 :   return handler_proto;
    1599             : }
    1600             : 
    1601      918939 : MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
    1602             :   Isolate* isolate = it->isolate();
    1603      918939 :   Handle<Object> structure = it->GetAccessors();
    1604             :   Handle<Object> receiver = it->GetReceiver();
    1605             :   // In case of global IC, the receiver is the global object. Replace by the
    1606             :   // global proxy.
    1607     1837881 :   if (receiver->IsJSGlobalObject()) {
    1608        4072 :     receiver = handle(JSGlobalObject::cast(*receiver)->global_proxy(), isolate);
    1609             :   }
    1610             : 
    1611             :   // We should never get here to initialize a const with the hole value since a
    1612             :   // const declaration would conflict with the getter.
    1613             :   DCHECK(!structure->IsForeign());
    1614             : 
    1615             :   // API style callbacks.
    1616             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1617     1837881 :   if (structure->IsAccessorInfo()) {
    1618      641292 :     Handle<Name> name = it->GetName();
    1619      641292 :     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
    1620      641292 :     if (!info->IsCompatibleReceiver(*receiver)) {
    1621          90 :       THROW_NEW_ERROR(isolate,
    1622             :                       NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
    1623             :                                    name, receiver),
    1624             :                       Object);
    1625             :     }
    1626             : 
    1627     1282524 :     if (!info->has_getter()) return isolate->factory()->undefined_value();
    1628             : 
    1629      883853 :     if (info->is_sloppy() && !receiver->IsJSReceiver()) {
    1630          30 :       ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
    1631             :                                  Object::ConvertReceiver(isolate, receiver),
    1632             :                                  Object);
    1633             :     }
    1634             : 
    1635             :     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
    1636      641082 :                                    kDontThrow);
    1637      641081 :     Handle<Object> result = args.CallAccessorGetter(info, name);
    1638      641081 :     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1639      648803 :     if (result.is_null()) return isolate->factory()->undefined_value();
    1640             :     Handle<Object> reboxed_result = handle(*result, isolate);
    1641      632747 :     if (info->replace_on_access() && receiver->IsJSReceiver()) {
    1642          30 :       RETURN_ON_EXCEPTION(isolate,
    1643             :                           Accessors::ReplaceAccessorWithDataProperty(
    1644             :                               receiver, holder, name, result),
    1645             :                           Object);
    1646             :     }
    1647      632715 :     return reboxed_result;
    1648             :   }
    1649             : 
    1650             :   // AccessorPair with 'cached' private property.
    1651      277649 :   if (it->TryLookupCachedProperty()) {
    1652          44 :     return Object::GetProperty(it);
    1653             :   }
    1654             : 
    1655             :   // Regular accessor.
    1656      555210 :   Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate);
    1657      555210 :   if (getter->IsFunctionTemplateInfo()) {
    1658      113845 :     SaveContext save(isolate);
    1659      227690 :     isolate->set_context(*holder->GetCreationContext());
    1660             :     return Builtins::InvokeApiFunction(
    1661             :         isolate, false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0,
    1662      227690 :         nullptr, isolate->factory()->undefined_value());
    1663      327520 :   } else if (getter->IsCallable()) {
    1664             :     // TODO(rossberg): nicer would be to cast to some JSCallable here...
    1665             :     return Object::GetPropertyWithDefinedGetter(
    1666      159441 :         receiver, Handle<JSReceiver>::cast(getter));
    1667             :   }
    1668             :   // Getter is not a function.
    1669        4319 :   return isolate->factory()->undefined_value();
    1670             : }
    1671             : 
    1672             : // static
    1673           0 : Address AccessorInfo::redirect(Address address, AccessorComponent component) {
    1674             :   ApiFunction fun(address);
    1675             :   DCHECK_EQ(ACCESSOR_GETTER, component);
    1676             :   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
    1677      182134 :   return ExternalReference::Create(&fun, type).address();
    1678             : }
    1679             : 
    1680       92069 : Address AccessorInfo::redirected_getter() const {
    1681       92069 :   Address accessor = v8::ToCData<Address>(getter());
    1682       92069 :   if (accessor == kNullAddress) return kNullAddress;
    1683       91067 :   return redirect(accessor, ACCESSOR_GETTER);
    1684             : }
    1685             : 
    1686     3618461 : Address CallHandlerInfo::redirected_callback() const {
    1687     3618461 :   Address address = v8::ToCData<Address>(callback());
    1688             :   ApiFunction fun(address);
    1689             :   ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
    1690     7236925 :   return ExternalReference::Create(&fun, type).address();
    1691             : }
    1692             : 
    1693       97376 : bool AccessorInfo::IsCompatibleReceiverMap(Handle<AccessorInfo> info,
    1694             :                                            Handle<Map> map) {
    1695       97376 :   if (!info->HasExpectedReceiverType()) return true;
    1696          60 :   if (!map->IsJSObjectMap()) return false;
    1697         120 :   return FunctionTemplateInfo::cast(info->expected_receiver_type())
    1698          60 :       ->IsTemplateFor(*map);
    1699             : }
    1700             : 
    1701      490400 : Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
    1702             :                                             Handle<Object> value,
    1703             :                                             ShouldThrow should_throw) {
    1704             :   Isolate* isolate = it->isolate();
    1705      490400 :   Handle<Object> structure = it->GetAccessors();
    1706             :   Handle<Object> receiver = it->GetReceiver();
    1707             :   // In case of global IC, the receiver is the global object. Replace by the
    1708             :   // global proxy.
    1709      980800 :   if (receiver->IsJSGlobalObject()) {
    1710       15046 :     receiver = handle(JSGlobalObject::cast(*receiver)->global_proxy(), isolate);
    1711             :   }
    1712             : 
    1713             :   // We should never get here to initialize a const with the hole value since a
    1714             :   // const declaration would conflict with the setter.
    1715             :   DCHECK(!structure->IsForeign());
    1716             : 
    1717             :   // API style callbacks.
    1718             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1719      980800 :   if (structure->IsAccessorInfo()) {
    1720      247822 :     Handle<Name> name = it->GetName();
    1721      247822 :     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
    1722      247822 :     if (!info->IsCompatibleReceiver(*receiver)) {
    1723             :       isolate->Throw(*isolate->factory()->NewTypeError(
    1724         180 :           MessageTemplate::kIncompatibleMethodReceiver, name, receiver));
    1725             :       return Nothing<bool>();
    1726             :     }
    1727             : 
    1728      495464 :     if (!info->has_setter()) {
    1729             :       // TODO(verwaest): We should not get here anymore once all AccessorInfos
    1730             :       // are marked as special_data_property. They cannot both be writable and
    1731             :       // not have a setter.
    1732             :       return Just(true);
    1733             :     }
    1734             : 
    1735      489100 :     if (info->is_sloppy() && !receiver->IsJSReceiver()) {
    1736           0 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1737             :           isolate, receiver, Object::ConvertReceiver(isolate, receiver),
    1738             :           Nothing<bool>());
    1739             :     }
    1740             : 
    1741             :     // The actual type of setter callback is either
    1742             :     // v8::AccessorNameSetterCallback or
    1743             :     // i::Accesors::AccessorNameBooleanSetterCallback, depending on whether the
    1744             :     // AccessorInfo was created by the API or internally (see accessors.cc).
    1745             :     // Here we handle both cases using GenericNamedPropertySetterCallback and
    1746             :     // its Call method.
    1747             :     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
    1748      247666 :                                    should_throw);
    1749      247666 :     Handle<Object> result = args.CallAccessorSetter(info, name, value);
    1750             :     // In the case of AccessorNameSetterCallback, we know that the result value
    1751             :     // cannot have been set, so the result of Call will be null.  In the case of
    1752             :     // AccessorNameBooleanSetterCallback, the result will either be null
    1753             :     // (signalling an exception) or a boolean Oddball.
    1754      247666 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    1755      247447 :     if (result.is_null()) return Just(true);
    1756             :     DCHECK(result->BooleanValue(isolate) || should_throw == kDontThrow);
    1757      253602 :     return Just(result->BooleanValue(isolate));
    1758             :   }
    1759             : 
    1760             :   // Regular accessor.
    1761      485156 :   Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
    1762      485156 :   if (setter->IsFunctionTemplateInfo()) {
    1763         657 :     SaveContext save(isolate);
    1764        1314 :     isolate->set_context(*holder->GetCreationContext());
    1765         657 :     Handle<Object> argv[] = {value};
    1766        1971 :     RETURN_ON_EXCEPTION_VALUE(
    1767             :         isolate, Builtins::InvokeApiFunction(
    1768             :                      isolate, false, Handle<FunctionTemplateInfo>::cast(setter),
    1769             :                      receiver, arraysize(argv), argv,
    1770             :                      isolate->factory()->undefined_value()),
    1771             :         Nothing<bool>());
    1772         657 :     return Just(true);
    1773      483842 :   } else if (setter->IsCallable()) {
    1774             :     // TODO(rossberg): nicer would be to cast to some JSCallable here...
    1775             :     return SetPropertyWithDefinedSetter(
    1776      230308 :         receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
    1777             :   }
    1778             : 
    1779       28866 :   RETURN_FAILURE(isolate, should_throw,
    1780             :                  NewTypeError(MessageTemplate::kNoSetterInCallback,
    1781             :                               it->GetName(), it->GetHolder<JSObject>()));
    1782             : }
    1783             : 
    1784             : 
    1785      159441 : MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
    1786             :     Handle<Object> receiver,
    1787             :     Handle<JSReceiver> getter) {
    1788             :   Isolate* isolate = getter->GetIsolate();
    1789             : 
    1790             :   // Platforms with simulators like arm/arm64 expose a funny issue. If the
    1791             :   // simulator has a separate JS stack pointer from the C++ stack pointer, it
    1792             :   // can miss C++ stack overflows in the stack guard at the start of JavaScript
    1793             :   // functions. It would be very expensive to check the C++ stack pointer at
    1794             :   // that location. The best solution seems to be to break the impasse by
    1795             :   // adding checks at possible recursion points. What's more, we don't put
    1796             :   // this stack check behind the USE_SIMULATOR define in order to keep
    1797             :   // behavior the same between hardware and simulators.
    1798             :   StackLimitCheck check(isolate);
    1799      159441 :   if (check.JsHasOverflowed()) {
    1800          10 :     isolate->StackOverflow();
    1801          10 :     return MaybeHandle<Object>();
    1802             :   }
    1803             : 
    1804      159431 :   return Execution::Call(isolate, getter, receiver, 0, nullptr);
    1805             : }
    1806             : 
    1807             : 
    1808      230308 : Maybe<bool> Object::SetPropertyWithDefinedSetter(Handle<Object> receiver,
    1809             :                                                  Handle<JSReceiver> setter,
    1810             :                                                  Handle<Object> value,
    1811             :                                                  ShouldThrow should_throw) {
    1812             :   Isolate* isolate = setter->GetIsolate();
    1813             : 
    1814      230308 :   Handle<Object> argv[] = { value };
    1815      460616 :   RETURN_ON_EXCEPTION_VALUE(isolate, Execution::Call(isolate, setter, receiver,
    1816             :                                                      arraysize(argv), argv),
    1817             :                             Nothing<bool>());
    1818             :   return Just(true);
    1819             : }
    1820             : 
    1821             : 
    1822             : // static
    1823        3636 : bool JSObject::AllCanRead(LookupIterator* it) {
    1824             :   // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
    1825             :   // which have already been checked.
    1826             :   DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
    1827             :          it->state() == LookupIterator::INTERCEPTOR);
    1828        4802 :   for (it->Next(); it->IsFound(); it->Next()) {
    1829        1236 :     if (it->state() == LookupIterator::ACCESSOR) {
    1830         122 :       auto accessors = it->GetAccessors();
    1831         244 :       if (accessors->IsAccessorInfo()) {
    1832          77 :         if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
    1833             :       }
    1834        1114 :     } else if (it->state() == LookupIterator::INTERCEPTOR) {
    1835        1260 :       if (it->GetInterceptor()->all_can_read()) return true;
    1836         484 :     } else if (it->state() == LookupIterator::JSPROXY) {
    1837             :       // Stop lookupiterating. And no, AllCanNotRead.
    1838             :       return false;
    1839             :     }
    1840             :   }
    1841             :   return false;
    1842             : }
    1843             : 
    1844             : namespace {
    1845             : 
    1846      114228 : MaybeHandle<Object> GetPropertyWithInterceptorInternal(
    1847      228068 :     LookupIterator* it, Handle<InterceptorInfo> interceptor, bool* done) {
    1848      114228 :   *done = false;
    1849             :   Isolate* isolate = it->isolate();
    1850             :   // Make sure that the top context does not change when doing callbacks or
    1851             :   // interceptor calls.
    1852             :   AssertNoContextChange ncc(isolate);
    1853             : 
    1854      228456 :   if (interceptor->getter()->IsUndefined(isolate)) {
    1855         388 :     return isolate->factory()->undefined_value();
    1856             :   }
    1857             : 
    1858             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1859             :   Handle<Object> result;
    1860             :   Handle<Object> receiver = it->GetReceiver();
    1861      227680 :   if (!receiver->IsJSReceiver()) {
    1862          32 :     ASSIGN_RETURN_ON_EXCEPTION(
    1863             :         isolate, receiver, Object::ConvertReceiver(isolate, receiver), Object);
    1864             :   }
    1865             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1866      113840 :                                  *holder, kDontThrow);
    1867             : 
    1868      113840 :   if (it->IsElement()) {
    1869        2350 :     result = args.CallIndexedGetter(interceptor, it->index());
    1870             :   } else {
    1871      111490 :     result = args.CallNamedGetter(interceptor, it->name());
    1872             :   }
    1873             : 
    1874      113840 :   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1875      224365 :   if (result.is_null()) return isolate->factory()->undefined_value();
    1876        3259 :   *done = true;
    1877             :   // Rebox handle before return
    1878        3259 :   return handle(*result, isolate);
    1879             : }
    1880             : 
    1881      250398 : Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptorInternal(
    1882      500676 :     LookupIterator* it, Handle<InterceptorInfo> interceptor) {
    1883             :   Isolate* isolate = it->isolate();
    1884             :   // Make sure that the top context does not change when doing
    1885             :   // callbacks or interceptor calls.
    1886             :   AssertNoContextChange ncc(isolate);
    1887             :   HandleScope scope(isolate);
    1888             : 
    1889             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1890             :   DCHECK_IMPLIES(!it->IsElement() && it->name()->IsSymbol(),
    1891             :                  interceptor->can_intercept_symbols());
    1892             :   Handle<Object> receiver = it->GetReceiver();
    1893      500796 :   if (!receiver->IsJSReceiver()) {
    1894          24 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1895             :                                      Object::ConvertReceiver(isolate, receiver),
    1896             :                                      Nothing<PropertyAttributes>());
    1897             :   }
    1898             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1899      250398 :                                  *holder, kDontThrow);
    1900      500796 :   if (!interceptor->query()->IsUndefined(isolate)) {
    1901             :     Handle<Object> result;
    1902         560 :     if (it->IsElement()) {
    1903         315 :       result = args.CallIndexedQuery(interceptor, it->index());
    1904             :     } else {
    1905         245 :       result = args.CallNamedQuery(interceptor, it->name());
    1906             :     }
    1907         560 :     if (!result.is_null()) {
    1908             :       int32_t value;
    1909         370 :       CHECK(result->ToInt32(&value));
    1910         370 :       return Just(static_cast<PropertyAttributes>(value));
    1911             :     }
    1912      499676 :   } else if (!interceptor->getter()->IsUndefined(isolate)) {
    1913             :     // TODO(verwaest): Use GetPropertyWithInterceptor?
    1914             :     Handle<Object> result;
    1915      249718 :     if (it->IsElement()) {
    1916      240203 :       result = args.CallIndexedGetter(interceptor, it->index());
    1917             :     } else {
    1918        9515 :       result = args.CallNamedGetter(interceptor, it->name());
    1919             :     }
    1920      249718 :     if (!result.is_null()) return Just(DONT_ENUM);
    1921             :   }
    1922             : 
    1923      240613 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
    1924             :   return Just(ABSENT);
    1925             : }
    1926             : 
    1927      193369 : Maybe<bool> SetPropertyWithInterceptorInternal(
    1928      566347 :     LookupIterator* it, Handle<InterceptorInfo> interceptor,
    1929             :     ShouldThrow should_throw, Handle<Object> value) {
    1930             :   Isolate* isolate = it->isolate();
    1931             :   // Make sure that the top context does not change when doing callbacks or
    1932             :   // interceptor calls.
    1933             :   AssertNoContextChange ncc(isolate);
    1934             : 
    1935      386738 :   if (interceptor->setter()->IsUndefined(isolate)) return Just(false);
    1936             : 
    1937             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1938             :   bool result;
    1939             :   Handle<Object> receiver = it->GetReceiver();
    1940      372978 :   if (!receiver->IsJSReceiver()) {
    1941           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1942             :                                      Object::ConvertReceiver(isolate, receiver),
    1943             :                                      Nothing<bool>());
    1944             :   }
    1945             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1946      186489 :                                  *holder, should_throw);
    1947             : 
    1948      186489 :   if (it->IsElement()) {
    1949             :     // TODO(neis): In the future, we may want to actually return the
    1950             :     // interceptor's result, which then should be a boolean.
    1951      131338 :     result = !args.CallIndexedSetter(interceptor, it->index(), value).is_null();
    1952             :   } else {
    1953      241640 :     result = !args.CallNamedSetter(interceptor, it->name(), value).is_null();
    1954             :   }
    1955             : 
    1956      186489 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    1957             :   return Just(result);
    1958             : }
    1959             : 
    1960         183 : Maybe<bool> DefinePropertyWithInterceptorInternal(
    1961         357 :     LookupIterator* it, Handle<InterceptorInfo> interceptor,
    1962             :     ShouldThrow should_throw, PropertyDescriptor& desc) {
    1963             :   Isolate* isolate = it->isolate();
    1964             :   // Make sure that the top context does not change when doing callbacks or
    1965             :   // interceptor calls.
    1966             :   AssertNoContextChange ncc(isolate);
    1967             : 
    1968         366 :   if (interceptor->definer()->IsUndefined(isolate)) return Just(false);
    1969             : 
    1970             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1971             :   bool result;
    1972             :   Handle<Object> receiver = it->GetReceiver();
    1973         174 :   if (!receiver->IsJSReceiver()) {
    1974           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1975             :                                      Object::ConvertReceiver(isolate, receiver),
    1976             :                                      Nothing<bool>());
    1977             :   }
    1978             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1979          87 :                                  *holder, should_throw);
    1980             : 
    1981             :   std::unique_ptr<v8::PropertyDescriptor> descriptor(
    1982          87 :       new v8::PropertyDescriptor());
    1983          87 :   if (PropertyDescriptor::IsAccessorDescriptor(&desc)) {
    1984             :     descriptor.reset(new v8::PropertyDescriptor(
    1985          66 :         v8::Utils::ToLocal(desc.get()), v8::Utils::ToLocal(desc.set())));
    1986          54 :   } else if (PropertyDescriptor::IsDataDescriptor(&desc)) {
    1987          44 :     if (desc.has_writable()) {
    1988             :       descriptor.reset(new v8::PropertyDescriptor(
    1989          18 :           v8::Utils::ToLocal(desc.value()), desc.writable()));
    1990             :     } else {
    1991             :       descriptor.reset(
    1992          76 :           new v8::PropertyDescriptor(v8::Utils::ToLocal(desc.value())));
    1993             :     }
    1994             :   }
    1995          87 :   if (desc.has_enumerable()) {
    1996          12 :     descriptor->set_enumerable(desc.enumerable());
    1997             :   }
    1998          87 :   if (desc.has_configurable()) {
    1999          12 :     descriptor->set_configurable(desc.configurable());
    2000             :   }
    2001             : 
    2002          87 :   if (it->IsElement()) {
    2003             :     result = !args.CallIndexedDefiner(interceptor, it->index(), *descriptor)
    2004          48 :                   .is_null();
    2005             :   } else {
    2006             :     result =
    2007         126 :         !args.CallNamedDefiner(interceptor, it->name(), *descriptor).is_null();
    2008             :   }
    2009             : 
    2010          87 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    2011             :   return Just(result);
    2012             : }
    2013             : 
    2014             : }  // namespace
    2015             : 
    2016        1169 : MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
    2017        1267 :     LookupIterator* it) {
    2018             :   Isolate* isolate = it->isolate();
    2019        1169 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    2020             :   Handle<InterceptorInfo> interceptor =
    2021        1169 :       it->GetInterceptorForFailedAccessCheck();
    2022        1169 :   if (interceptor.is_null()) {
    2023        1064 :     while (AllCanRead(it)) {
    2024          46 :       if (it->state() == LookupIterator::ACCESSOR) {
    2025          52 :         return Object::GetPropertyWithAccessor(it);
    2026             :       }
    2027             :       DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    2028             :       bool done;
    2029             :       Handle<Object> result;
    2030          60 :       ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
    2031             :                                  GetPropertyWithInterceptor(it, &done), Object);
    2032          30 :       if (done) return result;
    2033             :     }
    2034             : 
    2035             :   } else {
    2036             :     Handle<Object> result;
    2037             :     bool done;
    2038         230 :     ASSIGN_RETURN_ON_EXCEPTION(
    2039             :         isolate, result,
    2040             :         GetPropertyWithInterceptorInternal(it, interceptor, &done), Object);
    2041         105 :     if (done) return result;
    2042             :   }
    2043             : 
    2044             :   // Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns
    2045             :   // undefined.
    2046        1078 :   Handle<Name> name = it->GetName();
    2047        2213 :   if (name->IsSymbol() && Symbol::cast(*name)->is_well_known_symbol()) {
    2048          52 :     return it->factory()->undefined_value();
    2049             :   }
    2050             : 
    2051        1026 :   isolate->ReportFailedAccessCheck(checked);
    2052        1026 :   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    2053           0 :   return it->factory()->undefined_value();
    2054             : }
    2055             : 
    2056             : 
    2057         121 : Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
    2058         131 :     LookupIterator* it) {
    2059             :   Isolate* isolate = it->isolate();
    2060         121 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    2061             :   Handle<InterceptorInfo> interceptor =
    2062         121 :       it->GetInterceptorForFailedAccessCheck();
    2063         121 :   if (interceptor.is_null()) {
    2064         121 :     while (AllCanRead(it)) {
    2065          10 :       if (it->state() == LookupIterator::ACCESSOR) {
    2066             :         return Just(it->property_attributes());
    2067             :       }
    2068             :       DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    2069           0 :       auto result = GetPropertyAttributesWithInterceptor(it);
    2070           0 :       if (isolate->has_scheduled_exception()) break;
    2071           0 :       if (result.IsJust() && result.FromJust() != ABSENT) return result;
    2072             :     }
    2073             :   } else {
    2074             :     Maybe<PropertyAttributes> result =
    2075           0 :         GetPropertyAttributesWithInterceptorInternal(it, interceptor);
    2076           0 :     if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>();
    2077           0 :     if (result.FromMaybe(ABSENT) != ABSENT) return result;
    2078             :   }
    2079         111 :   isolate->ReportFailedAccessCheck(checked);
    2080         111 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
    2081             :   return Just(ABSENT);
    2082             : }
    2083             : 
    2084             : 
    2085             : // static
    2086         269 : bool JSObject::AllCanWrite(LookupIterator* it) {
    2087         382 :   for (; it->IsFound() && it->state() != LookupIterator::JSPROXY; it->Next()) {
    2088         123 :     if (it->state() == LookupIterator::ACCESSOR) {
    2089          25 :       Handle<Object> accessors = it->GetAccessors();
    2090          50 :       if (accessors->IsAccessorInfo()) {
    2091          15 :         if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
    2092             :       }
    2093             :     }
    2094             :   }
    2095             :   return false;
    2096             : }
    2097             : 
    2098             : 
    2099         108 : Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck(
    2100         108 :     LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) {
    2101             :   Isolate* isolate = it->isolate();
    2102         108 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    2103             :   Handle<InterceptorInfo> interceptor =
    2104         108 :       it->GetInterceptorForFailedAccessCheck();
    2105         108 :   if (interceptor.is_null()) {
    2106          78 :     if (AllCanWrite(it)) {
    2107          10 :       return Object::SetPropertyWithAccessor(it, value, should_throw);
    2108             :     }
    2109             :   } else {
    2110             :     Maybe<bool> result = SetPropertyWithInterceptorInternal(
    2111          30 :         it, interceptor, should_throw, value);
    2112          60 :     if (isolate->has_pending_exception()) return Nothing<bool>();
    2113          20 :     if (result.IsJust()) return result;
    2114             :   }
    2115          68 :   isolate->ReportFailedAccessCheck(checked);
    2116          68 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    2117             :   return Just(true);
    2118             : }
    2119             : 
    2120             : 
    2121      336337 : void JSObject::SetNormalizedProperty(Handle<JSObject> object,
    2122             :                                      Handle<Name> name,
    2123             :                                      Handle<Object> value,
    2124             :                                      PropertyDetails details) {
    2125             :   DCHECK(!object->HasFastProperties());
    2126             :   DCHECK(name->IsUniqueName());
    2127             :   Isolate* isolate = object->GetIsolate();
    2128             : 
    2129      336337 :   uint32_t hash = name->Hash();
    2130             : 
    2131      672674 :   if (object->IsJSGlobalObject()) {
    2132        9621 :     Handle<JSGlobalObject> global_obj = Handle<JSGlobalObject>::cast(object);
    2133             :     Handle<GlobalDictionary> dictionary(global_obj->global_dictionary(),
    2134       19242 :                                         isolate);
    2135       19242 :     int entry = dictionary->FindEntry(ReadOnlyRoots(isolate), name, hash);
    2136             : 
    2137        9621 :     if (entry == GlobalDictionary::kNotFound) {
    2138             :       DCHECK_IMPLIES(global_obj->map()->is_prototype_map(),
    2139             :                      Map::IsPrototypeChainInvalidated(global_obj->map()));
    2140        1014 :       auto cell = isolate->factory()->NewPropertyCell(name);
    2141        1014 :       cell->set_value(*value);
    2142        2028 :       auto cell_type = value->IsUndefined(isolate)
    2143             :                            ? PropertyCellType::kUndefined
    2144        1014 :                            : PropertyCellType::kConstant;
    2145             :       details = details.set_cell_type(cell_type);
    2146             :       value = cell;
    2147             :       dictionary =
    2148        1014 :           GlobalDictionary::Add(isolate, dictionary, name, value, details);
    2149        2028 :       global_obj->set_global_dictionary(*dictionary);
    2150             :     } else {
    2151             :       Handle<PropertyCell> cell = PropertyCell::PrepareForValue(
    2152        8607 :           isolate, dictionary, entry, value, details);
    2153        8607 :       cell->set_value(*value);
    2154             :     }
    2155             :   } else {
    2156      653432 :     Handle<NameDictionary> dictionary(object->property_dictionary(), isolate);
    2157             : 
    2158      326716 :     int entry = dictionary->FindEntry(isolate, name);
    2159      326716 :     if (entry == NameDictionary::kNotFound) {
    2160             :       DCHECK_IMPLIES(object->map()->is_prototype_map(),
    2161             :                      Map::IsPrototypeChainInvalidated(object->map()));
    2162             :       dictionary =
    2163       96519 :           NameDictionary::Add(isolate, dictionary, name, value, details);
    2164      193038 :       object->SetProperties(*dictionary);
    2165             :     } else {
    2166      230197 :       PropertyDetails original_details = dictionary->DetailsAt(entry);
    2167             :       int enumeration_index = original_details.dictionary_index();
    2168             :       DCHECK_GT(enumeration_index, 0);
    2169             :       details = details.set_index(enumeration_index);
    2170      460394 :       dictionary->SetEntry(isolate, entry, *name, *value, details);
    2171             :     }
    2172             :   }
    2173      336337 : }
    2174             : 
    2175             : // static
    2176        1287 : Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate,
    2177             :                                             Handle<JSReceiver> object,
    2178             :                                             Handle<Object> proto) {
    2179        1287 :   PrototypeIterator iter(isolate, object, kStartAtReceiver);
    2180             :   while (true) {
    2181     3688849 :     if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
    2182     3688741 :     if (iter.IsAtEnd()) return Just(false);
    2183     3687949 :     if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) {
    2184             :       return Just(true);
    2185             :     }
    2186             :   }
    2187             : }
    2188             : 
    2189             : namespace {
    2190             : 
    2191         519 : bool HasExcludedProperty(
    2192             :     const ScopedVector<Handle<Object>>* excluded_properties,
    2193             :     Handle<Object> search_element) {
    2194             :   // TODO(gsathya): Change this to be a hashtable.
    2195        1590 :   for (int i = 0; i < excluded_properties->length(); i++) {
    2196        1689 :     if (search_element->SameValue(*excluded_properties->at(i))) {
    2197             :       return true;
    2198             :     }
    2199             :   }
    2200             : 
    2201             :   return false;
    2202             : }
    2203             : 
    2204         752 : V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign(
    2205             :     Handle<JSReceiver> target, Handle<Object> source,
    2206             :     const ScopedVector<Handle<Object>>* excluded_properties, bool use_set) {
    2207             :   // Non-empty strings are the only non-JSReceivers that need to be handled
    2208             :   // explicitly by Object.assign.
    2209        1504 :   if (!source->IsJSReceiver()) {
    2210          36 :     return Just(!source->IsString() || String::cast(*source)->length() == 0);
    2211             :   }
    2212             : 
    2213             :   // If the target is deprecated, the object will be updated on first store. If
    2214             :   // the source for that store equals the target, this will invalidate the
    2215             :   // cached representation of the source. Preventively upgrade the target.
    2216             :   // Do this on each iteration since any property load could cause deprecation.
    2217         743 :   if (target->map()->is_deprecated()) {
    2218          18 :     JSObject::MigrateInstance(Handle<JSObject>::cast(target));
    2219             :   }
    2220             : 
    2221             :   Isolate* isolate = target->GetIsolate();
    2222             :   Handle<Map> map(JSReceiver::cast(*source)->map(), isolate);
    2223             : 
    2224         743 :   if (!map->IsJSObjectMap()) return Just(false);
    2225         635 :   if (!map->OnlyHasSimpleProperties()) return Just(false);
    2226             : 
    2227         446 :   Handle<JSObject> from = Handle<JSObject>::cast(source);
    2228         892 :   if (from->elements() != ReadOnlyRoots(isolate).empty_fixed_array()) {
    2229             :     return Just(false);
    2230             :   }
    2231             : 
    2232         694 :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    2233             :   int length = map->NumberOfOwnDescriptors();
    2234             : 
    2235             :   bool stable = true;
    2236             : 
    2237         866 :   for (int i = 0; i < length; i++) {
    2238        1038 :     Handle<Name> next_key(descriptors->GetKey(i), isolate);
    2239             :     Handle<Object> prop_value;
    2240             :     // Directly decode from the descriptor array if |from| did not change shape.
    2241         519 :     if (stable) {
    2242         519 :       PropertyDetails details = descriptors->GetDetails(i);
    2243         519 :       if (!details.IsEnumerable()) continue;
    2244         492 :       if (details.kind() == kData) {
    2245         492 :         if (details.location() == kDescriptor) {
    2246           0 :           prop_value = handle(descriptors->GetStrongValue(i), isolate);
    2247             :         } else {
    2248         492 :           Representation representation = details.representation();
    2249         492 :           FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    2250         492 :           prop_value = JSObject::FastPropertyAt(from, representation, index);
    2251             :         }
    2252             :       } else {
    2253           0 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2254             :             isolate, prop_value,
    2255             :             JSReceiver::GetProperty(isolate, from, next_key), Nothing<bool>());
    2256             :         stable = from->map() == *map;
    2257             :       }
    2258             :     } else {
    2259             :       // If the map did change, do a slower lookup. We are still guaranteed that
    2260             :       // the object has a simple shape, and that the key is a name.
    2261             :       LookupIterator it(from, next_key, from,
    2262           0 :                         LookupIterator::OWN_SKIP_INTERCEPTOR);
    2263           0 :       if (!it.IsFound()) continue;
    2264             :       DCHECK(it.state() == LookupIterator::DATA ||
    2265             :              it.state() == LookupIterator::ACCESSOR);
    2266           0 :       if (!it.IsEnumerable()) continue;
    2267           0 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2268             :           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
    2269             :     }
    2270             : 
    2271         492 :     if (use_set) {
    2272          36 :       LookupIterator it(target, next_key, target);
    2273             :       Maybe<bool> result = Object::SetProperty(
    2274          36 :           &it, prop_value, LanguageMode::kStrict, StoreOrigin::kNamed);
    2275          36 :       if (result.IsNothing()) return result;
    2276          36 :       if (stable) stable = from->map() == *map;
    2277             :     } else {
    2278        1368 :       if (excluded_properties != nullptr &&
    2279        1080 :           HasExcludedProperty(excluded_properties, next_key)) {
    2280          99 :         continue;
    2281             :       }
    2282             : 
    2283             :       // 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue).
    2284             :       bool success;
    2285             :       LookupIterator it = LookupIterator::PropertyOrElement(
    2286         357 :           isolate, target, next_key, &success, LookupIterator::OWN);
    2287         357 :       CHECK(success);
    2288         714 :       CHECK(JSObject::CreateDataProperty(&it, prop_value, kThrowOnError)
    2289             :                 .FromJust());
    2290             :     }
    2291             :   }
    2292             : 
    2293             :   return Just(true);
    2294             : }
    2295             : }  // namespace
    2296             : 
    2297             : // static
    2298         752 : Maybe<bool> JSReceiver::SetOrCopyDataProperties(
    2299             :     Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
    2300             :     const ScopedVector<Handle<Object>>* excluded_properties, bool use_set) {
    2301             :   Maybe<bool> fast_assign =
    2302         752 :       FastAssign(target, source, excluded_properties, use_set);
    2303         752 :   if (fast_assign.IsNothing()) return Nothing<bool>();
    2304         752 :   if (fast_assign.FromJust()) return Just(true);
    2305             : 
    2306         810 :   Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked();
    2307             :   // 3b. Let keys be ? from.[[OwnPropertyKeys]]().
    2308             :   Handle<FixedArray> keys;
    2309         810 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2310             :       isolate, keys,
    2311             :       KeyAccumulator::GetKeys(from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
    2312             :                               GetKeysConversion::kKeepNumbers),
    2313             :       Nothing<bool>());
    2314             : 
    2315             :   // 4. Repeat for each element nextKey of keys in List order,
    2316        3807 :   for (int j = 0; j < keys->length(); ++j) {
    2317             :     Handle<Object> next_key(keys->get(j), isolate);
    2318             :     // 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey).
    2319             :     PropertyDescriptor desc;
    2320             :     Maybe<bool> found =
    2321        1791 :         JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc);
    2322        1854 :     if (found.IsNothing()) return Nothing<bool>();
    2323             :     // 4a ii. If desc is not undefined and desc.[[Enumerable]] is true, then
    2324        3510 :     if (found.FromJust() && desc.enumerable()) {
    2325             :       // 4a ii 1. Let propValue be ? Get(from, nextKey).
    2326             :       Handle<Object> prop_value;
    2327        2241 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2328             :           isolate, prop_value,
    2329             :           Runtime::GetObjectProperty(isolate, from, next_key), Nothing<bool>());
    2330             : 
    2331        1080 :       if (use_set) {
    2332             :         // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true).
    2333             :         Handle<Object> status;
    2334        1422 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2335             :             isolate, status,
    2336             :             Runtime::SetObjectProperty(isolate, target, next_key, prop_value,
    2337             :                                        LanguageMode::kStrict,
    2338             :                                        StoreOrigin::kMaybeKeyed),
    2339             :             Nothing<bool>());
    2340             :       } else {
    2341         576 :         if (excluded_properties != nullptr &&
    2342         207 :             HasExcludedProperty(excluded_properties, next_key)) {
    2343          72 :           continue;
    2344             :         }
    2345             : 
    2346             :         // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue).
    2347             :         bool success;
    2348             :         LookupIterator it = LookupIterator::PropertyOrElement(
    2349         297 :             isolate, target, next_key, &success, LookupIterator::OWN);
    2350         297 :         CHECK(success);
    2351         594 :         CHECK(JSObject::CreateDataProperty(&it, prop_value, kThrowOnError)
    2352             :                   .FromJust());
    2353             :       }
    2354             :     }
    2355             :   }
    2356             : 
    2357             :   return Just(true);
    2358             : }
    2359             : 
    2360      368432 : Map Object::GetPrototypeChainRootMap(Isolate* isolate) const {
    2361             :   DisallowHeapAllocation no_alloc;
    2362      368433 :   if (IsSmi()) {
    2363       25625 :     Context native_context = isolate->context()->native_context();
    2364       25625 :     return native_context->number_function()->initial_map();
    2365             :   }
    2366             : 
    2367             :   const HeapObject heap_object = HeapObject::cast(*this);
    2368      342808 :   return heap_object->map()->GetPrototypeChainRootMap(isolate);
    2369             : }
    2370             : 
    2371     3703553 : Map Map::GetPrototypeChainRootMap(Isolate* isolate) const {
    2372             :   DisallowHeapAllocation no_alloc;
    2373     3703553 :   if (IsJSReceiverMap()) {
    2374     3325530 :     return *this;
    2375             :   }
    2376             :   int constructor_function_index = GetConstructorFunctionIndex();
    2377      378023 :   if (constructor_function_index != Map::kNoConstructorFunctionIndex) {
    2378      378023 :     Context native_context = isolate->context()->native_context();
    2379             :     JSFunction constructor_function =
    2380      378025 :         JSFunction::cast(native_context->get(constructor_function_index));
    2381      378025 :     return constructor_function->initial_map();
    2382             :   }
    2383             :   return ReadOnlyRoots(isolate).null_value()->map();
    2384             : }
    2385             : 
    2386    10165765 : Smi Object::GetOrCreateHash(Isolate* isolate) {
    2387             :   DisallowHeapAllocation no_gc;
    2388    10165765 :   Object hash = Object::GetSimpleHash(*this);
    2389    10165765 :   if (hash->IsSmi()) return Smi::cast(hash);
    2390             : 
    2391             :   DCHECK(IsJSReceiver());
    2392       20374 :   return JSReceiver::cast(*this)->GetOrCreateIdentityHash(isolate);
    2393             : }
    2394             : 
    2395      802521 : bool Object::SameValue(Object other) {
    2396      802521 :   if (other == *this) return true;
    2397             : 
    2398      174382 :   if (IsNumber() && other->IsNumber()) {
    2399       21292 :     double this_value = Number();
    2400       21292 :     double other_value = other->Number();
    2401             :     // SameValue(NaN, NaN) is true.
    2402       21292 :     if (this_value != other_value) {
    2403       18865 :       return std::isnan(this_value) && std::isnan(other_value);
    2404             :     }
    2405             :     // SameValue(0.0, -0.0) is false.
    2406        2427 :     return (std::signbit(this_value) == std::signbit(other_value));
    2407             :   }
    2408      217116 :   if (IsString() && other->IsString()) {
    2409       93490 :     return String::cast(*this)->Equals(String::cast(other));
    2410             :   }
    2411       29180 :   if (IsBigInt() && other->IsBigInt()) {
    2412          27 :     return BigInt::EqualToBigInt(BigInt::cast(*this), BigInt::cast(other));
    2413             :   }
    2414             :   return false;
    2415             : }
    2416             : 
    2417    23484053 : bool Object::SameValueZero(Object other) {
    2418    23484053 :   if (other == *this) return true;
    2419             : 
    2420    27520726 :   if (IsNumber() && other->IsNumber()) {
    2421     9287708 :     double this_value = Number();
    2422     9287708 :     double other_value = other->Number();
    2423             :     // +0 == -0 is true
    2424     9287708 :     return this_value == other_value ||
    2425           4 :            (std::isnan(this_value) && std::isnan(other_value));
    2426             :   }
    2427    17871564 :   if (IsString() && other->IsString()) {
    2428     8648576 :     return String::cast(*this)->Equals(String::cast(other));
    2429             :   }
    2430      292782 :   if (IsBigInt() && other->IsBigInt()) {
    2431           0 :     return BigInt::EqualToBigInt(BigInt::cast(*this), BigInt::cast(other));
    2432             :   }
    2433             :   return false;
    2434             : }
    2435             : 
    2436       14499 : MaybeHandle<Object> Object::ArraySpeciesConstructor(
    2437             :     Isolate* isolate, Handle<Object> original_array) {
    2438       14499 :   Handle<Object> default_species = isolate->array_function();
    2439       40059 :   if (original_array->IsJSArray() &&
    2440       35319 :       Handle<JSArray>::cast(original_array)->HasArrayPrototype(isolate) &&
    2441        9759 :       isolate->IsArraySpeciesLookupChainIntact()) {
    2442        8756 :     return default_species;
    2443             :   }
    2444             :   Handle<Object> constructor = isolate->factory()->undefined_value();
    2445             :   Maybe<bool> is_array = Object::IsArray(original_array);
    2446        5743 :   MAYBE_RETURN_NULL(is_array);
    2447        5743 :   if (is_array.FromJust()) {
    2448        4718 :     ASSIGN_RETURN_ON_EXCEPTION(
    2449             :         isolate, constructor,
    2450             :         Object::GetProperty(isolate, original_array,
    2451             :                             isolate->factory()->constructor_string()),
    2452             :         Object);
    2453        4700 :     if (constructor->IsConstructor()) {
    2454             :       Handle<Context> constructor_context;
    2455        4074 :       ASSIGN_RETURN_ON_EXCEPTION(
    2456             :           isolate, constructor_context,
    2457             :           JSReceiver::GetFunctionRealm(Handle<JSReceiver>::cast(constructor)),
    2458             :           Object);
    2459        6129 :       if (*constructor_context != *isolate->native_context() &&
    2460        2055 :           *constructor == constructor_context->array_function()) {
    2461             :         constructor = isolate->factory()->undefined_value();
    2462             :       }
    2463             :     }
    2464        4700 :     if (constructor->IsJSReceiver()) {
    2465        4112 :       ASSIGN_RETURN_ON_EXCEPTION(
    2466             :           isolate, constructor,
    2467             :           JSReceiver::GetProperty(isolate,
    2468             :                                   Handle<JSReceiver>::cast(constructor),
    2469             :                                   isolate->factory()->species_symbol()),
    2470             :           Object);
    2471        4094 :       if (constructor->IsNull(isolate)) {
    2472             :         constructor = isolate->factory()->undefined_value();
    2473             :       }
    2474             :     }
    2475             :   }
    2476       11450 :   if (constructor->IsUndefined(isolate)) {
    2477        3705 :     return default_species;
    2478             :   } else {
    2479        4040 :     if (!constructor->IsConstructor()) {
    2480           0 :       THROW_NEW_ERROR(isolate,
    2481             :           NewTypeError(MessageTemplate::kSpeciesNotConstructor),
    2482             :           Object);
    2483             :     }
    2484        2020 :     return constructor;
    2485             :   }
    2486             : }
    2487             : 
    2488             : // ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
    2489         782 : V8_WARN_UNUSED_RESULT MaybeHandle<Object> Object::SpeciesConstructor(
    2490             :     Isolate* isolate, Handle<JSReceiver> recv,
    2491             :     Handle<JSFunction> default_ctor) {
    2492             :   Handle<Object> ctor_obj;
    2493        1564 :   ASSIGN_RETURN_ON_EXCEPTION(
    2494             :       isolate, ctor_obj,
    2495             :       JSObject::GetProperty(isolate, recv,
    2496             :                             isolate->factory()->constructor_string()),
    2497             :       Object);
    2498             : 
    2499        1564 :   if (ctor_obj->IsUndefined(isolate)) return default_ctor;
    2500             : 
    2501        1546 :   if (!ctor_obj->IsJSReceiver()) {
    2502           0 :     THROW_NEW_ERROR(isolate,
    2503             :                     NewTypeError(MessageTemplate::kConstructorNotReceiver),
    2504             :                     Object);
    2505             :   }
    2506             : 
    2507         773 :   Handle<JSReceiver> ctor = Handle<JSReceiver>::cast(ctor_obj);
    2508             : 
    2509             :   Handle<Object> species;
    2510        1546 :   ASSIGN_RETURN_ON_EXCEPTION(
    2511             :       isolate, species,
    2512             :       JSObject::GetProperty(isolate, ctor,
    2513             :                             isolate->factory()->species_symbol()),
    2514             :       Object);
    2515             : 
    2516        1546 :   if (species->IsNullOrUndefined(isolate)) {
    2517           0 :     return default_ctor;
    2518             :   }
    2519             : 
    2520        1546 :   if (species->IsConstructor()) return species;
    2521             : 
    2522           0 :   THROW_NEW_ERROR(
    2523             :       isolate, NewTypeError(MessageTemplate::kSpeciesNotConstructor), Object);
    2524             : }
    2525             : 
    2526           0 : bool Object::IterationHasObservableEffects() {
    2527             :   // Check that this object is an array.
    2528           0 :   if (!IsJSArray()) return true;
    2529           0 :   JSArray array = JSArray::cast(*this);
    2530             :   Isolate* isolate = array->GetIsolate();
    2531             : 
    2532             : #ifdef V8_ENABLE_FORCE_SLOW_PATH
    2533             :   if (isolate->force_slow_path()) return true;
    2534             : #endif
    2535             : 
    2536             :   // Check that we have the original ArrayPrototype.
    2537           0 :   if (!array->map()->prototype()->IsJSObject()) return true;
    2538           0 :   JSObject array_proto = JSObject::cast(array->map()->prototype());
    2539           0 :   if (!isolate->is_initial_array_prototype(array_proto)) return true;
    2540             : 
    2541             :   // Check that the ArrayPrototype hasn't been modified in a way that would
    2542             :   // affect iteration.
    2543           0 :   if (!isolate->IsArrayIteratorLookupChainIntact()) return true;
    2544             : 
    2545             :   // For FastPacked kinds, iteration will have the same effect as simply
    2546             :   // accessing each property in order.
    2547           0 :   ElementsKind array_kind = array->GetElementsKind();
    2548           0 :   if (IsFastPackedElementsKind(array_kind)) return false;
    2549             : 
    2550             :   // For FastHoley kinds, an element access on a hole would cause a lookup on
    2551             :   // the prototype. This could have different results if the prototype has been
    2552             :   // changed.
    2553           0 :   if (IsHoleyElementsKind(array_kind) &&
    2554           0 :       isolate->IsNoElementsProtectorIntact()) {
    2555             :     return false;
    2556             :   }
    2557           0 :   return true;
    2558             : }
    2559             : 
    2560        8520 : void Object::ShortPrint(FILE* out) const {
    2561        8520 :   OFStream os(out);
    2562        8520 :   os << Brief(*this);
    2563        8520 : }
    2564             : 
    2565       14115 : void Object::ShortPrint(StringStream* accumulator) const {
    2566       14115 :   std::ostringstream os;
    2567       14115 :   os << Brief(*this);
    2568       28230 :   accumulator->Add(os.str().c_str());
    2569       14115 : }
    2570             : 
    2571      118720 : void Object::ShortPrint(std::ostream& os) const { os << Brief(*this); }
    2572             : 
    2573           2 : std::ostream& operator<<(std::ostream& os, const Object& obj) {
    2574             :   obj.ShortPrint(os);
    2575           2 :   return os;
    2576             : }
    2577             : 
    2578           0 : void MaybeObject::ShortPrint(FILE* out) {
    2579           0 :   OFStream os(out);
    2580           0 :   os << Brief(*this);
    2581           0 : }
    2582             : 
    2583           0 : void MaybeObject::ShortPrint(StringStream* accumulator) {
    2584           0 :   std::ostringstream os;
    2585           0 :   os << Brief(*this);
    2586           0 :   accumulator->Add(os.str().c_str());
    2587           0 : }
    2588             : 
    2589           0 : void MaybeObject::ShortPrint(std::ostream& os) { os << Brief(*this); }
    2590             : 
    2591      351124 : Brief::Brief(const Object v) : value(v->ptr()) {}
    2592           0 : Brief::Brief(const MaybeObject v) : value(v.ptr()) {}
    2593             : 
    2594      216969 : std::ostream& operator<<(std::ostream& os, const Brief& v) {
    2595      216969 :   MaybeObject maybe_object(v.value);
    2596      216969 :   Smi smi;
    2597      216969 :   HeapObject heap_object;
    2598      216969 :   if (maybe_object->ToSmi(&smi)) {
    2599             :     smi->SmiPrint(os);
    2600      181559 :   } else if (maybe_object->IsCleared()) {
    2601           0 :     os << "[cleared]";
    2602      181559 :   } else if (maybe_object->GetHeapObjectIfWeak(&heap_object)) {
    2603           0 :     os << "[weak] ";
    2604           0 :     heap_object->HeapObjectShortPrint(os);
    2605      181559 :   } else if (maybe_object->GetHeapObjectIfStrong(&heap_object)) {
    2606      181559 :     heap_object->HeapObjectShortPrint(os);
    2607             :   } else {
    2608           0 :     UNREACHABLE();
    2609             :   }
    2610      216969 :   return os;
    2611             : }
    2612             : 
    2613         725 : void Smi::SmiPrint(std::ostream& os) const {  // NOLINT
    2614       36135 :   os << value();
    2615         725 : }
    2616             : 
    2617     5781661 : Handle<String> String::SlowFlatten(Isolate* isolate, Handle<ConsString> cons,
    2618             :                                    PretenureFlag pretenure) {
    2619             :   DCHECK_NE(cons->second()->length(), 0);
    2620             : 
    2621             :   // TurboFan can create cons strings with empty first parts.
    2622    17344983 :   while (cons->first()->length() == 0) {
    2623             :     // We do not want to call this function recursively. Therefore we call
    2624             :     // String::Flatten only in those cases where String::SlowFlatten is not
    2625             :     // called again.
    2626          42 :     if (cons->second()->IsConsString() && !cons->second()->IsFlat()) {
    2627           0 :       cons = handle(ConsString::cast(cons->second()), isolate);
    2628             :     } else {
    2629          42 :       return String::Flatten(isolate, handle(cons->second(), isolate));
    2630             :     }
    2631             :   }
    2632             : 
    2633             :   DCHECK(AllowHeapAllocation::IsAllowed());
    2634             :   int length = cons->length();
    2635     5781640 :   PretenureFlag tenure = Heap::InNewSpace(*cons) ? pretenure : TENURED;
    2636             :   Handle<SeqString> result;
    2637     5781640 :   if (cons->IsOneByteRepresentation()) {
    2638             :     Handle<SeqOneByteString> flat = isolate->factory()->NewRawOneByteString(
    2639    11324488 :         length, tenure).ToHandleChecked();
    2640             :     DisallowHeapAllocation no_gc;
    2641     5662244 :     WriteToFlat(*cons, flat->GetChars(no_gc), 0, length);
    2642             :     result = flat;
    2643             :   } else {
    2644             :     Handle<SeqTwoByteString> flat = isolate->factory()->NewRawTwoByteString(
    2645      238792 :         length, tenure).ToHandleChecked();
    2646             :     DisallowHeapAllocation no_gc;
    2647      119396 :     WriteToFlat(*cons, flat->GetChars(no_gc), 0, length);
    2648             :     result = flat;
    2649             :   }
    2650    11563280 :   cons->set_first(isolate, *result);
    2651     5781640 :   cons->set_second(isolate, ReadOnlyRoots(isolate).empty_string());
    2652             :   DCHECK(result->IsFlat());
    2653     5781640 :   return result;
    2654             : }
    2655             : 
    2656             : 
    2657             : 
    2658         306 : bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
    2659             :   DisallowHeapAllocation no_allocation;
    2660             :   // Externalizing twice leaks the external resource, so it's
    2661             :   // prohibited by the API.
    2662             :   DCHECK(this->SupportsExternalization());
    2663             :   DCHECK(resource->IsCacheable());
    2664             : #ifdef ENABLE_SLOW_DCHECKS
    2665             :   if (FLAG_enable_slow_asserts) {
    2666             :     // Assert that the resource and the string are equivalent.
    2667             :     DCHECK(static_cast<size_t>(this->length()) == resource->length());
    2668             :     ScopedVector<uc16> smart_chars(this->length());
    2669             :     String::WriteToFlat(*this, smart_chars.start(), 0, this->length());
    2670             :     DCHECK_EQ(0, memcmp(smart_chars.start(), resource->data(),
    2671             :                         resource->length() * sizeof(smart_chars[0])));
    2672             :   }
    2673             : #endif  // DEBUG
    2674         306 :   int size = this->Size();  // Byte size of the original string.
    2675             :   // Abort if size does not allow in-place conversion.
    2676         306 :   if (size < ExternalString::kUncachedSize) return false;
    2677             :   Isolate* isolate;
    2678             :   // Read-only strings cannot be made external, since that would mutate the
    2679             :   // string.
    2680         306 :   if (!Isolate::FromWritableHeapObject(*this, &isolate)) return false;
    2681         306 :   Heap* heap = isolate->heap();
    2682         306 :   bool is_one_byte = this->IsOneByteRepresentation();
    2683             :   bool is_internalized = this->IsInternalizedString();
    2684             :   bool has_pointers = StringShape(*this).IsIndirect();
    2685         306 :   if (has_pointers) {
    2686          64 :     heap->NotifyObjectLayoutChange(*this, size, no_allocation);
    2687             :   }
    2688             :   // Morph the string to an external string by replacing the map and
    2689             :   // reinitializing the fields.  This won't work if the space the existing
    2690             :   // string occupies is too small for a regular external string.  Instead, we
    2691             :   // resort to an uncached external string instead, omitting the field caching
    2692             :   // the address of the backing store.  When we encounter uncached external
    2693             :   // strings in generated code, we need to bailout to runtime.
    2694             :   Map new_map;
    2695             :   ReadOnlyRoots roots(heap);
    2696         306 :   if (size < ExternalString::kSize) {
    2697         110 :     if (is_internalized) {
    2698          20 :       if (is_one_byte) {
    2699             :         new_map =
    2700             :             roots
    2701          15 :                 .uncached_external_internalized_string_with_one_byte_data_map();
    2702             :       } else {
    2703           5 :         new_map = roots.uncached_external_internalized_string_map();
    2704             :       }
    2705             :     } else {
    2706             :       new_map = is_one_byte
    2707             :                     ? roots.uncached_external_string_with_one_byte_data_map()
    2708         180 :                     : roots.uncached_external_string_map();
    2709             :     }
    2710             :   } else {
    2711             :     new_map =
    2712             :         is_internalized
    2713             :             ? (is_one_byte
    2714             :                    ? roots.external_internalized_string_with_one_byte_data_map()
    2715             :                    : roots.external_internalized_string_map())
    2716             :             : (is_one_byte ? roots.external_string_with_one_byte_data_map()
    2717         392 :                            : roots.external_string_map());
    2718             :   }
    2719             : 
    2720             :   // Byte size of the external String object.
    2721         306 :   int new_size = this->SizeFromMap(new_map);
    2722             :   heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
    2723         612 :                              ClearRecordedSlots::kNo);
    2724         306 :   if (has_pointers) {
    2725          64 :     heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
    2726             :   }
    2727             : 
    2728             :   // We are storing the new map using release store after creating a filler for
    2729             :   // the left-over space to avoid races with the sweeper thread.
    2730         306 :   this->synchronized_set_map(new_map);
    2731             : 
    2732         306 :   ExternalTwoByteString self = ExternalTwoByteString::cast(*this);
    2733         306 :   self->SetResource(isolate, resource);
    2734             :   heap->RegisterExternalString(*this);
    2735         306 :   if (is_internalized) self->Hash();  // Force regeneration of the hash value.
    2736             :   return true;
    2737             : }
    2738             : 
    2739             : 
    2740         315 : bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
    2741             :   DisallowHeapAllocation no_allocation;
    2742             :   // Externalizing twice leaks the external resource, so it's
    2743             :   // prohibited by the API.
    2744             :   DCHECK(this->SupportsExternalization());
    2745             :   DCHECK(resource->IsCacheable());
    2746             : #ifdef ENABLE_SLOW_DCHECKS
    2747             :   if (FLAG_enable_slow_asserts) {
    2748             :     // Assert that the resource and the string are equivalent.
    2749             :     DCHECK(static_cast<size_t>(this->length()) == resource->length());
    2750             :     if (this->IsTwoByteRepresentation()) {
    2751             :       ScopedVector<uint16_t> smart_chars(this->length());
    2752             :       String::WriteToFlat(*this, smart_chars.start(), 0, this->length());
    2753             :       DCHECK(String::IsOneByte(smart_chars.start(), this->length()));
    2754             :     }
    2755             :     ScopedVector<char> smart_chars(this->length());
    2756             :     String::WriteToFlat(*this, smart_chars.start(), 0, this->length());
    2757             :     DCHECK_EQ(0, memcmp(smart_chars.start(), resource->data(),
    2758             :                         resource->length() * sizeof(smart_chars[0])));
    2759             :   }
    2760             : #endif  // DEBUG
    2761         315 :   int size = this->Size();  // Byte size of the original string.
    2762             :   // Abort if size does not allow in-place conversion.
    2763         315 :   if (size < ExternalString::kUncachedSize) return false;
    2764             :   Isolate* isolate;
    2765             :   // Read-only strings cannot be made external, since that would mutate the
    2766             :   // string.
    2767         315 :   if (!Isolate::FromWritableHeapObject(*this, &isolate)) return false;
    2768         315 :   Heap* heap = isolate->heap();
    2769             :   bool is_internalized = this->IsInternalizedString();
    2770             :   bool has_pointers = StringShape(*this).IsIndirect();
    2771             : 
    2772         315 :   if (has_pointers) {
    2773          29 :     heap->NotifyObjectLayoutChange(*this, size, no_allocation);
    2774             :   }
    2775             : 
    2776             :   // Morph the string to an external string by replacing the map and
    2777             :   // reinitializing the fields.  This won't work if the space the existing
    2778             :   // string occupies is too small for a regular external string.  Instead, we
    2779             :   // resort to an uncached external string instead, omitting the field caching
    2780             :   // the address of the backing store.  When we encounter uncached external
    2781             :   // strings in generated code, we need to bailout to runtime.
    2782             :   Map new_map;
    2783             :   ReadOnlyRoots roots(heap);
    2784         315 :   if (size < ExternalString::kSize) {
    2785             :     new_map = is_internalized
    2786             :                   ? roots.uncached_external_one_byte_internalized_string_map()
    2787          38 :                   : roots.uncached_external_one_byte_string_map();
    2788             :   } else {
    2789             :     new_map = is_internalized
    2790             :                   ? roots.external_one_byte_internalized_string_map()
    2791         592 :                   : roots.external_one_byte_string_map();
    2792             :   }
    2793             : 
    2794             :   // Byte size of the external String object.
    2795         315 :   int new_size = this->SizeFromMap(new_map);
    2796             :   heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
    2797         630 :                              ClearRecordedSlots::kNo);
    2798         315 :   if (has_pointers) {
    2799          29 :     heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
    2800             :   }
    2801             : 
    2802             :   // We are storing the new map using release store after creating a filler for
    2803             :   // the left-over space to avoid races with the sweeper thread.
    2804         315 :   this->synchronized_set_map(new_map);
    2805             : 
    2806         315 :   ExternalOneByteString self = ExternalOneByteString::cast(*this);
    2807         315 :   self->SetResource(isolate, resource);
    2808             :   heap->RegisterExternalString(*this);
    2809         315 :   if (is_internalized) self->Hash();  // Force regeneration of the hash value.
    2810             :   return true;
    2811             : }
    2812             : 
    2813        1504 : bool String::SupportsExternalization() {
    2814        3008 :   if (this->IsThinString()) {
    2815           0 :     return i::ThinString::cast(*this)->actual()->SupportsExternalization();
    2816             :   }
    2817             : 
    2818             :   Isolate* isolate;
    2819             :   // RO_SPACE strings cannot be externalized.
    2820        1504 :   if (!Isolate::FromWritableHeapObject(*this, &isolate)) {
    2821             :     return false;
    2822             :   }
    2823             : 
    2824             :   // Already an external string.
    2825        1486 :   if (StringShape(*this).IsExternal()) {
    2826             :     return false;
    2827             :   }
    2828             : 
    2829        1138 :   return !isolate->heap()->IsInGCPostProcessing();
    2830             : }
    2831             : 
    2832       41947 : void String::StringShortPrint(StringStream* accumulator, bool show_details) {
    2833       83894 :   const char* internalized_marker = this->IsInternalizedString() ? "#" : "";
    2834             : 
    2835             :   int len = length();
    2836       41947 :   if (len > kMaxShortPrintLength) {
    2837           0 :     accumulator->Add("<Very long string[%s%u]>", internalized_marker, len);
    2838           0 :     return;
    2839             :   }
    2840             : 
    2841       41947 :   if (!LooksValid()) {
    2842           0 :     accumulator->Add("<Invalid String>");
    2843           0 :     return;
    2844             :   }
    2845             : 
    2846       41947 :   StringCharacterStream stream(*this);
    2847             : 
    2848             :   bool truncated = false;
    2849       41947 :   if (len > kMaxShortPrintLength) {
    2850             :     len = kMaxShortPrintLength;
    2851             :     truncated = true;
    2852             :   }
    2853             :   bool one_byte = true;
    2854      377495 :   for (int i = 0; i < len; i++) {
    2855      335548 :     uint16_t c = stream.GetNext();
    2856             : 
    2857      335548 :     if (c < 32 || c >= 127) {
    2858             :       one_byte = false;
    2859             :     }
    2860             :   }
    2861       41947 :   stream.Reset(*this);
    2862       41947 :   if (one_byte) {
    2863       41947 :     if (show_details)
    2864       39478 :       accumulator->Add("<String[%s%u]: ", internalized_marker, length());
    2865      335548 :     for (int i = 0; i < len; i++) {
    2866      335548 :       accumulator->Put(static_cast<char>(stream.GetNext()));
    2867             :     }
    2868       41947 :     if (show_details) accumulator->Put('>');
    2869             :   } else {
    2870             :     // Backslash indicates that the string contains control
    2871             :     // characters and that backslashes are therefore escaped.
    2872           0 :     if (show_details)
    2873           0 :       accumulator->Add("<String[%s%u]\\: ", internalized_marker, length());
    2874           0 :     for (int i = 0; i < len; i++) {
    2875           0 :       uint16_t c = stream.GetNext();
    2876           0 :       if (c == '\n') {
    2877           0 :         accumulator->Add("\\n");
    2878           0 :       } else if (c == '\r') {
    2879           0 :         accumulator->Add("\\r");
    2880           0 :       } else if (c == '\\') {
    2881           0 :         accumulator->Add("\\\\");
    2882           0 :       } else if (c < 32 || c > 126) {
    2883           0 :         accumulator->Add("\\x%02x", c);
    2884             :       } else {
    2885           0 :         accumulator->Put(static_cast<char>(c));
    2886             :       }
    2887             :     }
    2888           0 :     if (truncated) {
    2889           0 :       accumulator->Put('.');
    2890           0 :       accumulator->Put('.');
    2891           0 :       accumulator->Put('.');
    2892             :     }
    2893           0 :     if (show_details) accumulator->Put('>');
    2894             :   }
    2895             :   return;
    2896             : }
    2897             : 
    2898             : 
    2899          45 : void String::PrintUC16(std::ostream& os, int start, int end) {  // NOLINT
    2900          45 :   if (end < 0) end = length();
    2901          45 :   StringCharacterStream stream(*this, start);
    2902        5823 :   for (int i = start; i < end && stream.HasMore(); i++) {
    2903       11556 :     os << AsUC16(stream.GetNext());
    2904             :   }
    2905          45 : }
    2906             : 
    2907             : 
    2908       57573 : void JSObject::JSObjectShortPrint(StringStream* accumulator) {
    2909       57573 :   switch (map()->instance_type()) {
    2910             :     case JS_ARRAY_TYPE: {
    2911        2250 :       double length = JSArray::cast(*this)->length()->IsUndefined()
    2912             :                           ? 0
    2913        2250 :                           : JSArray::cast(*this)->length()->Number();
    2914        1125 :       accumulator->Add("<JSArray[%u]>", static_cast<uint32_t>(length));
    2915        1125 :       break;
    2916             :     }
    2917             :     case JS_BOUND_FUNCTION_TYPE: {
    2918           0 :       JSBoundFunction bound_function = JSBoundFunction::cast(*this);
    2919           0 :       accumulator->Add("<JSBoundFunction");
    2920             :       accumulator->Add(" (BoundTargetFunction %p)>",
    2921             :                        reinterpret_cast<void*>(
    2922           0 :                            bound_function->bound_target_function().ptr()));
    2923             :       break;
    2924             :     }
    2925             :     case JS_WEAK_MAP_TYPE: {
    2926           0 :       accumulator->Add("<JSWeakMap>");
    2927           0 :       break;
    2928             :     }
    2929             :     case JS_WEAK_SET_TYPE: {
    2930           0 :       accumulator->Add("<JSWeakSet>");
    2931           0 :       break;
    2932             :     }
    2933             :     case JS_REGEXP_TYPE: {
    2934          18 :       accumulator->Add("<JSRegExp");
    2935          18 :       JSRegExp regexp = JSRegExp::cast(*this);
    2936          36 :       if (regexp->source()->IsString()) {
    2937          18 :         accumulator->Add(" ");
    2938          36 :         String::cast(regexp->source())->StringShortPrint(accumulator);
    2939             :       }
    2940          18 :       accumulator->Add(">");
    2941             : 
    2942             :       break;
    2943             :     }
    2944             :     case JS_FUNCTION_TYPE: {
    2945       44738 :       JSFunction function = JSFunction::cast(*this);
    2946       44738 :       Object fun_name = function->shared()->DebugName();
    2947             :       bool printed = false;
    2948       44738 :       if (fun_name->IsString()) {
    2949             :         String str = String::cast(fun_name);
    2950       44738 :         if (str->length() > 0) {
    2951       38587 :           accumulator->Add("<JSFunction ");
    2952       38587 :           accumulator->Put(str);
    2953             :           printed = true;
    2954             :         }
    2955             :       }
    2956       44738 :       if (!printed) {
    2957        6151 :         accumulator->Add("<JSFunction");
    2958             :       }
    2959       44738 :       if (FLAG_trace_file_names) {
    2960           0 :         Object source_name = Script::cast(function->shared()->script())->name();
    2961           0 :         if (source_name->IsString()) {
    2962             :           String str = String::cast(source_name);
    2963           0 :           if (str->length() > 0) {
    2964           0 :             accumulator->Add(" <");
    2965           0 :             accumulator->Put(str);
    2966           0 :             accumulator->Add(">");
    2967             :           }
    2968             :         }
    2969             :       }
    2970             :       accumulator->Add(" (sfi = %p)",
    2971       89476 :                        reinterpret_cast<void*>(function->shared().ptr()));
    2972       44738 :       accumulator->Put('>');
    2973             :       break;
    2974             :     }
    2975             :     case JS_GENERATOR_OBJECT_TYPE: {
    2976           0 :       accumulator->Add("<JSGenerator>");
    2977           0 :       break;
    2978             :     }
    2979             :     case JS_ASYNC_FUNCTION_OBJECT_TYPE: {
    2980           0 :       accumulator->Add("<JSAsyncFunctionObject>");
    2981           0 :       break;
    2982             :     }
    2983             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE: {
    2984           0 :       accumulator->Add("<JS AsyncGenerator>");
    2985           0 :       break;
    2986             :     }
    2987             : 
    2988             :     // All other JSObjects are rather similar to each other (JSObject,
    2989             :     // JSGlobalProxy, JSGlobalObject, JSUndetectable, JSValue).
    2990             :     default: {
    2991       11692 :       Map map_of_this = map();
    2992             :       Heap* heap = GetHeap();
    2993       11692 :       Object constructor = map_of_this->GetConstructor();
    2994             :       bool printed = false;
    2995       23384 :       if (constructor->IsHeapObject() &&
    2996       11692 :           !heap->Contains(HeapObject::cast(constructor))) {
    2997           0 :         accumulator->Add("!!!INVALID CONSTRUCTOR!!!");
    2998             :       } else {
    2999       11692 :         bool global_object = IsJSGlobalProxy();
    3000       11692 :         if (constructor->IsJSFunction()) {
    3001       11692 :           if (!heap->Contains(JSFunction::cast(constructor)->shared())) {
    3002           0 :             accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!");
    3003             :           } else {
    3004             :             String constructor_name =
    3005       11692 :                 JSFunction::cast(constructor)->shared()->Name();
    3006       11692 :             if (constructor_name->length() > 0) {
    3007       10212 :               accumulator->Add(global_object ? "<GlobalObject " : "<");
    3008       10212 :               accumulator->Put(constructor_name);
    3009             :               accumulator->Add(
    3010             :                   " %smap = %p",
    3011       10212 :                   map_of_this->is_deprecated() ? "deprecated-" : "",
    3012       10212 :                   map_of_this);
    3013             :               printed = true;
    3014             :             }
    3015             :           }
    3016           0 :         } else if (constructor->IsFunctionTemplateInfo()) {
    3017           0 :           accumulator->Add(global_object ? "<RemoteObject>" : "<RemoteObject>");
    3018             :           printed = true;
    3019             :         }
    3020       11692 :         if (!printed) {
    3021        1480 :           accumulator->Add("<JS%sObject", global_object ? "Global " : "");
    3022             :         }
    3023             :       }
    3024       23384 :       if (IsJSValue()) {
    3025          84 :         accumulator->Add(" value = ");
    3026          84 :         JSValue::cast(*this)->value()->ShortPrint(accumulator);
    3027             :       }
    3028       11692 :       accumulator->Put('>');
    3029             :       break;
    3030             :     }
    3031             :   }
    3032       57573 : }
    3033             : 
    3034             : 
    3035           0 : void JSObject::PrintElementsTransition(
    3036             :     FILE* file, Handle<JSObject> object,
    3037             :     ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
    3038             :     ElementsKind to_kind, Handle<FixedArrayBase> to_elements) {
    3039           0 :   if (from_kind != to_kind) {
    3040           0 :     OFStream os(file);
    3041           0 :     os << "elements transition [" << ElementsKindToString(from_kind) << " -> "
    3042           0 :        << ElementsKindToString(to_kind) << "] in ";
    3043           0 :     JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true);
    3044           0 :     PrintF(file, " for ");
    3045           0 :     object->ShortPrint(file);
    3046           0 :     PrintF(file, " from ");
    3047           0 :     from_elements->ShortPrint(file);
    3048           0 :     PrintF(file, " to ");
    3049           0 :     to_elements->ShortPrint(file);
    3050           0 :     PrintF(file, "\n");
    3051             :   }
    3052           0 : }
    3053             : 
    3054             : 
    3055             : // static
    3056       27893 : MaybeHandle<JSFunction> Map::GetConstructorFunction(
    3057             :     Handle<Map> map, Handle<Context> native_context) {
    3058       27893 :   if (map->IsPrimitiveMap()) {
    3059             :     int const constructor_function_index = map->GetConstructorFunctionIndex();
    3060        8560 :     if (constructor_function_index != kNoConstructorFunctionIndex) {
    3061             :       return handle(
    3062             :           JSFunction::cast(native_context->get(constructor_function_index)),
    3063       17120 :           native_context->GetIsolate());
    3064             :     }
    3065             :   }
    3066       19333 :   return MaybeHandle<JSFunction>();
    3067             : }
    3068             : 
    3069           0 : void Map::PrintReconfiguration(Isolate* isolate, FILE* file, int modify_index,
    3070             :                                PropertyKind kind,
    3071             :                                PropertyAttributes attributes) {
    3072           0 :   OFStream os(file);
    3073           0 :   os << "[reconfiguring]";
    3074           0 :   Name name = instance_descriptors()->GetKey(modify_index);
    3075           0 :   if (name->IsString()) {
    3076           0 :     String::cast(name)->PrintOn(file);
    3077             :   } else {
    3078           0 :     os << "{symbol " << reinterpret_cast<void*>(name.ptr()) << "}";
    3079             :   }
    3080           0 :   os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: ";
    3081           0 :   os << attributes << " [";
    3082           0 :   JavaScriptFrame::PrintTop(isolate, file, false, true);
    3083           0 :   os << "]\n";
    3084           0 : }
    3085             : 
    3086    54733723 : VisitorId Map::GetVisitorId(Map map) {
    3087             :   STATIC_ASSERT(kVisitorIdCount <= 256);
    3088             : 
    3089    54733723 :   const int instance_type = map->instance_type();
    3090             : 
    3091    54733723 :   if (instance_type < FIRST_NONSTRING_TYPE) {
    3092        1288 :     switch (instance_type & kStringRepresentationMask) {
    3093             :       case kSeqStringTag:
    3094         224 :         if ((instance_type & kStringEncodingMask) == kOneByteStringTag) {
    3095             :           return kVisitSeqOneByteString;
    3096             :         } else {
    3097         112 :           return kVisitSeqTwoByteString;
    3098             :         }
    3099             : 
    3100             :       case kConsStringTag:
    3101         112 :         if (IsShortcutCandidate(instance_type)) {
    3102             :           return kVisitShortcutCandidate;
    3103             :         } else {
    3104           0 :           return kVisitConsString;
    3105             :         }
    3106             : 
    3107             :       case kSlicedStringTag:
    3108             :         return kVisitSlicedString;
    3109             : 
    3110             :       case kExternalStringTag:
    3111         728 :         return kVisitDataObject;
    3112             : 
    3113             :       case kThinStringTag:
    3114         112 :         return kVisitThinString;
    3115             :     }
    3116           0 :     UNREACHABLE();
    3117             :   }
    3118             : 
    3119    54732435 :   switch (instance_type) {
    3120             :     case BYTE_ARRAY_TYPE:
    3121             :       return kVisitByteArray;
    3122             : 
    3123             :     case BYTECODE_ARRAY_TYPE:
    3124          56 :       return kVisitBytecodeArray;
    3125             : 
    3126             :     case FREE_SPACE_TYPE:
    3127          56 :       return kVisitFreeSpace;
    3128             : 
    3129             :     case EMBEDDER_DATA_ARRAY_TYPE:
    3130          56 :       return kVisitEmbedderDataArray;
    3131             : 
    3132             :     case FIXED_ARRAY_TYPE:
    3133             :     case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
    3134             :     case HASH_TABLE_TYPE:
    3135             :     case ORDERED_HASH_MAP_TYPE:
    3136             :     case ORDERED_HASH_SET_TYPE:
    3137             :     case ORDERED_NAME_DICTIONARY_TYPE:
    3138             :     case NAME_DICTIONARY_TYPE:
    3139             :     case GLOBAL_DICTIONARY_TYPE:
    3140             :     case NUMBER_DICTIONARY_TYPE:
    3141             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
    3142             :     case STRING_TABLE_TYPE:
    3143             :     case SCOPE_INFO_TYPE:
    3144             :     case SCRIPT_CONTEXT_TABLE_TYPE:
    3145         952 :       return kVisitFixedArray;
    3146             : 
    3147             :     case AWAIT_CONTEXT_TYPE:
    3148             :     case BLOCK_CONTEXT_TYPE:
    3149             :     case CATCH_CONTEXT_TYPE:
    3150             :     case DEBUG_EVALUATE_CONTEXT_TYPE:
    3151             :     case EVAL_CONTEXT_TYPE:
    3152             :     case FUNCTION_CONTEXT_TYPE:
    3153             :     case MODULE_CONTEXT_TYPE:
    3154             :     case SCRIPT_CONTEXT_TYPE:
    3155             :     case WITH_CONTEXT_TYPE:
    3156         504 :       return kVisitContext;
    3157             : 
    3158             :     case NATIVE_CONTEXT_TYPE:
    3159          56 :       return kVisitNativeContext;
    3160             : 
    3161             :     case EPHEMERON_HASH_TABLE_TYPE:
    3162          56 :       return kVisitEphemeronHashTable;
    3163             : 
    3164             :     case WEAK_FIXED_ARRAY_TYPE:
    3165             :     case WEAK_ARRAY_LIST_TYPE:
    3166         112 :       return kVisitWeakArray;
    3167             : 
    3168             :     case FIXED_DOUBLE_ARRAY_TYPE:
    3169          56 :       return kVisitFixedDoubleArray;
    3170             : 
    3171             :     case PROPERTY_ARRAY_TYPE:
    3172          56 :       return kVisitPropertyArray;
    3173             : 
    3174             :     case FEEDBACK_CELL_TYPE:
    3175         224 :       return kVisitFeedbackCell;
    3176             : 
    3177             :     case FEEDBACK_VECTOR_TYPE:
    3178          56 :       return kVisitFeedbackVector;
    3179             : 
    3180             :     case ODDBALL_TYPE:
    3181         616 :       return kVisitOddball;
    3182             : 
    3183             :     case MAP_TYPE:
    3184          56 :       return kVisitMap;
    3185             : 
    3186             :     case CODE_TYPE:
    3187          56 :       return kVisitCode;
    3188             : 
    3189             :     case CELL_TYPE:
    3190          56 :       return kVisitCell;
    3191             : 
    3192             :     case PROPERTY_CELL_TYPE:
    3193          56 :       return kVisitPropertyCell;
    3194             : 
    3195             :     case DESCRIPTOR_ARRAY_TYPE:
    3196          56 :       return kVisitDescriptorArray;
    3197             : 
    3198             :     case TRANSITION_ARRAY_TYPE:
    3199          56 :       return kVisitTransitionArray;
    3200             : 
    3201             :     case JS_WEAK_MAP_TYPE:
    3202             :     case JS_WEAK_SET_TYPE:
    3203       23222 :       return kVisitJSWeakCollection;
    3204             : 
    3205             :     case CALL_HANDLER_INFO_TYPE:
    3206         168 :       return kVisitStruct;
    3207             : 
    3208             :     case SHARED_FUNCTION_INFO_TYPE:
    3209          56 :       return kVisitSharedFunctionInfo;
    3210             : 
    3211             :     case JS_PROXY_TYPE:
    3212         555 :       return kVisitStruct;
    3213             : 
    3214             :     case SYMBOL_TYPE:
    3215          56 :       return kVisitSymbol;
    3216             : 
    3217             :     case JS_ARRAY_BUFFER_TYPE:
    3218       12856 :       return kVisitJSArrayBuffer;
    3219             : 
    3220             :     case JS_DATA_VIEW_TYPE:
    3221         901 :       return kVisitJSDataView;
    3222             : 
    3223             :     case JS_TYPED_ARRAY_TYPE:
    3224       31642 :       return kVisitJSTypedArray;
    3225             : 
    3226             :     case SMALL_ORDERED_HASH_MAP_TYPE:
    3227          56 :       return kVisitSmallOrderedHashMap;
    3228             : 
    3229             :     case SMALL_ORDERED_HASH_SET_TYPE:
    3230          56 :       return kVisitSmallOrderedHashSet;
    3231             : 
    3232             :     case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
    3233          56 :       return kVisitSmallOrderedNameDictionary;
    3234             : 
    3235             :     case CODE_DATA_CONTAINER_TYPE:
    3236          56 :       return kVisitCodeDataContainer;
    3237             : 
    3238             :     case WASM_INSTANCE_TYPE:
    3239       92999 :       return kVisitWasmInstanceObject;
    3240             : 
    3241             :     case PREPARSE_DATA_TYPE:
    3242          56 :       return kVisitPreparseData;
    3243             : 
    3244             :     case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE:
    3245          56 :       return kVisitUncompiledDataWithoutPreparseData;
    3246             : 
    3247             :     case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE:
    3248          56 :       return kVisitUncompiledDataWithPreparseData;
    3249             : 
    3250             :     case JS_OBJECT_TYPE:
    3251             :     case JS_ERROR_TYPE:
    3252             :     case JS_ARGUMENTS_TYPE:
    3253             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
    3254             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    3255             :     case JS_GENERATOR_OBJECT_TYPE:
    3256             :     case JS_ASYNC_FUNCTION_OBJECT_TYPE:
    3257             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
    3258             :     case JS_MODULE_NAMESPACE_TYPE:
    3259             :     case JS_VALUE_TYPE:
    3260             :     case JS_DATE_TYPE:
    3261             :     case JS_ARRAY_ITERATOR_TYPE:
    3262             :     case JS_ARRAY_TYPE:
    3263             :     case JS_FUNCTION_TYPE:
    3264             :     case JS_GLOBAL_PROXY_TYPE:
    3265             :     case JS_GLOBAL_OBJECT_TYPE:
    3266             :     case JS_MESSAGE_OBJECT_TYPE:
    3267             :     case JS_SET_TYPE:
    3268             :     case JS_MAP_TYPE:
    3269             :     case JS_SET_KEY_VALUE_ITERATOR_TYPE:
    3270             :     case JS_SET_VALUE_ITERATOR_TYPE:
    3271             :     case JS_MAP_KEY_ITERATOR_TYPE:
    3272             :     case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
    3273             :     case JS_MAP_VALUE_ITERATOR_TYPE:
    3274             :     case JS_STRING_ITERATOR_TYPE:
    3275             :     case JS_PROMISE_TYPE:
    3276             :     case JS_REGEXP_TYPE:
    3277             :     case JS_REGEXP_STRING_ITERATOR_TYPE:
    3278             :     case JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE:
    3279             :     case JS_WEAK_FACTORY_TYPE:
    3280             : #ifdef V8_INTL_SUPPORT
    3281             :     case JS_INTL_V8_BREAK_ITERATOR_TYPE:
    3282             :     case JS_INTL_COLLATOR_TYPE:
    3283             :     case JS_INTL_DATE_TIME_FORMAT_TYPE:
    3284             :     case JS_INTL_LIST_FORMAT_TYPE:
    3285             :     case JS_INTL_LOCALE_TYPE:
    3286             :     case JS_INTL_NUMBER_FORMAT_TYPE:
    3287             :     case JS_INTL_PLURAL_RULES_TYPE:
    3288             :     case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
    3289             :     case JS_INTL_SEGMENT_ITERATOR_TYPE:
    3290             :     case JS_INTL_SEGMENTER_TYPE:
    3291             : #endif  // V8_INTL_SUPPORT
    3292             :     case WASM_EXCEPTION_TYPE:
    3293             :     case WASM_GLOBAL_TYPE:
    3294             :     case WASM_MEMORY_TYPE:
    3295             :     case WASM_MODULE_TYPE:
    3296             :     case WASM_TABLE_TYPE:
    3297             :     case JS_BOUND_FUNCTION_TYPE: {
    3298             :       const bool has_raw_data_fields =
    3299    47050237 :           (FLAG_unbox_double_fields && !map->HasFastPointerLayout()) ||
    3300             :           (COMPRESS_POINTERS_BOOL && JSObject::GetEmbedderFieldCount(map) > 0);
    3301    47050278 :       return has_raw_data_fields ? kVisitJSObject : kVisitJSObjectFast;
    3302             :     }
    3303             :     case JS_API_OBJECT_TYPE:
    3304             :     case JS_SPECIAL_API_OBJECT_TYPE:
    3305     7511716 :       return kVisitJSApiObject;
    3306             : 
    3307             :     case JS_WEAK_REF_TYPE:
    3308         726 :       return kVisitJSWeakRef;
    3309             : 
    3310             :     case JS_WEAK_CELL_TYPE:
    3311         363 :       return kVisitJSWeakCell;
    3312             : 
    3313             :     case FILLER_TYPE:
    3314             :     case FOREIGN_TYPE:
    3315             :     case HEAP_NUMBER_TYPE:
    3316             :     case MUTABLE_HEAP_NUMBER_TYPE:
    3317             :     case FEEDBACK_METADATA_TYPE:
    3318         341 :       return kVisitDataObject;
    3319             : 
    3320             :     case BIGINT_TYPE:
    3321          56 :       return kVisitBigInt;
    3322             : 
    3323             :     case FIXED_UINT8_ARRAY_TYPE:
    3324             :     case FIXED_INT8_ARRAY_TYPE:
    3325             :     case FIXED_UINT16_ARRAY_TYPE:
    3326             :     case FIXED_INT16_ARRAY_TYPE:
    3327             :     case FIXED_UINT32_ARRAY_TYPE:
    3328             :     case FIXED_INT32_ARRAY_TYPE:
    3329             :     case FIXED_FLOAT32_ARRAY_TYPE:
    3330             :     case FIXED_UINT8_CLAMPED_ARRAY_TYPE:
    3331             :     case FIXED_BIGUINT64_ARRAY_TYPE:
    3332             :     case FIXED_BIGINT64_ARRAY_TYPE:
    3333         560 :       return kVisitFixedTypedArrayBase;
    3334             : 
    3335             :     case FIXED_FLOAT64_ARRAY_TYPE:
    3336          56 :       return kVisitFixedFloat64Array;
    3337             : 
    3338             :     case ALLOCATION_SITE_TYPE:
    3339         112 :       return kVisitAllocationSite;
    3340             : 
    3341             : #define MAKE_STRUCT_CASE(TYPE, Name, name) case TYPE:
    3342             :       STRUCT_LIST(MAKE_STRUCT_CASE)
    3343             : #undef MAKE_STRUCT_CASE
    3344        1792 :       if (instance_type == PROTOTYPE_INFO_TYPE) {
    3345             :         return kVisitPrototypeInfo;
    3346             :       }
    3347        1736 :       return kVisitStruct;
    3348             : 
    3349             :     case LOAD_HANDLER_TYPE:
    3350             :     case STORE_HANDLER_TYPE:
    3351         392 :       return kVisitDataHandler;
    3352             : 
    3353             :     default:
    3354           0 :       UNREACHABLE();
    3355             :   }
    3356             : }
    3357             : 
    3358           0 : void Map::PrintGeneralization(
    3359             :     Isolate* isolate, FILE* file, const char* reason, int modify_index,
    3360             :     int split, int descriptors, bool descriptor_to_field,
    3361             :     Representation old_representation, Representation new_representation,
    3362             :     MaybeHandle<FieldType> old_field_type, MaybeHandle<Object> old_value,
    3363             :     MaybeHandle<FieldType> new_field_type, MaybeHandle<Object> new_value) {
    3364           0 :   OFStream os(file);
    3365           0 :   os << "[generalizing]";
    3366           0 :   Name name = instance_descriptors()->GetKey(modify_index);
    3367           0 :   if (name->IsString()) {
    3368           0 :     String::cast(name)->PrintOn(file);
    3369             :   } else {
    3370           0 :     os << "{symbol " << reinterpret_cast<void*>(name.ptr()) << "}";
    3371             :   }
    3372           0 :   os << ":";
    3373           0 :   if (descriptor_to_field) {
    3374           0 :     os << "c";
    3375             :   } else {
    3376           0 :     os << old_representation.Mnemonic() << "{";
    3377           0 :     if (old_field_type.is_null()) {
    3378           0 :       os << Brief(*(old_value.ToHandleChecked()));
    3379             :     } else {
    3380           0 :       old_field_type.ToHandleChecked()->PrintTo(os);
    3381             :     }
    3382           0 :     os << "}";
    3383             :   }
    3384           0 :   os << "->" << new_representation.Mnemonic() << "{";
    3385           0 :   if (new_field_type.is_null()) {
    3386           0 :     os << Brief(*(new_value.ToHandleChecked()));
    3387             :   } else {
    3388           0 :     new_field_type.ToHandleChecked()->PrintTo(os);
    3389             :   }
    3390           0 :   os << "} (";
    3391           0 :   if (strlen(reason) > 0) {
    3392           0 :     os << reason;
    3393             :   } else {
    3394           0 :     os << "+" << (descriptors - split) << " maps";
    3395             :   }
    3396           0 :   os << ") [";
    3397           0 :   JavaScriptFrame::PrintTop(isolate, file, false, true);
    3398           0 :   os << "]\n";
    3399           0 : }
    3400             : 
    3401           0 : void JSObject::PrintInstanceMigration(FILE* file, Map original_map,
    3402             :                                       Map new_map) {
    3403           0 :   if (new_map->is_dictionary_map()) {
    3404           0 :     PrintF(file, "[migrating to slow]\n");
    3405           0 :     return;
    3406             :   }
    3407           0 :   PrintF(file, "[migrating]");
    3408           0 :   DescriptorArray o = original_map->instance_descriptors();
    3409           0 :   DescriptorArray n = new_map->instance_descriptors();
    3410           0 :   for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) {
    3411           0 :     Representation o_r = o->GetDetails(i).representation();
    3412           0 :     Representation n_r = n->GetDetails(i).representation();
    3413           0 :     if (!o_r.Equals(n_r)) {
    3414           0 :       String::cast(o->GetKey(i))->PrintOn(file);
    3415           0 :       PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic());
    3416           0 :     } else if (o->GetDetails(i).location() == kDescriptor &&
    3417           0 :                n->GetDetails(i).location() == kField) {
    3418           0 :       Name name = o->GetKey(i);
    3419           0 :       if (name->IsString()) {
    3420           0 :         String::cast(name)->PrintOn(file);
    3421             :       } else {
    3422           0 :         PrintF(file, "{symbol %p}", reinterpret_cast<void*>(name.ptr()));
    3423             :       }
    3424           0 :       PrintF(file, " ");
    3425             :     }
    3426             :   }
    3427           0 :   if (original_map->elements_kind() != new_map->elements_kind()) {
    3428             :     PrintF(file, "elements_kind[%i->%i]", original_map->elements_kind(),
    3429           0 :            new_map->elements_kind());
    3430             :   }
    3431           0 :   PrintF(file, "\n");
    3432             : }
    3433             : 
    3434      138074 : bool JSObject::IsUnmodifiedApiObject(FullObjectSlot o) {
    3435      138074 :   Object object = *o;
    3436      138074 :   if (object->IsSmi()) return false;
    3437             :   HeapObject heap_object = HeapObject::cast(object);
    3438      138074 :   if (!object->IsJSObject()) return false;
    3439       26797 :   JSObject js_object = JSObject::cast(object);
    3440       26797 :   if (!js_object->IsDroppableApiWrapper()) return false;
    3441          51 :   Object maybe_constructor = js_object->map()->GetConstructor();
    3442          51 :   if (!maybe_constructor->IsJSFunction()) return false;
    3443          51 :   JSFunction constructor = JSFunction::cast(maybe_constructor);
    3444         102 :   if (js_object->elements()->length() != 0) return false;
    3445             : 
    3446          92 :   return constructor->initial_map() == heap_object->map();
    3447             : }
    3448             : 
    3449      181559 : void HeapObject::HeapObjectShortPrint(std::ostream& os) {  // NOLINT
    3450      181559 :   os << AsHex(this->ptr(), kSystemPointerHexDigits, true) << " ";
    3451             : 
    3452      181559 :   if (IsString()) {
    3453             :     HeapStringAllocator allocator;
    3454             :     StringStream accumulator(&allocator);
    3455       39460 :     String::cast(*this)->StringShortPrint(&accumulator);
    3456      118380 :     os << accumulator.ToCString().get();
    3457             :     return;
    3458             :   }
    3459      142099 :   if (IsJSObject()) {
    3460             :     HeapStringAllocator allocator;
    3461             :     StringStream accumulator(&allocator);
    3462       57573 :     JSObject::cast(*this)->JSObjectShortPrint(&accumulator);
    3463      172719 :     os << accumulator.ToCString().get();
    3464             :     return;
    3465             :   }
    3466       84526 :   switch (map()->instance_type()) {
    3467             :     case MAP_TYPE: {
    3468        1754 :       os << "<Map";
    3469             :       Map mapInstance = Map::cast(*this);
    3470        1754 :       if (mapInstance->IsJSObjectMap()) {
    3471        1754 :         os << "(" << ElementsKindToString(mapInstance->elements_kind()) << ")";
    3472           0 :       } else if (mapInstance->instance_size() != kVariableSizeSentinel) {
    3473           0 :         os << "[" << mapInstance->instance_size() << "]";
    3474             :       }
    3475        1754 :       os << ">";
    3476        1754 :     } break;
    3477             :     case AWAIT_CONTEXT_TYPE: {
    3478           0 :       os << "<AwaitContext generator= ";
    3479             :       HeapStringAllocator allocator;
    3480             :       StringStream accumulator(&allocator);
    3481           0 :       Context::cast(*this)->extension()->ShortPrint(&accumulator);
    3482           0 :       os << accumulator.ToCString().get();
    3483             :       os << '>';
    3484             :       break;
    3485             :     }
    3486             :     case BLOCK_CONTEXT_TYPE:
    3487           0 :       os << "<BlockContext[" << Context::cast(*this)->length() << "]>";
    3488           0 :       break;
    3489             :     case CATCH_CONTEXT_TYPE:
    3490           0 :       os << "<CatchContext[" << Context::cast(*this)->length() << "]>";
    3491           0 :       break;
    3492             :     case DEBUG_EVALUATE_CONTEXT_TYPE:
    3493           0 :       os << "<DebugEvaluateContext[" << Context::cast(*this)->length() << "]>";
    3494           0 :       break;
    3495             :     case EVAL_CONTEXT_TYPE:
    3496           0 :       os << "<EvalContext[" << Context::cast(*this)->length() << "]>";
    3497           0 :       break;
    3498             :     case FUNCTION_CONTEXT_TYPE:
    3499           0 :       os << "<FunctionContext[" << Context::cast(*this)->length() << "]>";
    3500           0 :       break;
    3501             :     case MODULE_CONTEXT_TYPE:
    3502           0 :       os << "<ModuleContext[" << Context::cast(*this)->length() << "]>";
    3503           0 :       break;
    3504             :     case NATIVE_CONTEXT_TYPE:
    3505        1388 :       os << "<NativeContext[" << Context::cast(*this)->length() << "]>";
    3506         694 :       break;
    3507             :     case SCRIPT_CONTEXT_TYPE:
    3508           0 :       os << "<ScriptContext[" << Context::cast(*this)->length() << "]>";
    3509           0 :       break;
    3510             :     case WITH_CONTEXT_TYPE:
    3511           0 :       os << "<WithContext[" << Context::cast(*this)->length() << "]>";
    3512           0 :       break;
    3513             :     case SCRIPT_CONTEXT_TABLE_TYPE:
    3514           0 :       os << "<ScriptContextTable[" << FixedArray::cast(*this)->length() << "]>";
    3515           0 :       break;
    3516             :     case HASH_TABLE_TYPE:
    3517           0 :       os << "<HashTable[" << FixedArray::cast(*this)->length() << "]>";
    3518           0 :       break;
    3519             :     case ORDERED_HASH_MAP_TYPE:
    3520           0 :       os << "<OrderedHashMap[" << FixedArray::cast(*this)->length() << "]>";
    3521           0 :       break;
    3522             :     case ORDERED_HASH_SET_TYPE:
    3523           0 :       os << "<OrderedHashSet[" << FixedArray::cast(*this)->length() << "]>";
    3524           0 :       break;
    3525             :     case ORDERED_NAME_DICTIONARY_TYPE:
    3526           0 :       os << "<OrderedNameDictionary[" << FixedArray::cast(*this)->length()
    3527           0 :          << "]>";
    3528           0 :       break;
    3529             :     case NAME_DICTIONARY_TYPE:
    3530           0 :       os << "<NameDictionary[" << FixedArray::cast(*this)->length() << "]>";
    3531           0 :       break;
    3532             :     case GLOBAL_DICTIONARY_TYPE:
    3533           0 :       os << "<GlobalDictionary[" << FixedArray::cast(*this)->length() << "]>";
    3534           0 :       break;
    3535             :     case NUMBER_DICTIONARY_TYPE:
    3536           0 :       os << "<NumberDictionary[" << FixedArray::cast(*this)->length() << "]>";
    3537           0 :       break;
    3538             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
    3539           0 :       os << "<SimpleNumberDictionary[" << FixedArray::cast(*this)->length()
    3540           0 :          << "]>";
    3541           0 :       break;
    3542             :     case STRING_TABLE_TYPE:
    3543           0 :       os << "<StringTable[" << FixedArray::cast(*this)->length() << "]>";
    3544           0 :       break;
    3545             :     case FIXED_ARRAY_TYPE:
    3546           0 :       os << "<FixedArray[" << FixedArray::cast(*this)->length() << "]>";
    3547           0 :       break;
    3548             :     case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
    3549          32 :       os << "<ObjectBoilerplateDescription["
    3550          32 :          << FixedArray::cast(*this)->length() << "]>";
    3551          32 :       break;
    3552             :     case FIXED_DOUBLE_ARRAY_TYPE:
    3553           0 :       os << "<FixedDoubleArray[" << FixedDoubleArray::cast(*this)->length()
    3554           0 :          << "]>";
    3555           0 :       break;
    3556             :     case BYTE_ARRAY_TYPE:
    3557           0 :       os << "<ByteArray[" << ByteArray::cast(*this)->length() << "]>";
    3558           0 :       break;
    3559             :     case BYTECODE_ARRAY_TYPE:
    3560         300 :       os << "<BytecodeArray[" << BytecodeArray::cast(*this)->length() << "]>";
    3561         300 :       break;
    3562             :     case DESCRIPTOR_ARRAY_TYPE:
    3563       15867 :       os << "<DescriptorArray["
    3564       31734 :          << DescriptorArray::cast(*this)->number_of_descriptors() << "]>";
    3565       15867 :       break;
    3566             :     case TRANSITION_ARRAY_TYPE:
    3567         125 :       os << "<TransitionArray[" << TransitionArray::cast(*this)->length()
    3568         125 :          << "]>";
    3569         125 :       break;
    3570             :     case PROPERTY_ARRAY_TYPE:
    3571           0 :       os << "<PropertyArray[" << PropertyArray::cast(*this)->length() << "]>";
    3572           0 :       break;
    3573             :     case FEEDBACK_CELL_TYPE: {
    3574             :       {
    3575           0 :         ReadOnlyRoots roots = GetReadOnlyRoots();
    3576           0 :         os << "<FeedbackCell[";
    3577           0 :         if (map() == roots.no_closures_cell_map()) {
    3578           0 :           os << "no feedback";
    3579           0 :         } else if (map() == roots.no_closures_cell_map()) {
    3580           0 :           os << "no closures";
    3581           0 :         } else if (map() == roots.one_closure_cell_map()) {
    3582           0 :           os << "one closure";
    3583           0 :         } else if (map() == roots.many_closures_cell_map()) {
    3584           0 :           os << "many closures";
    3585             :         } else {
    3586           0 :           os << "!!!INVALID MAP!!!";
    3587             :         }
    3588           0 :         os << "]>";
    3589             :       }
    3590           0 :       break;
    3591             :     }
    3592             :     case FEEDBACK_VECTOR_TYPE:
    3593           0 :       os << "<FeedbackVector[" << FeedbackVector::cast(*this)->length() << "]>";
    3594           0 :       break;
    3595             :     case FREE_SPACE_TYPE:
    3596           0 :       os << "<FreeSpace[" << FreeSpace::cast(*this)->size() << "]>";
    3597           0 :       break;
    3598             : #define TYPED_ARRAY_SHORT_PRINT(Type, type, TYPE, ctype)                       \
    3599             :   case FIXED_##TYPE##_ARRAY_TYPE:                                              \
    3600             :     os << "<Fixed" #Type "Array[" << Fixed##Type##Array::cast(*this)->length() \
    3601             :        << "]>";                                                                \
    3602             :     break;
    3603             : 
    3604           0 :       TYPED_ARRAYS(TYPED_ARRAY_SHORT_PRINT)
    3605             : #undef TYPED_ARRAY_SHORT_PRINT
    3606             : 
    3607             :     case PREPARSE_DATA_TYPE: {
    3608             :       PreparseData data = PreparseData::cast(*this);
    3609           0 :       os << "<PreparseData[data=" << data->data_length()
    3610           0 :          << " children=" << data->children_length() << "]>";
    3611             :       break;
    3612             :     }
    3613             : 
    3614             :     case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE: {
    3615             :       UncompiledDataWithoutPreparseData data =
    3616             :           UncompiledDataWithoutPreparseData::cast(*this);
    3617           0 :       os << "<UncompiledDataWithoutPreparseData (" << data->start_position()
    3618           0 :          << ", " << data->end_position() << ")]>";
    3619             :       break;
    3620             :     }
    3621             : 
    3622             :     case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE: {
    3623             :       UncompiledDataWithPreparseData data =
    3624           0 :           UncompiledDataWithPreparseData::cast(*this);
    3625           0 :       os << "<UncompiledDataWithPreparseData (" << data->start_position()
    3626           0 :          << ", " << data->end_position()
    3627           0 :          << ") preparsed=" << Brief(data->preparse_data()) << ">";
    3628             :       break;
    3629             :     }
    3630             : 
    3631             :     case SHARED_FUNCTION_INFO_TYPE: {
    3632          74 :       SharedFunctionInfo shared = SharedFunctionInfo::cast(*this);
    3633         148 :       std::unique_ptr<char[]> debug_name = shared->DebugName()->ToCString();
    3634          74 :       if (debug_name[0] != 0) {
    3635          74 :         os << "<SharedFunctionInfo " << debug_name.get() << ">";
    3636             :       } else {
    3637           0 :         os << "<SharedFunctionInfo>";
    3638             :       }
    3639             :       break;
    3640             :     }
    3641             :     case JS_MESSAGE_OBJECT_TYPE:
    3642           0 :       os << "<JSMessageObject>";
    3643           0 :       break;
    3644             : #define MAKE_STRUCT_CASE(TYPE, Name, name)    \
    3645             :   case TYPE:                                  \
    3646             :     os << "<" #Name;                          \
    3647             :     Name::cast(*this)->BriefPrintDetails(os); \
    3648             :     os << ">";                                \
    3649             :     break;
    3650       11799 :       STRUCT_LIST(MAKE_STRUCT_CASE)
    3651             : #undef MAKE_STRUCT_CASE
    3652             :     case ALLOCATION_SITE_TYPE: {
    3653           0 :       os << "<AllocationSite";
    3654             :       AllocationSite::cast(*this)->BriefPrintDetails(os);
    3655           0 :       os << ">";
    3656           0 :       break;
    3657             :     }
    3658             :     case SCOPE_INFO_TYPE: {
    3659           0 :       ScopeInfo scope = ScopeInfo::cast(*this);
    3660           0 :       os << "<ScopeInfo";
    3661           0 :       if (scope->length()) os << " " << scope->scope_type() << " ";
    3662           0 :       os << "[" << scope->length() << "]>";
    3663             :       break;
    3664             :     }
    3665             :     case CODE_TYPE: {
    3666             :       Code code = Code::cast(*this);
    3667          50 :       os << "<Code " << Code::Kind2String(code->kind());
    3668          50 :       if (code->is_builtin()) {
    3669          50 :         os << " " << Builtins::name(code->builtin_index());
    3670             :       }
    3671          50 :       os << ">";
    3672             :       break;
    3673             :     }
    3674             :     case ODDBALL_TYPE: {
    3675       20363 :       if (IsUndefined()) {
    3676       11103 :         os << "<undefined>";
    3677        9260 :       } else if (IsTheHole()) {
    3678           0 :         os << "<the_hole>";
    3679        9260 :       } else if (IsNull()) {
    3680        6347 :         os << "<null>";
    3681        2913 :       } else if (IsTrue()) {
    3682         129 :         os << "<true>";
    3683        2784 :       } else if (IsFalse()) {
    3684          34 :         os << "<false>";
    3685             :       } else {
    3686        2750 :         os << "<Odd Oddball: ";
    3687        8250 :         os << Oddball::cast(*this)->to_string()->ToCString().get();
    3688        2750 :         os << ">";
    3689             :       }
    3690             :       break;
    3691             :     }
    3692             :     case SYMBOL_TYPE: {
    3693        4303 :       Symbol symbol = Symbol::cast(*this);
    3694        4303 :       symbol->SymbolShortPrint(os);
    3695             :       break;
    3696             :     }
    3697             :     case HEAP_NUMBER_TYPE: {
    3698          81 :       os << "<HeapNumber ";
    3699          81 :       HeapNumber::cast(*this)->HeapNumberPrint(os);
    3700          81 :       os << ">";
    3701          81 :       break;
    3702             :     }
    3703             :     case MUTABLE_HEAP_NUMBER_TYPE: {
    3704           0 :       os << "<MutableHeapNumber ";
    3705           0 :       MutableHeapNumber::cast(*this)->MutableHeapNumberPrint(os);
    3706             :       os << '>';
    3707             :       break;
    3708             :     }
    3709             :     case BIGINT_TYPE: {
    3710           0 :       os << "<BigInt ";
    3711           0 :       BigInt::cast(*this)->BigIntShortPrint(os);
    3712           0 :       os << ">";
    3713           0 :       break;
    3714             :     }
    3715             :     case JS_PROXY_TYPE:
    3716           9 :       os << "<JSProxy>";
    3717           9 :       break;
    3718             :     case FOREIGN_TYPE:
    3719           0 :       os << "<Foreign>";
    3720           0 :       break;
    3721             :     case CELL_TYPE: {
    3722       13208 :       os << "<Cell value= ";
    3723             :       HeapStringAllocator allocator;
    3724             :       StringStream accumulator(&allocator);
    3725       13208 :       Cell::cast(*this)->value()->ShortPrint(&accumulator);
    3726       39624 :       os << accumulator.ToCString().get();
    3727             :       os << '>';
    3728             :       break;
    3729             :     }
    3730             :     case PROPERTY_CELL_TYPE: {
    3731           0 :       PropertyCell cell = PropertyCell::cast(*this);
    3732           0 :       os << "<PropertyCell name=";
    3733           0 :       cell->name()->ShortPrint(os);
    3734           0 :       os << " value=";
    3735             :       HeapStringAllocator allocator;
    3736             :       StringStream accumulator(&allocator);
    3737           0 :       cell->value()->ShortPrint(&accumulator);
    3738           0 :       os << accumulator.ToCString().get();
    3739             :       os << '>';
    3740             :       break;
    3741             :     }
    3742             :     case CALL_HANDLER_INFO_TYPE: {
    3743           0 :       CallHandlerInfo info = CallHandlerInfo::cast(*this);
    3744           0 :       os << "<CallHandlerInfo ";
    3745           0 :       os << "callback= " << Brief(info->callback());
    3746           0 :       os << ", js_callback= " << Brief(info->js_callback());
    3747           0 :       os << ", data= " << Brief(info->data());
    3748           0 :       if (info->IsSideEffectFreeCallHandlerInfo()) {
    3749           0 :         os << ", side_effect_free= true>";
    3750             :       } else {
    3751           0 :         os << ", side_effect_free= false>";
    3752             :       }
    3753             :       break;
    3754             :     }
    3755             :     default:
    3756       15867 :       os << "<Other heap object (" << map()->instance_type() << ")>";
    3757       15867 :       break;
    3758             :   }
    3759             : }
    3760             : 
    3761           0 : void Struct::BriefPrintDetails(std::ostream& os) {}
    3762             : 
    3763         409 : void Tuple2::BriefPrintDetails(std::ostream& os) {
    3764        1227 :   os << " " << Brief(value1()) << ", " << Brief(value2());
    3765         409 : }
    3766             : 
    3767           0 : void Tuple3::BriefPrintDetails(std::ostream& os) {
    3768           0 :   os << " " << Brief(value1()) << ", " << Brief(value2()) << ", "
    3769           0 :      << Brief(value3());
    3770           0 : }
    3771             : 
    3772           0 : void ArrayBoilerplateDescription::BriefPrintDetails(std::ostream& os) {
    3773           0 :   os << " " << elements_kind() << ", " << Brief(constant_elements());
    3774           0 : }
    3775             : 
    3776           0 : void CallableTask::BriefPrintDetails(std::ostream& os) {
    3777           0 :   os << " callable=" << Brief(callable());
    3778           0 : }
    3779             : 
    3780    13391297 : void HeapObject::Iterate(ObjectVisitor* v) { IterateFast<ObjectVisitor>(v); }
    3781             : 
    3782             : 
    3783           0 : void HeapObject::IterateBody(ObjectVisitor* v) {
    3784             :   Map m = map();
    3785           0 :   IterateBodyFast<ObjectVisitor>(m, SizeFromMap(m), v);
    3786           0 : }
    3787             : 
    3788     1837909 : void HeapObject::IterateBody(Map map, int object_size, ObjectVisitor* v) {
    3789             :   IterateBodyFast<ObjectVisitor>(map, object_size, v);
    3790     1837909 : }
    3791             : 
    3792             : 
    3793             : struct CallIsValidSlot {
    3794             :   template <typename BodyDescriptor>
    3795           0 :   static bool apply(Map map, HeapObject obj, int offset, int) {
    3796           0 :     return BodyDescriptor::IsValidSlot(map, obj, offset);
    3797             :   }
    3798             : };
    3799             : 
    3800      767216 : bool HeapObject::IsValidSlot(Map map, int offset) {
    3801             :   DCHECK_NE(0, offset);
    3802             :   return BodyDescriptorApply<CallIsValidSlot, bool>(map->instance_type(), map,
    3803      767216 :                                                     *this, offset, 0);
    3804             : }
    3805             : 
    3806      878167 : String JSReceiver::class_name() {
    3807      878167 :   ReadOnlyRoots roots = GetReadOnlyRoots();
    3808      878167 :   if (IsFunction()) return roots.Function_string();
    3809      878162 :   if (IsJSArgumentsObject()) return roots.Arguments_string();
    3810      878162 :   if (IsJSArray()) return roots.Array_string();
    3811      874287 :   if (IsJSArrayBuffer()) {
    3812           0 :     if (JSArrayBuffer::cast(*this)->is_shared()) {
    3813             :       return roots.SharedArrayBuffer_string();
    3814             :     }
    3815             :     return roots.ArrayBuffer_string();
    3816             :   }
    3817      874287 :   if (IsJSArrayIterator()) return roots.ArrayIterator_string();
    3818      874287 :   if (IsJSDate()) return roots.Date_string();
    3819      874278 :   if (IsJSError()) return roots.Error_string();
    3820      874278 :   if (IsJSGeneratorObject()) return roots.Generator_string();
    3821      874278 :   if (IsJSMap()) return roots.Map_string();
    3822      874278 :   if (IsJSMapIterator()) return roots.MapIterator_string();
    3823      874278 :   if (IsJSProxy()) {
    3824             :     return map()->is_callable() ? roots.Function_string()
    3825        1106 :                                 : roots.Object_string();
    3826             :   }
    3827      873172 :   if (IsJSRegExp()) return roots.RegExp_string();
    3828      872758 :   if (IsJSSet()) return roots.Set_string();
    3829      872758 :   if (IsJSSetIterator()) return roots.SetIterator_string();
    3830      872758 :   if (IsJSTypedArray()) {
    3831             : #define SWITCH_KIND(Type, type, TYPE, ctype)       \
    3832             :   if (map()->elements_kind() == TYPE##_ELEMENTS) { \
    3833             :     return roots.Type##Array_string();             \
    3834             :   }
    3835        4266 :     TYPED_ARRAYS(SWITCH_KIND)
    3836             : #undef SWITCH_KIND
    3837             :   }
    3838      872047 :   if (IsJSValue()) {
    3839        2645 :     Object value = JSValue::cast(*this)->value();
    3840        2645 :     if (value->IsBoolean()) return roots.Boolean_string();
    3841        1812 :     if (value->IsString()) return roots.String_string();
    3842         871 :     if (value->IsNumber()) return roots.Number_string();
    3843          10 :     if (value->IsBigInt()) return roots.BigInt_string();
    3844          10 :     if (value->IsSymbol()) return roots.Symbol_string();
    3845           0 :     if (value->IsScript()) return roots.Script_string();
    3846           0 :     UNREACHABLE();
    3847             :   }
    3848      869402 :   if (IsJSWeakMap()) return roots.WeakMap_string();
    3849      869402 :   if (IsJSWeakSet()) return roots.WeakSet_string();
    3850      869402 :   if (IsJSGlobalProxy()) return roots.global_string();
    3851             : 
    3852      815292 :   Object maybe_constructor = map()->GetConstructor();
    3853      815292 :   if (maybe_constructor->IsJSFunction()) {
    3854      815160 :     JSFunction constructor = JSFunction::cast(maybe_constructor);
    3855      815160 :     if (constructor->shared()->IsApiFunction()) {
    3856        3045 :       maybe_constructor = constructor->shared()->get_api_func_data();
    3857             :     }
    3858             :   }
    3859             : 
    3860      815292 :   if (maybe_constructor->IsFunctionTemplateInfo()) {
    3861        3046 :     FunctionTemplateInfo info = FunctionTemplateInfo::cast(maybe_constructor);
    3862        6115 :     if (info->class_name()->IsString()) return String::cast(info->class_name());
    3863             :   }
    3864             : 
    3865             :   return roots.Object_string();
    3866             : }
    3867             : 
    3868       35660 : bool HeapObject::CanBeRehashed() const {
    3869             :   DCHECK(NeedsRehashing());
    3870       35660 :   switch (map()->instance_type()) {
    3871             :     case ORDERED_HASH_MAP_TYPE:
    3872             :     case ORDERED_HASH_SET_TYPE:
    3873             :     case ORDERED_NAME_DICTIONARY_TYPE:
    3874             :       // TODO(yangguo): actually support rehashing OrderedHash{Map,Set}.
    3875             :       return false;
    3876             :     case NAME_DICTIONARY_TYPE:
    3877             :     case GLOBAL_DICTIONARY_TYPE:
    3878             :     case NUMBER_DICTIONARY_TYPE:
    3879             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
    3880             :     case STRING_TABLE_TYPE:
    3881        1260 :       return true;
    3882             :     case DESCRIPTOR_ARRAY_TYPE:
    3883       34390 :       return true;
    3884             :     case TRANSITION_ARRAY_TYPE:
    3885           5 :       return true;
    3886             :     case SMALL_ORDERED_HASH_MAP_TYPE:
    3887           0 :       return SmallOrderedHashMap::cast(*this)->NumberOfElements() == 0;
    3888             :     case SMALL_ORDERED_HASH_SET_TYPE:
    3889           0 :       return SmallOrderedHashMap::cast(*this)->NumberOfElements() == 0;
    3890             :     case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
    3891           0 :       return SmallOrderedNameDictionary::cast(*this)->NumberOfElements() == 0;
    3892             :     default:
    3893             :       return false;
    3894             :   }
    3895             :   return false;
    3896             : }
    3897             : 
    3898    14229956 : void HeapObject::RehashBasedOnMap(Isolate* isolate) {
    3899    14229956 :   switch (map()->instance_type()) {
    3900             :     case HASH_TABLE_TYPE:
    3901           0 :       UNREACHABLE();
    3902             :       break;
    3903             :     case NAME_DICTIONARY_TYPE:
    3904       62822 :       NameDictionary::cast(*this)->Rehash(isolate);
    3905       62822 :       break;
    3906             :     case GLOBAL_DICTIONARY_TYPE:
    3907       91775 :       GlobalDictionary::cast(*this)->Rehash(isolate);
    3908       91775 :       break;
    3909             :     case NUMBER_DICTIONARY_TYPE:
    3910       62772 :       NumberDictionary::cast(*this)->Rehash(isolate);
    3911       62772 :       break;
    3912             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
    3913       91775 :       SimpleNumberDictionary::cast(*this)->Rehash(isolate);
    3914       91775 :       break;
    3915             :     case STRING_TABLE_TYPE:
    3916       62767 :       StringTable::cast(*this)->Rehash(isolate);
    3917       62767 :       break;
    3918             :     case DESCRIPTOR_ARRAY_TYPE:
    3919             :       DCHECK_LE(1, DescriptorArray::cast(*this)->number_of_descriptors());
    3920    13858044 :       DescriptorArray::cast(*this)->Sort();
    3921    13858040 :       break;
    3922             :     case TRANSITION_ARRAY_TYPE:
    3923           5 :       TransitionArray::cast(*this)->Sort();
    3924           5 :       break;
    3925             :     case SMALL_ORDERED_HASH_MAP_TYPE:
    3926             :       DCHECK_EQ(0, SmallOrderedHashMap::cast(*this)->NumberOfElements());
    3927             :       break;
    3928             :     case SMALL_ORDERED_HASH_SET_TYPE:
    3929             :       DCHECK_EQ(0, SmallOrderedHashSet::cast(*this)->NumberOfElements());
    3930             :       break;
    3931             :     case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
    3932             :       DCHECK_EQ(0, SmallOrderedNameDictionary::cast(*this)->NumberOfElements());
    3933             :       break;
    3934             :     default:
    3935             :       break;
    3936             :   }
    3937    14229952 : }
    3938             : 
    3939             : namespace {
    3940     3911543 : std::pair<MaybeHandle<JSFunction>, Handle<String>> GetConstructorHelper(
    3941             :     Handle<JSReceiver> receiver) {
    3942             :   Isolate* isolate = receiver->GetIsolate();
    3943             : 
    3944             :   // If the object was instantiated simply with base == new.target, the
    3945             :   // constructor on the map provides the most accurate name.
    3946             :   // Don't provide the info for prototypes, since their constructors are
    3947             :   // reclaimed and replaced by Object in OptimizeAsPrototype.
    3948    15645535 :   if (!receiver->IsJSProxy() && receiver->map()->new_target_is_base() &&
    3949             :       !receiver->map()->is_prototype_map()) {
    3950     3737674 :     Object maybe_constructor = receiver->map()->GetConstructor();
    3951     3737674 :     if (maybe_constructor->IsJSFunction()) {
    3952     3499024 :       JSFunction constructor = JSFunction::cast(maybe_constructor);
    3953     3499024 :       String name = constructor->shared()->DebugName();
    3954     6402828 :       if (name->length() != 0 &&
    3955     2903804 :           !name->Equals(ReadOnlyRoots(isolate).Object_string())) {
    3956             :         return std::make_pair(handle(constructor, isolate),
    3957     2023241 :                               handle(name, isolate));
    3958             :       }
    3959      238650 :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
    3960           0 :       FunctionTemplateInfo info = FunctionTemplateInfo::cast(maybe_constructor);
    3961           0 :       if (info->class_name()->IsString()) {
    3962             :         return std::make_pair(
    3963             :             MaybeHandle<JSFunction>(),
    3964           0 :             handle(String::cast(info->class_name()), isolate));
    3965             :       }
    3966             :     }
    3967             :   }
    3968             : 
    3969             :   Handle<Object> maybe_tag = JSReceiver::GetDataProperty(
    3970     1888302 :       receiver, isolate->factory()->to_string_tag_symbol());
    3971     3776604 :   if (maybe_tag->IsString())
    3972             :     return std::make_pair(MaybeHandle<JSFunction>(),
    3973     1428846 :                           Handle<String>::cast(maybe_tag));
    3974             : 
    3975     1173879 :   PrototypeIterator iter(isolate, receiver);
    3976     1173879 :   if (iter.IsAtEnd()) {
    3977             :     return std::make_pair(MaybeHandle<JSFunction>(),
    3978      952716 :                           handle(receiver->class_name(), isolate));
    3979             :   }
    3980             : 
    3981      697521 :   Handle<JSReceiver> start = PrototypeIterator::GetCurrent<JSReceiver>(iter);
    3982             :   LookupIterator it(receiver, isolate->factory()->constructor_string(), start,
    3983      697521 :                     LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
    3984      697521 :   Handle<Object> maybe_constructor = JSReceiver::GetDataProperty(&it);
    3985     1395042 :   if (maybe_constructor->IsJSFunction()) {
    3986      697521 :     JSFunction constructor = JSFunction::cast(*maybe_constructor);
    3987      697521 :     String name = constructor->shared()->DebugName();
    3988             : 
    3989     1341372 :     if (name->length() != 0 &&
    3990      643851 :         !name->Equals(ReadOnlyRoots(isolate).Object_string())) {
    3991             :       return std::make_pair(handle(constructor, isolate),
    3992      307246 :                             handle(name, isolate));
    3993             :     }
    3994             :   }
    3995             : 
    3996             :   return std::make_pair(MaybeHandle<JSFunction>(),
    3997      780550 :                         handle(receiver->class_name(), isolate));
    3998             : }
    3999             : }  // anonymous namespace
    4000             : 
    4001             : // static
    4002      143253 : MaybeHandle<JSFunction> JSReceiver::GetConstructor(
    4003             :     Handle<JSReceiver> receiver) {
    4004      143253 :   return GetConstructorHelper(receiver).first;
    4005             : }
    4006             : 
    4007             : // static
    4008     3768290 : Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
    4009     3768290 :   return GetConstructorHelper(receiver).second;
    4010             : }
    4011             : 
    4012      417970 : Handle<Context> JSReceiver::GetCreationContext() {
    4013      417970 :   JSReceiver receiver = *this;
    4014             :   // Externals are JSObjects with null as a constructor.
    4015             :   DCHECK(!receiver->IsExternal(GetIsolate()));
    4016      417970 :   Object constructor = receiver->map()->GetConstructor();
    4017      417970 :   JSFunction function;
    4018      417970 :   if (constructor->IsJSFunction()) {
    4019      211589 :     function = JSFunction::cast(constructor);
    4020      206381 :   } else if (constructor->IsFunctionTemplateInfo()) {
    4021             :     // Remote objects don't have a creation context.
    4022           2 :     return Handle<Context>::null();
    4023      206379 :   } else if (receiver->IsJSGeneratorObject()) {
    4024           0 :     function = JSGeneratorObject::cast(receiver)->function();
    4025             :   } else {
    4026             :     // Functions have null as a constructor,
    4027             :     // but any JSFunction knows its context immediately.
    4028      206379 :     CHECK(receiver->IsJSFunction());
    4029      206379 :     function = JSFunction::cast(receiver);
    4030             :   }
    4031             : 
    4032      417968 :   return function->has_context()
    4033     1253904 :              ? Handle<Context>(function->context()->native_context(),
    4034             :                                receiver->GetIsolate())
    4035      835936 :              : Handle<Context>::null();
    4036             : }
    4037             : 
    4038             : // static
    4039     7595180 : MaybeObjectHandle Map::WrapFieldType(Isolate* isolate, Handle<FieldType> type) {
    4040     7595186 :   if (type->IsClass()) {
    4041     1494974 :     return MaybeObjectHandle::Weak(type->AsClass(), isolate);
    4042             :   }
    4043     6847697 :   return MaybeObjectHandle(type);
    4044             : }
    4045             : 
    4046             : // static
    4047    39420503 : FieldType Map::UnwrapFieldType(MaybeObject wrapped_type) {
    4048    39420503 :   if (wrapped_type->IsCleared()) {
    4049          45 :     return FieldType::None();
    4050             :   }
    4051    39420458 :   HeapObject heap_object;
    4052    39420458 :   if (wrapped_type->GetHeapObjectIfWeak(&heap_object)) {
    4053     2640083 :     return FieldType::cast(heap_object);
    4054             :   }
    4055             :   return wrapped_type->cast<FieldType>();
    4056             : }
    4057             : 
    4058     7292153 : MaybeHandle<Map> Map::CopyWithField(Isolate* isolate, Handle<Map> map,
    4059             :                                     Handle<Name> name, Handle<FieldType> type,
    4060             :                                     PropertyAttributes attributes,
    4061             :                                     PropertyConstness constness,
    4062             :                                     Representation representation,
    4063             :                                     TransitionFlag flag) {
    4064             :   DCHECK(DescriptorArray::kNotFound ==
    4065             :          map->instance_descriptors()->Search(
    4066             :              *name, map->NumberOfOwnDescriptors()));
    4067             : 
    4068             :   // Ensure the descriptor array does not get too big.
    4069     7292156 :   if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
    4070          82 :     return MaybeHandle<Map>();
    4071             :   }
    4072             : 
    4073             :   // Compute the new index for new field.
    4074     7292075 :   int index = map->NextFreePropertyIndex();
    4075             : 
    4076     7292077 :   if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) {
    4077             :     constness = PropertyConstness::kMutable;
    4078        2946 :     representation = Representation::Tagged();
    4079        2946 :     type = FieldType::Any(isolate);
    4080             :   } else {
    4081             :     Map::GeneralizeIfCanHaveTransitionableFastElementsKind(
    4082     7289127 :         isolate, map->instance_type(), &constness, &representation, &type);
    4083             :   }
    4084             : 
    4085     7292076 :   MaybeObjectHandle wrapped_type = WrapFieldType(isolate, type);
    4086             : 
    4087             :   DCHECK_IMPLIES(!FLAG_track_constant_fields,
    4088             :                  constness == PropertyConstness::kMutable);
    4089             :   Descriptor d = Descriptor::DataField(name, index, attributes, constness,
    4090     7292075 :                                        representation, wrapped_type);
    4091     7292076 :   Handle<Map> new_map = Map::CopyAddDescriptor(isolate, map, &d, flag);
    4092     7292076 :   new_map->AccountAddedPropertyField();
    4093     7292075 :   return new_map;
    4094             : }
    4095             : 
    4096     9768767 : MaybeHandle<Map> Map::CopyWithConstant(Isolate* isolate, Handle<Map> map,
    4097             :                                        Handle<Name> name,
    4098             :                                        Handle<Object> constant,
    4099             :                                        PropertyAttributes attributes,
    4100             :                                        TransitionFlag flag) {
    4101             :   // Ensure the descriptor array does not get too big.
    4102     9768774 :   if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
    4103          14 :     return MaybeHandle<Map>();
    4104             :   }
    4105             : 
    4106             :   if (FLAG_track_constant_fields) {
    4107             :     Representation representation = constant->OptimalRepresentation();
    4108             :     Handle<FieldType> type = constant->OptimalType(isolate, representation);
    4109             :     return CopyWithField(isolate, map, name, type, attributes,
    4110             :                          PropertyConstness::kConst, representation, flag);
    4111             :   } else {
    4112             :     // Allocate new instance descriptors with (name, constant) added.
    4113             :     Descriptor d =
    4114     9768760 :         Descriptor::DataConstant(isolate, name, 0, constant, attributes);
    4115     9768771 :     Handle<Map> new_map = Map::CopyAddDescriptor(isolate, map, &d, flag);
    4116     9768762 :     return new_map;
    4117             :   }
    4118             : }
    4119             : 
    4120       10744 : const char* Representation::Mnemonic() const {
    4121       10744 :   switch (kind_) {
    4122             :     case kNone: return "v";
    4123        1890 :     case kTagged: return "t";
    4124        5758 :     case kSmi: return "s";
    4125         508 :     case kDouble: return "d";
    4126           0 :     case kInteger32: return "i";
    4127        2588 :     case kHeapObject: return "h";
    4128           0 :     case kExternal: return "x";
    4129             :     default:
    4130           0 :       UNREACHABLE();
    4131             :   }
    4132             : }
    4133             : 
    4134           0 : bool Map::TransitionRemovesTaggedField(Map target) const {
    4135           0 :   int inobject = NumberOfFields();
    4136           0 :   int target_inobject = target->NumberOfFields();
    4137           0 :   for (int i = target_inobject; i < inobject; i++) {
    4138           0 :     FieldIndex index = FieldIndex::ForPropertyIndex(*this, i);
    4139           0 :     if (!IsUnboxedDoubleField(index)) return true;
    4140             :   }
    4141             :   return false;
    4142             : }
    4143             : 
    4144           0 : bool Map::TransitionChangesTaggedFieldToUntaggedField(Map target) const {
    4145           0 :   int inobject = NumberOfFields();
    4146           0 :   int target_inobject = target->NumberOfFields();
    4147             :   int limit = Min(inobject, target_inobject);
    4148           0 :   for (int i = 0; i < limit; i++) {
    4149           0 :     FieldIndex index = FieldIndex::ForPropertyIndex(target, i);
    4150           0 :     if (!IsUnboxedDoubleField(index) && target->IsUnboxedDoubleField(index)) {
    4151           0 :       return true;
    4152             :     }
    4153             :   }
    4154             :   return false;
    4155             : }
    4156             : 
    4157           0 : bool Map::TransitionRequiresSynchronizationWithGC(Map target) const {
    4158           0 :   return TransitionRemovesTaggedField(target) ||
    4159           0 :          TransitionChangesTaggedFieldToUntaggedField(target);
    4160             : }
    4161             : 
    4162       80120 : bool Map::InstancesNeedRewriting(Map target) const {
    4163       80120 :   int target_number_of_fields = target->NumberOfFields();
    4164       80121 :   int target_inobject = target->GetInObjectProperties();
    4165       80121 :   int target_unused = target->UnusedPropertyFields();
    4166             :   int old_number_of_fields;
    4167             : 
    4168             :   return InstancesNeedRewriting(target, target_number_of_fields,
    4169             :                                 target_inobject, target_unused,
    4170       80121 :                                 &old_number_of_fields);
    4171             : }
    4172             : 
    4173    16914123 : bool Map::InstancesNeedRewriting(Map target, int target_number_of_fields,
    4174             :                                  int target_inobject, int target_unused,
    4175             :                                  int* old_number_of_fields) const {
    4176             :   // If fields were added (or removed), rewrite the instance.
    4177    16914123 :   *old_number_of_fields = NumberOfFields();
    4178             :   DCHECK(target_number_of_fields >= *old_number_of_fields);
    4179    16914134 :   if (target_number_of_fields != *old_number_of_fields) return true;
    4180             : 
    4181             :   // If smi descriptors were replaced by double descriptors, rewrite.
    4182    15154478 :   DescriptorArray old_desc = instance_descriptors();
    4183    15154482 :   DescriptorArray new_desc = target->instance_descriptors();
    4184             :   int limit = NumberOfOwnDescriptors();
    4185    57316631 :   for (int i = 0; i < limit; i++) {
    4186    84329059 :     if (new_desc->GetDetails(i).representation().IsDouble() !=
    4187    84329052 :         old_desc->GetDetails(i).representation().IsDouble()) {
    4188             :       return true;
    4189             :     }
    4190             :   }
    4191             : 
    4192             :   // If no fields were added, and no inobject properties were removed, setting
    4193             :   // the map is sufficient.
    4194    15152095 :   if (target_inobject == GetInObjectProperties()) return false;
    4195             :   // In-object slack tracking may have reduced the object size of the new map.
    4196             :   // In that case, succeed if all existing fields were inobject, and they still
    4197             :   // fit within the new inobject size.
    4198             :   DCHECK(target_inobject < GetInObjectProperties());
    4199           1 :   if (target_number_of_fields <= target_inobject) {
    4200             :     DCHECK(target_number_of_fields + target_unused == target_inobject);
    4201             :     return false;
    4202             :   }
    4203             :   // Otherwise, properties will need to be moved to the backing store.
    4204           0 :   return true;
    4205             : }
    4206             : 
    4207             : 
    4208             : // static
    4209     4252989 : void JSObject::UpdatePrototypeUserRegistration(Handle<Map> old_map,
    4210             :                                                Handle<Map> new_map,
    4211             :                                                Isolate* isolate) {
    4212             :   DCHECK(old_map->is_prototype_map());
    4213             :   DCHECK(new_map->is_prototype_map());
    4214     4252989 :   bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
    4215     4252987 :   new_map->set_prototype_info(old_map->prototype_info());
    4216     4252987 :   old_map->set_prototype_info(Smi::kZero);
    4217     4252992 :   if (FLAG_trace_prototype_users) {
    4218             :     PrintF("Moving prototype_info %p from map %p to map %p.\n",
    4219             :            reinterpret_cast<void*>(new_map->prototype_info()->ptr()),
    4220             :            reinterpret_cast<void*>(old_map->ptr()),
    4221           0 :            reinterpret_cast<void*>(new_map->ptr()));
    4222             :   }
    4223     4252986 :   if (was_registered) {
    4224      384498 :     if (new_map->prototype_info()->IsPrototypeInfo()) {
    4225             :       // The new map isn't registered with its prototype yet; reflect this fact
    4226             :       // in the PrototypeInfo it just inherited from the old map.
    4227             :       PrototypeInfo::cast(new_map->prototype_info())
    4228             :           ->set_registry_slot(PrototypeInfo::UNREGISTERED);
    4229             :     }
    4230      192249 :     JSObject::LazyRegisterPrototypeUser(new_map, isolate);
    4231             :   }
    4232     4252987 : }
    4233             : 
    4234             : namespace {
    4235             : // To migrate a fast instance to a fast map:
    4236             : // - First check whether the instance needs to be rewritten. If not, simply
    4237             : //   change the map.
    4238             : // - Otherwise, allocate a fixed array large enough to hold all fields, in
    4239             : //   addition to unused space.
    4240             : // - Copy all existing properties in, in the following order: backing store
    4241             : //   properties, unused fields, inobject properties.
    4242             : // - If all allocation succeeded, commit the state atomically:
    4243             : //   * Copy inobject properties from the backing store back into the object.
    4244             : //   * Trim the difference in instance size of the object. This also cleanly
    4245             : //     frees inobject properties that moved to the backing store.
    4246             : //   * If there are properties left in the backing store, trim of the space used
    4247             : //     to temporarily store the inobject properties.
    4248             : //   * If there are properties left in the backing store, install the backing
    4249             : //     store.
    4250    28856456 : void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
    4251             :   Isolate* isolate = object->GetIsolate();
    4252             :   Handle<Map> old_map(object->map(), isolate);
    4253             :   // In case of a regular transition.
    4254    57712991 :   if (new_map->GetBackPointer() == *old_map) {
    4255             :     // If the map does not add named properties, simply set the map.
    4256    12022471 :     if (old_map->NumberOfOwnDescriptors() ==
    4257             :         new_map->NumberOfOwnDescriptors()) {
    4258      541987 :       object->synchronized_set_map(*new_map);
    4259      541975 :       return;
    4260             :     }
    4261             : 
    4262    11480490 :     PropertyDetails details = new_map->GetLastDescriptorDetails();
    4263    11480488 :     int target_index = details.field_index() - new_map->GetInObjectProperties();
    4264    22960982 :     int property_array_length = object->property_array()->length();
    4265    26155486 :     bool have_space = old_map->UnusedPropertyFields() > 0 ||
    4266     6138922 :                       (details.location() == kField && target_index >= 0 &&
    4267     3069461 :                        property_array_length > target_index);
    4268             :     // Either new_map adds an kDescriptor property, or a kField property for
    4269             :     // which there is still space, and which does not require a mutable double
    4270             :     // box (an out-of-object double).
    4271    22960980 :     if (details.location() == kDescriptor ||
    4272    11988181 :         (have_space && ((FLAG_unbox_double_fields && target_index < 0) ||
    4273             :                         !details.representation().IsDouble()))) {
    4274     8408314 :       object->synchronized_set_map(*new_map);
    4275     8408307 :       return;
    4276             :     }
    4277             : 
    4278             :     // If there is still space in the object, we need to allocate a mutable
    4279             :     // double box.
    4280     3072182 :     if (have_space) {
    4281             :       FieldIndex index =
    4282        6000 :           FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
    4283             :       DCHECK(details.representation().IsDouble());
    4284             :       DCHECK(!new_map->IsUnboxedDoubleField(index));
    4285             :       auto value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
    4286        6000 :       object->RawFastPropertyAtPut(index, *value);
    4287        3000 :       object->synchronized_set_map(*new_map);
    4288             :       return;
    4289             :     }
    4290             : 
    4291             :     // This migration is a transition from a map that has run out of property
    4292             :     // space. Extend the backing store.
    4293     3069182 :     int grow_by = new_map->UnusedPropertyFields() + 1;
    4294     6138364 :     Handle<PropertyArray> old_storage(object->property_array(), isolate);
    4295             :     Handle<PropertyArray> new_storage =
    4296     3069182 :         isolate->factory()->CopyPropertyArrayAndGrow(old_storage, grow_by);
    4297             : 
    4298             :     // Properly initialize newly added property.
    4299             :     Handle<Object> value;
    4300     3069182 :     if (details.representation().IsDouble()) {
    4301             :       value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
    4302             :     } else {
    4303             :       value = isolate->factory()->uninitialized_value();
    4304             :     }
    4305             :     DCHECK_EQ(kField, details.location());
    4306             :     DCHECK_EQ(kData, details.kind());
    4307             :     DCHECK_GE(target_index, 0);  // Must be a backing store index.
    4308     3069182 :     new_storage->set(target_index, *value);
    4309             : 
    4310             :     // From here on we cannot fail and we shouldn't GC anymore.
    4311             :     DisallowHeapAllocation no_allocation;
    4312             : 
    4313             :     // Set the new property value and do the map transition.
    4314     6138364 :     object->SetProperties(*new_storage);
    4315     3069182 :     object->synchronized_set_map(*new_map);
    4316     3069182 :     return;
    4317             :   }
    4318             : 
    4319             :   int old_number_of_fields;
    4320    16834005 :   int number_of_fields = new_map->NumberOfFields();
    4321    16834012 :   int inobject = new_map->GetInObjectProperties();
    4322    16834009 :   int unused = new_map->UnusedPropertyFields();
    4323             : 
    4324             :   // Nothing to do if no functions were converted to fields and no smis were
    4325             :   // converted to doubles.
    4326    16834013 :   if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
    4327    16834010 :                                        unused, &old_number_of_fields)) {
    4328    15072005 :     object->synchronized_set_map(*new_map);
    4329    15072013 :     return;
    4330             :   }
    4331             : 
    4332     1762005 :   int total_size = number_of_fields + unused;
    4333     1762005 :   int external = total_size - inobject;
    4334     1762005 :   Handle<PropertyArray> array = isolate->factory()->NewPropertyArray(external);
    4335             : 
    4336             :   // We use this array to temporarily store the inobject properties.
    4337             :   Handle<FixedArray> inobject_props =
    4338     1762004 :       isolate->factory()->NewFixedArray(inobject);
    4339             : 
    4340             :   Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors(),
    4341     3524012 :                                           isolate);
    4342             :   Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors(),
    4343     3524015 :                                           isolate);
    4344             :   int old_nof = old_map->NumberOfOwnDescriptors();
    4345             :   int new_nof = new_map->NumberOfOwnDescriptors();
    4346             : 
    4347             :   // This method only supports generalizing instances to at least the same
    4348             :   // number of properties.
    4349             :   DCHECK(old_nof <= new_nof);
    4350             : 
    4351    55705707 :   for (int i = 0; i < old_nof; i++) {
    4352    53943703 :     PropertyDetails details = new_descriptors->GetDetails(i);
    4353    53943703 :     if (details.location() != kField) continue;
    4354             :     DCHECK_EQ(kData, details.kind());
    4355    43934923 :     PropertyDetails old_details = old_descriptors->GetDetails(i);
    4356             :     Representation old_representation = old_details.representation();
    4357             :     Representation representation = details.representation();
    4358             :     Handle<Object> value;
    4359    43934924 :     if (old_details.location() == kDescriptor) {
    4360       20900 :       if (old_details.kind() == kAccessor) {
    4361             :         // In case of kAccessor -> kData property reconfiguration, the property
    4362             :         // must already be prepared for data of certain type.
    4363             :         DCHECK(!details.representation().IsNone());
    4364       14843 :         if (details.representation().IsDouble()) {
    4365             :           value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
    4366             :         } else {
    4367             :           value = isolate->factory()->uninitialized_value();
    4368             :         }
    4369             :       } else {
    4370             :         DCHECK_EQ(kData, old_details.kind());
    4371       12114 :         value = handle(old_descriptors->GetStrongValue(i), isolate);
    4372             :         DCHECK(!old_representation.IsDouble() && !representation.IsDouble());
    4373             :       }
    4374             :     } else {
    4375             :       DCHECK_EQ(kField, old_details.location());
    4376    43914023 :       FieldIndex index = FieldIndex::ForDescriptor(*old_map, i);
    4377    43914022 :       if (object->IsUnboxedDoubleField(index)) {
    4378             :         uint64_t old_bits = object->RawFastDoublePropertyAsBitsAt(index);
    4379        6119 :         if (representation.IsDouble()) {
    4380        5440 :           value = isolate->factory()->NewMutableHeapNumberFromBits(old_bits);
    4381             :         } else {
    4382         679 :           value = isolate->factory()->NewHeapNumberFromBits(old_bits);
    4383             :         }
    4384             :       } else {
    4385    87815805 :         value = handle(object->RawFastPropertyAt(index), isolate);
    4386    43907902 :         if (!old_representation.IsDouble() && representation.IsDouble()) {
    4387             :           DCHECK_IMPLIES(old_representation.IsNone(),
    4388             :                          value->IsUninitialized(isolate));
    4389        1932 :           value = Object::NewStorageFor(isolate, value, representation);
    4390    43905970 :         } else if (old_representation.IsDouble() &&
    4391             :                    !representation.IsDouble()) {
    4392         609 :           value = Object::WrapForRead(isolate, value, old_representation);
    4393             :         }
    4394             :       }
    4395             :     }
    4396             :     DCHECK(!(representation.IsDouble() && value->IsSmi()));
    4397    87869842 :     int target_index = new_descriptors->GetFieldIndex(i);
    4398    43934921 :     if (target_index < inobject) {
    4399      307044 :       inobject_props->set(target_index, *value);
    4400             :     } else {
    4401    87255757 :       array->set(target_index - inobject, *value);
    4402             :     }
    4403             :   }
    4404             : 
    4405     1738831 :   for (int i = old_nof; i < new_nof; i++) {
    4406     1738828 :     PropertyDetails details = new_descriptors->GetDetails(i);
    4407     1738828 :     if (details.location() != kField) continue;
    4408             :     DCHECK_EQ(kData, details.kind());
    4409             :     Handle<Object> value;
    4410     1738828 :     if (details.representation().IsDouble()) {
    4411             :       value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
    4412             :     } else {
    4413             :       value = isolate->factory()->uninitialized_value();
    4414             :     }
    4415     3477660 :     int target_index = new_descriptors->GetFieldIndex(i);
    4416     1738830 :     if (target_index < inobject) {
    4417      841456 :       inobject_props->set(target_index, *value);
    4418             :     } else {
    4419     1794750 :       array->set(target_index - inobject, *value);
    4420             :     }
    4421             :   }
    4422             : 
    4423             :   // From here on we cannot fail and we shouldn't GC anymore.
    4424             :   DisallowHeapAllocation no_allocation;
    4425             : 
    4426     1762007 :   Heap* heap = isolate->heap();
    4427             : 
    4428             :   int old_instance_size = old_map->instance_size();
    4429             : 
    4430     1762005 :   heap->NotifyObjectLayoutChange(*object, old_instance_size, no_allocation);
    4431             : 
    4432             :   // Copy (real) inobject properties. If necessary, stop at number_of_fields to
    4433             :   // avoid overwriting |one_pointer_filler_map|.
    4434             :   int limit = Min(inobject, number_of_fields);
    4435     2910501 :   for (int i = 0; i < limit; i++) {
    4436     1148499 :     FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
    4437             :     Object value = inobject_props->get(i);
    4438             :     // Can't use JSObject::FastPropertyAtPut() because proper map was not set
    4439             :     // yet.
    4440     1148500 :     if (new_map->IsUnboxedDoubleField(index)) {
    4441             :       DCHECK(value->IsMutableHeapNumber());
    4442             :       // Ensure that all bits of the double value are preserved.
    4443             :       object->RawFastDoublePropertyAsBitsAtPut(
    4444             :           index, MutableHeapNumber::cast(value)->value_as_bits());
    4445       14054 :       if (i < old_number_of_fields && !old_map->IsUnboxedDoubleField(index)) {
    4446             :         // Transition from tagged to untagged slot.
    4447             :         heap->ClearRecordedSlot(*object,
    4448        1366 :                                 HeapObject::RawField(*object, index.offset()));
    4449             :       } else {
    4450             : #ifdef DEBUG
    4451             :         heap->VerifyClearedSlot(*object,
    4452             :                                 HeapObject::RawField(*object, index.offset()));
    4453             : #endif
    4454             :       }
    4455             :     } else {
    4456     1141241 :       object->RawFastPropertyAtPut(index, value);
    4457             :     }
    4458             :   }
    4459             : 
    4460     3524010 :   object->SetProperties(*array);
    4461             : 
    4462             :   // Create filler object past the new instance size.
    4463             :   int new_instance_size = new_map->instance_size();
    4464     1762005 :   int instance_size_delta = old_instance_size - new_instance_size;
    4465             :   DCHECK_GE(instance_size_delta, 0);
    4466             : 
    4467     1762005 :   if (instance_size_delta > 0) {
    4468             :     Address address = object->address();
    4469             :     heap->CreateFillerObjectAt(address + new_instance_size, instance_size_delta,
    4470          12 :                                ClearRecordedSlots::kYes);
    4471             :   }
    4472             : 
    4473             :   // We are storing the new map using release store after creating a filler for
    4474             :   // the left-over space to avoid races with the sweeper thread.
    4475     1762004 :   object->synchronized_set_map(*new_map);
    4476             : }
    4477             : 
    4478      679150 : void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
    4479             :                        int expected_additional_properties) {
    4480             :   // The global object is always normalized.
    4481             :   DCHECK(!object->IsJSGlobalObject());
    4482             :   // JSGlobalProxy must never be normalized
    4483             :   DCHECK(!object->IsJSGlobalProxy());
    4484             : 
    4485             :   DCHECK_IMPLIES(new_map->is_prototype_map(),
    4486             :                  Map::IsPrototypeChainInvalidated(*new_map));
    4487             : 
    4488             :   Isolate* isolate = object->GetIsolate();
    4489             :   HandleScope scope(isolate);
    4490             :   Handle<Map> map(object->map(), isolate);
    4491             : 
    4492             :   // Allocate new content.
    4493             :   int real_size = map->NumberOfOwnDescriptors();
    4494             :   int property_count = real_size;
    4495      679152 :   if (expected_additional_properties > 0) {
    4496         552 :     property_count += expected_additional_properties;
    4497             :   } else {
    4498             :     // Make space for two more properties.
    4499      678600 :     property_count += NameDictionary::kInitialCapacity;
    4500             :   }
    4501             :   Handle<NameDictionary> dictionary =
    4502      679152 :       NameDictionary::New(isolate, property_count);
    4503             : 
    4504     1358302 :   Handle<DescriptorArray> descs(map->instance_descriptors(), isolate);
    4505     3312012 :   for (int i = 0; i < real_size; i++) {
    4506     2632858 :     PropertyDetails details = descs->GetDetails(i);
    4507     5265701 :     Handle<Name> key(descs->GetKey(i), isolate);
    4508             :     Handle<Object> value;
    4509     2632844 :     if (details.location() == kField) {
    4510     1838741 :       FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    4511     1838741 :       if (details.kind() == kData) {
    4512     1838741 :         if (object->IsUnboxedDoubleField(index)) {
    4513             :           double old_value = object->RawFastDoublePropertyAt(index);
    4514         979 :           value = isolate->factory()->NewHeapNumber(old_value);
    4515             :         } else {
    4516     3675524 :           value = handle(object->RawFastPropertyAt(index), isolate);
    4517     1837762 :           if (details.representation().IsDouble()) {
    4518             :             DCHECK(value->IsMutableHeapNumber());
    4519         370 :             double old_value = Handle<MutableHeapNumber>::cast(value)->value();
    4520         185 :             value = isolate->factory()->NewHeapNumber(old_value);
    4521             :           }
    4522             :         }
    4523             :       } else {
    4524             :         DCHECK_EQ(kAccessor, details.kind());
    4525           0 :         value = handle(object->RawFastPropertyAt(index), isolate);
    4526             :       }
    4527             : 
    4528             :     } else {
    4529             :       DCHECK_EQ(kDescriptor, details.location());
    4530     1588206 :       value = handle(descs->GetStrongValue(i), isolate);
    4531             :     }
    4532             :     DCHECK(!value.is_null());
    4533             :     PropertyDetails d(details.kind(), details.attributes(),
    4534             :                       PropertyCellType::kNoCell);
    4535     2632847 :     dictionary = NameDictionary::Add(isolate, dictionary, key, value, d);
    4536             :   }
    4537             : 
    4538             :   // Copy the next enumeration index from instance descriptor.
    4539      679154 :   dictionary->SetNextEnumerationIndex(real_size + 1);
    4540             : 
    4541             :   // From here on we cannot fail and we shouldn't GC anymore.
    4542             :   DisallowHeapAllocation no_allocation;
    4543             : 
    4544      679154 :   Heap* heap = isolate->heap();
    4545             :   int old_instance_size = map->instance_size();
    4546      679154 :   heap->NotifyObjectLayoutChange(*object, old_instance_size, no_allocation);
    4547             : 
    4548             :   // Resize the object in the heap if necessary.
    4549             :   int new_instance_size = new_map->instance_size();
    4550      679152 :   int instance_size_delta = old_instance_size - new_instance_size;
    4551             :   DCHECK_GE(instance_size_delta, 0);
    4552             : 
    4553      679152 :   if (instance_size_delta > 0) {
    4554             :     heap->CreateFillerObjectAt(object->address() + new_instance_size,
    4555      303823 :                                instance_size_delta, ClearRecordedSlots::kYes);
    4556             :   }
    4557             : 
    4558             :   // We are storing the new map using release store after creating a filler for
    4559             :   // the left-over space to avoid races with the sweeper thread.
    4560      679154 :   object->synchronized_set_map(*new_map);
    4561             : 
    4562     1358307 :   object->SetProperties(*dictionary);
    4563             : 
    4564             :   // Ensure that in-object space of slow-mode object does not contain random
    4565             :   // garbage.
    4566      679153 :   int inobject_properties = new_map->GetInObjectProperties();
    4567      679153 :   if (inobject_properties) {
    4568             :     Heap* heap = isolate->heap();
    4569             :     heap->ClearRecordedSlotRange(
    4570             :         object->address() + map->GetInObjectPropertyOffset(0),
    4571      630442 :         object->address() + new_instance_size);
    4572             : 
    4573     1676245 :     for (int i = 0; i < inobject_properties; i++) {
    4574     1361026 :       FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
    4575     1361023 :       object->RawFastPropertyAtPut(index, Smi::kZero);
    4576             :     }
    4577             :   }
    4578             : 
    4579      679153 :   isolate->counters()->props_to_dictionary()->Increment();
    4580             : 
    4581             : #ifdef DEBUG
    4582             :   if (FLAG_trace_normalization) {
    4583             :     StdoutStream os;
    4584             :     os << "Object properties have been normalized:\n";
    4585             :     object->Print(os);
    4586             :   }
    4587             : #endif
    4588      679154 : }
    4589             : 
    4590             : }  // namespace
    4591             : 
    4592             : // static
    4593    30513497 : void JSObject::NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
    4594             :                                Isolate* isolate) {
    4595    61027002 :   if (!old_map->is_prototype_map()) return;
    4596             : 
    4597             :   InvalidatePrototypeChains(*old_map);
    4598             : 
    4599             :   // If the map was registered with its prototype before, ensure that it
    4600             :   // registers with its new prototype now. This preserves the invariant that
    4601             :   // when a map on a prototype chain is registered with its prototype, then
    4602             :   // all prototypes further up the chain are also registered with their
    4603             :   // respective prototypes.
    4604     4252990 :   UpdatePrototypeUserRegistration(old_map, new_map, isolate);
    4605             : }
    4606             : 
    4607    33893702 : void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
    4608             :                             int expected_additional_properties) {
    4609    67787441 :   if (object->map() == *new_map) return;
    4610             :   Handle<Map> old_map(object->map(), object->GetIsolate());
    4611    30086681 :   NotifyMapChange(old_map, new_map, object->GetIsolate());
    4612             : 
    4613    30086678 :   if (old_map->is_dictionary_map()) {
    4614             :     // For slow-to-fast migrations JSObject::MigrateSlowToFast()
    4615             :     // must be used instead.
    4616      551054 :     CHECK(new_map->is_dictionary_map());
    4617             : 
    4618             :     // Slow-to-slow migration is trivial.
    4619      551054 :     object->synchronized_set_map(*new_map);
    4620    29535622 :   } else if (!new_map->is_dictionary_map()) {
    4621    28856467 :     MigrateFastToFast(object, new_map);
    4622    28856485 :     if (old_map->is_prototype_map()) {
    4623             :       DCHECK(!old_map->is_stable());
    4624             :       DCHECK(new_map->is_stable());
    4625             :       DCHECK(new_map->owns_descriptors());
    4626             :       DCHECK(old_map->owns_descriptors());
    4627             :       // Transfer ownership to the new map. Keep the descriptor pointer of the
    4628             :       // old map intact because the concurrent marker might be iterating the
    4629             :       // object with the old map.
    4630     3830903 :       old_map->set_owns_descriptors(false);
    4631             :       DCHECK(old_map->is_abandoned_prototype_map());
    4632             :       // Ensure that no transition was inserted for prototype migrations.
    4633             :       DCHECK_EQ(0, TransitionsAccessor(object->GetIsolate(), old_map)
    4634             :                        .NumberOfTransitions());
    4635             :       DCHECK(new_map->GetBackPointer()->IsUndefined());
    4636             :       DCHECK(object->map() != *old_map);
    4637             :     }
    4638             :   } else {
    4639      679150 :     MigrateFastToSlow(object, new_map, expected_additional_properties);
    4640             :   }
    4641             : 
    4642             :   // Careful: Don't allocate here!
    4643             :   // For some callers of this method, |object| might be in an inconsistent
    4644             :   // state now: the new map might have a new elements_kind, but the object's
    4645             :   // elements pointer hasn't been updated yet. Callers will fix this, but in
    4646             :   // the meantime, (indirectly) calling JSObjectVerify() must be avoided.
    4647             :   // When adding code here, add a DisallowHeapAllocation too.
    4648             : }
    4649             : 
    4650      295437 : void JSObject::ForceSetPrototype(Handle<JSObject> object,
    4651             :                                  Handle<Object> proto) {
    4652             :   // object.__proto__ = proto;
    4653             :   Handle<Map> old_map = Handle<Map>(object->map(), object->GetIsolate());
    4654             :   Handle<Map> new_map =
    4655      295437 :       Map::Copy(object->GetIsolate(), old_map, "ForceSetPrototype");
    4656      295437 :   Map::SetPrototype(object->GetIsolate(), new_map, proto);
    4657      295437 :   JSObject::MigrateToMap(object, new_map);
    4658      295437 : }
    4659             : 
    4660    41579192 : int Map::NumberOfFields() const {
    4661    41579192 :   DescriptorArray descriptors = instance_descriptors();
    4662             :   int result = 0;
    4663   557930364 :   for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
    4664   474771940 :     if (descriptors->GetDetails(i).location() == kField) result++;
    4665             :   }
    4666    41579213 :   return result;
    4667             : }
    4668             : 
    4669     2602154 : Map::FieldCounts Map::GetFieldCounts() const {
    4670     2602154 :   DescriptorArray descriptors = instance_descriptors();
    4671             :   int mutable_count = 0;
    4672             :   int const_count = 0;
    4673   151657236 :   for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
    4674    73226464 :     PropertyDetails details = descriptors->GetDetails(i);
    4675    73226464 :     if (details.location() == kField) {
    4676    64417405 :       switch (details.constness()) {
    4677             :         case PropertyConstness::kMutable:
    4678    64417405 :           mutable_count++;
    4679    64417405 :           break;
    4680             :         case PropertyConstness::kConst:
    4681           0 :           const_count++;
    4682           0 :           break;
    4683             :       }
    4684             :     }
    4685             :   }
    4686     2602154 :   return FieldCounts(mutable_count, const_count);
    4687             : }
    4688             : 
    4689           0 : bool Map::HasOutOfObjectProperties() const {
    4690           0 :   return GetInObjectProperties() < NumberOfFields();
    4691             : }
    4692             : 
    4693     5756253 : void DescriptorArray::GeneralizeAllFields() {
    4694     5756253 :   int length = number_of_descriptors();
    4695    10844245 :   for (int i = 0; i < length; i++) {
    4696     5087990 :     PropertyDetails details = GetDetails(i);
    4697             :     details = details.CopyWithRepresentation(Representation::Tagged());
    4698     5087990 :     if (details.location() == kField) {
    4699             :       DCHECK_EQ(kData, details.kind());
    4700             :       details = details.CopyWithConstness(PropertyConstness::kMutable);
    4701      472460 :       SetValue(i, FieldType::Any());
    4702             :     }
    4703     5087990 :     set(ToDetailsIndex(i), MaybeObject::FromObject(details.AsSmi()));
    4704             :   }
    4705     5756255 : }
    4706             : 
    4707       21191 : Handle<Map> Map::CopyGeneralizeAllFields(Isolate* isolate, Handle<Map> map,
    4708             :                                          ElementsKind elements_kind,
    4709             :                                          int modify_index, PropertyKind kind,
    4710             :                                          PropertyAttributes attributes,
    4711             :                                          const char* reason) {
    4712       42382 :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
    4713             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    4714             :   Handle<DescriptorArray> descriptors = DescriptorArray::CopyUpTo(
    4715             :       isolate, old_descriptors, number_of_own_descriptors);
    4716       21191 :   descriptors->GeneralizeAllFields();
    4717             : 
    4718             :   Handle<LayoutDescriptor> new_layout_descriptor(
    4719             :       LayoutDescriptor::FastPointerLayout(), isolate);
    4720             :   Handle<Map> new_map = CopyReplaceDescriptors(
    4721             :       isolate, map, descriptors, new_layout_descriptor, OMIT_TRANSITION,
    4722       21191 :       MaybeHandle<Name>(), reason, SPECIAL_TRANSITION);
    4723             : 
    4724             :   // Unless the instance is being migrated, ensure that modify_index is a field.
    4725       21191 :   if (modify_index >= 0) {
    4726       21107 :     PropertyDetails details = descriptors->GetDetails(modify_index);
    4727       22181 :     if (details.constness() != PropertyConstness::kMutable ||
    4728       22181 :         details.location() != kField || details.attributes() != attributes) {
    4729             :       int field_index = details.location() == kField
    4730             :                             ? details.field_index()
    4731       40343 :                             : new_map->NumberOfFields();
    4732             :       Descriptor d = Descriptor::DataField(
    4733             :           isolate, handle(descriptors->GetKey(modify_index), isolate),
    4734       40620 :           field_index, attributes, Representation::Tagged());
    4735       20310 :       descriptors->Replace(modify_index, &d);
    4736       20310 :       if (details.location() != kField) {
    4737       20033 :         new_map->AccountAddedPropertyField();
    4738             :       }
    4739             :     } else {
    4740             :       DCHECK(details.attributes() == attributes);
    4741             :     }
    4742             : 
    4743       21107 :     if (FLAG_trace_generalization) {
    4744           0 :       MaybeHandle<FieldType> field_type = FieldType::None(isolate);
    4745           0 :       if (details.location() == kField) {
    4746             :         field_type = handle(
    4747           0 :             map->instance_descriptors()->GetFieldType(modify_index), isolate);
    4748             :       }
    4749             :       map->PrintGeneralization(
    4750             :           isolate, stdout, reason, modify_index,
    4751             :           new_map->NumberOfOwnDescriptors(), new_map->NumberOfOwnDescriptors(),
    4752             :           details.location() == kDescriptor, details.representation(),
    4753             :           Representation::Tagged(), field_type, MaybeHandle<Object>(),
    4754           0 :           FieldType::Any(isolate), MaybeHandle<Object>());
    4755             :     }
    4756             :   }
    4757       42382 :   new_map->set_elements_kind(elements_kind);
    4758       21191 :   return new_map;
    4759             : }
    4760             : 
    4761       47920 : void Map::DeprecateTransitionTree(Isolate* isolate) {
    4762       47872 :   if (is_deprecated()) return;
    4763             :   DisallowHeapAllocation no_gc;
    4764             :   TransitionsAccessor transitions(isolate, *this, &no_gc);
    4765       47872 :   int num_transitions = transitions.NumberOfTransitions();
    4766       76594 :   for (int i = 0; i < num_transitions; ++i) {
    4767       28722 :     transitions.GetTarget(i)->DeprecateTransitionTree(isolate);
    4768             :   }
    4769             :   DCHECK(!constructor_or_backpointer()->IsFunctionTemplateInfo());
    4770       47872 :   set_is_deprecated(true);
    4771       47872 :   if (FLAG_trace_maps) {
    4772          96 :     LOG(isolate, MapEvent("Deprecate", *this, Map()));
    4773             :   }
    4774             :   dependent_code()->DeoptimizeDependentCodeGroup(
    4775       47872 :       isolate, DependentCode::kTransitionGroup);
    4776       47872 :   NotifyLeafMapLayoutChange(isolate);
    4777             : }
    4778             : 
    4779             : 
    4780             : // Installs |new_descriptors| over the current instance_descriptors to ensure
    4781             : // proper sharing of descriptor arrays.
    4782       20726 : void Map::ReplaceDescriptors(Isolate* isolate, DescriptorArray new_descriptors,
    4783             :                              LayoutDescriptor new_layout_descriptor) {
    4784             :   // Don't overwrite the empty descriptor array or initial map's descriptors.
    4785       29011 :   if (NumberOfOwnDescriptors() == 0 || GetBackPointer()->IsUndefined(isolate)) {
    4786       12735 :     return;
    4787             :   }
    4788             : 
    4789        7991 :   DescriptorArray to_replace = instance_descriptors();
    4790             :   // Replace descriptors by new_descriptors in all maps that share it. The old
    4791             :   // descriptors will not be trimmed in the mark-compactor, we need to mark
    4792             :   // all its elements.
    4793        7991 :   Map current = *this;
    4794             :   MarkingBarrierForDescriptorArray(isolate->heap(), current, to_replace,
    4795        7991 :                                    to_replace->number_of_descriptors());
    4796       58814 :   while (current->instance_descriptors() == to_replace) {
    4797       43151 :     Object next = current->GetBackPointer();
    4798       43151 :     if (next->IsUndefined(isolate)) break;  // Stop overwriting at initial map.
    4799       42832 :     current->SetEnumLength(kInvalidEnumCacheSentinel);
    4800             :     current->UpdateDescriptors(isolate, new_descriptors, new_layout_descriptor,
    4801       42832 :                                current->NumberOfOwnDescriptors());
    4802       42832 :     current = Map::cast(next);
    4803             :   }
    4804        7991 :   set_owns_descriptors(false);
    4805             : }
    4806             : 
    4807      982757 : Map Map::FindRootMap(Isolate* isolate) const {
    4808      982757 :   Map result = *this;
    4809             :   while (true) {
    4810     1462305 :     Object back = result->GetBackPointer();
    4811     1462319 :     if (back->IsUndefined(isolate)) {
    4812             :       // Initial map always owns descriptors and doesn't have unused entries
    4813             :       // in the descriptor array.
    4814             :       DCHECK(result->owns_descriptors());
    4815             :       DCHECK_EQ(result->NumberOfOwnDescriptors(),
    4816             :                 result->instance_descriptors()->number_of_descriptors());
    4817      982769 :       return result;
    4818             :     }
    4819      479548 :     result = Map::cast(back);
    4820      479548 :   }
    4821             : }
    4822             : 
    4823      401293 : Map Map::FindFieldOwner(Isolate* isolate, int descriptor) const {
    4824             :   DisallowHeapAllocation no_allocation;
    4825             :   DCHECK_EQ(kField, instance_descriptors()->GetDetails(descriptor).location());
    4826      401293 :   Map result = *this;
    4827             :   while (true) {
    4828     1513238 :     Object back = result->GetBackPointer();
    4829     1513240 :     if (back->IsUndefined(isolate)) break;
    4830             :     const Map parent = Map::cast(back);
    4831     1513239 :     if (parent->NumberOfOwnDescriptors() <= descriptor) break;
    4832     1111945 :     result = parent;
    4833             :   }
    4834     1111945 :   return result;
    4835             : }
    4836             : 
    4837      436762 : void Map::UpdateFieldType(Isolate* isolate, int descriptor, Handle<Name> name,
    4838             :                           PropertyConstness new_constness,
    4839             :                           Representation new_representation,
    4840             :                           const MaybeObjectHandle& new_wrapped_type) {
    4841             :   DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeak());
    4842             :   // We store raw pointers in the queue, so no allocations are allowed.
    4843             :   DisallowHeapAllocation no_allocation;
    4844      218380 :   PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
    4845      218382 :   if (details.location() != kField) return;
    4846             :   DCHECK_EQ(kData, details.kind());
    4847             : 
    4848      218382 :   Zone zone(isolate->allocator(), ZONE_NAME);
    4849      218379 :   ZoneQueue<Map> backlog(&zone);
    4850             :   backlog.push(*this);
    4851             : 
    4852     1566198 :   while (!backlog.empty()) {
    4853     1347817 :     Map current = backlog.front();
    4854             :     backlog.pop();
    4855             : 
    4856             :     TransitionsAccessor transitions(isolate, current, &no_allocation);
    4857     1347820 :     int num_transitions = transitions.NumberOfTransitions();
    4858     2477256 :     for (int i = 0; i < num_transitions; ++i) {
    4859     1129436 :       Map target = transitions.GetTarget(i);
    4860             :       backlog.push(target);
    4861             :     }
    4862     1347820 :     DescriptorArray descriptors = current->instance_descriptors();
    4863     1347821 :     PropertyDetails details = descriptors->GetDetails(descriptor);
    4864             : 
    4865             :     // Currently constness change implies map change.
    4866             :     DCHECK_IMPLIES(new_constness != details.constness(),
    4867             :                    FLAG_modify_map_inplace);
    4868             : 
    4869             :     // It is allowed to change representation here only from None to something.
    4870             :     DCHECK(details.representation().Equals(new_representation) ||
    4871             :            details.representation().IsNone());
    4872             : 
    4873             :     // Skip if already updated the shared descriptor.
    4874     4043457 :     if ((FLAG_modify_map_inplace && new_constness != details.constness()) ||
    4875             :         descriptors->GetFieldType(descriptor) != *new_wrapped_type.object()) {
    4876             :       DCHECK_IMPLIES(!FLAG_track_constant_fields,
    4877             :                      new_constness == PropertyConstness::kMutable);
    4878             :       Descriptor d = Descriptor::DataField(
    4879             :           name, descriptors->GetFieldIndex(descriptor), details.attributes(),
    4880      218421 :           new_constness, new_representation, new_wrapped_type);
    4881      218420 :       descriptors->Replace(descriptor, &d);
    4882             :     }
    4883      218381 :   }
    4884             : }
    4885             : 
    4886           0 : bool FieldTypeIsCleared(Representation rep, FieldType type) {
    4887     1359884 :   return type->IsNone() && rep.IsHeapObject();
    4888             : }
    4889             : 
    4890             : 
    4891             : // static
    4892      565529 : Handle<FieldType> Map::GeneralizeFieldType(Representation rep1,
    4893             :                                            Handle<FieldType> type1,
    4894             :                                            Representation rep2,
    4895             :                                            Handle<FieldType> type2,
    4896             :                                            Isolate* isolate) {
    4897             :   // Cleared field types need special treatment. They represent lost knowledge,
    4898             :   // so we must be conservative, so their generalization with any other type
    4899             :   // is "Any".
    4900     1131054 :   if (FieldTypeIsCleared(rep1, *type1) || FieldTypeIsCleared(rep2, *type2)) {
    4901        5455 :     return FieldType::Any(isolate);
    4902             :   }
    4903      560087 :   if (type1->NowIs(type2)) return type2;
    4904       49835 :   if (type2->NowIs(type1)) return type1;
    4905       20260 :   return FieldType::Any(isolate);
    4906             : }
    4907             : 
    4908             : // static
    4909      403312 : void Map::GeneralizeField(Isolate* isolate, Handle<Map> map, int modify_index,
    4910             :                           PropertyConstness new_constness,
    4911             :                           Representation new_representation,
    4912             :                           Handle<FieldType> new_field_type) {
    4913             :   // Check if we actually need to generalize the field type at all.
    4914      806622 :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
    4915      403314 :   PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
    4916             :   PropertyConstness old_constness = old_details.constness();
    4917             :   Representation old_representation = old_details.representation();
    4918             :   Handle<FieldType> old_field_type(old_descriptors->GetFieldType(modify_index),
    4919      806630 :                                    isolate);
    4920             : 
    4921             :   // Return if the current map is general enough to hold requested constness and
    4922             :   // representation/field type.
    4923      581936 :   if (((FLAG_modify_map_inplace &&
    4924             :         IsGeneralizableTo(new_constness, old_constness)) ||
    4925      403318 :        (!FLAG_modify_map_inplace && (old_constness == new_constness))) &&
    4926      224699 :       old_representation.Equals(new_representation) &&
    4927      628003 :       !FieldTypeIsCleared(new_representation, *new_field_type) &&
    4928             :       // Checking old_field_type for being cleared is not necessary because
    4929             :       // the NowIs check below would fail anyway in that case.
    4930      852693 :       new_field_type->NowIs(old_field_type)) {
    4931             :     DCHECK(GeneralizeFieldType(old_representation, old_field_type,
    4932             :                                new_representation, new_field_type, isolate)
    4933             :                ->NowIs(old_field_type));
    4934      184935 :     return;
    4935             :   }
    4936             : 
    4937             :   // Determine the field owner.
    4938      436765 :   Handle<Map> field_owner(map->FindFieldOwner(isolate, modify_index), isolate);
    4939             :   Handle<DescriptorArray> descriptors(field_owner->instance_descriptors(),
    4940      436763 :                                       isolate);
    4941             :   DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index));
    4942             : 
    4943             :   new_field_type =
    4944             :       Map::GeneralizeFieldType(old_representation, old_field_type,
    4945      218381 :                                new_representation, new_field_type, isolate);
    4946             :   if (FLAG_modify_map_inplace) {
    4947             :     new_constness = GeneralizeConstness(old_constness, new_constness);
    4948             :   }
    4949             : 
    4950      218385 :   PropertyDetails details = descriptors->GetDetails(modify_index);
    4951      436765 :   Handle<Name> name(descriptors->GetKey(modify_index), isolate);
    4952             : 
    4953      218380 :   MaybeObjectHandle wrapped_type(WrapFieldType(isolate, new_field_type));
    4954             :   field_owner->UpdateFieldType(isolate, modify_index, name, new_constness,
    4955      218383 :                                new_representation, wrapped_type);
    4956      436759 :   field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
    4957      218380 :       isolate, DependentCode::kFieldOwnerGroup);
    4958             : 
    4959      218379 :   if (FLAG_trace_generalization) {
    4960             :     map->PrintGeneralization(
    4961             :         isolate, stdout, "field type generalization", modify_index,
    4962             :         map->NumberOfOwnDescriptors(), map->NumberOfOwnDescriptors(), false,
    4963             :         details.representation(), details.representation(), old_field_type,
    4964           0 :         MaybeHandle<Object>(), new_field_type, MaybeHandle<Object>());
    4965             :   }
    4966             : }
    4967             : 
    4968             : // TODO(ishell): remove.
    4969             : // static
    4970         495 : Handle<Map> Map::ReconfigureProperty(Isolate* isolate, Handle<Map> map,
    4971             :                                      int modify_index, PropertyKind new_kind,
    4972             :                                      PropertyAttributes new_attributes,
    4973             :                                      Representation new_representation,
    4974             :                                      Handle<FieldType> new_field_type) {
    4975             :   DCHECK_EQ(kData, new_kind);  // Only kData case is supported.
    4976         495 :   MapUpdater mu(isolate, map);
    4977             :   return mu.ReconfigureToDataField(modify_index, new_attributes,
    4978             :                                    PropertyConstness::kConst,
    4979         495 :                                    new_representation, new_field_type);
    4980             : }
    4981             : 
    4982             : // TODO(ishell): remove.
    4983             : // static
    4984          30 : Handle<Map> Map::ReconfigureElementsKind(Isolate* isolate, Handle<Map> map,
    4985             :                                          ElementsKind new_elements_kind) {
    4986      294665 :   MapUpdater mu(isolate, map);
    4987      294665 :   return mu.ReconfigureElementsKind(new_elements_kind);
    4988             : }
    4989             : 
    4990             : namespace {
    4991             : 
    4992             : Map SearchMigrationTarget(Isolate* isolate, Map old_map) {
    4993             :   DisallowHeapAllocation no_allocation;
    4994             :   DisallowDeoptimization no_deoptimization(isolate);
    4995             : 
    4996             :   Map target = old_map;
    4997             :   do {
    4998             :     target = TransitionsAccessor(isolate, target, &no_allocation)
    4999             :                  .GetMigrationTarget();
    5000             :   } while (!target.is_null() && target->is_deprecated());
    5001             :   if (target.is_null()) return Map();
    5002             : 
    5003             :   // TODO(ishell): if this validation ever become a bottleneck consider adding a
    5004             :   // bit to the Map telling whether it contains fields whose field types may be
    5005             :   // cleared.
    5006             :   // TODO(ishell): revisit handling of cleared field types in
    5007             :   // TryReplayPropertyTransitions() and consider checking the target map's field
    5008             :   // types instead of old_map's types.
    5009             :   // Go to slow map updating if the old_map has fast properties with cleared
    5010             :   // field types.
    5011             :   int old_nof = old_map->NumberOfOwnDescriptors();
    5012             :   DescriptorArray old_descriptors = old_map->instance_descriptors();
    5013             :   for (int i = 0; i < old_nof; i++) {
    5014             :     PropertyDetails old_details = old_descriptors->GetDetails(i);
    5015             :     if (old_details.location() == kField && old_details.kind() == kData) {
    5016             :       FieldType old_type = old_descriptors->GetFieldType(i);
    5017             :       if (FieldTypeIsCleared(old_details.representation(), old_type)) {
    5018             :         return Map();
    5019             :       }
    5020             :     }
    5021             :   }
    5022             : 
    5023             :   SLOW_DCHECK(Map::TryUpdateSlow(isolate, old_map) == target);
    5024             :   return target;
    5025             : }
    5026             : }  // namespace
    5027             : 
    5028             : // TODO(ishell): Move TryUpdate() and friends to MapUpdater
    5029             : // static
    5030      185344 : MaybeHandle<Map> Map::TryUpdate(Isolate* isolate, Handle<Map> old_map) {
    5031             :   DisallowHeapAllocation no_allocation;
    5032             :   DisallowDeoptimization no_deoptimization(isolate);
    5033             : 
    5034      185344 :   if (!old_map->is_deprecated()) return old_map;
    5035             : 
    5036             :   if (FLAG_fast_map_update) {
    5037             :     Map target_map = SearchMigrationTarget(isolate, *old_map);
    5038             :     if (!target_map.is_null()) {
    5039             :       return handle(target_map, isolate);
    5040             :     }
    5041             :   }
    5042             : 
    5043         560 :   Map new_map = TryUpdateSlow(isolate, *old_map);
    5044         560 :   if (new_map.is_null()) return MaybeHandle<Map>();
    5045             :   if (FLAG_fast_map_update) {
    5046             :     TransitionsAccessor(isolate, *old_map, &no_allocation)
    5047             :         .SetMigrationTarget(new_map);
    5048             :   }
    5049         460 :   return handle(new_map, isolate);
    5050             : }
    5051             : 
    5052         560 : Map Map::TryUpdateSlow(Isolate* isolate, Map old_map) {
    5053             :   DisallowHeapAllocation no_allocation;
    5054             :   DisallowDeoptimization no_deoptimization(isolate);
    5055             : 
    5056             :   // Check the state of the root map.
    5057         560 :   Map root_map = old_map->FindRootMap(isolate);
    5058         560 :   if (root_map->is_deprecated()) {
    5059           0 :     JSFunction constructor = JSFunction::cast(root_map->GetConstructor());
    5060             :     DCHECK(constructor->has_initial_map());
    5061             :     DCHECK(constructor->initial_map()->is_dictionary_map());
    5062           0 :     if (constructor->initial_map()->elements_kind() !=
    5063             :         old_map->elements_kind()) {
    5064           0 :       return Map();
    5065             :     }
    5066           0 :     return constructor->initial_map();
    5067             :   }
    5068         560 :   if (!old_map->EquivalentToForTransition(root_map)) return Map();
    5069             : 
    5070             :   ElementsKind from_kind = root_map->elements_kind();
    5071             :   ElementsKind to_kind = old_map->elements_kind();
    5072         490 :   if (from_kind != to_kind) {
    5073             :     // Try to follow existing elements kind transitions.
    5074          21 :     root_map = root_map->LookupElementsTransitionMap(isolate, to_kind);
    5075          21 :     if (root_map.is_null()) return Map();
    5076             :     // From here on, use the map with correct elements kind as root map.
    5077             :   }
    5078         490 :   return root_map->TryReplayPropertyTransitions(isolate, old_map);
    5079             : }
    5080             : 
    5081       86685 : Map Map::TryReplayPropertyTransitions(Isolate* isolate, Map old_map) {
    5082             :   DisallowHeapAllocation no_allocation;
    5083             :   DisallowDeoptimization no_deoptimization(isolate);
    5084             : 
    5085             :   int root_nof = NumberOfOwnDescriptors();
    5086             : 
    5087             :   int old_nof = old_map->NumberOfOwnDescriptors();
    5088       86685 :   DescriptorArray old_descriptors = old_map->instance_descriptors();
    5089             : 
    5090       86685 :   Map new_map = *this;
    5091       88915 :   for (int i = root_nof; i < old_nof; ++i) {
    5092        8335 :     PropertyDetails old_details = old_descriptors->GetDetails(i);
    5093             :     Map transition =
    5094             :         TransitionsAccessor(isolate, new_map, &no_allocation)
    5095             :             .SearchTransition(old_descriptors->GetKey(i), old_details.kind(),
    5096       16670 :                               old_details.attributes());
    5097        8335 :     if (transition.is_null()) return Map();
    5098        2291 :     new_map = transition;
    5099        2291 :     DescriptorArray new_descriptors = new_map->instance_descriptors();
    5100             : 
    5101        2291 :     PropertyDetails new_details = new_descriptors->GetDetails(i);
    5102             :     DCHECK_EQ(old_details.kind(), new_details.kind());
    5103             :     DCHECK_EQ(old_details.attributes(), new_details.attributes());
    5104        2291 :     if (!IsGeneralizableTo(old_details.constness(), new_details.constness())) {
    5105           0 :       return Map();
    5106             :     }
    5107             :     DCHECK(IsGeneralizableTo(old_details.location(), new_details.location()));
    5108        6873 :     if (!old_details.representation().fits_into(new_details.representation())) {
    5109          38 :       return Map();
    5110             :     }
    5111        2253 :     if (new_details.location() == kField) {
    5112        2119 :       if (new_details.kind() == kData) {
    5113        2119 :         FieldType new_type = new_descriptors->GetFieldType(i);
    5114             :         // Cleared field types need special treatment. They represent lost
    5115             :         // knowledge, so we must first generalize the new_type to "Any".
    5116        2119 :         if (FieldTypeIsCleared(new_details.representation(), new_type)) {
    5117           0 :           return Map();
    5118             :         }
    5119             :         DCHECK_EQ(kData, old_details.kind());
    5120        2119 :         if (old_details.location() == kField) {
    5121        2012 :           FieldType old_type = old_descriptors->GetFieldType(i);
    5122        4024 :           if (FieldTypeIsCleared(old_details.representation(), old_type) ||
    5123        2012 :               !old_type->NowIs(new_type)) {
    5124          15 :             return Map();
    5125             :           }
    5126             :         } else {
    5127             :           DCHECK_EQ(kDescriptor, old_details.location());
    5128             :           DCHECK(!FLAG_track_constant_fields);
    5129         107 :           Object old_value = old_descriptors->GetStrongValue(i);
    5130         107 :           if (!new_type->NowContains(old_value)) {
    5131           0 :             return Map();
    5132             :           }
    5133             :         }
    5134             : 
    5135             :       } else {
    5136             :         DCHECK_EQ(kAccessor, new_details.kind());
    5137             : #ifdef DEBUG
    5138             :         FieldType new_type = new_descriptors->GetFieldType(i);
    5139             :         DCHECK(new_type->IsAny());
    5140             : #endif
    5141           0 :         UNREACHABLE();
    5142             :       }
    5143             :     } else {
    5144             :       DCHECK_EQ(kDescriptor, new_details.location());
    5145         402 :       if (old_details.location() == kField ||
    5146         402 :           old_descriptors->GetStrongValue(i) !=
    5147             :               new_descriptors->GetStrongValue(i)) {
    5148           8 :         return Map();
    5149             :       }
    5150             :     }
    5151             :   }
    5152       80580 :   if (new_map->NumberOfOwnDescriptors() != old_nof) return Map();
    5153       80580 :   return new_map;
    5154             : }
    5155             : 
    5156             : 
    5157             : // static
    5158    24318456 : Handle<Map> Map::Update(Isolate* isolate, Handle<Map> map) {
    5159    24318467 :   if (!map->is_deprecated()) return map;
    5160             :   if (FLAG_fast_map_update) {
    5161             :     Map target_map = SearchMigrationTarget(isolate, *map);
    5162             :     if (!target_map.is_null()) {
    5163             :       return handle(target_map, isolate);
    5164             :     }
    5165             :   }
    5166        2981 :   MapUpdater mu(isolate, map);
    5167        2981 :   return mu.Update();
    5168             : }
    5169             : 
    5170      193339 : Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
    5171             :                                                  ShouldThrow should_throw,
    5172             :                                                  Handle<Object> value) {
    5173             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    5174             :   return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(),
    5175      193339 :                                             should_throw, value);
    5176             : }
    5177             : 
    5178     3788744 : MaybeHandle<Object> Object::SetProperty(Isolate* isolate, Handle<Object> object,
    5179             :                                         Handle<Name> name, Handle<Object> value,
    5180             :                                         LanguageMode language_mode,
    5181             :                                         StoreOrigin store_origin) {
    5182     3788744 :   LookupIterator it(isolate, object, name);
    5183     3788744 :   MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_origin));
    5184     3788132 :   return value;
    5185             : }
    5186             : 
    5187    11674401 : Maybe<bool> Object::SetPropertyInternal(LookupIterator* it,
    5188             :                                         Handle<Object> value,
    5189             :                                         LanguageMode language_mode,
    5190             :                                         StoreOrigin store_origin, bool* found) {
    5191     5627950 :   it->UpdateProtector();
    5192             :   DCHECK(it->IsFound());
    5193             :   ShouldThrow should_throw =
    5194     5627953 :       is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
    5195             : 
    5196             :   // Make sure that the top context does not change when doing callbacks or
    5197             :   // interceptor calls.
    5198             :   AssertNoContextChange ncc(it->isolate());
    5199             : 
    5200      272575 :   do {
    5201     5771593 :     switch (it->state()) {
    5202             :       case LookupIterator::NOT_FOUND:
    5203           0 :         UNREACHABLE();
    5204             : 
    5205             :       case LookupIterator::ACCESS_CHECK:
    5206       79721 :         if (it->HasAccess()) break;
    5207             :         // Check whether it makes sense to reuse the lookup iterator. Here it
    5208             :         // might still call into setters up the prototype chain.
    5209             :         return JSObject::SetPropertyWithFailedAccessCheck(it, value,
    5210         103 :                                                           should_throw);
    5211             : 
    5212             :       case LookupIterator::JSPROXY: {
    5213             :         Handle<Object> receiver = it->GetReceiver();
    5214             :         // In case of global IC, the receiver is the global object. Replace by
    5215             :         // the global proxy.
    5216      105542 :         if (receiver->IsJSGlobalObject()) {
    5217             :           receiver = handle(JSGlobalObject::cast(*receiver)->global_proxy(),
    5218         234 :                             it->isolate());
    5219             :         }
    5220             :         return JSProxy::SetProperty(it->GetHolder<JSProxy>(), it->GetName(),
    5221      105542 :                                     value, receiver, language_mode);
    5222             :       }
    5223             : 
    5224             :       case LookupIterator::INTERCEPTOR: {
    5225      202368 :         if (it->HolderIsReceiverOrHiddenPrototype()) {
    5226             :           Maybe<bool> result =
    5227      193127 :               JSObject::SetPropertyWithInterceptor(it, should_throw, value);
    5228      386254 :           if (result.IsNothing() || result.FromJust()) return result;
    5229             :         } else {
    5230             :           Maybe<PropertyAttributes> maybe_attributes =
    5231        9241 :               JSObject::GetPropertyAttributesWithInterceptor(it);
    5232       18384 :           if (maybe_attributes.IsNothing()) return Nothing<bool>();
    5233        9241 :           if ((maybe_attributes.FromJust() & READ_ONLY) != 0) {
    5234           0 :             return WriteToReadOnlyProperty(it, value, should_throw);
    5235             :           }
    5236        9241 :           if (maybe_attributes.FromJust() == ABSENT) break;
    5237        9143 :           *found = false;
    5238             :           return Nothing<bool>();
    5239             :         }
    5240             :         break;
    5241             :       }
    5242             : 
    5243             :       case LookupIterator::ACCESSOR: {
    5244      487505 :         if (it->IsReadOnly()) {
    5245        1485 :           return WriteToReadOnlyProperty(it, value, should_throw);
    5246             :         }
    5247      486020 :         Handle<Object> accessors = it->GetAccessors();
    5248     1215482 :         if (accessors->IsAccessorInfo() &&
    5249      606709 :             !it->HolderIsReceiverOrHiddenPrototype() &&
    5250      606709 :             AccessorInfo::cast(*accessors)->is_special_data_property()) {
    5251         451 :           *found = false;
    5252             :           return Nothing<bool>();
    5253             :         }
    5254      485569 :         return SetPropertyWithAccessor(it, value, should_throw);
    5255             :       }
    5256             :       case LookupIterator::INTEGER_INDEXED_EXOTIC: {
    5257             :         // IntegerIndexedElementSet converts value to a Number/BigInt prior to
    5258             :         // the bounds check. The bounds check has already happened here, but
    5259             :         // perform the possibly effectful ToNumber (or ToBigInt) operation
    5260             :         // anyways.
    5261             :         auto holder = it->GetHolder<JSTypedArray>();
    5262             :         Handle<Object> throwaway_value;
    5263        6498 :         if (holder->type() == kExternalBigInt64Array ||
    5264        4332 :             holder->type() == kExternalBigUint64Array) {
    5265          36 :           ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5266             :               it->isolate(), throwaway_value,
    5267             :               BigInt::FromObject(it->isolate(), value), Nothing<bool>());
    5268             :         } else {
    5269        4296 :           ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5270             :               it->isolate(), throwaway_value,
    5271             :               Object::ToNumber(it->isolate(), value), Nothing<bool>());
    5272             :         }
    5273             : 
    5274             :         // FIXME: Throw a TypeError if the holder is detached here
    5275             :         // (IntegerIndexedElementSpec step 5).
    5276             : 
    5277             :         // TODO(verwaest): Per spec, we should return false here (steps 6-9
    5278             :         // in IntegerIndexedElementSpec), resulting in an exception being thrown
    5279             :         // on OOB accesses in strict code. Historically, v8 has not done made
    5280             :         // this change due to uncertainty about web compat. (v8:4901)
    5281             :         return Just(true);
    5282             :       }
    5283             : 
    5284             :       case LookupIterator::DATA:
    5285     4471377 :         if (it->IsReadOnly()) {
    5286       26668 :           return WriteToReadOnlyProperty(it, value, should_throw);
    5287             :         }
    5288     4444709 :         if (it->HolderIsReceiverOrHiddenPrototype()) {
    5289     4385491 :           return SetDataProperty(it, value);
    5290             :         }
    5291             :         V8_FALLTHROUGH;
    5292             :       case LookupIterator::TRANSITION:
    5293      534895 :         *found = false;
    5294             :         return Nothing<bool>();
    5295             :     }
    5296      272586 :     it->Next();
    5297             :   } while (it->IsFound());
    5298             : 
    5299      128935 :   *found = false;
    5300             :   return Nothing<bool>();
    5301             : }
    5302             : 
    5303    10352113 : Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
    5304             :                                 LanguageMode language_mode,
    5305             :                                 StoreOrigin store_origin) {
    5306    10350995 :   if (it->IsFound()) {
    5307     5571808 :     bool found = true;
    5308             :     Maybe<bool> result =
    5309     5571808 :         SetPropertyInternal(it, value, language_mode, store_origin, &found);
    5310     5571807 :     if (found) return result;
    5311             :   }
    5312             : 
    5313             :   // If the receiver is the JSGlobalObject, the store was contextual. In case
    5314             :   // the property did not exist yet on the global object itself, we have to
    5315             :   // throw a reference error in strict mode.  In sloppy mode, we continue.
    5316     9489899 :   if (is_strict(language_mode) && it->GetReceiver()->IsJSGlobalObject()) {
    5317             :     it->isolate()->Throw(*it->isolate()->factory()->NewReferenceError(
    5318        1118 :         MessageTemplate::kNotDefined, it->name()));
    5319             :     return Nothing<bool>();
    5320             :   }
    5321             : 
    5322             :   ShouldThrow should_throw =
    5323     5449857 :       is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
    5324     5449857 :   return AddDataProperty(it, value, NONE, should_throw, store_origin);
    5325             : }
    5326             : 
    5327       66122 : Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
    5328             :                                      LanguageMode language_mode,
    5329             :                                      StoreOrigin store_origin) {
    5330             :   Isolate* isolate = it->isolate();
    5331             : 
    5332       60400 :   if (it->IsFound()) {
    5333       56145 :     bool found = true;
    5334             :     Maybe<bool> result =
    5335       56145 :         SetPropertyInternal(it, value, language_mode, store_origin, &found);
    5336       56145 :     if (found) return result;
    5337             :   }
    5338             : 
    5339        6451 :   it->UpdateProtector();
    5340             : 
    5341             :   // The property either doesn't exist on the holder or exists there as a data
    5342             :   // property.
    5343             : 
    5344             :   ShouldThrow should_throw =
    5345        6451 :       is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
    5346             : 
    5347       12902 :   if (!it->GetReceiver()->IsJSReceiver()) {
    5348         729 :     return WriteToReadOnlyProperty(it, value, should_throw);
    5349             :   }
    5350        5722 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    5351             : 
    5352             :   LookupIterator::Configuration c = LookupIterator::OWN;
    5353             :   LookupIterator own_lookup =
    5354             :       it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
    5355       11444 :                       : LookupIterator(isolate, receiver, it->name(), c);
    5356             : 
    5357          36 :   for (; own_lookup.IsFound(); own_lookup.Next()) {
    5358        4358 :     switch (own_lookup.state()) {
    5359             :       case LookupIterator::ACCESS_CHECK:
    5360          41 :         if (!own_lookup.HasAccess()) {
    5361             :           return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value,
    5362           5 :                                                             should_throw);
    5363             :         }
    5364             :         break;
    5365             : 
    5366             :       case LookupIterator::ACCESSOR:
    5367        2943 :         if (own_lookup.GetAccessors()->IsAccessorInfo()) {
    5368           9 :           if (own_lookup.IsReadOnly()) {
    5369           0 :             return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
    5370             :           }
    5371             :           return Object::SetPropertyWithAccessor(&own_lookup, value,
    5372           9 :                                                  should_throw);
    5373             :         }
    5374             :         V8_FALLTHROUGH;
    5375             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    5376             :         return RedefineIncompatibleProperty(isolate, it->GetName(), value,
    5377        1944 :                                             should_throw);
    5378             : 
    5379             :       case LookupIterator::DATA: {
    5380         981 :         if (own_lookup.IsReadOnly()) {
    5381         297 :           return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
    5382             :         }
    5383         684 :         return SetDataProperty(&own_lookup, value);
    5384             :       }
    5385             : 
    5386             :       case LookupIterator::INTERCEPTOR:
    5387             :       case LookupIterator::JSPROXY: {
    5388             :         PropertyDescriptor desc;
    5389             :         Maybe<bool> owned =
    5390        2355 :             JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc);
    5391        2355 :         MAYBE_RETURN(owned, Nothing<bool>());
    5392        1905 :         if (!owned.FromJust()) {
    5393             :           return JSReceiver::CreateDataProperty(&own_lookup, value,
    5394        1005 :                                                 should_throw);
    5395             :         }
    5396        1800 :         if (PropertyDescriptor::IsAccessorDescriptor(&desc) ||
    5397             :             !desc.writable()) {
    5398             :           return RedefineIncompatibleProperty(isolate, it->GetName(), value,
    5399           0 :                                               should_throw);
    5400             :         }
    5401             : 
    5402             :         PropertyDescriptor value_desc;
    5403             :         value_desc.set_value(value);
    5404             :         return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
    5405        1800 :                                              &value_desc, should_throw);
    5406             :       }
    5407             : 
    5408             :       case LookupIterator::NOT_FOUND:
    5409             :       case LookupIterator::TRANSITION:
    5410           0 :         UNREACHABLE();
    5411             :     }
    5412             :   }
    5413             : 
    5414        1400 :   return AddDataProperty(&own_lookup, value, NONE, should_throw, store_origin);
    5415             : }
    5416             : 
    5417        5990 : Maybe<bool> Object::CannotCreateProperty(Isolate* isolate,
    5418             :                                          Handle<Object> receiver,
    5419             :                                          Handle<Object> name,
    5420             :                                          Handle<Object> value,
    5421             :                                          ShouldThrow should_throw) {
    5422        6224 :   RETURN_FAILURE(
    5423             :       isolate, should_throw,
    5424             :       NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name,
    5425             :                    Object::TypeOf(isolate, receiver), receiver));
    5426             : }
    5427             : 
    5428             : 
    5429       58358 : Maybe<bool> Object::WriteToReadOnlyProperty(LookupIterator* it,
    5430             :                                             Handle<Object> value,
    5431             :                                             ShouldThrow should_throw) {
    5432             :   return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
    5433       58358 :                                  it->GetName(), value, should_throw);
    5434             : }
    5435             : 
    5436             : 
    5437       29179 : Maybe<bool> Object::WriteToReadOnlyProperty(Isolate* isolate,
    5438             :                                             Handle<Object> receiver,
    5439             :                                             Handle<Object> name,
    5440             :                                             Handle<Object> value,
    5441             :                                             ShouldThrow should_throw) {
    5442       47053 :   RETURN_FAILURE(isolate, should_throw,
    5443             :                  NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
    5444             :                               Object::TypeOf(isolate, receiver), receiver));
    5445             : }
    5446             : 
    5447             : 
    5448         981 : Maybe<bool> Object::RedefineIncompatibleProperty(Isolate* isolate,
    5449             :                                                  Handle<Object> name,
    5450             :                                                  Handle<Object> value,
    5451             :                                                  ShouldThrow should_throw) {
    5452        1215 :   RETURN_FAILURE(isolate, should_throw,
    5453             :                  NewTypeError(MessageTemplate::kRedefineDisallowed, name));
    5454             : }
    5455             : 
    5456             : 
    5457     9797230 : Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) {
    5458             :   DCHECK_IMPLIES(it->GetReceiver()->IsJSProxy(),
    5459             :                  it->GetName()->IsPrivateName());
    5460             :   DCHECK_IMPLIES(!it->IsElement() && it->GetName()->IsPrivateName(),
    5461             :                  it->state() == LookupIterator::DATA);
    5462     4897620 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    5463             : 
    5464             :   // Store on the holder which may be hidden behind the receiver.
    5465             :   DCHECK(it->HolderIsReceiverOrHiddenPrototype());
    5466             : 
    5467     4897621 :   Handle<Object> to_assign = value;
    5468             :   // Convert the incoming value to a number for storing into typed arrays.
    5469    12520031 :   if (it->IsElement() && receiver->IsJSObject() &&
    5470     5805883 :       JSObject::cast(*receiver)->HasFixedTypedArrayElements()) {
    5471      700825 :     ElementsKind elements_kind = JSObject::cast(*receiver)->GetElementsKind();
    5472      700825 :     if (elements_kind == BIGINT64_ELEMENTS ||
    5473             :         elements_kind == BIGUINT64_ELEMENTS) {
    5474         126 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(it->isolate(), to_assign,
    5475             :                                        BigInt::FromObject(it->isolate(), value),
    5476             :                                        Nothing<bool>());
    5477             :       // We have to recheck the length. However, it can only change if the
    5478             :       // underlying buffer was detached, so just check that.
    5479         126 :       if (Handle<JSArrayBufferView>::cast(receiver)->WasDetached()) {
    5480             :         return Just(true);
    5481             :         // TODO(neis): According to the spec, this should throw a TypeError.
    5482             :       }
    5483     1403630 :     } else if (!value->IsNumber() && !value->IsUndefined(it->isolate())) {
    5484        1746 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(it->isolate(), to_assign,
    5485             :                                        Object::ToNumber(it->isolate(), value),
    5486             :                                        Nothing<bool>());
    5487             :       // We have to recheck the length. However, it can only change if the
    5488             :       // underlying buffer was detached, so just check that.
    5489        1746 :       if (Handle<JSArrayBufferView>::cast(receiver)->WasDetached()) {
    5490             :         return Just(true);
    5491             :         // TODO(neis): According to the spec, this should throw a TypeError.
    5492             :       }
    5493             :     }
    5494             :   }
    5495             : 
    5496             :   // Possibly migrate to the most up-to-date map that will be able to store
    5497             :   // |value| under it->name().
    5498     4897620 :   it->PrepareForDataProperty(to_assign);
    5499             : 
    5500             :   // Write the property value.
    5501     4897626 :   it->WriteDataValue(to_assign, false);
    5502             : 
    5503             : #if VERIFY_HEAP
    5504             :   if (FLAG_verify_heap) {
    5505             :     receiver->HeapObjectVerify(it->isolate());
    5506             :   }
    5507             : #endif
    5508             :   return Just(true);
    5509             : }
    5510             : 
    5511   128786279 : Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
    5512             :                                     PropertyAttributes attributes,
    5513             :                                     ShouldThrow should_throw,
    5514             :                                     StoreOrigin store_origin) {
    5515    79903362 :   if (!it->GetReceiver()->IsJSReceiver()) {
    5516             :     return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
    5517       11980 :                                 value, should_throw);
    5518             :   }
    5519             : 
    5520             :   // Private symbols should be installed on JSProxy using
    5521             :   // JSProxy::SetPrivateSymbol.
    5522   119837112 :   if (it->GetReceiver()->IsJSProxy() && it->GetName()->IsPrivate() &&
    5523    39945756 :       !it->GetName()->IsPrivateName()) {
    5524          45 :     RETURN_FAILURE(it->isolate(), should_throw,
    5525             :                    NewTypeError(MessageTemplate::kProxyPrivate));
    5526             :   }
    5527             : 
    5528             :   DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
    5529             : 
    5530    39945639 :   Handle<JSReceiver> receiver = it->GetStoreTarget<JSReceiver>();
    5531             :   DCHECK_IMPLIES(receiver->IsJSProxy(), it->GetName()->IsPrivateName());
    5532             :   DCHECK_IMPLIES(receiver->IsJSProxy(),
    5533             :                  it->state() == LookupIterator::NOT_FOUND);
    5534             : 
    5535             :   // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
    5536             :   // instead. If the prototype is Null, the proxy is detached.
    5537    79891297 :   if (receiver->IsJSGlobalProxy()) return Just(true);
    5538             : 
    5539             :   Isolate* isolate = it->isolate();
    5540             : 
    5541    39945652 :   if (it->ExtendingNonExtensible(receiver)) {
    5542      364967 :     RETURN_FAILURE(
    5543             :         isolate, should_throw,
    5544             :         NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName()));
    5545             :   }
    5546             : 
    5547    39852268 :   if (it->IsElement()) {
    5548    12378139 :     if (receiver->IsJSArray()) {
    5549     2841875 :       Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    5550     2841875 :       if (JSArray::WouldChangeReadOnlyLength(array, it->index())) {
    5551        1035 :         RETURN_FAILURE(isolate, should_throw,
    5552             :                        NewTypeError(MessageTemplate::kStrictReadOnlyProperty,
    5553             :                                     isolate->factory()->length_string(),
    5554             :                                     Object::TypeOf(isolate, array), array));
    5555             :       }
    5556             : 
    5557     8524791 :       if (FLAG_trace_external_array_abuse &&
    5558     2841597 :           array->HasFixedTypedArrayElements()) {
    5559           0 :         CheckArrayAbuse(array, "typed elements write", it->index(), true);
    5560             :       }
    5561             : 
    5562     2841597 :       if (FLAG_trace_js_array_abuse && !array->HasFixedTypedArrayElements()) {
    5563           0 :         CheckArrayAbuse(array, "elements write", it->index(), false);
    5564             :       }
    5565             :     }
    5566             : 
    5567     6188791 :     Handle<JSObject> receiver_obj = Handle<JSObject>::cast(receiver);
    5568     6188793 :     JSObject::AddDataElement(receiver_obj, it->index(), value, attributes);
    5569             :     JSObject::ValidateElements(*receiver_obj);
    5570             :     return Just(true);
    5571             :   } else {
    5572    33663198 :     it->UpdateProtector();
    5573             :     // Migrate to the most up-to-date map that will be able to store |value|
    5574             :     // under it->name() with |attributes|.
    5575             :     it->PrepareTransitionToDataProperty(receiver, value, attributes,
    5576    33663214 :                                         store_origin);
    5577             :     DCHECK_EQ(LookupIterator::TRANSITION, it->state());
    5578    33663215 :     it->ApplyTransitionToDataProperty(receiver);
    5579             : 
    5580             :     // Write the property value.
    5581    33663230 :     it->WriteDataValue(value, true);
    5582             : 
    5583             : #if VERIFY_HEAP
    5584             :     if (FLAG_verify_heap) {
    5585             :       receiver->HeapObjectVerify(isolate);
    5586             :     }
    5587             : #endif
    5588             :   }
    5589             : 
    5590             :   return Just(true);
    5591             : }
    5592             : 
    5593     2277170 : void Map::EnsureDescriptorSlack(Isolate* isolate, Handle<Map> map, int slack) {
    5594             :   // Only supports adding slack to owned descriptors.
    5595             :   DCHECK(map->owns_descriptors());
    5596             : 
    5597     4554344 :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    5598             :   int old_size = map->NumberOfOwnDescriptors();
    5599     2281397 :   if (slack <= descriptors->number_of_slack_descriptors()) return;
    5600             : 
    5601             :   Handle<DescriptorArray> new_descriptors =
    5602             :       DescriptorArray::CopyUpTo(isolate, descriptors, old_size, slack);
    5603             : 
    5604             :   DisallowHeapAllocation no_allocation;
    5605             :   // The descriptors are still the same, so keep the layout descriptor.
    5606     4554348 :   LayoutDescriptor layout_descriptor = map->GetLayoutDescriptor();
    5607             : 
    5608     2277175 :   if (old_size == 0) {
    5609             :     map->UpdateDescriptors(isolate, *new_descriptors, layout_descriptor,
    5610        4223 :                            map->NumberOfOwnDescriptors());
    5611        4223 :     return;
    5612             :   }
    5613             : 
    5614             :   // If the source descriptors had an enum cache we copy it. This ensures
    5615             :   // that the maps to which we push the new descriptor array back can rely
    5616             :   // on a cache always being available once it is set. If the map has more
    5617             :   // enumerated descriptors than available in the original cache, the cache
    5618             :   // will be lazily replaced by the extended cache when needed.
    5619     2272951 :   new_descriptors->CopyEnumCacheFrom(*descriptors);
    5620             : 
    5621             :   // Replace descriptors by new_descriptors in all maps that share it. The old
    5622             :   // descriptors will not be trimmed in the mark-compactor, we need to mark
    5623             :   // all its elements.
    5624             :   MarkingBarrierForDescriptorArray(isolate->heap(), *map, *descriptors,
    5625     6818857 :                                    descriptors->number_of_descriptors());
    5626             : 
    5627     2272949 :   Map current = *map;
    5628    53282529 :   while (current->instance_descriptors() == *descriptors) {
    5629    23232519 :     Object next = current->GetBackPointer();
    5630    23232526 :     if (next->IsUndefined(isolate)) break;  // Stop overwriting at initial map.
    5631             :     current->UpdateDescriptors(isolate, *new_descriptors, layout_descriptor,
    5632    23231843 :                                current->NumberOfOwnDescriptors());
    5633    23231840 :     current = Map::cast(next);
    5634             :   }
    5635             :   map->UpdateDescriptors(isolate, *new_descriptors, layout_descriptor,
    5636     2272954 :                          map->NumberOfOwnDescriptors());
    5637             : }
    5638             : 
    5639             : // static
    5640      119997 : Handle<Map> Map::GetObjectCreateMap(Isolate* isolate,
    5641             :                                     Handle<HeapObject> prototype) {
    5642      359991 :   Handle<Map> map(isolate->native_context()->object_function()->initial_map(),
    5643      239994 :                   isolate);
    5644      119997 :   if (map->prototype() == *prototype) return map;
    5645      239940 :   if (prototype->IsNull(isolate)) {
    5646         366 :     return isolate->slow_object_with_null_prototype_map();
    5647             :   }
    5648      239208 :   if (prototype->IsJSObject()) {
    5649      118875 :     Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype);
    5650      118875 :     if (!js_prototype->map()->is_prototype_map()) {
    5651      116302 :       JSObject::OptimizeAsPrototype(js_prototype);
    5652             :     }
    5653             :     Handle<PrototypeInfo> info =
    5654      118875 :         Map::GetOrCreatePrototypeInfo(js_prototype, isolate);
    5655             :     // TODO(verwaest): Use inobject slack tracking for this map.
    5656      118875 :     if (info->HasObjectCreateMap()) {
    5657         200 :       map = handle(info->ObjectCreateMap(), isolate);
    5658             :     } else {
    5659      118775 :       map = Map::CopyInitialMap(isolate, map);
    5660      118775 :       Map::SetPrototype(isolate, map, prototype);
    5661      118775 :       PrototypeInfo::SetObjectCreateMap(info, map);
    5662             :     }
    5663      118875 :     return map;
    5664             :   }
    5665             : 
    5666         729 :   return Map::TransitionToPrototype(isolate, map, prototype);
    5667             : }
    5668             : 
    5669             : // static
    5670           0 : MaybeHandle<Map> Map::TryGetObjectCreateMap(Isolate* isolate,
    5671             :                                             Handle<HeapObject> prototype) {
    5672           0 :   Handle<Map> map(isolate->native_context()->object_function()->initial_map(),
    5673           0 :                   isolate);
    5674           0 :   if (map->prototype() == *prototype) return map;
    5675           0 :   if (prototype->IsNull(isolate)) {
    5676           0 :     return isolate->slow_object_with_null_prototype_map();
    5677             :   }
    5678           0 :   if (!prototype->IsJSObject()) return MaybeHandle<Map>();
    5679           0 :   Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype);
    5680           0 :   if (!js_prototype->map()->is_prototype_map()) return MaybeHandle<Map>();
    5681             :   Handle<PrototypeInfo> info =
    5682           0 :       Map::GetOrCreatePrototypeInfo(js_prototype, isolate);
    5683           0 :   if (!info->HasObjectCreateMap()) return MaybeHandle<Map>();
    5684           0 :   return handle(info->ObjectCreateMap(), isolate);
    5685             : }
    5686             : 
    5687             : template <class T>
    5688       52023 : static int AppendUniqueCallbacks(Isolate* isolate,
    5689             :                                  Handle<TemplateList> callbacks,
    5690             :                                  Handle<typename T::Array> array,
    5691             :                                  int valid_descriptors) {
    5692       52023 :   int nof_callbacks = callbacks->length();
    5693             : 
    5694             :   // Fill in new callback descriptors.  Process the callbacks from
    5695             :   // back to front so that the last callback with a given name takes
    5696             :   // precedence over previously added callbacks with that name.
    5697      104331 :   for (int i = nof_callbacks - 1; i >= 0; i--) {
    5698      104616 :     Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)), isolate);
    5699      104616 :     Handle<Name> key(Name::cast(entry->name()), isolate);
    5700             :     DCHECK(key->IsUniqueName());
    5701             :     // Check if a descriptor with this name already exists before writing.
    5702       52308 :     if (!T::Contains(key, entry, valid_descriptors, array)) {
    5703       52296 :       T::Insert(key, entry, valid_descriptors, array);
    5704       52296 :       valid_descriptors++;
    5705             :     }
    5706             :   }
    5707             : 
    5708       52023 :   return valid_descriptors;
    5709             : }
    5710             : 
    5711             : struct FixedArrayAppender {
    5712             :   typedef FixedArray Array;
    5713       52308 :   static bool Contains(Handle<Name> key,
    5714             :                        Handle<AccessorInfo> entry,
    5715             :                        int valid_descriptors,
    5716             :                        Handle<FixedArray> array) {
    5717       52833 :     for (int i = 0; i < valid_descriptors; i++) {
    5718        1074 :       if (*key == AccessorInfo::cast(array->get(i))->name()) return true;
    5719             :     }
    5720             :     return false;
    5721             :   }
    5722       52296 :   static void Insert(Handle<Name> key,
    5723             :                      Handle<AccessorInfo> entry,
    5724             :                      int valid_descriptors,
    5725             :                      Handle<FixedArray> array) {
    5726             :     DisallowHeapAllocation no_gc;
    5727      104592 :     array->set(valid_descriptors, *entry);
    5728       52296 :   }
    5729             : };
    5730             : 
    5731       52023 : int AccessorInfo::AppendUnique(Isolate* isolate, Handle<Object> descriptors,
    5732             :                                Handle<FixedArray> array,
    5733             :                                int valid_descriptors) {
    5734       52023 :   Handle<TemplateList> callbacks = Handle<TemplateList>::cast(descriptors);
    5735             :   DCHECK_GE(array->length(), callbacks->length() + valid_descriptors);
    5736             :   return AppendUniqueCallbacks<FixedArrayAppender>(isolate, callbacks, array,
    5737       52023 :                                                    valid_descriptors);
    5738             : }
    5739             : 
    5740       80076 : static bool ContainsMap(MapHandles const& maps, Map map) {
    5741             :   DCHECK(!map.is_null());
    5742      234836 :   for (Handle<Map> current : maps) {
    5743      177193 :     if (!current.is_null() && *current == map) return true;
    5744             :   }
    5745             :   return false;
    5746             : }
    5747             : 
    5748       52112 : Map Map::FindElementsKindTransitionedMap(Isolate* isolate,
    5749             :                                          MapHandles const& candidates) {
    5750             :   DisallowHeapAllocation no_allocation;
    5751             :   DisallowDeoptimization no_deoptimization(isolate);
    5752             : 
    5753       52112 :   if (is_prototype_map()) return Map();
    5754             : 
    5755             :   ElementsKind kind = elements_kind();
    5756             :   bool packed = IsFastPackedElementsKind(kind);
    5757             : 
    5758             :   Map transition;
    5759       51544 :   if (IsTransitionableFastElementsKind(kind)) {
    5760             :     // Check the state of the root map.
    5761       26577 :     Map root_map = FindRootMap(isolate);
    5762       26579 :     if (!EquivalentToForElementsKindTransition(root_map)) return Map();
    5763       26579 :     root_map = root_map->LookupElementsTransitionMap(isolate, kind);
    5764             :     DCHECK(!root_map.is_null());
    5765             :     // Starting from the next existing elements kind transition try to
    5766             :     // replay the property transitions that does not involve instance rewriting
    5767             :     // (ElementsTransitionAndStoreStub does not support that).
    5768      225547 :     for (root_map = root_map->ElementsTransitionMap();
    5769      201040 :          !root_map.is_null() && root_map->has_fast_elements();
    5770             :          root_map = root_map->ElementsTransitionMap()) {
    5771       86196 :       Map current = root_map->TryReplayPropertyTransitions(isolate, *this);
    5772       86195 :       if (current.is_null()) continue;
    5773       80120 :       if (InstancesNeedRewriting(current)) continue;
    5774             : 
    5775      160155 :       if (ContainsMap(candidates, current) &&
    5776        1347 :           (packed || !IsFastPackedElementsKind(current->elements_kind()))) {
    5777             :         transition = current;
    5778       26124 :         packed = packed && IsFastPackedElementsKind(current->elements_kind());
    5779             :       }
    5780             :     }
    5781             :   }
    5782       51545 :   return transition;
    5783             : }
    5784             : 
    5785     3299158 : static Map FindClosestElementsTransition(Isolate* isolate, Map map,
    5786             :                                          ElementsKind to_kind) {
    5787             :   // Ensure we are requested to search elements kind transition "near the root".
    5788             :   DCHECK_EQ(map->FindRootMap(isolate)->NumberOfOwnDescriptors(),
    5789             :             map->NumberOfOwnDescriptors());
    5790     3299158 :   Map current_map = map;
    5791             : 
    5792             :   ElementsKind kind = map->elements_kind();
    5793    11118665 :   while (kind != to_kind) {
    5794     7988236 :     Map next_map = current_map->ElementsTransitionMap();
    5795     7988253 :     if (next_map.is_null()) return current_map;
    5796             :     kind = next_map->elements_kind();
    5797     7819507 :     current_map = next_map;
    5798             :   }
    5799             : 
    5800             :   DCHECK_EQ(to_kind, current_map->elements_kind());
    5801     3130429 :   return current_map;
    5802             : }
    5803             : 
    5804       26598 : Map Map::LookupElementsTransitionMap(Isolate* isolate, ElementsKind to_kind) {
    5805       26598 :   Map to_map = FindClosestElementsTransition(isolate, *this, to_kind);
    5806       26598 :   if (to_map->elements_kind() == to_kind) return to_map;
    5807           0 :   return Map();
    5808             : }
    5809             : 
    5810      147542 : bool Map::IsMapInArrayPrototypeChain(Isolate* isolate) const {
    5811      295084 :   if (isolate->initial_array_prototype()->map() == *this) {
    5812             :     return true;
    5813             :   }
    5814             : 
    5815      293838 :   if (isolate->initial_object_prototype()->map() == *this) {
    5816             :     return true;
    5817             :   }
    5818             : 
    5819      146718 :   return false;
    5820             : }
    5821             : 
    5822      168746 : static Handle<Map> AddMissingElementsTransitions(Isolate* isolate,
    5823             :                                                  Handle<Map> map,
    5824             :                                                  ElementsKind to_kind) {
    5825             :   DCHECK(IsTransitionElementsKind(map->elements_kind()));
    5826             : 
    5827             :   Handle<Map> current_map = map;
    5828             : 
    5829             :   ElementsKind kind = map->elements_kind();
    5830             :   TransitionFlag flag;
    5831      168746 :   if (map->is_prototype_map()) {
    5832             :     flag = OMIT_TRANSITION;
    5833             :   } else {
    5834             :     flag = INSERT_TRANSITION;
    5835      167456 :     if (IsFastElementsKind(kind)) {
    5836      342928 :       while (kind != to_kind && !IsTerminalElementsKind(kind)) {
    5837        5273 :         kind = GetNextTransitionElementsKind(kind);
    5838        5273 :         current_map = Map::CopyAsElementsKind(isolate, current_map, kind, flag);
    5839             :       }
    5840             :     }
    5841             :   }
    5842             : 
    5843             :   // In case we are exiting the fast elements kind system, just add the map in
    5844             :   // the end.
    5845      168746 :   if (kind != to_kind) {
    5846      166390 :     current_map = Map::CopyAsElementsKind(isolate, current_map, to_kind, flag);
    5847             :   }
    5848             : 
    5849             :   DCHECK(current_map->elements_kind() == to_kind);
    5850      168746 :   return current_map;
    5851             : }
    5852             : 
    5853     1214981 : Handle<Map> Map::TransitionElementsTo(Isolate* isolate, Handle<Map> map,
    5854             :                                       ElementsKind to_kind) {
    5855             :   ElementsKind from_kind = map->elements_kind();
    5856     1214982 :   if (from_kind == to_kind) return map;
    5857             : 
    5858      469351 :   Context native_context = isolate->context()->native_context();
    5859      469353 :   if (from_kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
    5860        1482 :     if (*map == native_context->fast_aliased_arguments_map()) {
    5861             :       DCHECK_EQ(SLOW_SLOPPY_ARGUMENTS_ELEMENTS, to_kind);
    5862         678 :       return handle(native_context->slow_aliased_arguments_map(), isolate);
    5863             :     }
    5864      468612 :   } else if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
    5865           0 :     if (*map == native_context->slow_aliased_arguments_map()) {
    5866             :       DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, to_kind);
    5867           0 :       return handle(native_context->fast_aliased_arguments_map(), isolate);
    5868             :     }
    5869      468612 :   } else if (IsFastElementsKind(from_kind) && IsFastElementsKind(to_kind)) {
    5870             :     // Reuse map transitions for JSArrays.
    5871             :     DisallowHeapAllocation no_gc;
    5872      357341 :     if (native_context->GetInitialJSArrayMap(from_kind) == *map) {
    5873             :       Object maybe_transitioned_map =
    5874      173544 :           native_context->get(Context::ArrayMapIndex(to_kind));
    5875      173544 :       if (maybe_transitioned_map->IsMap()) {
    5876      173542 :         return handle(Map::cast(maybe_transitioned_map), isolate);
    5877             :       }
    5878             :     }
    5879             :   }
    5880             : 
    5881             :   DCHECK(!map->IsUndefined(isolate));
    5882             :   // Check if we can go back in the elements kind transition chain.
    5883      875163 :   if (IsHoleyElementsKind(from_kind) &&
    5884           0 :       to_kind == GetPackedElementsKind(from_kind) &&
    5885      590264 :       map->GetBackPointer()->IsMap() &&
    5886      295132 :       Map::cast(map->GetBackPointer())->elements_kind() == to_kind) {
    5887           0 :     return handle(Map::cast(map->GetBackPointer()), isolate);
    5888             :   }
    5889             : 
    5890             :   bool allow_store_transition = IsTransitionElementsKind(from_kind);
    5891             :   // Only store fast element maps in ascending generality.
    5892      295132 :   if (IsFastElementsKind(to_kind)) {
    5893             :     allow_store_transition =
    5894       15896 :         allow_store_transition && IsTransitionableFastElementsKind(from_kind) &&
    5895        5127 :         IsMoreGeneralElementsKindTransition(from_kind, to_kind);
    5896             :   }
    5897             : 
    5898      295132 :   if (!allow_store_transition) {
    5899         524 :     return Map::CopyAsElementsKind(isolate, map, to_kind, OMIT_TRANSITION);
    5900             :   }
    5901             : 
    5902             :   return Map::ReconfigureElementsKind(isolate, map, to_kind);
    5903             : }
    5904             : 
    5905             : 
    5906             : // static
    5907     3272567 : Handle<Map> Map::AsElementsKind(Isolate* isolate, Handle<Map> map,
    5908             :                                 ElementsKind kind) {
    5909             :   Handle<Map> closest_map(FindClosestElementsTransition(isolate, *map, kind),
    5910     6545145 :                           isolate);
    5911             : 
    5912     3272580 :   if (closest_map->elements_kind() == kind) {
    5913     3103834 :     return closest_map;
    5914             :   }
    5915             : 
    5916      168746 :   return AddMissingElementsTransitions(isolate, closest_map, kind);
    5917             : }
    5918             : 
    5919             : 
    5920     1192594 : Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
    5921             :                                                ElementsKind to_kind) {
    5922             :   Handle<Map> map(object->map(), object->GetIsolate());
    5923     2385191 :   return Map::TransitionElementsTo(object->GetIsolate(), map, to_kind);
    5924             : }
    5925             : 
    5926             : 
    5927           5 : void JSProxy::Revoke(Handle<JSProxy> proxy) {
    5928             :   Isolate* isolate = proxy->GetIsolate();
    5929             :   // ES#sec-proxy-revocation-functions
    5930          10 :   if (!proxy->IsRevoked()) {
    5931             :     // 5. Set p.[[ProxyTarget]] to null.
    5932          10 :     proxy->set_target(ReadOnlyRoots(isolate).null_value());
    5933             :     // 6. Set p.[[ProxyHandler]] to null.
    5934          10 :     proxy->set_handler(ReadOnlyRoots(isolate).null_value());
    5935             :   }
    5936             :   DCHECK(proxy->IsRevoked());
    5937           5 : }
    5938             : 
    5939             : // static
    5940        1233 : Maybe<bool> JSProxy::IsArray(Handle<JSProxy> proxy) {
    5941             :   Isolate* isolate = proxy->GetIsolate();
    5942        1233 :   Handle<JSReceiver> object = Handle<JSReceiver>::cast(proxy);
    5943      922860 :   for (int i = 0; i < JSProxy::kMaxIterationLimit; i++) {
    5944      922851 :     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
    5945     1845702 :     if (proxy->IsRevoked()) {
    5946             :       isolate->Throw(*isolate->factory()->NewTypeError(
    5947             :           MessageTemplate::kProxyRevoked,
    5948         324 :           isolate->factory()->NewStringFromAsciiChecked("IsArray")));
    5949             :       return Nothing<bool>();
    5950             :     }
    5951     1845486 :     object = handle(JSReceiver::cast(proxy->target()), isolate);
    5952     1845486 :     if (object->IsJSArray()) return Just(true);
    5953     1844748 :     if (!object->IsJSProxy()) return Just(false);
    5954             :   }
    5955             : 
    5956             :   // Too deep recursion, throw a RangeError.
    5957           9 :   isolate->StackOverflow();
    5958             :   return Nothing<bool>();
    5959             : }
    5960             : 
    5961       52903 : Maybe<bool> JSProxy::HasProperty(Isolate* isolate, Handle<JSProxy> proxy,
    5962             :                                  Handle<Name> name) {
    5963             :   DCHECK(!name->IsPrivate());
    5964       52903 :   STACK_CHECK(isolate, Nothing<bool>());
    5965             :   // 1. (Assert)
    5966             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    5967      105788 :   Handle<Object> handler(proxy->handler(), isolate);
    5968             :   // 3. If handler is null, throw a TypeError exception.
    5969             :   // 4. Assert: Type(handler) is Object.
    5970      105788 :   if (proxy->IsRevoked()) {
    5971             :     isolate->Throw(*isolate->factory()->NewTypeError(
    5972           0 :         MessageTemplate::kProxyRevoked, isolate->factory()->has_string()));
    5973             :     return Nothing<bool>();
    5974             :   }
    5975             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    5976      105788 :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    5977             :   // 6. Let trap be ? GetMethod(handler, "has").
    5978             :   Handle<Object> trap;
    5979      105788 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5980             :       isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler),
    5981             :                                        isolate->factory()->has_string()),
    5982             :       Nothing<bool>());
    5983             :   // 7. If trap is undefined, then
    5984      105788 :   if (trap->IsUndefined(isolate)) {
    5985             :     // 7a. Return target.[[HasProperty]](P).
    5986       44470 :     return JSReceiver::HasProperty(target, name);
    5987             :   }
    5988             :   // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, P»)).
    5989             :   Handle<Object> trap_result_obj;
    5990             :   Handle<Object> args[] = {target, name};
    5991       16848 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5992             :       isolate, trap_result_obj,
    5993             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    5994             :       Nothing<bool>());
    5995        8379 :   bool boolean_trap_result = trap_result_obj->BooleanValue(isolate);
    5996             :   // 9. If booleanTrapResult is false, then:
    5997        8379 :   if (!boolean_trap_result) {
    5998        5481 :     MAYBE_RETURN(JSProxy::CheckHasTrap(isolate, name, target), Nothing<bool>());
    5999             :   }
    6000             :   // 10. Return booleanTrapResult.
    6001             :   return Just(boolean_trap_result);
    6002             : }
    6003             : 
    6004        5490 : Maybe<bool> JSProxy::CheckHasTrap(Isolate* isolate, Handle<Name> name,
    6005             :                                   Handle<JSReceiver> target) {
    6006             :   // 9a. Let targetDesc be ? target.[[GetOwnProperty]](P).
    6007             :   PropertyDescriptor target_desc;
    6008             :   Maybe<bool> target_found =
    6009        5490 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    6010        5490 :   MAYBE_RETURN(target_found, Nothing<bool>());
    6011             :   // 9b. If targetDesc is not undefined, then:
    6012        5490 :   if (target_found.FromJust()) {
    6013             :     // 9b i. If targetDesc.[[Configurable]] is false, throw a TypeError
    6014             :     //       exception.
    6015           9 :     if (!target_desc.configurable()) {
    6016             :       isolate->Throw(*isolate->factory()->NewTypeError(
    6017          18 :           MessageTemplate::kProxyHasNonConfigurable, name));
    6018           9 :       return Nothing<bool>();
    6019             :     }
    6020             :     // 9b ii. Let extensibleTarget be ? IsExtensible(target).
    6021           0 :     Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    6022           0 :     MAYBE_RETURN(extensible_target, Nothing<bool>());
    6023             :     // 9b iii. If extensibleTarget is false, throw a TypeError exception.
    6024           0 :     if (!extensible_target.FromJust()) {
    6025             :       isolate->Throw(*isolate->factory()->NewTypeError(
    6026           0 :           MessageTemplate::kProxyHasNonExtensible, name));
    6027             :       return Nothing<bool>();
    6028             :     }
    6029             :   }
    6030             :   return Just(true);
    6031             : }
    6032             : 
    6033       52771 : Maybe<bool> JSProxy::SetProperty(Handle<JSProxy> proxy, Handle<Name> name,
    6034             :                                  Handle<Object> value, Handle<Object> receiver,
    6035             :                                  LanguageMode language_mode) {
    6036             :   DCHECK(!name->IsPrivate());
    6037             :   Isolate* isolate = proxy->GetIsolate();
    6038       52771 :   STACK_CHECK(isolate, Nothing<bool>());
    6039             :   Factory* factory = isolate->factory();
    6040             :   Handle<String> trap_name = factory->set_string();
    6041             :   ShouldThrow should_throw =
    6042       52743 :       is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
    6043             : 
    6044      105486 :   if (proxy->IsRevoked()) {
    6045             :     isolate->Throw(
    6046          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    6047             :     return Nothing<bool>();
    6048             :   }
    6049      105450 :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    6050      105450 :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    6051             : 
    6052             :   Handle<Object> trap;
    6053      105450 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    6054             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    6055      104946 :   if (trap->IsUndefined(isolate)) {
    6056             :     LookupIterator it =
    6057       44421 :         LookupIterator::PropertyOrElement(isolate, receiver, name, target);
    6058             :     return Object::SetSuperProperty(&it, value, language_mode,
    6059       44421 :                                     StoreOrigin::kMaybeKeyed);
    6060             :   }
    6061             : 
    6062             :   Handle<Object> trap_result;
    6063        8052 :   Handle<Object> args[] = {target, name, value, receiver};
    6064       16104 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    6065             :       isolate, trap_result,
    6066             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    6067             :       Nothing<bool>());
    6068        2781 :   if (!trap_result->BooleanValue(isolate)) {
    6069         585 :     RETURN_FAILURE(isolate, should_throw,
    6070             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    6071             :                                 trap_name, name));
    6072             :   }
    6073             : 
    6074             :   MaybeHandle<Object> result =
    6075        2286 :       JSProxy::CheckGetSetTrapResult(isolate, name, target, value, kSet);
    6076             : 
    6077        2286 :   if (result.is_null()) {
    6078             :     return Nothing<bool>();
    6079             :   }
    6080             :   return Just(true);
    6081             : }
    6082             : 
    6083             : 
    6084       26664 : Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy,
    6085             :                                              Handle<Name> name,
    6086             :                                              LanguageMode language_mode) {
    6087             :   DCHECK(!name->IsPrivate());
    6088             :   ShouldThrow should_throw =
    6089       26664 :       is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
    6090             :   Isolate* isolate = proxy->GetIsolate();
    6091       26664 :   STACK_CHECK(isolate, Nothing<bool>());
    6092             :   Factory* factory = isolate->factory();
    6093             :   Handle<String> trap_name = factory->deleteProperty_string();
    6094             : 
    6095       53294 :   if (proxy->IsRevoked()) {
    6096             :     isolate->Throw(
    6097          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    6098             :     return Nothing<bool>();
    6099             :   }
    6100       53258 :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    6101       53258 :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    6102             : 
    6103             :   Handle<Object> trap;
    6104       53258 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    6105             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    6106       52988 :   if (trap->IsUndefined(isolate)) {
    6107       17973 :     return JSReceiver::DeletePropertyOrElement(target, name, language_mode);
    6108             :   }
    6109             : 
    6110             :   Handle<Object> trap_result;
    6111             :   Handle<Object> args[] = {target, name};
    6112       17042 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    6113             :       isolate, trap_result,
    6114             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    6115             :       Nothing<bool>());
    6116        1809 :   if (!trap_result->BooleanValue(isolate)) {
    6117        1242 :     RETURN_FAILURE(isolate, should_throw,
    6118             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    6119             :                                 trap_name, name));
    6120             :   }
    6121             : 
    6122             :   // Enforce the invariant.
    6123             :   PropertyDescriptor target_desc;
    6124             :   Maybe<bool> owned =
    6125        1053 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    6126        1053 :   MAYBE_RETURN(owned, Nothing<bool>());
    6127        1593 :   if (owned.FromJust() && !target_desc.configurable()) {
    6128             :     isolate->Throw(*factory->NewTypeError(
    6129         720 :         MessageTemplate::kProxyDeletePropertyNonConfigurable, name));
    6130             :     return Nothing<bool>();
    6131             :   }
    6132             :   return Just(true);
    6133             : }
    6134             : 
    6135             : 
    6136             : // static
    6137          17 : MaybeHandle<JSProxy> JSProxy::New(Isolate* isolate, Handle<Object> target,
    6138             :                                   Handle<Object> handler) {
    6139          34 :   if (!target->IsJSReceiver()) {
    6140           0 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject),
    6141             :                     JSProxy);
    6142             :   }
    6143          34 :   if (target->IsJSProxy() && JSProxy::cast(*target)->IsRevoked()) {
    6144           0 :     THROW_NEW_ERROR(isolate,
    6145             :                     NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
    6146             :                     JSProxy);
    6147             :   }
    6148          34 :   if (!handler->IsJSReceiver()) {
    6149           0 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject),
    6150             :                     JSProxy);
    6151             :   }
    6152          34 :   if (handler->IsJSProxy() && JSProxy::cast(*handler)->IsRevoked()) {
    6153           0 :     THROW_NEW_ERROR(isolate,
    6154             :                     NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
    6155             :                     JSProxy);
    6156             :   }
    6157             :   return isolate->factory()->NewJSProxy(Handle<JSReceiver>::cast(target),
    6158          17 :                                         Handle<JSReceiver>::cast(handler));
    6159             : }
    6160             : 
    6161             : 
    6162             : // static
    6163          36 : MaybeHandle<Context> JSProxy::GetFunctionRealm(Handle<JSProxy> proxy) {
    6164             :   DCHECK(proxy->map()->is_constructor());
    6165          72 :   if (proxy->IsRevoked()) {
    6166           0 :     THROW_NEW_ERROR(proxy->GetIsolate(),
    6167             :                     NewTypeError(MessageTemplate::kProxyRevoked), Context);
    6168             :   }
    6169             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()),
    6170          72 :                             proxy->GetIsolate());
    6171          36 :   return JSReceiver::GetFunctionRealm(target);
    6172             : }
    6173             : 
    6174             : 
    6175             : // static
    6176           9 : MaybeHandle<Context> JSBoundFunction::GetFunctionRealm(
    6177             :     Handle<JSBoundFunction> function) {
    6178             :   DCHECK(function->map()->is_constructor());
    6179             :   return JSReceiver::GetFunctionRealm(
    6180          18 :       handle(function->bound_target_function(), function->GetIsolate()));
    6181             : }
    6182             : 
    6183             : // static
    6184          77 : MaybeHandle<String> JSBoundFunction::GetName(Isolate* isolate,
    6185             :                                              Handle<JSBoundFunction> function) {
    6186             :   Handle<String> prefix = isolate->factory()->bound__string();
    6187             :   Handle<String> target_name = prefix;
    6188             :   Factory* factory = isolate->factory();
    6189             :   // Concatenate the "bound " up to the last non-bound target.
    6190         231 :   while (function->bound_target_function()->IsJSBoundFunction()) {
    6191           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, target_name,
    6192             :                                factory->NewConsString(prefix, target_name),
    6193             :                                String);
    6194           0 :     function = handle(JSBoundFunction::cast(function->bound_target_function()),
    6195           0 :                       isolate);
    6196             :   }
    6197         154 :   if (function->bound_target_function()->IsJSFunction()) {
    6198             :     Handle<JSFunction> target(
    6199         154 :         JSFunction::cast(function->bound_target_function()), isolate);
    6200          77 :     Handle<Object> name = JSFunction::GetName(isolate, target);
    6201         154 :     if (!name->IsString()) return target_name;
    6202          77 :     return factory->NewConsString(target_name, Handle<String>::cast(name));
    6203             :   }
    6204             :   // This will omit the proper target name for bound JSProxies.
    6205           0 :   return target_name;
    6206             : }
    6207             : 
    6208             : // static
    6209         311 : Maybe<int> JSBoundFunction::GetLength(Isolate* isolate,
    6210             :                                       Handle<JSBoundFunction> function) {
    6211         622 :   int nof_bound_arguments = function->bound_arguments()->length();
    6212        1689 :   while (function->bound_target_function()->IsJSBoundFunction()) {
    6213         756 :     function = handle(JSBoundFunction::cast(function->bound_target_function()),
    6214         756 :                       isolate);
    6215             :     // Make sure we never overflow {nof_bound_arguments}, the number of
    6216             :     // arguments of a function is strictly limited by the max length of an
    6217             :     // JSAarray, Smi::kMaxValue is thus a reasonably good overestimate.
    6218         756 :     int length = function->bound_arguments()->length();
    6219         378 :     if (V8_LIKELY(Smi::kMaxValue - nof_bound_arguments > length)) {
    6220         378 :       nof_bound_arguments += length;
    6221             :     } else {
    6222             :       nof_bound_arguments = Smi::kMaxValue;
    6223             :     }
    6224             :   }
    6225             :   // All non JSFunction targets get a direct property and don't use this
    6226             :   // accessor.
    6227         622 :   Handle<JSFunction> target(JSFunction::cast(function->bound_target_function()),
    6228         622 :                             isolate);
    6229         311 :   Maybe<int> target_length = JSFunction::GetLength(isolate, target);
    6230         311 :   if (target_length.IsNothing()) return target_length;
    6231             : 
    6232         311 :   int length = Max(0, target_length.FromJust() - nof_bound_arguments);
    6233             :   return Just(length);
    6234             : }
    6235             : 
    6236             : // static
    6237      128882 : Handle<Object> JSFunction::GetName(Isolate* isolate,
    6238             :                                    Handle<JSFunction> function) {
    6239      128882 :   if (function->shared()->name_should_print_as_anonymous()) {
    6240          20 :     return isolate->factory()->anonymous_string();
    6241             :   }
    6242      257724 :   return handle(function->shared()->Name(), isolate);
    6243             : }
    6244             : 
    6245             : // static
    6246       54229 : Maybe<int> JSFunction::GetLength(Isolate* isolate,
    6247             :                                  Handle<JSFunction> function) {
    6248             :   int length = 0;
    6249       54229 :   IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
    6250       54229 :   if (is_compiled_scope.is_compiled()) {
    6251      106278 :     length = function->shared()->GetLength();
    6252             :   } else {
    6253             :     // If the function isn't compiled yet, the length is not computed
    6254             :     // correctly yet. Compile it now and return the right length.
    6255        1090 :     if (Compiler::Compile(function, Compiler::KEEP_EXCEPTION,
    6256             :                           &is_compiled_scope)) {
    6257        1510 :       length = function->shared()->GetLength();
    6258             :     }
    6259        1090 :     if (isolate->has_pending_exception()) return Nothing<int>();
    6260             :   }
    6261             :   DCHECK_GE(length, 0);
    6262             :   return Just(length);
    6263             : }
    6264             : 
    6265             : // static
    6266        3387 : Handle<Context> JSFunction::GetFunctionRealm(Handle<JSFunction> function) {
    6267             :   DCHECK(function->map()->is_constructor());
    6268        6774 :   return handle(function->context()->native_context(), function->GetIsolate());
    6269             : }
    6270             : 
    6271             : 
    6272             : // static
    6273           0 : MaybeHandle<Context> JSObject::GetFunctionRealm(Handle<JSObject> object) {
    6274             :   DCHECK(object->map()->is_constructor());
    6275             :   DCHECK(!object->IsJSFunction());
    6276           0 :   return object->GetCreationContext();
    6277             : }
    6278             : 
    6279             : 
    6280             : // static
    6281        3432 : MaybeHandle<Context> JSReceiver::GetFunctionRealm(Handle<JSReceiver> receiver) {
    6282        6864 :   if (receiver->IsJSProxy()) {
    6283          36 :     return JSProxy::GetFunctionRealm(Handle<JSProxy>::cast(receiver));
    6284             :   }
    6285             : 
    6286        6792 :   if (receiver->IsJSFunction()) {
    6287        3387 :     return JSFunction::GetFunctionRealm(Handle<JSFunction>::cast(receiver));
    6288             :   }
    6289             : 
    6290          18 :   if (receiver->IsJSBoundFunction()) {
    6291             :     return JSBoundFunction::GetFunctionRealm(
    6292           9 :         Handle<JSBoundFunction>::cast(receiver));
    6293             :   }
    6294             : 
    6295           0 :   return JSObject::GetFunctionRealm(Handle<JSObject>::cast(receiver));
    6296             : }
    6297             : 
    6298             : 
    6299        4266 : Maybe<PropertyAttributes> JSProxy::GetPropertyAttributes(LookupIterator* it) {
    6300             :   PropertyDescriptor desc;
    6301             :   Maybe<bool> found = JSProxy::GetOwnPropertyDescriptor(
    6302        4266 :       it->isolate(), it->GetHolder<JSProxy>(), it->GetName(), &desc);
    6303        2133 :   MAYBE_RETURN(found, Nothing<PropertyAttributes>());
    6304        1836 :   if (!found.FromJust()) return Just(ABSENT);
    6305        1629 :   return Just(desc.ToAttributes());
    6306             : }
    6307             : 
    6308             : 
    6309     7682027 : void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
    6310             :   DCHECK(object->map()->GetInObjectProperties() ==
    6311             :          map->GetInObjectProperties());
    6312             :   ElementsKind obj_kind = object->map()->elements_kind();
    6313             :   ElementsKind map_kind = map->elements_kind();
    6314     7682027 :   if (map_kind != obj_kind) {
    6315             :     ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind);
    6316          27 :     if (IsDictionaryElementsKind(obj_kind)) {
    6317             :       to_kind = obj_kind;
    6318             :     }
    6319          27 :     if (IsDictionaryElementsKind(to_kind)) {
    6320          27 :       NormalizeElements(object);
    6321             :     } else {
    6322           0 :       TransitionElementsKind(object, to_kind);
    6323             :     }
    6324             :     map = Map::ReconfigureElementsKind(object->GetIsolate(), map, to_kind);
    6325             :   }
    6326     7682027 :   int number_of_fields = map->NumberOfFields();
    6327     7682027 :   int inobject = map->GetInObjectProperties();
    6328     7682027 :   int unused = map->UnusedPropertyFields();
    6329     7682027 :   int total_size = number_of_fields + unused;
    6330     7682027 :   int external = total_size - inobject;
    6331             :   // Allocate mutable double boxes if necessary. It is always necessary if we
    6332             :   // have external properties, but is also necessary if we only have inobject
    6333             :   // properties but don't unbox double fields.
    6334     7682027 :   if (!FLAG_unbox_double_fields || external > 0) {
    6335             :     Isolate* isolate = object->GetIsolate();
    6336             : 
    6337     5819504 :     Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    6338             :     Handle<FixedArray> storage;
    6339             :     if (!FLAG_unbox_double_fields) {
    6340             :       storage = isolate->factory()->NewFixedArray(inobject);
    6341             :     }
    6342             : 
    6343             :     Handle<PropertyArray> array =
    6344     2909752 :         isolate->factory()->NewPropertyArray(external);
    6345             : 
    6346    41507480 :     for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
    6347    17843988 :       PropertyDetails details = descriptors->GetDetails(i);
    6348             :       Representation representation = details.representation();
    6349    35687868 :       if (!representation.IsDouble()) continue;
    6350        6096 :       FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    6351        6096 :       if (map->IsUnboxedDoubleField(index)) continue;
    6352             :       auto box = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
    6353         108 :       if (index.is_inobject()) {
    6354           0 :         storage->set(index.property_index(), *box);
    6355             :       } else {
    6356         216 :         array->set(index.outobject_array_index(), *box);
    6357             :       }
    6358             :     }
    6359             : 
    6360     5819504 :     object->SetProperties(*array);
    6361             : 
    6362             :     if (!FLAG_unbox_double_fields) {
    6363             :       for (int i = 0; i < inobject; i++) {
    6364             :         FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
    6365             :         Object value = storage->get(i);
    6366             :         object->RawFastPropertyAtPut(index, value);
    6367             :       }
    6368             :     }
    6369             :   }
    6370     7682027 :   object->synchronized_set_map(*map);
    6371     7682027 : }
    6372             : 
    6373             : 
    6374        2457 : void JSObject::MigrateInstance(Handle<JSObject> object) {
    6375             :   Handle<Map> original_map(object->map(), object->GetIsolate());
    6376        2457 :   Handle<Map> map = Map::Update(object->GetIsolate(), original_map);
    6377        2457 :   map->set_is_migration_target(true);
    6378        2457 :   MigrateToMap(object, map);
    6379        2457 :   if (FLAG_trace_migration) {
    6380           0 :     object->PrintInstanceMigration(stdout, *original_map, *map);
    6381             :   }
    6382             : #if VERIFY_HEAP
    6383             :   if (FLAG_verify_heap) {
    6384             :     object->JSObjectVerify(object->GetIsolate());
    6385             :   }
    6386             : #endif
    6387        2457 : }
    6388             : 
    6389             : 
    6390             : // static
    6391        6858 : bool JSObject::TryMigrateInstance(Handle<JSObject> object) {
    6392             :   Isolate* isolate = object->GetIsolate();
    6393             :   DisallowDeoptimization no_deoptimization(isolate);
    6394             :   Handle<Map> original_map(object->map(), isolate);
    6395             :   Handle<Map> new_map;
    6396       13716 :   if (!Map::TryUpdate(isolate, original_map).ToHandle(&new_map)) {
    6397             :     return false;
    6398             :   }
    6399        6842 :   JSObject::MigrateToMap(object, new_map);
    6400        6842 :   if (FLAG_trace_migration && *original_map != object->map()) {
    6401           0 :     object->PrintInstanceMigration(stdout, *original_map, object->map());
    6402             :   }
    6403             : #if VERIFY_HEAP
    6404             :   if (FLAG_verify_heap) {
    6405             :     object->JSObjectVerify(isolate);
    6406             :   }
    6407             : #endif
    6408             :   return true;
    6409             : }
    6410             : 
    6411    20246593 : void JSObject::AddProperty(Isolate* isolate, Handle<JSObject> object,
    6412             :                            Handle<Name> name, Handle<Object> value,
    6413             :                            PropertyAttributes attributes) {
    6414             :   LookupIterator it(isolate, object, name, object,
    6415    20246593 :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
    6416    20246588 :   CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
    6417             : #ifdef DEBUG
    6418             :   uint32_t index;
    6419             :   DCHECK(!object->IsJSProxy());
    6420             :   DCHECK(!name->AsArrayIndex(&index));
    6421             :   Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
    6422             :   DCHECK(maybe.IsJust());
    6423             :   DCHECK(!it.IsFound());
    6424             :   DCHECK(object->map()->is_extensible() || name->IsPrivate());
    6425             : #endif
    6426    20246588 :   CHECK(Object::AddDataProperty(&it, value, attributes, kThrowOnError,
    6427             :                                 StoreOrigin::kNamed)
    6428             :             .IsJust());
    6429    20246585 : }
    6430             : 
    6431      185521 : void JSObject::AddProperty(Isolate* isolate, Handle<JSObject> object,
    6432             :                            const char* name, Handle<Object> value,
    6433             :                            PropertyAttributes attributes) {
    6434             :   JSObject::AddProperty(isolate, object,
    6435             :                         isolate->factory()->InternalizeUtf8String(name), value,
    6436      371042 :                         attributes);
    6437      185521 : }
    6438             : 
    6439             : // Reconfigures a property to a data property with attributes, even if it is not
    6440             : // reconfigurable.
    6441             : // Requires a LookupIterator that does not look at the prototype chain beyond
    6442             : // hidden prototypes.
    6443    11682438 : MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
    6444             :     LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
    6445             :     AccessorInfoHandling handling) {
    6446    11682438 :   MAYBE_RETURN_NULL(DefineOwnPropertyIgnoreAttributes(it, value, attributes,
    6447             :                                                       kThrowOnError, handling));
    6448    11682435 :   return value;
    6449             : }
    6450             : 
    6451             : 
    6452    12009159 : Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
    6453    12031186 :     LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
    6454             :     ShouldThrow should_throw, AccessorInfoHandling handling) {
    6455    12009159 :   it->UpdateProtector();
    6456    12009190 :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    6457             : 
    6458    24019602 :   for (; it->IsFound(); it->Next()) {
    6459      538865 :     switch (it->state()) {
    6460             :       case LookupIterator::JSPROXY:
    6461             :       case LookupIterator::NOT_FOUND:
    6462             :       case LookupIterator::TRANSITION:
    6463           0 :         UNREACHABLE();
    6464             : 
    6465             :       case LookupIterator::ACCESS_CHECK:
    6466         412 :         if (!it->HasAccess()) {
    6467           0 :           it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    6468           0 :           RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    6469             :           return Just(true);
    6470             :         }
    6471             :         break;
    6472             : 
    6473             :       // If there's an interceptor, try to store the property with the
    6474             :       // interceptor.
    6475             :       // In case of success, the attributes will have been reset to the default
    6476             :       // attributes of the interceptor, rather than the incoming attributes.
    6477             :       //
    6478             :       // TODO(verwaest): JSProxy afterwards verify the attributes that the
    6479             :       // JSProxy claims it has, and verifies that they are compatible. If not,
    6480             :       // they throw. Here we should do the same.
    6481             :       case LookupIterator::INTERCEPTOR:
    6482         212 :         if (handling == DONT_FORCE_FIELD) {
    6483             :           Maybe<bool> result =
    6484         212 :               JSObject::SetPropertyWithInterceptor(it, should_throw, value);
    6485         424 :           if (result.IsNothing() || result.FromJust()) return result;
    6486             :         }
    6487             :         break;
    6488             : 
    6489             :       case LookupIterator::ACCESSOR: {
    6490        5420 :         Handle<Object> accessors = it->GetAccessors();
    6491             : 
    6492             :         // Special handling for AccessorInfo, which behaves like a data
    6493             :         // property.
    6494       10840 :         if (accessors->IsAccessorInfo() && handling == DONT_FORCE_FIELD) {
    6495             :           PropertyAttributes current_attributes = it->property_attributes();
    6496             :           // Ensure the context isn't changed after calling into accessors.
    6497             :           AssertNoContextChange ncc(it->isolate());
    6498             : 
    6499             :           // Update the attributes before calling the setter. The setter may
    6500             :           // later change the shape of the property.
    6501        4812 :           if (current_attributes != attributes) {
    6502        1165 :             it->TransitionToAccessorPair(accessors, attributes);
    6503             :           }
    6504             : 
    6505        4812 :           return Object::SetPropertyWithAccessor(it, value, should_throw);
    6506             :         }
    6507             : 
    6508         608 :         it->ReconfigureDataProperty(value, attributes);
    6509             :         return Just(true);
    6510             :       }
    6511             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    6512             :         return Object::RedefineIncompatibleProperty(
    6513          18 :             it->isolate(), it->GetName(), value, should_throw);
    6514             : 
    6515             :       case LookupIterator::DATA: {
    6516             :         // Regular property update if the attributes match.
    6517      532812 :         if (it->property_attributes() == attributes) {
    6518      511435 :           return Object::SetDataProperty(it, value);
    6519             :         }
    6520             : 
    6521             :         // Special case: properties of typed arrays cannot be reconfigured to
    6522             :         // non-writable nor to non-enumerable.
    6523       40732 :         if (it->IsElement() && object->HasFixedTypedArrayElements()) {
    6524             :           return Object::RedefineIncompatibleProperty(
    6525           0 :               it->isolate(), it->GetName(), value, should_throw);
    6526             :         }
    6527             : 
    6528             :         // Reconfigure the data property if the attributes mismatch.
    6529       21377 :         it->ReconfigureDataProperty(value, attributes);
    6530             : 
    6531             :         return Just(true);
    6532             :       }
    6533             :     }
    6534             :   }
    6535             : 
    6536             :   return Object::AddDataProperty(it, value, attributes, should_throw,
    6537    11470935 :                                  StoreOrigin::kNamed);
    6538             : }
    6539             : 
    6540     3965094 : MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
    6541             :     Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
    6542             :     PropertyAttributes attributes) {
    6543             :   DCHECK(!value->IsTheHole());
    6544     3965094 :   LookupIterator it(object, name, object, LookupIterator::OWN);
    6545     3965096 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    6546             : }
    6547             : 
    6548     2475634 : MaybeHandle<Object> JSObject::SetOwnElementIgnoreAttributes(
    6549             :     Handle<JSObject> object, uint32_t index, Handle<Object> value,
    6550             :     PropertyAttributes attributes) {
    6551             :   Isolate* isolate = object->GetIsolate();
    6552             :   LookupIterator it(isolate, object, index, object, LookupIterator::OWN);
    6553     2475634 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    6554             : }
    6555             : 
    6556      432276 : MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes(
    6557             :     Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
    6558             :     PropertyAttributes attributes) {
    6559             :   Isolate* isolate = object->GetIsolate();
    6560             :   LookupIterator it = LookupIterator::PropertyOrElement(
    6561      432276 :       isolate, object, name, object, LookupIterator::OWN);
    6562      432276 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    6563             : }
    6564             : 
    6565      250398 : Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
    6566             :     LookupIterator* it) {
    6567      250398 :   return GetPropertyAttributesWithInterceptorInternal(it, it->GetInterceptor());
    6568             : }
    6569             : 
    6570    16666550 : Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
    6571    18950932 :     LookupIterator* it) {
    6572    37901864 :   for (; it->IsFound(); it->Next()) {
    6573    12130427 :     switch (it->state()) {
    6574             :       case LookupIterator::NOT_FOUND:
    6575             :       case LookupIterator::TRANSITION:
    6576           0 :         UNREACHABLE();
    6577             :       case LookupIterator::JSPROXY:
    6578         909 :         return JSProxy::GetPropertyAttributes(it);
    6579             :       case LookupIterator::INTERCEPTOR: {
    6580             :         Maybe<PropertyAttributes> result =
    6581         682 :             JSObject::GetPropertyAttributesWithInterceptor(it);
    6582        1041 :         if (result.IsNothing()) return result;
    6583         682 :         if (result.FromJust() != ABSENT) return result;
    6584         323 :         break;
    6585             :       }
    6586             :       case LookupIterator::ACCESS_CHECK:
    6587     2284140 :         if (it->HasAccess()) break;
    6588          81 :         return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
    6589             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    6590             :         return Just(ABSENT);
    6591             :       case LookupIterator::ACCESSOR:
    6592      430398 :         if (it->GetHolder<Object>()->IsJSModuleNamespace()) {
    6593         792 :           return JSModuleNamespace::GetPropertyAttributes(it);
    6594             :         } else {
    6595             :           return Just(it->property_attributes());
    6596             :         }
    6597             :       case LookupIterator::DATA:
    6598             :         return Just(it->property_attributes());
    6599             :     }
    6600             :   }
    6601             :   return Just(ABSENT);
    6602             : }
    6603             : 
    6604             : 
    6605         111 : Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) {
    6606             :   Handle<WeakFixedArray> array(
    6607         111 :       isolate->factory()->NewWeakFixedArray(kEntries, TENURED));
    6608         111 :   return Handle<NormalizedMapCache>::cast(array);
    6609             : }
    6610             : 
    6611             : 
    6612      596975 : MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
    6613             :                                          PropertyNormalizationMode mode) {
    6614             :   DisallowHeapAllocation no_gc;
    6615      596975 :   MaybeObject value = WeakFixedArray::Get(GetIndex(fast_map));
    6616      596975 :   HeapObject heap_object;
    6617      596975 :   if (!value->GetHeapObjectIfWeak(&heap_object)) {
    6618       69680 :     return MaybeHandle<Map>();
    6619             :   }
    6620             : 
    6621      527295 :   Map normalized_map = Map::cast(heap_object);
    6622      527295 :   if (!normalized_map->EquivalentToForNormalization(*fast_map, mode)) {
    6623       92193 :     return MaybeHandle<Map>();
    6624             :   }
    6625      435102 :   return handle(normalized_map, GetIsolate());
    6626             : }
    6627             : 
    6628      161873 : void NormalizedMapCache::Set(Handle<Map> fast_map, Handle<Map> normalized_map) {
    6629             :   DisallowHeapAllocation no_gc;
    6630             :   DCHECK(normalized_map->is_dictionary_map());
    6631             :   WeakFixedArray::Set(GetIndex(fast_map),
    6632      161873 :                       HeapObjectReference::Weak(*normalized_map));
    6633      161873 : }
    6634             : 
    6635      676519 : void JSObject::NormalizeProperties(Handle<JSObject> object,
    6636             :                                    PropertyNormalizationMode mode,
    6637             :                                    int expected_additional_properties,
    6638             :                                    const char* reason) {
    6639      930376 :   if (!object->HasFastProperties()) return;
    6640             : 
    6641             :   Handle<Map> map(object->map(), object->GetIsolate());
    6642      422666 :   Handle<Map> new_map = Map::Normalize(object->GetIsolate(), map, mode, reason);
    6643             : 
    6644      422666 :   MigrateToMap(object, new_map, expected_additional_properties);
    6645             : }
    6646             : 
    6647             : 
    6648     1125395 : void JSObject::MigrateSlowToFast(Handle<JSObject> object,
    6649             :                                  int unused_property_fields,
    6650             :                                  const char* reason) {
    6651     1979601 :   if (object->HasFastProperties()) return;
    6652             :   DCHECK(!object->IsJSGlobalObject());
    6653         409 :   Isolate* isolate = object->GetIsolate();
    6654             :   Factory* factory = isolate->factory();
    6655      671085 :   Handle<NameDictionary> dictionary(object->property_dictionary(), isolate);
    6656             : 
    6657             :   // Make sure we preserve dictionary representation if there are too many
    6658             :   // descriptors.
    6659      335541 :   int number_of_elements = dictionary->NumberOfElements();
    6660      335542 :   if (number_of_elements > kMaxNumberOfDescriptors) return;
    6661             : 
    6662             :   Handle<FixedArray> iteration_order =
    6663      334947 :       NameDictionary::IterationIndices(isolate, dictionary);
    6664             : 
    6665             :   int instance_descriptor_length = iteration_order->length();
    6666             :   int number_of_fields = 0;
    6667             : 
    6668             :   // Compute the length of the instance descriptor.
    6669             :   ReadOnlyRoots roots(isolate);
    6670     2014277 :   for (int i = 0; i < instance_descriptor_length; i++) {
    6671     1679329 :     int index = Smi::ToInt(iteration_order->get(i));
    6672             :     DCHECK(dictionary->IsKey(roots, dictionary->KeyAt(index)));
    6673             : 
    6674     3358662 :     PropertyKind kind = dictionary->DetailsAt(index).kind();
    6675     1679332 :     if (kind == kData) {
    6676             :       if (FLAG_track_constant_fields) {
    6677             :         number_of_fields += 1;
    6678             :       } else {
    6679     1270218 :         Object value = dictionary->ValueAt(index);
    6680     1270215 :         if (!value->IsJSFunction()) {
    6681      241824 :           number_of_fields += 1;
    6682             :         }
    6683             :       }
    6684             :     }
    6685             :   }
    6686             : 
    6687             :   Handle<Map> old_map(object->map(), isolate);
    6688             : 
    6689      334949 :   int inobject_props = old_map->GetInObjectProperties();
    6690             : 
    6691             :   // Allocate new map.
    6692      334949 :   Handle<Map> new_map = Map::CopyDropDescriptors(isolate, old_map);
    6693             :   // We should not only set this bit if we need to. We should not retain the
    6694             :   // old bit because turning a map into dictionary always sets this bit.
    6695      669707 :   new_map->set_may_have_interesting_symbols(new_map->has_named_interceptor() ||
    6696      669898 :                                             new_map->is_access_check_needed());
    6697      334949 :   new_map->set_is_dictionary_map(false);
    6698             : 
    6699      334949 :   NotifyMapChange(old_map, new_map, isolate);
    6700             : 
    6701             : 
    6702      334948 :   if (instance_descriptor_length == 0) {
    6703             :     DisallowHeapAllocation no_gc;
    6704             :     DCHECK_LE(unused_property_fields, inobject_props);
    6705             :     // Transform the object.
    6706       63749 :     new_map->SetInObjectUnusedPropertyFields(inobject_props);
    6707       63749 :     object->synchronized_set_map(*new_map);
    6708      127498 :     object->SetProperties(ReadOnlyRoots(isolate).empty_fixed_array());
    6709             :     // Check that it really works.
    6710             :     DCHECK(object->HasFastProperties());
    6711       63749 :     if (FLAG_trace_maps) {
    6712           0 :       LOG(isolate, MapEvent("SlowToFast", *old_map, *new_map, reason));
    6713             :     }
    6714             :     return;
    6715             :   }
    6716             : 
    6717             :   // Allocate the instance descriptor.
    6718             :   Handle<DescriptorArray> descriptors = DescriptorArray::Allocate(
    6719             :       isolate, instance_descriptor_length, 0, TENURED);
    6720             : 
    6721             :   int number_of_allocated_fields =
    6722      271199 :       number_of_fields + unused_property_fields - inobject_props;
    6723      271199 :   if (number_of_allocated_fields < 0) {
    6724             :     // There is enough inobject space for all fields (including unused).
    6725             :     number_of_allocated_fields = 0;
    6726       65025 :     unused_property_fields = inobject_props - number_of_fields;
    6727             :   }
    6728             : 
    6729             :   // Allocate the property array for the fields.
    6730             :   Handle<PropertyArray> fields =
    6731      271199 :       factory->NewPropertyArray(number_of_allocated_fields);
    6732             : 
    6733             :   bool is_transitionable_elements_kind =
    6734             :       IsTransitionableFastElementsKind(old_map->elements_kind());
    6735             : 
    6736             :   // Fill in the instance descriptor and the fields.
    6737             :   int current_offset = 0;
    6738     1679323 :   for (int i = 0; i < instance_descriptor_length; i++) {
    6739     1679328 :     int index = Smi::ToInt(iteration_order->get(i));
    6740     1679323 :     Name k = dictionary->NameAt(index);
    6741             :     // Dictionary keys are internalized upon insertion.
    6742             :     // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild.
    6743     1679325 :     CHECK(k->IsUniqueName());
    6744             :     Handle<Name> key(k, isolate);
    6745             : 
    6746             :     // Properly mark the {new_map} if the {key} is an "interesting symbol".
    6747     1679325 :     if (key->IsInterestingSymbol()) {
    6748        1962 :       new_map->set_may_have_interesting_symbols(true);
    6749             :     }
    6750             : 
    6751     1679326 :     Object value = dictionary->ValueAt(index);
    6752             : 
    6753     1679325 :     PropertyDetails details = dictionary->DetailsAt(index);
    6754             :     DCHECK_EQ(kField, details.location());
    6755             :     DCHECK_EQ(PropertyConstness::kMutable, details.constness());
    6756             : 
    6757     1679325 :     Descriptor d;
    6758     1679325 :     if (details.kind() == kData) {
    6759     1270212 :       if (!FLAG_track_constant_fields && value->IsJSFunction()) {
    6760             :         d = Descriptor::DataConstant(key, handle(value, isolate),
    6761     1028387 :                                      details.attributes());
    6762             :       } else {
    6763             :         // Ensure that we make constant field only when elements kind is not
    6764             :         // transitionable.
    6765             :         PropertyConstness constness =
    6766             :             FLAG_track_constant_fields && !is_transitionable_elements_kind
    6767             :                 ? PropertyConstness::kConst
    6768             :                 : PropertyConstness::kMutable;
    6769             :         d = Descriptor::DataField(
    6770             :             key, current_offset, details.attributes(), constness,
    6771             :             // TODO(verwaest): value->OptimalRepresentation();
    6772             :             Representation::Tagged(),
    6773      483648 :             MaybeObjectHandle(FieldType::Any(isolate)));
    6774             :       }
    6775             :     } else {
    6776             :       DCHECK_EQ(kAccessor, details.kind());
    6777             :       d = Descriptor::AccessorConstant(key, handle(value, isolate),
    6778      409112 :                                        details.attributes());
    6779             :     }
    6780             :     details = d.GetDetails();
    6781     1679329 :     if (details.location() == kField) {
    6782      241824 :       if (current_offset < inobject_props) {
    6783             :         object->InObjectPropertyAtPut(current_offset, value,
    6784       17539 :                                       UPDATE_WRITE_BARRIER);
    6785             :       } else {
    6786      224285 :         int offset = current_offset - inobject_props;
    6787      224285 :         fields->set(offset, value);
    6788             :       }
    6789      241824 :       current_offset += details.field_width_in_words();
    6790             :     }
    6791     1679328 :     descriptors->Set(i, &d);
    6792             :   }
    6793             :   DCHECK(current_offset == number_of_fields);
    6794             : 
    6795      271200 :   descriptors->Sort();
    6796             : 
    6797             :   Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New(
    6798      271198 :       isolate, new_map, descriptors, descriptors->number_of_descriptors());
    6799             : 
    6800             :   DisallowHeapAllocation no_gc;
    6801      271200 :   new_map->InitializeDescriptors(isolate, *descriptors, *layout_descriptor);
    6802      271199 :   if (number_of_allocated_fields == 0) {
    6803      242944 :     new_map->SetInObjectUnusedPropertyFields(unused_property_fields);
    6804             :   } else {
    6805       28255 :     new_map->SetOutOfObjectUnusedPropertyFields(unused_property_fields);
    6806             :   }
    6807             : 
    6808      271200 :   if (FLAG_trace_maps) {
    6809         818 :     LOG(isolate, MapEvent("SlowToFast", *old_map, *new_map, reason));
    6810             :   }
    6811             :   // Transform the object.
    6812      271199 :   object->synchronized_set_map(*new_map);
    6813             : 
    6814      542400 :   object->SetProperties(*fields);
    6815             :   DCHECK(object->IsJSObject());
    6816             : 
    6817             :   // Check that it really works.
    6818             :   DCHECK(object->HasFastProperties());
    6819             : }
    6820             : 
    6821       74677 : void JSObject::RequireSlowElements(NumberDictionary dictionary) {
    6822      149354 :   if (dictionary->requires_slow_elements()) return;
    6823             :   dictionary->set_requires_slow_elements();
    6824       42370 :   if (map()->is_prototype_map()) {
    6825             :     // If this object is a prototype (the callee will check), invalidate any
    6826             :     // prototype chains involving it.
    6827             :     InvalidatePrototypeChains(map());
    6828             :   }
    6829             : }
    6830             : 
    6831      291140 : Handle<NumberDictionary> JSObject::NormalizeElements(Handle<JSObject> object) {
    6832             :   DCHECK(!object->HasFixedTypedArrayElements());
    6833             :   Isolate* isolate = object->GetIsolate();
    6834      582280 :   bool is_sloppy_arguments = object->HasSloppyArgumentsElements();
    6835             :   {
    6836             :     DisallowHeapAllocation no_gc;
    6837      291140 :     FixedArrayBase elements = object->elements();
    6838             : 
    6839      291140 :     if (is_sloppy_arguments) {
    6840         777 :       elements = SloppyArgumentsElements::cast(elements)->arguments();
    6841             :     }
    6842             : 
    6843      291140 :     if (elements->IsNumberDictionary()) {
    6844        4284 :       return handle(NumberDictionary::cast(elements), isolate);
    6845             :     }
    6846             :   }
    6847             : 
    6848             :   DCHECK(object->HasSmiOrObjectElements() || object->HasDoubleElements() ||
    6849             :          object->HasFastArgumentsElements() ||
    6850             :          object->HasFastStringWrapperElements());
    6851             : 
    6852             :   Handle<NumberDictionary> dictionary =
    6853      573712 :       object->GetElementsAccessor()->Normalize(object);
    6854             : 
    6855             :   // Switch to using the dictionary as the backing storage for elements.
    6856             :   ElementsKind target_kind = is_sloppy_arguments
    6857             :                                  ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS
    6858      859086 :                                  : object->HasFastStringWrapperElements()
    6859             :                                        ? SLOW_STRING_WRAPPER_ELEMENTS
    6860      573712 :                                        : DICTIONARY_ELEMENTS;
    6861      286856 :   Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind);
    6862             :   // Set the new map first to satify the elements type assert in set_elements().
    6863      286856 :   JSObject::MigrateToMap(object, new_map);
    6864             : 
    6865      286856 :   if (is_sloppy_arguments) {
    6866        1482 :     SloppyArgumentsElements::cast(object->elements())
    6867        1482 :         ->set_arguments(*dictionary);
    6868             :   } else {
    6869      572230 :     object->set_elements(*dictionary);
    6870             :   }
    6871             : 
    6872      286856 :   isolate->counters()->elements_to_dictionary()->Increment();
    6873             : 
    6874             : #ifdef DEBUG
    6875             :   if (FLAG_trace_normalization) {
    6876             :     StdoutStream os;
    6877             :     os << "Object elements have been normalized:\n";
    6878             :     object->Print(os);
    6879             :   }
    6880             : #endif
    6881             : 
    6882             :   DCHECK(object->HasDictionaryElements() ||
    6883             :          object->HasSlowArgumentsElements() ||
    6884             :          object->HasSlowStringWrapperElements());
    6885      286856 :   return dictionary;
    6886             : }
    6887             : 
    6888             : namespace {
    6889             : 
    6890       39131 : Object SetHashAndUpdateProperties(HeapObject properties, int hash) {
    6891             :   DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
    6892             :   DCHECK(PropertyArray::HashField::is_valid(hash));
    6893             : 
    6894       39131 :   ReadOnlyRoots roots = properties->GetReadOnlyRoots();
    6895       44868 :   if (properties == roots.empty_fixed_array() ||
    6896       44858 :       properties == roots.empty_property_array() ||
    6897             :       properties == roots.empty_property_dictionary()) {
    6898       33782 :     return Smi::FromInt(hash);
    6899             :   }
    6900             : 
    6901        5349 :   if (properties->IsPropertyArray()) {
    6902         147 :     PropertyArray::cast(properties)->SetHash(hash);
    6903             :     DCHECK_LT(0, PropertyArray::cast(properties)->length());
    6904         147 :     return properties;
    6905             :   }
    6906             : 
    6907        5202 :   if (properties->IsGlobalDictionary()) {
    6908             :     GlobalDictionary::cast(properties)->SetHash(hash);
    6909           0 :     return properties;
    6910             :   }
    6911             : 
    6912             :   DCHECK(properties->IsNameDictionary());
    6913             :   NameDictionary::cast(properties)->SetHash(hash);
    6914        5202 :   return properties;
    6915             : }
    6916             : 
    6917    29341265 : int GetIdentityHashHelper(JSReceiver object) {
    6918             :   DisallowHeapAllocation no_gc;
    6919    29341265 :   Object properties = object->raw_properties_or_hash();
    6920    29341256 :   if (properties->IsSmi()) {
    6921       38793 :     return Smi::ToInt(properties);
    6922             :   }
    6923             : 
    6924    29302470 :   if (properties->IsPropertyArray()) {
    6925    11235938 :     return PropertyArray::cast(properties)->Hash();
    6926             :   }
    6927             : 
    6928    18066536 :   if (properties->IsNameDictionary()) {
    6929     3617501 :     return NameDictionary::cast(properties)->Hash();
    6930             :   }
    6931             : 
    6932    14449037 :   if (properties->IsGlobalDictionary()) {
    6933     8235072 :     return GlobalDictionary::cast(properties)->Hash();
    6934             :   }
    6935             : 
    6936             : #ifdef DEBUG
    6937             :   ReadOnlyRoots roots = object->GetReadOnlyRoots();
    6938             :   DCHECK(properties == roots.empty_fixed_array() ||
    6939             :          properties == roots.empty_property_dictionary());
    6940             : #endif
    6941             : 
    6942             :   return PropertyArray::kNoHashSentinel;
    6943             : }
    6944             : }  // namespace
    6945             : 
    6946       33843 : void JSReceiver::SetIdentityHash(int hash) {
    6947             :   DisallowHeapAllocation no_gc;
    6948             :   DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
    6949             :   DCHECK(PropertyArray::HashField::is_valid(hash));
    6950             : 
    6951       67686 :   HeapObject existing_properties = HeapObject::cast(raw_properties_or_hash());
    6952       33843 :   Object new_properties = SetHashAndUpdateProperties(existing_properties, hash);
    6953       33843 :   set_raw_properties_or_hash(new_properties);
    6954       33843 : }
    6955             : 
    6956    29279266 : void JSReceiver::SetProperties(HeapObject properties) {
    6957             :   DCHECK_IMPLIES(properties->IsPropertyArray() &&
    6958             :                      PropertyArray::cast(properties)->length() == 0,
    6959             :                  properties == GetReadOnlyRoots().empty_property_array());
    6960             :   DisallowHeapAllocation no_gc;
    6961    29279266 :   int hash = GetIdentityHashHelper(*this);
    6962    29279269 :   Object new_properties = properties;
    6963             : 
    6964             :   // TODO(cbruni): Make GetIdentityHashHelper return a bool so that we
    6965             :   // don't have to manually compare against kNoHashSentinel.
    6966    29279269 :   if (hash != PropertyArray::kNoHashSentinel) {
    6967        5288 :     new_properties = SetHashAndUpdateProperties(properties, hash);
    6968             :   }
    6969             : 
    6970    29279269 :   set_raw_properties_or_hash(new_properties);
    6971    29279261 : }
    6972             : 
    6973       40517 : Object JSReceiver::GetIdentityHash() {
    6974             :   DisallowHeapAllocation no_gc;
    6975             : 
    6976       40517 :   int hash = GetIdentityHashHelper(*this);
    6977       40517 :   if (hash == PropertyArray::kNoHashSentinel) {
    6978        4190 :     return GetReadOnlyRoots().undefined_value();
    6979             :   }
    6980             : 
    6981       38422 :   return Smi::FromInt(hash);
    6982             : }
    6983             : 
    6984             : // static
    6985       33808 : Smi JSReceiver::CreateIdentityHash(Isolate* isolate, JSReceiver key) {
    6986             :   DisallowHeapAllocation no_gc;
    6987       33808 :   int hash = isolate->GenerateIdentityHash(PropertyArray::HashField::kMax);
    6988             :   DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
    6989             : 
    6990       33808 :   key->SetIdentityHash(hash);
    6991       33808 :   return Smi::FromInt(hash);
    6992             : }
    6993             : 
    6994       21480 : Smi JSReceiver::GetOrCreateIdentityHash(Isolate* isolate) {
    6995             :   DisallowHeapAllocation no_gc;
    6996             : 
    6997       21480 :   int hash = GetIdentityHashHelper(*this);
    6998       21480 :   if (hash != PropertyArray::kNoHashSentinel) {
    6999             :     return Smi::FromInt(hash);
    7000             :   }
    7001             : 
    7002       20999 :   return JSReceiver::CreateIdentityHash(isolate, *this);
    7003             : }
    7004             : 
    7005         158 : Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
    7006             :                                                     ShouldThrow should_throw) {
    7007             :   Isolate* isolate = it->isolate();
    7008             :   // Make sure that the top context does not change when doing callbacks or
    7009             :   // interceptor calls.
    7010             :   AssertNoContextChange ncc(isolate);
    7011             : 
    7012             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    7013         100 :   Handle<InterceptorInfo> interceptor(it->GetInterceptor());
    7014         200 :   if (interceptor->deleter()->IsUndefined(isolate)) return Nothing<bool>();
    7015             : 
    7016             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    7017             :   Handle<Object> receiver = it->GetReceiver();
    7018         116 :   if (!receiver->IsJSReceiver()) {
    7019           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    7020             :                                      Object::ConvertReceiver(isolate, receiver),
    7021             :                                      Nothing<bool>());
    7022             :   }
    7023             : 
    7024             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    7025          58 :                                  *holder, should_throw);
    7026             :   Handle<Object> result;
    7027          58 :   if (it->IsElement()) {
    7028          23 :     result = args.CallIndexedDeleter(interceptor, it->index());
    7029             :   } else {
    7030          35 :     result = args.CallNamedDeleter(interceptor, it->name());
    7031             :   }
    7032             : 
    7033          58 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    7034          58 :   if (result.is_null()) return Nothing<bool>();
    7035             : 
    7036             :   DCHECK(result->IsBoolean());
    7037             :   // Rebox CustomArguments::kReturnValueOffset before returning.
    7038          48 :   return Just(result->IsTrue(isolate));
    7039             : }
    7040             : 
    7041       54275 : void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object,
    7042             :                                           int entry) {
    7043             :   DCHECK(!object->HasFastProperties());
    7044             :   Isolate* isolate = object->GetIsolate();
    7045             : 
    7046      108550 :   if (object->IsJSGlobalObject()) {
    7047             :     // If we have a global object, invalidate the cell and swap in a new one.
    7048             :     Handle<GlobalDictionary> dictionary(
    7049       22576 :         JSGlobalObject::cast(*object)->global_dictionary(), isolate);
    7050             :     DCHECK_NE(GlobalDictionary::kNotFound, entry);
    7051             : 
    7052       11288 :     auto cell = PropertyCell::InvalidateEntry(isolate, dictionary, entry);
    7053       22576 :     cell->set_value(ReadOnlyRoots(isolate).the_hole_value());
    7054             :     cell->set_property_details(
    7055       22576 :         PropertyDetails::Empty(PropertyCellType::kUninitialized));
    7056             :   } else {
    7057       85974 :     Handle<NameDictionary> dictionary(object->property_dictionary(), isolate);
    7058             :     DCHECK_NE(NameDictionary::kNotFound, entry);
    7059             : 
    7060       42987 :     dictionary = NameDictionary::DeleteEntry(isolate, dictionary, entry);
    7061       85974 :     object->SetProperties(*dictionary);
    7062             :   }
    7063       54275 :   if (object->map()->is_prototype_map()) {
    7064             :     // Invalidate prototype validity cell as this may invalidate transitioning
    7065             :     // store IC handlers.
    7066             :     JSObject::InvalidatePrototypeChains(object->map());
    7067             :   }
    7068       54275 : }
    7069             : 
    7070             : 
    7071    19148293 : Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it,
    7072             :                                        LanguageMode language_mode) {
    7073     6388351 :   it->UpdateProtector();
    7074             : 
    7075             :   Isolate* isolate = it->isolate();
    7076             : 
    7077     6388351 :   if (it->state() == LookupIterator::JSPROXY) {
    7078             :     return JSProxy::DeletePropertyOrElement(it->GetHolder<JSProxy>(),
    7079       53328 :                                             it->GetName(), language_mode);
    7080             :   }
    7081             : 
    7082    12723374 :   if (it->GetReceiver()->IsJSProxy()) {
    7083          39 :     if (it->state() != LookupIterator::NOT_FOUND) {
    7084             :       DCHECK_EQ(LookupIterator::DATA, it->state());
    7085             :       DCHECK(it->name()->IsPrivate());
    7086           6 :       it->Delete();
    7087             :     }
    7088             :     return Just(true);
    7089             :   }
    7090     6361648 :   Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
    7091             : 
    7092    12743104 :   for (; it->IsFound(); it->Next()) {
    7093      170165 :     switch (it->state()) {
    7094             :       case LookupIterator::JSPROXY:
    7095             :       case LookupIterator::NOT_FOUND:
    7096             :       case LookupIterator::TRANSITION:
    7097           0 :         UNREACHABLE();
    7098             :       case LookupIterator::ACCESS_CHECK:
    7099        9864 :         if (it->HasAccess()) break;
    7100          36 :         isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    7101          36 :         RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    7102             :         return Just(false);
    7103             :       case LookupIterator::INTERCEPTOR: {
    7104             :         ShouldThrow should_throw =
    7105         100 :             is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
    7106             :         Maybe<bool> result =
    7107         100 :             JSObject::DeletePropertyWithInterceptor(it, should_throw);
    7108             :         // An exception was thrown in the interceptor. Propagate.
    7109         124 :         if (isolate->has_pending_exception()) return Nothing<bool>();
    7110             :         // Delete with interceptor succeeded. Return result.
    7111             :         // TODO(neis): In strict mode, we should probably throw if the
    7112             :         // interceptor returns false.
    7113         100 :         if (result.IsJust()) return result;
    7114          76 :         break;
    7115             :       }
    7116             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    7117             :         return Just(true);
    7118             :       case LookupIterator::DATA:
    7119             :       case LookupIterator::ACCESSOR: {
    7120      160156 :         if (!it->IsConfigurable()) {
    7121             :           // Fail if the property is not configurable.
    7122        2485 :           if (is_strict(language_mode)) {
    7123             :             isolate->Throw(*isolate->factory()->NewTypeError(
    7124             :                 MessageTemplate::kStrictDeleteProperty, it->GetName(),
    7125        2031 :                 receiver));
    7126             :             return Nothing<bool>();
    7127             :           }
    7128             :           return Just(false);
    7129             :         }
    7130             : 
    7131      157671 :         it->Delete();
    7132             : 
    7133             :         return Just(true);
    7134             :       }
    7135             :     }
    7136             :   }
    7137             : 
    7138             :   return Just(true);
    7139             : }
    7140             : 
    7141             : 
    7142        1027 : Maybe<bool> JSReceiver::DeleteElement(Handle<JSReceiver> object, uint32_t index,
    7143             :                                       LanguageMode language_mode) {
    7144             :   LookupIterator it(object->GetIsolate(), object, index, object,
    7145             :                     LookupIterator::OWN);
    7146        1027 :   return DeleteProperty(&it, language_mode);
    7147             : }
    7148             : 
    7149             : 
    7150         899 : Maybe<bool> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
    7151             :                                        Handle<Name> name,
    7152             :                                        LanguageMode language_mode) {
    7153         899 :   LookupIterator it(object, name, object, LookupIterator::OWN);
    7154         899 :   return DeleteProperty(&it, language_mode);
    7155             : }
    7156             : 
    7157             : 
    7158      622058 : Maybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object,
    7159             :                                                 Handle<Name> name,
    7160             :                                                 LanguageMode language_mode) {
    7161             :   LookupIterator it = LookupIterator::PropertyOrElement(
    7162      622058 :       object->GetIsolate(), object, name, object, LookupIterator::OWN);
    7163      622058 :   return DeleteProperty(&it, language_mode);
    7164             : }
    7165             : 
    7166             : // ES6 19.1.2.4
    7167             : // static
    7168      114325 : Object JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object,
    7169             :                                   Handle<Object> key,
    7170             :                                   Handle<Object> attributes) {
    7171             :   // 1. If Type(O) is not Object, throw a TypeError exception.
    7172      228650 :   if (!object->IsJSReceiver()) {
    7173             :     Handle<String> fun_name =
    7174          63 :         isolate->factory()->InternalizeUtf8String("Object.defineProperty");
    7175         126 :     THROW_NEW_ERROR_RETURN_FAILURE(
    7176             :         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name));
    7177             :   }
    7178             :   // 2. Let key be ToPropertyKey(P).
    7179             :   // 3. ReturnIfAbrupt(key).
    7180      228524 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
    7181             :                                      Object::ToPropertyKey(isolate, key));
    7182             :   // 4. Let desc be ToPropertyDescriptor(Attributes).
    7183             :   // 5. ReturnIfAbrupt(desc).
    7184             :   PropertyDescriptor desc;
    7185      114262 :   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
    7186         135 :     return ReadOnlyRoots(isolate).exception();
    7187             :   }
    7188             :   // 6. Let success be DefinePropertyOrThrow(O,key, desc).
    7189             :   Maybe<bool> success = DefineOwnProperty(
    7190      114127 :       isolate, Handle<JSReceiver>::cast(object), key, &desc, kThrowOnError);
    7191             :   // 7. ReturnIfAbrupt(success).
    7192      115165 :   MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
    7193      113089 :   CHECK(success.FromJust());
    7194             :   // 8. Return O.
    7195             :   return *object;
    7196             : }
    7197             : 
    7198             : // ES6 19.1.2.3.1
    7199             : // static
    7200        1854 : MaybeHandle<Object> JSReceiver::DefineProperties(Isolate* isolate,
    7201             :                                                  Handle<Object> object,
    7202             :                                                  Handle<Object> properties) {
    7203             :   // 1. If Type(O) is not Object, throw a TypeError exception.
    7204        3708 :   if (!object->IsJSReceiver()) {
    7205             :     Handle<String> fun_name =
    7206          27 :         isolate->factory()->InternalizeUtf8String("Object.defineProperties");
    7207          27 :     THROW_NEW_ERROR(isolate,
    7208             :                     NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name),
    7209             :                     Object);
    7210             :   }
    7211             :   // 2. Let props be ToObject(Properties).
    7212             :   // 3. ReturnIfAbrupt(props).
    7213             :   Handle<JSReceiver> props;
    7214        3654 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, props,
    7215             :                              Object::ToObject(isolate, properties), Object);
    7216             : 
    7217             :   // 4. Let keys be props.[[OwnPropertyKeys]]().
    7218             :   // 5. ReturnIfAbrupt(keys).
    7219             :   Handle<FixedArray> keys;
    7220        3636 :   ASSIGN_RETURN_ON_EXCEPTION(
    7221             :       isolate, keys, KeyAccumulator::GetKeys(props, KeyCollectionMode::kOwnOnly,
    7222             :                                              ALL_PROPERTIES),
    7223             :       Object);
    7224             :   // 6. Let descriptors be an empty List.
    7225             :   int capacity = keys->length();
    7226        1818 :   std::vector<PropertyDescriptor> descriptors(capacity);
    7227             :   size_t descriptors_index = 0;
    7228             :   // 7. Repeat for each element nextKey of keys in List order,
    7229       13786 :   for (int i = 0; i < keys->length(); ++i) {
    7230             :     Handle<Object> next_key(keys->get(i), isolate);
    7231             :     // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey).
    7232             :     // 7b. ReturnIfAbrupt(propDesc).
    7233        5300 :     bool success = false;
    7234             :     LookupIterator it = LookupIterator::PropertyOrElement(
    7235        5300 :         isolate, props, next_key, &success, LookupIterator::OWN);
    7236             :     DCHECK(success);
    7237        5300 :     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
    7238        5300 :     if (maybe.IsNothing()) return MaybeHandle<Object>();
    7239             :     PropertyAttributes attrs = maybe.FromJust();
    7240             :     // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true:
    7241        6425 :     if (attrs == ABSENT) continue;
    7242        5300 :     if (attrs & DONT_ENUM) continue;
    7243             :     // 7c i. Let descObj be Get(props, nextKey).
    7244             :     // 7c ii. ReturnIfAbrupt(descObj).
    7245             :     Handle<Object> desc_obj;
    7246        8350 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, desc_obj, Object::GetProperty(&it),
    7247             :                                Object);
    7248             :     // 7c iii. Let desc be ToPropertyDescriptor(descObj).
    7249             :     success = PropertyDescriptor::ToPropertyDescriptor(
    7250        8350 :         isolate, desc_obj, &descriptors[descriptors_index]);
    7251             :     // 7c iv. ReturnIfAbrupt(desc).
    7252        4175 :     if (!success) return MaybeHandle<Object>();
    7253             :     // 7c v. Append the pair (a two element List) consisting of nextKey and
    7254             :     //       desc to the end of descriptors.
    7255        3950 :     descriptors[descriptors_index].set_name(next_key);
    7256        3950 :     descriptors_index++;
    7257             :   }
    7258             :   // 8. For each pair from descriptors in list order,
    7259        3572 :   for (size_t i = 0; i < descriptors_index; ++i) {
    7260        3572 :     PropertyDescriptor* desc = &descriptors[i];
    7261             :     // 8a. Let P be the first element of pair.
    7262             :     // 8b. Let desc be the second element of pair.
    7263             :     // 8c. Let status be DefinePropertyOrThrow(O, P, desc).
    7264             :     Maybe<bool> status =
    7265             :         DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object),
    7266        3572 :                           desc->name(), desc, kThrowOnError);
    7267             :     // 8d. ReturnIfAbrupt(status).
    7268        3572 :     if (status.IsNothing()) return MaybeHandle<Object>();
    7269        3572 :     CHECK(status.FromJust());
    7270             :   }
    7271             :   // 9. Return o.
    7272        1593 :   return object;
    7273             : }
    7274             : 
    7275             : // static
    7276      599340 : Maybe<bool> JSReceiver::DefineOwnProperty(Isolate* isolate,
    7277             :                                           Handle<JSReceiver> object,
    7278             :                                           Handle<Object> key,
    7279             :                                           PropertyDescriptor* desc,
    7280             :                                           ShouldThrow should_throw) {
    7281     1198693 :   if (object->IsJSArray()) {
    7282             :     return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object),
    7283       30484 :                                       key, desc, should_throw);
    7284             :   }
    7285     1137729 :   if (object->IsJSProxy()) {
    7286             :     return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object),
    7287       41059 :                                       key, desc, should_throw);
    7288             :   }
    7289     1055612 :   if (object->IsJSTypedArray()) {
    7290             :     return JSTypedArray::DefineOwnProperty(
    7291        3610 :         isolate, Handle<JSTypedArray>::cast(object), key, desc, should_throw);
    7292             :   }
    7293             : 
    7294             :   // OrdinaryDefineOwnProperty, by virtue of calling
    7295             :   // DefineOwnPropertyIgnoreAttributes, can handle arguments
    7296             :   // (ES#sec-arguments-exotic-objects-defineownproperty-p-desc).
    7297             :   return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key,
    7298      524197 :                                    desc, should_throw);
    7299             : }
    7300             : 
    7301             : 
    7302             : // static
    7303      564157 : Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate,
    7304             :                                                   Handle<JSObject> object,
    7305             :                                                   Handle<Object> key,
    7306             :                                                   PropertyDescriptor* desc,
    7307             :                                                   ShouldThrow should_throw) {
    7308      564157 :   bool success = false;
    7309             :   DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey...
    7310             :   LookupIterator it = LookupIterator::PropertyOrElement(
    7311      564157 :       isolate, object, key, &success, LookupIterator::OWN);
    7312             :   DCHECK(success);  // ...so creating a LookupIterator can't fail.
    7313             : 
    7314             :   // Deal with access checks first.
    7315      564159 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    7316        2440 :     if (!it.HasAccess()) {
    7317          30 :       isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
    7318          30 :       RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    7319             :       return Just(true);
    7320             :     }
    7321        2410 :     it.Next();
    7322             :   }
    7323             : 
    7324      564129 :   return OrdinaryDefineOwnProperty(&it, desc, should_throw);
    7325             : }
    7326             : 
    7327             : 
    7328             : // ES6 9.1.6.1
    7329             : // static
    7330     1315746 : Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it,
    7331             :                                                   PropertyDescriptor* desc,
    7332             :                                                   ShouldThrow should_throw) {
    7333             :   Isolate* isolate = it->isolate();
    7334             :   // 1. Let current be O.[[GetOwnProperty]](P).
    7335             :   // 2. ReturnIfAbrupt(current).
    7336             :   PropertyDescriptor current;
    7337      564122 :   MAYBE_RETURN(GetOwnPropertyDescriptor(it, &current), Nothing<bool>());
    7338             : 
    7339      564104 :   it->Restart();
    7340             :   // Handle interceptor
    7341     1503262 :   for (; it->IsFound(); it->Next()) {
    7342      187575 :     if (it->state() == LookupIterator::INTERCEPTOR) {
    7343         183 :       if (it->HolderIsReceiverOrHiddenPrototype()) {
    7344             :         Maybe<bool> result = DefinePropertyWithInterceptorInternal(
    7345         183 :             it, it->GetInterceptor(), should_throw, *desc);
    7346         366 :         if (result.IsNothing() || result.FromJust()) {
    7347          54 :           return result;
    7348             :         }
    7349             :       }
    7350             :     }
    7351             :   }
    7352             : 
    7353             :   // TODO(jkummerow/verwaest): It would be nice if we didn't have to reset
    7354             :   // the iterator every time. Currently, the reasons why we need it are:
    7355             :   // - handle interceptors correctly
    7356             :   // - handle accessors correctly (which might change the holder's map)
    7357      564049 :   it->Restart();
    7358             :   // 3. Let extensible be the value of the [[Extensible]] internal slot of O.
    7359      564051 :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    7360      564060 :   bool extensible = JSObject::IsExtensible(object);
    7361             : 
    7362             :   return ValidateAndApplyPropertyDescriptor(
    7363      564061 :       isolate, it, extensible, desc, &current, should_throw, Handle<Name>());
    7364             : }
    7365             : 
    7366             : 
    7367             : // ES6 9.1.6.2
    7368             : // static
    7369           0 : Maybe<bool> JSReceiver::IsCompatiblePropertyDescriptor(
    7370             :     Isolate* isolate, bool extensible, PropertyDescriptor* desc,
    7371             :     PropertyDescriptor* current, Handle<Name> property_name,
    7372             :     ShouldThrow should_throw) {
    7373             :   // 1. Return ValidateAndApplyPropertyDescriptor(undefined, undefined,
    7374             :   //    Extensible, Desc, Current).
    7375             :   return ValidateAndApplyPropertyDescriptor(
    7376        4806 :       isolate, nullptr, extensible, desc, current, should_throw, property_name);
    7377             : }
    7378             : 
    7379             : 
    7380             : // ES6 9.1.6.3
    7381             : // static
    7382      568858 : Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
    7383             :     Isolate* isolate, LookupIterator* it, bool extensible,
    7384             :     PropertyDescriptor* desc, PropertyDescriptor* current,
    7385             :     ShouldThrow should_throw, Handle<Name> property_name) {
    7386             :   // We either need a LookupIterator, or a property name.
    7387             :   DCHECK((it == nullptr) != property_name.is_null());
    7388             :   Handle<JSObject> object;
    7389      568858 :   if (it != nullptr) object = Handle<JSObject>::cast(it->GetReceiver());
    7390             :   bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc);
    7391             :   bool desc_is_accessor_descriptor =
    7392             :       PropertyDescriptor::IsAccessorDescriptor(desc);
    7393             :   bool desc_is_generic_descriptor =
    7394             :       PropertyDescriptor::IsGenericDescriptor(desc);
    7395             :   // 1. (Assert)
    7396             :   // 2. If current is undefined, then
    7397      568856 :   if (current->is_empty()) {
    7398             :     // 2a. If extensible is false, return false.
    7399      381778 :     if (!extensible) {
    7400         262 :       RETURN_FAILURE(
    7401             :           isolate, should_throw,
    7402             :           NewTypeError(MessageTemplate::kDefineDisallowed,
    7403             :                        it != nullptr ? it->GetName() : property_name));
    7404             :     }
    7405             :     // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then:
    7406             :     // (This is equivalent to !IsAccessorDescriptor(desc).)
    7407             :     DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) ==
    7408             :            !desc_is_accessor_descriptor);
    7409      381678 :     if (!desc_is_accessor_descriptor) {
    7410             :       // 2c i. If O is not undefined, create an own data property named P of
    7411             :       // object O whose [[Value]], [[Writable]], [[Enumerable]] and
    7412             :       // [[Configurable]] attribute values are described by Desc. If the value
    7413             :       // of an attribute field of Desc is absent, the attribute of the newly
    7414             :       // created property is set to its default value.
    7415      313812 :       if (it != nullptr) {
    7416      311242 :         if (!desc->has_writable()) desc->set_writable(false);
    7417      311242 :         if (!desc->has_enumerable()) desc->set_enumerable(false);
    7418      311242 :         if (!desc->has_configurable()) desc->set_configurable(false);
    7419             :         Handle<Object> value(
    7420             :             desc->has_value()
    7421             :                 ? desc->value()
    7422      320755 :                 : Handle<Object>::cast(isolate->factory()->undefined_value()));
    7423             :         MaybeHandle<Object> result =
    7424             :             JSObject::DefineOwnPropertyIgnoreAttributes(it, value,
    7425      311242 :                                                         desc->ToAttributes());
    7426      311245 :         if (result.is_null()) return Nothing<bool>();
    7427             :       }
    7428             :     } else {
    7429             :       // 2d. Else Desc must be an accessor Property Descriptor,
    7430             :       DCHECK(desc_is_accessor_descriptor);
    7431             :       // 2d i. If O is not undefined, create an own accessor property named P
    7432             :       // of object O whose [[Get]], [[Set]], [[Enumerable]] and
    7433             :       // [[Configurable]] attribute values are described by Desc. If the value
    7434             :       // of an attribute field of Desc is absent, the attribute of the newly
    7435             :       // created property is set to its default value.
    7436       67866 :       if (it != nullptr) {
    7437       67722 :         if (!desc->has_enumerable()) desc->set_enumerable(false);
    7438       67722 :         if (!desc->has_configurable()) desc->set_configurable(false);
    7439             :         Handle<Object> getter(
    7440             :             desc->has_get()
    7441             :                 ? desc->get()
    7442       80177 :                 : Handle<Object>::cast(isolate->factory()->null_value()));
    7443             :         Handle<Object> setter(
    7444             :             desc->has_set()
    7445             :                 ? desc->set()
    7446      109664 :                 : Handle<Object>::cast(isolate->factory()->null_value()));
    7447             :         MaybeHandle<Object> result =
    7448       67722 :             JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes());
    7449       67722 :         if (result.is_null()) return Nothing<bool>();
    7450             :       }
    7451             :     }
    7452             :     // 2e. Return true.
    7453             :     return Just(true);
    7454             :   }
    7455             :   // 3. Return true, if every field in Desc is absent.
    7456             :   // 4. Return true, if every field in Desc also occurs in current and the
    7457             :   // value of every field in Desc is the same value as the corresponding field
    7458             :   // in current when compared using the SameValue algorithm.
    7459      332034 :   if ((!desc->has_enumerable() ||
    7460       70918 :        desc->enumerable() == current->enumerable()) &&
    7461       47674 :       (!desc->has_configurable() ||
    7462       68530 :        desc->configurable() == current->configurable()) &&
    7463       50899 :       (!desc->has_value() ||
    7464      281836 :        (current->has_value() && current->value()->SameValue(*desc->value()))) &&
    7465       27436 :       (!desc->has_writable() ||
    7466       70622 :        (current->has_writable() && current->writable() == desc->writable())) &&
    7467        5808 :       (!desc->has_get() ||
    7468      415744 :        (current->has_get() && current->get()->SameValue(*desc->get()))) &&
    7469        7197 :       (!desc->has_set() ||
    7470        7008 :        (current->has_set() && current->set()->SameValue(*desc->set())))) {
    7471             :     return Just(true);
    7472             :   }
    7473             :   // 5. If the [[Configurable]] field of current is false, then
    7474      156563 :   if (!current->configurable()) {
    7475             :     // 5a. Return false, if the [[Configurable]] field of Desc is true.
    7476        8016 :     if (desc->has_configurable() && desc->configurable()) {
    7477         543 :       RETURN_FAILURE(
    7478             :           isolate, should_throw,
    7479             :           NewTypeError(MessageTemplate::kRedefineDisallowed,
    7480             :                        it != nullptr ? it->GetName() : property_name));
    7481             :     }
    7482             :     // 5b. Return false, if the [[Enumerable]] field of Desc is present and the
    7483             :     // [[Enumerable]] fields of current and Desc are the Boolean negation of
    7484             :     // each other.
    7485        7352 :     if (desc->has_enumerable() && desc->enumerable() != current->enumerable()) {
    7486         284 :       RETURN_FAILURE(
    7487             :           isolate, should_throw,
    7488             :           NewTypeError(MessageTemplate::kRedefineDisallowed,
    7489             :                        it != nullptr ? it->GetName() : property_name));
    7490             :     }
    7491             :   }
    7492             : 
    7493             :   bool current_is_data_descriptor =
    7494             :       PropertyDescriptor::IsDataDescriptor(current);
    7495             :   // 6. If IsGenericDescriptor(Desc) is true, no further validation is required.
    7496      156264 :   if (desc_is_generic_descriptor) {
    7497             :     // Nothing to see here.
    7498             : 
    7499             :     // 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) have
    7500             :     // different results, then:
    7501      155345 :   } else if (current_is_data_descriptor != desc_is_data_descriptor) {
    7502             :     // 7a. Return false, if the [[Configurable]] field of current is false.
    7503      118103 :     if (!current->configurable()) {
    7504         435 :       RETURN_FAILURE(
    7505             :           isolate, should_throw,
    7506             :           NewTypeError(MessageTemplate::kRedefineDisallowed,
    7507             :                        it != nullptr ? it->GetName() : property_name));
    7508             :     }
    7509             :     // 7b. If IsDataDescriptor(current) is true, then:
    7510             :     if (current_is_data_descriptor) {
    7511             :       // 7b i. If O is not undefined, convert the property named P of object O
    7512             :       // from a data property to an accessor property. Preserve the existing
    7513             :       // values of the converted property's [[Configurable]] and [[Enumerable]]
    7514             :       // attributes and set the rest of the property's attributes to their
    7515             :       // default values.
    7516             :       // --> Folded into step 10.
    7517             :     } else {
    7518             :       // 7c i. If O is not undefined, convert the property named P of object O
    7519             :       // from an accessor property to a data property. Preserve the existing
    7520             :       // values of the converted property’s [[Configurable]] and [[Enumerable]]
    7521             :       // attributes and set the rest of the property’s attributes to their
    7522             :       // default values.
    7523             :       // --> Folded into step 10.
    7524             :     }
    7525             : 
    7526             :     // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both
    7527             :     // true, then:
    7528       37242 :   } else if (current_is_data_descriptor && desc_is_data_descriptor) {
    7529             :     // 8a. If the [[Configurable]] field of current is false, then:
    7530       26246 :     if (!current->configurable()) {
    7531             :       // 8a i. Return false, if the [[Writable]] field of current is false and
    7532             :       // the [[Writable]] field of Desc is true.
    7533        4340 :       if (!current->writable() && desc->has_writable() && desc->writable()) {
    7534         189 :         RETURN_FAILURE(
    7535             :             isolate, should_throw,
    7536             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    7537             :                          it != nullptr ? it->GetName() : property_name));
    7538             :       }
    7539             :       // 8a ii. If the [[Writable]] field of current is false, then:
    7540        3907 :       if (!current->writable()) {
    7541             :         // 8a ii 1. Return false, if the [[Value]] field of Desc is present and
    7542             :         // SameValue(Desc.[[Value]], current.[[Value]]) is false.
    7543         470 :         if (desc->has_value() && !desc->value()->SameValue(*current->value())) {
    7544         775 :           RETURN_FAILURE(
    7545             :               isolate, should_throw,
    7546             :               NewTypeError(MessageTemplate::kRedefineDisallowed,
    7547             :                            it != nullptr ? it->GetName() : property_name));
    7548             :         }
    7549             :       }
    7550             :     }
    7551             :   } else {
    7552             :     // 9. Else IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc)
    7553             :     // are both true,
    7554             :     DCHECK(PropertyDescriptor::IsAccessorDescriptor(current) &&
    7555             :            desc_is_accessor_descriptor);
    7556             :     // 9a. If the [[Configurable]] field of current is false, then:
    7557       10996 :     if (!current->configurable()) {
    7558             :       // 9a i. Return false, if the [[Set]] field of Desc is present and
    7559             :       // SameValue(Desc.[[Set]], current.[[Set]]) is false.
    7560         143 :       if (desc->has_set() && !desc->set()->SameValue(*current->set())) {
    7561         117 :         RETURN_FAILURE(
    7562             :             isolate, should_throw,
    7563             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    7564             :                          it != nullptr ? it->GetName() : property_name));
    7565             :       }
    7566             :       // 9a ii. Return false, if the [[Get]] field of Desc is present and
    7567             :       // SameValue(Desc.[[Get]], current.[[Get]]) is false.
    7568         106 :       if (desc->has_get() && !desc->get()->SameValue(*current->get())) {
    7569         170 :         RETURN_FAILURE(
    7570             :             isolate, should_throw,
    7571             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    7572             :                          it != nullptr ? it->GetName() : property_name));
    7573             :       }
    7574             :     }
    7575             :   }
    7576             : 
    7577             :   // 10. If O is not undefined, then:
    7578      155757 :   if (it != nullptr) {
    7579             :     // 10a. For each field of Desc that is present, set the corresponding
    7580             :     // attribute of the property named P of object O to the value of the field.
    7581             :     PropertyAttributes attrs = NONE;
    7582             : 
    7583      155496 :     if (desc->has_enumerable()) {
    7584             :       attrs = static_cast<PropertyAttributes>(
    7585      121269 :           attrs | (desc->enumerable() ? NONE : DONT_ENUM));
    7586             :     } else {
    7587             :       attrs = static_cast<PropertyAttributes>(
    7588       34227 :           attrs | (current->enumerable() ? NONE : DONT_ENUM));
    7589             :     }
    7590      155496 :     if (desc->has_configurable()) {
    7591             :       attrs = static_cast<PropertyAttributes>(
    7592      133388 :           attrs | (desc->configurable() ? NONE : DONT_DELETE));
    7593             :     } else {
    7594             :       attrs = static_cast<PropertyAttributes>(
    7595       22108 :           attrs | (current->configurable() ? NONE : DONT_DELETE));
    7596             :     }
    7597      284729 :     if (desc_is_data_descriptor ||
    7598      129233 :         (desc_is_generic_descriptor && current_is_data_descriptor)) {
    7599       27083 :       if (desc->has_writable()) {
    7600             :         attrs = static_cast<PropertyAttributes>(
    7601       24179 :             attrs | (desc->writable() ? NONE : READ_ONLY));
    7602             :       } else {
    7603             :         attrs = static_cast<PropertyAttributes>(
    7604        2904 :             attrs | (current->writable() ? NONE : READ_ONLY));
    7605             :       }
    7606             :       Handle<Object> value(
    7607             :           desc->has_value() ? desc->value()
    7608             :                             : current->has_value()
    7609             :                                   ? current->value()
    7610             :                                   : Handle<Object>::cast(
    7611       29914 :                                         isolate->factory()->undefined_value()));
    7612             :       return JSObject::DefineOwnPropertyIgnoreAttributes(it, value, attrs,
    7613       27083 :                                                          should_throw);
    7614             :     } else {
    7615             :       DCHECK(desc_is_accessor_descriptor ||
    7616             :              (desc_is_generic_descriptor &&
    7617             :               PropertyDescriptor::IsAccessorDescriptor(current)));
    7618             :       Handle<Object> getter(
    7619             :           desc->has_get()
    7620             :               ? desc->get()
    7621             :               : current->has_get()
    7622             :                     ? current->get()
    7623      135898 :                     : Handle<Object>::cast(isolate->factory()->null_value()));
    7624             :       Handle<Object> setter(
    7625             :           desc->has_set()
    7626             :               ? desc->set()
    7627             :               : current->has_set()
    7628             :                     ? current->set()
    7629      365801 :                     : Handle<Object>::cast(isolate->factory()->null_value()));
    7630             :       MaybeHandle<Object> result =
    7631      128413 :           JSObject::DefineAccessor(it, getter, setter, attrs);
    7632      128413 :       if (result.is_null()) return Nothing<bool>();
    7633             :     }
    7634             :   }
    7635             : 
    7636             :   // 11. Return true.
    7637             :   return Just(true);
    7638             : }
    7639             : 
    7640             : // static
    7641      111580 : Maybe<bool> JSReceiver::CreateDataProperty(Isolate* isolate,
    7642             :                                            Handle<JSReceiver> object,
    7643             :                                            Handle<Name> key,
    7644             :                                            Handle<Object> value,
    7645             :                                            ShouldThrow should_throw) {
    7646             :   LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, key,
    7647      111580 :                                                         LookupIterator::OWN);
    7648      111580 :   return CreateDataProperty(&it, value, should_throw);
    7649             : }
    7650             : 
    7651             : // static
    7652     2323470 : Maybe<bool> JSReceiver::CreateDataProperty(LookupIterator* it,
    7653             :                                            Handle<Object> value,
    7654             :                                            ShouldThrow should_throw) {
    7655             :   DCHECK(!it->check_prototype_chain());
    7656     2323470 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    7657             :   Isolate* isolate = receiver->GetIsolate();
    7658             : 
    7659     4646940 :   if (receiver->IsJSObject()) {
    7660     2322438 :     return JSObject::CreateDataProperty(it, value, should_throw);  // Shortcut.
    7661             :   }
    7662             : 
    7663             :   PropertyDescriptor new_desc;
    7664             :   new_desc.set_value(value);
    7665             :   new_desc.set_writable(true);
    7666             :   new_desc.set_enumerable(true);
    7667             :   new_desc.set_configurable(true);
    7668             : 
    7669             :   return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
    7670        2064 :                                        &new_desc, should_throw);
    7671             : }
    7672             : 
    7673     4649437 : Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
    7674             :                                          Handle<Object> value,
    7675             :                                          ShouldThrow should_throw) {
    7676             :   DCHECK(it->GetReceiver()->IsJSObject());
    7677     2324721 :   MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
    7678     2324716 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    7679             :   Isolate* isolate = receiver->GetIsolate();
    7680             : 
    7681     2324716 :   if (it->IsFound()) {
    7682         444 :     Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
    7683         481 :     MAYBE_RETURN(attributes, Nothing<bool>());
    7684         444 :     if ((attributes.FromJust() & DONT_DELETE) != 0) {
    7685         118 :       RETURN_FAILURE(
    7686             :           isolate, should_throw,
    7687             :           NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
    7688             :     }
    7689             :   } else {
    7690     2324272 :     if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) {
    7691         329 :       RETURN_FAILURE(
    7692             :           isolate, should_throw,
    7693             :           NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
    7694             :     }
    7695             :   }
    7696             : 
    7697     4649186 :   RETURN_ON_EXCEPTION_VALUE(it->isolate(),
    7698             :                             DefineOwnPropertyIgnoreAttributes(it, value, NONE),
    7699             :                             Nothing<bool>());
    7700             : 
    7701             :   return Just(true);
    7702             : }
    7703             : 
    7704             : // TODO(jkummerow): Consider unification with FastAsArrayLength() in
    7705             : // accessors.cc.
    7706       32998 : bool PropertyKeyToArrayLength(Handle<Object> value, uint32_t* length) {
    7707             :   DCHECK(value->IsNumber() || value->IsName());
    7708       65996 :   if (value->ToArrayLength(length)) return true;
    7709       88776 :   if (value->IsString()) return String::cast(*value)->AsArrayIndex(length);
    7710             :   return false;
    7711             : }
    7712             : 
    7713           0 : bool PropertyKeyToArrayIndex(Handle<Object> index_obj, uint32_t* output) {
    7714       32998 :   return PropertyKeyToArrayLength(index_obj, output) && *output != kMaxUInt32;
    7715             : }
    7716             : 
    7717             : 
    7718             : // ES6 9.4.2.1
    7719             : // static
    7720       33364 : Maybe<bool> JSArray::DefineOwnProperty(Isolate* isolate, Handle<JSArray> o,
    7721             :                                        Handle<Object> name,
    7722             :                                        PropertyDescriptor* desc,
    7723             :                                        ShouldThrow should_throw) {
    7724             :   // 1. Assert: IsPropertyKey(P) is true. ("P" is |name|.)
    7725             :   // 2. If P is "length", then:
    7726             :   // TODO(jkummerow): Check if we need slow string comparison.
    7727       33364 :   if (*name == ReadOnlyRoots(isolate).length_string()) {
    7728             :     // 2a. Return ArraySetLength(A, Desc).
    7729         366 :     return ArraySetLength(isolate, o, desc, should_throw);
    7730             :   }
    7731             :   // 3. Else if P is an array index, then:
    7732       32998 :   uint32_t index = 0;
    7733       32998 :   if (PropertyKeyToArrayIndex(name, &index)) {
    7734             :     // 3a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    7735             :     PropertyDescriptor old_len_desc;
    7736             :     Maybe<bool> success = GetOwnPropertyDescriptor(
    7737       28065 :         isolate, o, isolate->factory()->length_string(), &old_len_desc);
    7738             :     // 3b. (Assert)
    7739             :     DCHECK(success.FromJust());
    7740             :     USE(success);
    7741             :     // 3c. Let oldLen be oldLenDesc.[[Value]].
    7742       28065 :     uint32_t old_len = 0;
    7743       56130 :     CHECK(old_len_desc.value()->ToArrayLength(&old_len));
    7744             :     // 3d. Let index be ToUint32(P).
    7745             :     // (Already done above.)
    7746             :     // 3e. (Assert)
    7747             :     // 3f. If index >= oldLen and oldLenDesc.[[Writable]] is false,
    7748             :     //     return false.
    7749       34519 :     if (index >= old_len && old_len_desc.has_writable() &&
    7750             :         !old_len_desc.writable()) {
    7751           0 :       RETURN_FAILURE(isolate, should_throw,
    7752             :                      NewTypeError(MessageTemplate::kDefineDisallowed, name));
    7753             :     }
    7754             :     // 3g. Let succeeded be OrdinaryDefineOwnProperty(A, P, Desc).
    7755             :     Maybe<bool> succeeded =
    7756       28065 :         OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
    7757             :     // 3h. Assert: succeeded is not an abrupt completion.
    7758             :     //     In our case, if should_throw == kThrowOnError, it can be!
    7759             :     // 3i. If succeeded is false, return false.
    7760       56044 :     if (succeeded.IsNothing() || !succeeded.FromJust()) return succeeded;
    7761             :     // 3j. If index >= oldLen, then:
    7762       27970 :     if (index >= old_len) {
    7763             :       // 3j i. Set oldLenDesc.[[Value]] to index + 1.
    7764        3227 :       old_len_desc.set_value(isolate->factory()->NewNumberFromUint(index + 1));
    7765             :       // 3j ii. Let succeeded be
    7766             :       //        OrdinaryDefineOwnProperty(A, "length", oldLenDesc).
    7767             :       succeeded = OrdinaryDefineOwnProperty(isolate, o,
    7768             :                                             isolate->factory()->length_string(),
    7769        3227 :                                             &old_len_desc, should_throw);
    7770             :       // 3j iii. Assert: succeeded is true.
    7771             :       DCHECK(succeeded.FromJust());
    7772             :       USE(succeeded);
    7773             :     }
    7774             :     // 3k. Return true.
    7775             :     return Just(true);
    7776             :   }
    7777             : 
    7778             :   // 4. Return OrdinaryDefineOwnProperty(A, P, Desc).
    7779        4933 :   return OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
    7780             : }
    7781             : 
    7782             : 
    7783             : // Part of ES6 9.4.2.4 ArraySetLength.
    7784             : // static
    7785      485129 : bool JSArray::AnythingToArrayLength(Isolate* isolate,
    7786             :                                     Handle<Object> length_object,
    7787             :                                     uint32_t* output) {
    7788             :   // Fast path: check numbers and strings that can be converted directly
    7789             :   // and unobservably.
    7790      970258 :   if (length_object->ToArrayLength(output)) return true;
    7791     1310598 :   if (length_object->IsString() &&
    7792      436896 :       Handle<String>::cast(length_object)->AsArrayIndex(output)) {
    7793             :     return true;
    7794             :   }
    7795             :   // Slow path: follow steps in ES6 9.4.2.4 "ArraySetLength".
    7796             :   // 3. Let newLen be ToUint32(Desc.[[Value]]).
    7797             :   Handle<Object> uint32_v;
    7798      873702 :   if (!Object::ToUint32(isolate, length_object).ToHandle(&uint32_v)) {
    7799             :     // 4. ReturnIfAbrupt(newLen).
    7800             :     return false;
    7801             :   }
    7802             :   // 5. Let numberLen be ToNumber(Desc.[[Value]]).
    7803             :   Handle<Object> number_v;
    7804      873684 :   if (!Object::ToNumber(isolate, length_object).ToHandle(&number_v)) {
    7805             :     // 6. ReturnIfAbrupt(newLen).
    7806             :     return false;
    7807             :   }
    7808             :   // 7. If newLen != numberLen, throw a RangeError exception.
    7809      873684 :   if (uint32_v->Number() != number_v->Number()) {
    7810             :     Handle<Object> exception =
    7811         153 :         isolate->factory()->NewRangeError(MessageTemplate::kInvalidArrayLength);
    7812         153 :     isolate->Throw(*exception);
    7813             :     return false;
    7814             :   }
    7815      873378 :   CHECK(uint32_v->ToArrayLength(output));
    7816             :   return true;
    7817             : }
    7818             : 
    7819             : 
    7820             : // ES6 9.4.2.4
    7821             : // static
    7822         366 : Maybe<bool> JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a,
    7823             :                                     PropertyDescriptor* desc,
    7824             :                                     ShouldThrow should_throw) {
    7825             :   // 1. If the [[Value]] field of Desc is absent, then
    7826         366 :   if (!desc->has_value()) {
    7827             :     // 1a. Return OrdinaryDefineOwnProperty(A, "length", Desc).
    7828             :     return OrdinaryDefineOwnProperty(
    7829         285 :         isolate, a, isolate->factory()->length_string(), desc, should_throw);
    7830             :   }
    7831             :   // 2. Let newLenDesc be a copy of Desc.
    7832             :   // (Actual copying is not necessary.)
    7833             :   PropertyDescriptor* new_len_desc = desc;
    7834             :   // 3. - 7. Convert Desc.[[Value]] to newLen.
    7835          81 :   uint32_t new_len = 0;
    7836          81 :   if (!AnythingToArrayLength(isolate, desc->value(), &new_len)) {
    7837             :     DCHECK(isolate->has_pending_exception());
    7838             :     return Nothing<bool>();
    7839             :   }
    7840             :   // 8. Set newLenDesc.[[Value]] to newLen.
    7841             :   // (Done below, if needed.)
    7842             :   // 9. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    7843             :   PropertyDescriptor old_len_desc;
    7844             :   Maybe<bool> success = GetOwnPropertyDescriptor(
    7845          72 :       isolate, a, isolate->factory()->length_string(), &old_len_desc);
    7846             :   // 10. (Assert)
    7847             :   DCHECK(success.FromJust());
    7848             :   USE(success);
    7849             :   // 11. Let oldLen be oldLenDesc.[[Value]].
    7850          72 :   uint32_t old_len = 0;
    7851         144 :   CHECK(old_len_desc.value()->ToArrayLength(&old_len));
    7852             :   // 12. If newLen >= oldLen, then
    7853          72 :   if (new_len >= old_len) {
    7854             :     // 8. Set newLenDesc.[[Value]] to newLen.
    7855             :     // 12a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc).
    7856          63 :     new_len_desc->set_value(isolate->factory()->NewNumberFromUint(new_len));
    7857             :     return OrdinaryDefineOwnProperty(isolate, a,
    7858             :                                      isolate->factory()->length_string(),
    7859          63 :                                      new_len_desc, should_throw);
    7860             :   }
    7861             :   // 13. If oldLenDesc.[[Writable]] is false, return false.
    7862           9 :   if (!old_len_desc.writable()) {
    7863           0 :     RETURN_FAILURE(isolate, should_throw,
    7864             :                    NewTypeError(MessageTemplate::kRedefineDisallowed,
    7865             :                                 isolate->factory()->length_string()));
    7866             :   }
    7867             :   // 14. If newLenDesc.[[Writable]] is absent or has the value true,
    7868             :   // let newWritable be true.
    7869             :   bool new_writable = false;
    7870           9 :   if (!new_len_desc->has_writable() || new_len_desc->writable()) {
    7871             :     new_writable = true;
    7872             :   } else {
    7873             :     // 15. Else,
    7874             :     // 15a. Need to defer setting the [[Writable]] attribute to false in case
    7875             :     //      any elements cannot be deleted.
    7876             :     // 15b. Let newWritable be false. (It's initialized as "false" anyway.)
    7877             :     // 15c. Set newLenDesc.[[Writable]] to true.
    7878             :     // (Not needed.)
    7879             :   }
    7880             :   // Most of steps 16 through 19 is implemented by JSArray::SetLength.
    7881           9 :   JSArray::SetLength(a, new_len);
    7882             :   // Steps 19d-ii, 20.
    7883           9 :   if (!new_writable) {
    7884             :     PropertyDescriptor readonly;
    7885             :     readonly.set_writable(false);
    7886             :     Maybe<bool> success = OrdinaryDefineOwnProperty(
    7887             :         isolate, a, isolate->factory()->length_string(), &readonly,
    7888           0 :         should_throw);
    7889             :     DCHECK(success.FromJust());
    7890             :     USE(success);
    7891             :   }
    7892           9 :   uint32_t actual_new_len = 0;
    7893          18 :   CHECK(a->length()->ToArrayLength(&actual_new_len));
    7894             :   // Steps 19d-v, 21. Return false if there were non-deletable elements.
    7895           9 :   bool result = actual_new_len == new_len;
    7896           9 :   if (!result) {
    7897           9 :     RETURN_FAILURE(
    7898             :         isolate, should_throw,
    7899             :         NewTypeError(MessageTemplate::kStrictDeleteProperty,
    7900             :                      isolate->factory()->NewNumberFromUint(actual_new_len - 1),
    7901             :                      a));
    7902             :   }
    7903             :   return Just(result);
    7904             : }
    7905             : 
    7906             : 
    7907             : // ES6 9.5.6
    7908             : // static
    7909       41059 : Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy,
    7910             :                                        Handle<Object> key,
    7911             :                                        PropertyDescriptor* desc,
    7912             :                                        ShouldThrow should_throw) {
    7913       41059 :   STACK_CHECK(isolate, Nothing<bool>());
    7914       82388 :   if (key->IsSymbol() && Handle<Symbol>::cast(key)->IsPrivate()) {
    7915             :     DCHECK(!Handle<Symbol>::cast(key)->IsPrivateName());
    7916             :     return JSProxy::SetPrivateSymbol(isolate, proxy, Handle<Symbol>::cast(key),
    7917          18 :                                      desc, should_throw);
    7918             :   }
    7919             :   Handle<String> trap_name = isolate->factory()->defineProperty_string();
    7920             :   // 1. Assert: IsPropertyKey(P) is true.
    7921             :   DCHECK(key->IsName() || key->IsNumber());
    7922             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    7923       82064 :   Handle<Object> handler(proxy->handler(), isolate);
    7924             :   // 3. If handler is null, throw a TypeError exception.
    7925             :   // 4. Assert: Type(handler) is Object.
    7926       82064 :   if (proxy->IsRevoked()) {
    7927             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7928          18 :         MessageTemplate::kProxyRevoked, trap_name));
    7929             :     return Nothing<bool>();
    7930             :   }
    7931             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    7932       82046 :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    7933             :   // 6. Let trap be ? GetMethod(handler, "defineProperty").
    7934             :   Handle<Object> trap;
    7935       82046 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7936             :       isolate, trap,
    7937             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    7938             :       Nothing<bool>());
    7939             :   // 7. If trap is undefined, then:
    7940       81866 :   if (trap->IsUndefined(isolate)) {
    7941             :     // 7a. Return target.[[DefineOwnProperty]](P, Desc).
    7942             :     return JSReceiver::DefineOwnProperty(isolate, target, key, desc,
    7943       31983 :                                          should_throw);
    7944             :   }
    7945             :   // 8. Let descObj be FromPropertyDescriptor(Desc).
    7946        8950 :   Handle<Object> desc_obj = desc->ToObject(isolate);
    7947             :   // 9. Let booleanTrapResult be
    7948             :   //    ToBoolean(? Call(trap, handler, «target, P, descObj»)).
    7949             :   Handle<Name> property_name =
    7950       17900 :       key->IsName()
    7951             :           ? Handle<Name>::cast(key)
    7952        8950 :           : Handle<Name>::cast(isolate->factory()->NumberToString(key));
    7953             :   // Do not leak private property names.
    7954             :   DCHECK(!property_name->IsPrivate());
    7955             :   Handle<Object> trap_result_obj;
    7956        8950 :   Handle<Object> args[] = {target, property_name, desc_obj};
    7957       17900 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7958             :       isolate, trap_result_obj,
    7959             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    7960             :       Nothing<bool>());
    7961             :   // 10. If booleanTrapResult is false, return false.
    7962        1323 :   if (!trap_result_obj->BooleanValue(isolate)) {
    7963          99 :     RETURN_FAILURE(isolate, should_throw,
    7964             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    7965             :                                 trap_name, property_name));
    7966             :   }
    7967             :   // 11. Let targetDesc be ? target.[[GetOwnProperty]](P).
    7968             :   PropertyDescriptor target_desc;
    7969             :   Maybe<bool> target_found =
    7970        1242 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, key, &target_desc);
    7971        1242 :   MAYBE_RETURN(target_found, Nothing<bool>());
    7972             :   // 12. Let extensibleTarget be ? IsExtensible(target).
    7973        1242 :   Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target);
    7974        1242 :   MAYBE_RETURN(maybe_extensible, Nothing<bool>());
    7975             :   bool extensible_target = maybe_extensible.FromJust();
    7976             :   // 13. If Desc has a [[Configurable]] field and if Desc.[[Configurable]]
    7977             :   //     is false, then:
    7978             :   // 13a. Let settingConfigFalse be true.
    7979             :   // 14. Else let settingConfigFalse be false.
    7980        1935 :   bool setting_config_false = desc->has_configurable() && !desc->configurable();
    7981             :   // 15. If targetDesc is undefined, then
    7982        1242 :   if (!target_found.FromJust()) {
    7983             :     // 15a. If extensibleTarget is false, throw a TypeError exception.
    7984         621 :     if (!extensible_target) {
    7985             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7986          18 :           MessageTemplate::kProxyDefinePropertyNonExtensible, property_name));
    7987             :       return Nothing<bool>();
    7988             :     }
    7989             :     // 15b. If settingConfigFalse is true, throw a TypeError exception.
    7990         612 :     if (setting_config_false) {
    7991             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7992          18 :           MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
    7993             :       return Nothing<bool>();
    7994             :     }
    7995             :   } else {
    7996             :     // 16. Else targetDesc is not undefined,
    7997             :     // 16a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc,
    7998             :     //      targetDesc) is false, throw a TypeError exception.
    7999             :     Maybe<bool> valid =
    8000             :         IsCompatiblePropertyDescriptor(isolate, extensible_target, desc,
    8001             :                                        &target_desc, property_name, kDontThrow);
    8002         621 :     MAYBE_RETURN(valid, Nothing<bool>());
    8003         621 :     if (!valid.FromJust()) {
    8004             :       isolate->Throw(*isolate->factory()->NewTypeError(
    8005          18 :           MessageTemplate::kProxyDefinePropertyIncompatible, property_name));
    8006             :       return Nothing<bool>();
    8007             :     }
    8008             :     // 16b. If settingConfigFalse is true and targetDesc.[[Configurable]] is
    8009             :     //      true, throw a TypeError exception.
    8010         702 :     if (setting_config_false && target_desc.configurable()) {
    8011             :       isolate->Throw(*isolate->factory()->NewTypeError(
    8012          18 :           MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
    8013             :       return Nothing<bool>();
    8014             :     }
    8015             :   }
    8016             :   // 17. Return true.
    8017             :   return Just(true);
    8018             : }
    8019             : 
    8020             : // static
    8021          36 : Maybe<bool> JSProxy::SetPrivateSymbol(Isolate* isolate, Handle<JSProxy> proxy,
    8022             :                                       Handle<Symbol> private_name,
    8023             :                                       PropertyDescriptor* desc,
    8024             :                                       ShouldThrow should_throw) {
    8025             :   DCHECK(!private_name->IsPrivateName());
    8026             :   // Despite the generic name, this can only add private data properties.
    8027          54 :   if (!PropertyDescriptor::IsDataDescriptor(desc) ||
    8028          18 :       desc->ToAttributes() != DONT_ENUM) {
    8029          36 :     RETURN_FAILURE(isolate, should_throw,
    8030             :                    NewTypeError(MessageTemplate::kProxyPrivate));
    8031             :   }
    8032             :   DCHECK(proxy->map()->is_dictionary_map());
    8033             :   Handle<Object> value =
    8034             :       desc->has_value()
    8035             :           ? desc->value()
    8036          18 :           : Handle<Object>::cast(isolate->factory()->undefined_value());
    8037             : 
    8038          18 :   LookupIterator it(proxy, private_name, proxy);
    8039             : 
    8040          18 :   if (it.IsFound()) {
    8041             :     DCHECK_EQ(LookupIterator::DATA, it.state());
    8042             :     DCHECK_EQ(DONT_ENUM, it.property_attributes());
    8043           6 :     it.WriteDataValue(value, false);
    8044             :     return Just(true);
    8045             :   }
    8046             : 
    8047          24 :   Handle<NameDictionary> dict(proxy->property_dictionary(), isolate);
    8048             :   PropertyDetails details(kData, DONT_ENUM, PropertyCellType::kNoCell);
    8049             :   Handle<NameDictionary> result =
    8050          12 :       NameDictionary::Add(isolate, dict, private_name, value, details);
    8051          24 :   if (!dict.is_identical_to(result)) proxy->SetProperties(*result);
    8052             :   return Just(true);
    8053             : }
    8054             : 
    8055             : // static
    8056     3167302 : Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate,
    8057             :                                                  Handle<JSReceiver> object,
    8058             :                                                  Handle<Object> key,
    8059             :                                                  PropertyDescriptor* desc) {
    8060     3167302 :   bool success = false;
    8061             :   DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey...
    8062             :   LookupIterator it = LookupIterator::PropertyOrElement(
    8063     3167302 :       isolate, object, key, &success, LookupIterator::OWN);
    8064             :   DCHECK(success);  // ...so creating a LookupIterator can't fail.
    8065     3167302 :   return GetOwnPropertyDescriptor(&it, desc);
    8066             : }
    8067             : 
    8068             : namespace {
    8069             : 
    8070     7417527 : Maybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
    8071             :                                                  PropertyDescriptor* desc) {
    8072     3708480 :   if (it->state() == LookupIterator::ACCESS_CHECK) {
    8073     2294572 :     if (it->HasAccess()) {
    8074     2294522 :       it->Next();
    8075          55 :     } else if (!JSObject::AllCanRead(it) ||
    8076             :                it->state() != LookupIterator::INTERCEPTOR) {
    8077          50 :       it->Restart();
    8078             :       return Just(false);
    8079             :     }
    8080             :   }
    8081             : 
    8082     3708430 :   if (it->state() != LookupIterator::INTERCEPTOR) return Just(false);
    8083             : 
    8084             :   Isolate* isolate = it->isolate();
    8085         555 :   Handle<InterceptorInfo> interceptor = it->GetInterceptor();
    8086        1110 :   if (interceptor->descriptor()->IsUndefined(isolate)) return Just(false);
    8087             : 
    8088             :   Handle<Object> result;
    8089             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    8090             : 
    8091             :   Handle<Object> receiver = it->GetReceiver();
    8092          90 :   if (!receiver->IsJSReceiver()) {
    8093           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    8094             :                                      Object::ConvertReceiver(isolate, receiver),
    8095             :                                      Nothing<bool>());
    8096             :   }
    8097             : 
    8098             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    8099          45 :                                  *holder, kDontThrow);
    8100          45 :   if (it->IsElement()) {
    8101          12 :     result = args.CallIndexedDescriptor(interceptor, it->index());
    8102             :   } else {
    8103          33 :     result = args.CallNamedDescriptor(interceptor, it->name());
    8104             :   }
    8105          45 :   if (!result.is_null()) {
    8106             :     // Request successfully intercepted, try to set the property
    8107             :     // descriptor.
    8108             :     Utils::ApiCheck(
    8109          12 :         PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
    8110             :         it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
    8111             :                         : "v8::NamedPropertyDescriptorCallback",
    8112          12 :         "Invalid property descriptor.");
    8113             : 
    8114             :     return Just(true);
    8115             :   }
    8116             : 
    8117          33 :   it->Next();
    8118             :   return Just(false);
    8119             : }
    8120             : }  // namespace
    8121             : 
    8122             : // ES6 9.1.5.1
    8123             : // Returns true on success, false if the property didn't exist, nothing if
    8124             : // an exception was thrown.
    8125             : // static
    8126     7031711 : Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it,
    8127             :                                                  PropertyDescriptor* desc) {
    8128             :   Isolate* isolate = it->isolate();
    8129             :   // "Virtual" dispatch.
    8130    10381268 :   if (it->IsFound() && it->GetHolder<JSReceiver>()->IsJSProxy()) {
    8131             :     return JSProxy::GetOwnPropertyDescriptor(isolate, it->GetHolder<JSProxy>(),
    8132       50596 :                                              it->GetName(), desc);
    8133             :   }
    8134             : 
    8135     3708480 :   Maybe<bool> intercepted = GetPropertyDescriptorWithInterceptor(it, desc);
    8136     3708480 :   MAYBE_RETURN(intercepted, Nothing<bool>());
    8137     3708480 :   if (intercepted.FromJust()) {
    8138             :     return Just(true);
    8139             :   }
    8140             : 
    8141             :   // Request was not intercepted, continue as normal.
    8142             :   // 1. (Assert)
    8143             :   // 2. If O does not have an own property with key P, return undefined.
    8144     3708468 :   Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it);
    8145     3708470 :   MAYBE_RETURN(maybe, Nothing<bool>());
    8146             :   PropertyAttributes attrs = maybe.FromJust();
    8147     3708280 :   if (attrs == ABSENT) return Just(false);
    8148             :   DCHECK(!isolate->has_pending_exception());
    8149             : 
    8150             :   // 3. Let D be a newly created Property Descriptor with no fields.
    8151             :   DCHECK(desc->is_empty());
    8152             :   // 4. Let X be O's own property whose key is P.
    8153             :   // 5. If X is a data property, then
    8154     3470320 :   bool is_accessor_pair = it->state() == LookupIterator::ACCESSOR &&
    8155     3642707 :                           it->GetAccessors()->IsAccessorPair();
    8156     3297933 :   if (!is_accessor_pair) {
    8157             :     // 5a. Set D.[[Value]] to the value of X's [[Value]] attribute.
    8158             :     Handle<Object> value;
    8159     6505266 :     if (!Object::GetProperty(it).ToHandle(&value)) {
    8160             :       DCHECK(isolate->has_pending_exception());
    8161             :       return Nothing<bool>();
    8162             :     }
    8163             :     desc->set_value(value);
    8164             :     // 5b. Set D.[[Writable]] to the value of X's [[Writable]] attribute
    8165     3252533 :     desc->set_writable((attrs & READ_ONLY) == 0);
    8166             :   } else {
    8167             :     // 6. Else X is an accessor property, so
    8168             :     Handle<AccessorPair> accessors =
    8169       45300 :         Handle<AccessorPair>::cast(it->GetAccessors());
    8170             :     // 6a. Set D.[[Get]] to the value of X's [[Get]] attribute.
    8171             :     desc->set_get(
    8172       45300 :         AccessorPair::GetComponent(isolate, accessors, ACCESSOR_GETTER));
    8173             :     // 6b. Set D.[[Set]] to the value of X's [[Set]] attribute.
    8174             :     desc->set_set(
    8175       45300 :         AccessorPair::GetComponent(isolate, accessors, ACCESSOR_SETTER));
    8176             :   }
    8177             : 
    8178             :   // 7. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
    8179     3297833 :   desc->set_enumerable((attrs & DONT_ENUM) == 0);
    8180             :   // 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
    8181     3297833 :   desc->set_configurable((attrs & DONT_DELETE) == 0);
    8182             :   // 9. Return D.
    8183             :   DCHECK(PropertyDescriptor::IsAccessorDescriptor(desc) !=
    8184             :          PropertyDescriptor::IsDataDescriptor(desc));
    8185             :   return Just(true);
    8186             : }
    8187             : 
    8188             : 
    8189             : // ES6 9.5.5
    8190             : // static
    8191       29428 : Maybe<bool> JSProxy::GetOwnPropertyDescriptor(Isolate* isolate,
    8192             :                                               Handle<JSProxy> proxy,
    8193             :                                               Handle<Name> name,
    8194             :                                               PropertyDescriptor* desc) {
    8195             :   DCHECK(!name->IsPrivate());
    8196       29428 :   STACK_CHECK(isolate, Nothing<bool>());
    8197             : 
    8198             :   Handle<String> trap_name =
    8199             :       isolate->factory()->getOwnPropertyDescriptor_string();
    8200             :   // 1. (Assert)
    8201             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    8202       58834 :   Handle<Object> handler(proxy->handler(), isolate);
    8203             :   // 3. If handler is null, throw a TypeError exception.
    8204             :   // 4. Assert: Type(handler) is Object.
    8205       58834 :   if (proxy->IsRevoked()) {
    8206             :     isolate->Throw(*isolate->factory()->NewTypeError(
    8207          36 :         MessageTemplate::kProxyRevoked, trap_name));
    8208             :     return Nothing<bool>();
    8209             :   }
    8210             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    8211       58798 :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    8212             :   // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor").
    8213             :   Handle<Object> trap;
    8214       58798 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8215             :       isolate, trap,
    8216             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    8217             :       Nothing<bool>());
    8218             :   // 7. If trap is undefined, then
    8219       58690 :   if (trap->IsUndefined(isolate)) {
    8220             :     // 7a. Return target.[[GetOwnProperty]](P).
    8221       17852 :     return JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, desc);
    8222             :   }
    8223             :   // 8. Let trapResultObj be ? Call(trap, handler, «target, P»).
    8224             :   Handle<Object> trap_result_obj;
    8225             :   Handle<Object> args[] = {target, name};
    8226       22986 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8227             :       isolate, trap_result_obj,
    8228             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    8229             :       Nothing<bool>());
    8230             :   // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a
    8231             :   //    TypeError exception.
    8232       16011 :   if (!trap_result_obj->IsJSReceiver() &&
    8233        5877 :       !trap_result_obj->IsUndefined(isolate)) {
    8234             :     isolate->Throw(*isolate->factory()->NewTypeError(
    8235          36 :         MessageTemplate::kProxyGetOwnPropertyDescriptorInvalid, name));
    8236             :     return Nothing<bool>();
    8237             :   }
    8238             :   // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
    8239             :   PropertyDescriptor target_desc;
    8240             :   Maybe<bool> found =
    8241        5049 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    8242        5049 :   MAYBE_RETURN(found, Nothing<bool>());
    8243             :   // 11. If trapResultObj is undefined, then
    8244       10098 :   if (trap_result_obj->IsUndefined(isolate)) {
    8245             :     // 11a. If targetDesc is undefined, return undefined.
    8246         792 :     if (!found.FromJust()) return Just(false);
    8247             :     // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError
    8248             :     //      exception.
    8249          45 :     if (!target_desc.configurable()) {
    8250             :       isolate->Throw(*isolate->factory()->NewTypeError(
    8251          54 :           MessageTemplate::kProxyGetOwnPropertyDescriptorUndefined, name));
    8252             :       return Nothing<bool>();
    8253             :     }
    8254             :     // 11c. Let extensibleTarget be ? IsExtensible(target).
    8255          18 :     Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    8256          18 :     MAYBE_RETURN(extensible_target, Nothing<bool>());
    8257             :     // 11d. (Assert)
    8258             :     // 11e. If extensibleTarget is false, throw a TypeError exception.
    8259          18 :     if (!extensible_target.FromJust()) {
    8260             :       isolate->Throw(*isolate->factory()->NewTypeError(
    8261           0 :           MessageTemplate::kProxyGetOwnPropertyDescriptorNonExtensible, name));
    8262             :       return Nothing<bool>();
    8263             :     }
    8264             :     // 11f. Return undefined.
    8265             :     return Just(false);
    8266             :   }
    8267             :   // 12. Let extensibleTarget be ? IsExtensible(target).
    8268        4257 :   Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    8269        4257 :   MAYBE_RETURN(extensible_target, Nothing<bool>());
    8270             :   // 13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj).
    8271        4257 :   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj,
    8272        4257 :                                                 desc)) {
    8273             :     DCHECK(isolate->has_pending_exception());
    8274             :     return Nothing<bool>();
    8275             :   }
    8276             :   // 14. Call CompletePropertyDescriptor(resultDesc).
    8277        4185 :   PropertyDescriptor::CompletePropertyDescriptor(isolate, desc);
    8278             :   // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget,
    8279             :   //     resultDesc, targetDesc).
    8280             :   Maybe<bool> valid =
    8281             :       IsCompatiblePropertyDescriptor(isolate, extensible_target.FromJust(),
    8282             :                                      desc, &target_desc, name, kDontThrow);
    8283        4185 :   MAYBE_RETURN(valid, Nothing<bool>());
    8284             :   // 16. If valid is false, throw a TypeError exception.
    8285        4185 :   if (!valid.FromJust()) {
    8286             :     isolate->Throw(*isolate->factory()->NewTypeError(
    8287          36 :         MessageTemplate::kProxyGetOwnPropertyDescriptorIncompatible, name));
    8288             :     return Nothing<bool>();
    8289             :   }
    8290             :   // 17. If resultDesc.[[Configurable]] is false, then
    8291        4167 :   if (!desc->configurable()) {
    8292             :     // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true:
    8293         639 :     if (target_desc.is_empty() || target_desc.configurable()) {
    8294             :       // 17a i. Throw a TypeError exception.
    8295             :       isolate->Throw(*isolate->factory()->NewTypeError(
    8296             :           MessageTemplate::kProxyGetOwnPropertyDescriptorNonConfigurable,
    8297          36 :           name));
    8298             :       return Nothing<bool>();
    8299             :     }
    8300             :   }
    8301             :   // 18. Return resultDesc.
    8302             :   return Just(true);
    8303             : }
    8304             : 
    8305             : 
    8306      252893 : Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver,
    8307             :                                           IntegrityLevel level,
    8308             :                                           ShouldThrow should_throw) {
    8309             :   DCHECK(level == SEALED || level == FROZEN);
    8310             : 
    8311      505803 :   if (receiver->IsJSObject()) {
    8312      252492 :     Handle<JSObject> object = Handle<JSObject>::cast(receiver);
    8313             : 
    8314     1009923 :     if (!object->HasSloppyArgumentsElements() &&
    8315      504939 :         !object->IsJSModuleNamespace()) {  // Fast path.
    8316             :       // Prevent memory leaks by not adding unnecessary transitions.
    8317      252376 :       Maybe<bool> test = JSObject::TestIntegrityLevel(object, level);
    8318      252372 :       MAYBE_RETURN(test, Nothing<bool>());
    8319      252372 :       if (test.FromJust()) return test;
    8320             : 
    8321      247009 :       if (level == SEALED) {
    8322             :         return JSObject::PreventExtensionsWithTransition<SEALED>(object,
    8323         506 :                                                                  should_throw);
    8324             :       } else {
    8325             :         return JSObject::PreventExtensionsWithTransition<FROZEN>(object,
    8326      246503 :                                                                  should_throw);
    8327             :       }
    8328             :     }
    8329             :   }
    8330             : 
    8331             :   Isolate* isolate = receiver->GetIsolate();
    8332             : 
    8333         532 :   MAYBE_RETURN(JSReceiver::PreventExtensions(receiver, should_throw),
    8334             :                Nothing<bool>());
    8335             : 
    8336             :   Handle<FixedArray> keys;
    8337         532 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8338             :       isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
    8339             : 
    8340             :   PropertyDescriptor no_conf;
    8341             :   no_conf.set_configurable(false);
    8342             : 
    8343             :   PropertyDescriptor no_conf_no_write;
    8344             :   no_conf_no_write.set_configurable(false);
    8345             :   no_conf_no_write.set_writable(false);
    8346             : 
    8347         532 :   if (level == SEALED) {
    8348         452 :     for (int i = 0; i < keys->length(); ++i) {
    8349             :       Handle<Object> key(keys->get(i), isolate);
    8350         176 :       MAYBE_RETURN(
    8351             :           DefineOwnProperty(isolate, receiver, key, &no_conf, kThrowOnError),
    8352             :           Nothing<bool>());
    8353             :     }
    8354             :     return Just(true);
    8355             :   }
    8356             : 
    8357        2916 :   for (int i = 0; i < keys->length(); ++i) {
    8358             :     Handle<Object> key(keys->get(i), isolate);
    8359             :     PropertyDescriptor current_desc;
    8360             :     Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
    8361        1296 :         isolate, receiver, key, &current_desc);
    8362        1332 :     MAYBE_RETURN(owned, Nothing<bool>());
    8363        1287 :     if (owned.FromJust()) {
    8364             :       PropertyDescriptor desc =
    8365             :           PropertyDescriptor::IsAccessorDescriptor(&current_desc)
    8366             :               ? no_conf
    8367        1287 :               : no_conf_no_write;
    8368        1287 :       MAYBE_RETURN(
    8369             :           DefineOwnProperty(isolate, receiver, key, &desc, kThrowOnError),
    8370             :           Nothing<bool>());
    8371             :     }
    8372             :   }
    8373             :   return Just(true);
    8374             : }
    8375             : 
    8376             : namespace {
    8377             : 
    8378             : template <typename Dictionary>
    8379        6355 : bool TestDictionaryPropertiesIntegrityLevel(Dictionary dict,
    8380             :                                             ReadOnlyRoots roots,
    8381             :                                             PropertyAttributes level) {
    8382             :   DCHECK(level == SEALED || level == FROZEN);
    8383             : 
    8384        6355 :   uint32_t capacity = dict->Capacity();
    8385       18227 :   for (uint32_t i = 0; i < capacity; i++) {
    8386       12009 :     Object key;
    8387       21037 :     if (!dict->ToKey(roots, i, &key)) continue;
    8388        2999 :     if (key->FilterKey(ALL_PROPERTIES)) continue;
    8389        2981 :     PropertyDetails details = dict->DetailsAt(i);
    8390        3118 :     if (details.IsConfigurable()) return false;
    8391        7269 :     if (level == FROZEN && details.kind() == kData && !details.IsReadOnly()) {
    8392             :       return false;
    8393             :     }
    8394             :   }
    8395             :   return true;
    8396             : }
    8397             : 
    8398        6078 : bool TestFastPropertiesIntegrityLevel(Map map, PropertyAttributes level) {
    8399             :   DCHECK(level == SEALED || level == FROZEN);
    8400             :   DCHECK(!map->IsCustomElementsReceiverMap());
    8401             :   DCHECK(!map->is_dictionary_map());
    8402             : 
    8403        6078 :   DescriptorArray descriptors = map->instance_descriptors();
    8404             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    8405        7932 :   for (int i = 0; i < number_of_own_descriptors; i++) {
    8406        1997 :     if (descriptors->GetKey(i)->IsPrivate()) continue;
    8407        1979 :     PropertyDetails details = descriptors->GetDetails(i);
    8408        1979 :     if (details.IsConfigurable()) return false;
    8409        4361 :     if (level == FROZEN && details.kind() == kData && !details.IsReadOnly()) {
    8410             :       return false;
    8411             :     }
    8412             :   }
    8413             :   return true;
    8414             : }
    8415             : 
    8416        6169 : bool TestPropertiesIntegrityLevel(JSObject object, PropertyAttributes level) {
    8417             :   DCHECK(!object->map()->IsCustomElementsReceiverMap());
    8418             : 
    8419        6169 :   if (object->HasFastProperties()) {
    8420        6078 :     return TestFastPropertiesIntegrityLevel(object->map(), level);
    8421             :   }
    8422             : 
    8423             :   return TestDictionaryPropertiesIntegrityLevel(
    8424          91 :       object->property_dictionary(), object->GetReadOnlyRoots(), level);
    8425             : }
    8426             : 
    8427        6269 : bool TestElementsIntegrityLevel(JSObject object, PropertyAttributes level) {
    8428             :   DCHECK(!object->HasSloppyArgumentsElements());
    8429             : 
    8430        6269 :   ElementsKind kind = object->GetElementsKind();
    8431             : 
    8432        6269 :   if (IsDictionaryElementsKind(kind)) {
    8433             :     return TestDictionaryPropertiesIntegrityLevel(
    8434             :         NumberDictionary::cast(object->elements()), object->GetReadOnlyRoots(),
    8435       12528 :         level);
    8436             :   }
    8437           5 :   if (IsFixedTypedArrayElementsKind(kind)) {
    8438           5 :     return TestPropertiesIntegrityLevel(object, level);
    8439             :   }
    8440             : 
    8441             :   ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
    8442             :   // Only DICTIONARY_ELEMENTS and SLOW_SLOPPY_ARGUMENTS_ELEMENTS have
    8443             :   // PropertyAttributes so just test if empty
    8444           0 :   return accessor->NumberOfElements(object) == 0;
    8445             : }
    8446             : 
    8447      253250 : bool FastTestIntegrityLevel(JSObject object, PropertyAttributes level) {
    8448             :   DCHECK(!object->map()->IsCustomElementsReceiverMap());
    8449             : 
    8450        6269 :   return !object->map()->is_extensible() &&
    8451      259414 :          TestElementsIntegrityLevel(object, level) &&
    8452      259414 :          TestPropertiesIntegrityLevel(object, level);
    8453             : }
    8454             : 
    8455         273 : Maybe<bool> GenericTestIntegrityLevel(Handle<JSReceiver> receiver,
    8456             :                                       PropertyAttributes level) {
    8457             :   DCHECK(level == SEALED || level == FROZEN);
    8458             : 
    8459         273 :   Maybe<bool> extensible = JSReceiver::IsExtensible(receiver);
    8460         273 :   MAYBE_RETURN(extensible, Nothing<bool>());
    8461         273 :   if (extensible.FromJust()) return Just(false);
    8462             : 
    8463             :   Isolate* isolate = receiver->GetIsolate();
    8464             : 
    8465             :   Handle<FixedArray> keys;
    8466         163 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8467             :       isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
    8468             : 
    8469        4781 :   for (int i = 0; i < keys->length(); ++i) {
    8470             :     Handle<Object> key(keys->get(i), isolate);
    8471             :     PropertyDescriptor current_desc;
    8472             :     Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
    8473        2390 :         isolate, receiver, key, &current_desc);
    8474        2471 :     MAYBE_RETURN(owned, Nothing<bool>());
    8475        2363 :     if (owned.FromJust()) {
    8476        2363 :       if (current_desc.configurable()) return Just(false);
    8477        3524 :       if (level == FROZEN &&
    8478        3515 :           PropertyDescriptor::IsDataDescriptor(&current_desc) &&
    8479             :           current_desc.writable()) {
    8480             :         return Just(false);
    8481             :       }
    8482             :     }
    8483             :   }
    8484             :   return Just(true);
    8485             : }
    8486             : 
    8487             : }  // namespace
    8488             : 
    8489        1157 : Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> receiver,
    8490             :                                            IntegrityLevel level) {
    8491        1157 :   if (!receiver->map()->IsCustomElementsReceiverMap()) {
    8492             :     return JSObject::TestIntegrityLevel(Handle<JSObject>::cast(receiver),
    8493        1004 :                                         level);
    8494             :   }
    8495         153 :   return GenericTestIntegrityLevel(receiver, level);
    8496             : }
    8497             : 
    8498      253365 : Maybe<bool> JSObject::TestIntegrityLevel(Handle<JSObject> object,
    8499             :                                          IntegrityLevel level) {
    8500      760022 :   if (!object->map()->IsCustomElementsReceiverMap() &&
    8501      506651 :       !object->HasSloppyArgumentsElements()) {
    8502      253255 :     return Just(FastTestIntegrityLevel(*object, level));
    8503             :   }
    8504         120 :   return GenericTestIntegrityLevel(Handle<JSReceiver>::cast(object), level);
    8505             : }
    8506             : 
    8507       77283 : Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object,
    8508             :                                           ShouldThrow should_throw) {
    8509      154566 :   if (object->IsJSProxy()) {
    8510             :     return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object),
    8511       73237 :                                       should_throw);
    8512             :   }
    8513             :   DCHECK(object->IsJSObject());
    8514             :   return JSObject::PreventExtensions(Handle<JSObject>::cast(object),
    8515        4046 :                                      should_throw);
    8516             : }
    8517             : 
    8518             : 
    8519       73237 : Maybe<bool> JSProxy::PreventExtensions(Handle<JSProxy> proxy,
    8520             :                                        ShouldThrow should_throw) {
    8521             :   Isolate* isolate = proxy->GetIsolate();
    8522       73237 :   STACK_CHECK(isolate, Nothing<bool>());
    8523             :   Factory* factory = isolate->factory();
    8524             :   Handle<String> trap_name = factory->preventExtensions_string();
    8525             : 
    8526      146454 :   if (proxy->IsRevoked()) {
    8527             :     isolate->Throw(
    8528          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    8529             :     return Nothing<bool>();
    8530             :   }
    8531      146418 :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    8532      146418 :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    8533             : 
    8534             :   Handle<Object> trap;
    8535      146418 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8536             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    8537      146382 :   if (trap->IsUndefined(isolate)) {
    8538       63477 :     return JSReceiver::PreventExtensions(target, should_throw);
    8539             :   }
    8540             : 
    8541             :   Handle<Object> trap_result;
    8542             :   Handle<Object> args[] = {target};
    8543       19428 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8544             :       isolate, trap_result,
    8545             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    8546             :       Nothing<bool>());
    8547          54 :   if (!trap_result->BooleanValue(isolate)) {
    8548          18 :     RETURN_FAILURE(
    8549             :         isolate, should_throw,
    8550             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
    8551             :   }
    8552             : 
    8553             :   // Enforce the invariant.
    8554          36 :   Maybe<bool> target_result = JSReceiver::IsExtensible(target);
    8555          36 :   MAYBE_RETURN(target_result, Nothing<bool>());
    8556          36 :   if (target_result.FromJust()) {
    8557             :     isolate->Throw(*factory->NewTypeError(
    8558          18 :         MessageTemplate::kProxyPreventExtensionsExtensible));
    8559             :     return Nothing<bool>();
    8560             :   }
    8561             :   return Just(true);
    8562             : }
    8563             : 
    8564             : 
    8565        4491 : Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
    8566             :                                         ShouldThrow should_throw) {
    8567             :   Isolate* isolate = object->GetIsolate();
    8568             : 
    8569        8982 :   if (!object->HasSloppyArgumentsElements()) {
    8570        4436 :     return PreventExtensionsWithTransition<NONE>(object, should_throw);
    8571             :   }
    8572             : 
    8573         110 :   if (object->IsAccessCheckNeeded() &&
    8574           0 :       !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
    8575           0 :     isolate->ReportFailedAccessCheck(object);
    8576           0 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    8577           0 :     RETURN_FAILURE(isolate, should_throw,
    8578             :                    NewTypeError(MessageTemplate::kNoAccess));
    8579             :   }
    8580             : 
    8581          55 :   if (!object->map()->is_extensible()) return Just(true);
    8582             : 
    8583         110 :   if (object->IsJSGlobalProxy()) {
    8584           0 :     PrototypeIterator iter(isolate, object);
    8585           0 :     if (iter.IsAtEnd()) return Just(true);
    8586             :     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
    8587             :     return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter),
    8588           0 :                              should_throw);
    8589             :   }
    8590             : 
    8591         110 :   if (object->map()->has_named_interceptor() ||
    8592             :       object->map()->has_indexed_interceptor()) {
    8593           0 :     RETURN_FAILURE(isolate, should_throw,
    8594             :                    NewTypeError(MessageTemplate::kCannotPreventExt));
    8595             :   }
    8596             : 
    8597          55 :   if (!object->HasFixedTypedArrayElements()) {
    8598             :     // If there are fast elements we normalize.
    8599          55 :     Handle<NumberDictionary> dictionary = NormalizeElements(object);
    8600             :     DCHECK(object->HasDictionaryElements() ||
    8601             :            object->HasSlowArgumentsElements());
    8602             : 
    8603             :     // Make sure that we never go back to fast case.
    8604          55 :     object->RequireSlowElements(*dictionary);
    8605             :   }
    8606             : 
    8607             :   // Do a map transition, other objects with this map may still
    8608             :   // be extensible.
    8609             :   // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
    8610             :   Handle<Map> new_map =
    8611          55 :       Map::Copy(isolate, handle(object->map(), isolate), "PreventExtensions");
    8612             : 
    8613             :   new_map->set_is_extensible(false);
    8614          55 :   JSObject::MigrateToMap(object, new_map);
    8615             :   DCHECK(!object->map()->is_extensible());
    8616             : 
    8617             :   return Just(true);
    8618             : }
    8619             : 
    8620             : 
    8621     1012968 : Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) {
    8622     2025936 :   if (object->IsJSProxy()) {
    8623       81249 :     return JSProxy::IsExtensible(Handle<JSProxy>::cast(object));
    8624             :   }
    8625      931719 :   return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object)));
    8626             : }
    8627             : 
    8628             : 
    8629       81249 : Maybe<bool> JSProxy::IsExtensible(Handle<JSProxy> proxy) {
    8630             :   Isolate* isolate = proxy->GetIsolate();
    8631       81249 :   STACK_CHECK(isolate, Nothing<bool>());
    8632             :   Factory* factory = isolate->factory();
    8633             :   Handle<String> trap_name = factory->isExtensible_string();
    8634             : 
    8635      162464 :   if (proxy->IsRevoked()) {
    8636             :     isolate->Throw(
    8637          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    8638             :     return Nothing<bool>();
    8639             :   }
    8640      162428 :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
    8641      162428 :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    8642             : 
    8643             :   Handle<Object> trap;
    8644      162428 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8645             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    8646      162392 :   if (trap->IsUndefined(isolate)) {
    8647       70948 :     return JSReceiver::IsExtensible(target);
    8648             :   }
    8649             : 
    8650             :   Handle<Object> trap_result;
    8651             :   Handle<Object> args[] = {target};
    8652       20496 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8653             :       isolate, trap_result,
    8654             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    8655             :       Nothing<bool>());
    8656             : 
    8657             :   // Enforce the invariant.
    8658         423 :   Maybe<bool> target_result = JSReceiver::IsExtensible(target);
    8659         423 :   MAYBE_RETURN(target_result, Nothing<bool>());
    8660         423 :   if (target_result.FromJust() != trap_result->BooleanValue(isolate)) {
    8661             :     isolate->Throw(
    8662             :         *factory->NewTypeError(MessageTemplate::kProxyIsExtensibleInconsistent,
    8663          54 :                                factory->ToBoolean(target_result.FromJust())));
    8664             :     return Nothing<bool>();
    8665             :   }
    8666         396 :   return target_result;
    8667             : }
    8668             : 
    8669             : 
    8670     3820202 : bool JSObject::IsExtensible(Handle<JSObject> object) {
    8671             :   Isolate* isolate = object->GetIsolate();
    8672     7640464 :   if (object->IsAccessCheckNeeded() &&
    8673          40 :       !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
    8674             :     return true;
    8675             :   }
    8676     7640361 :   if (object->IsJSGlobalProxy()) {
    8677             :     PrototypeIterator iter(isolate, *object);
    8678        2783 :     if (iter.IsAtEnd()) return false;
    8679             :     DCHECK(iter.GetCurrent()->IsJSGlobalObject());
    8680        5566 :     return iter.GetCurrent<JSObject>()->map()->is_extensible();
    8681             :   }
    8682             :   return object->map()->is_extensible();
    8683             : }
    8684             : 
    8685             : namespace {
    8686             : 
    8687             : template <typename Dictionary>
    8688        6693 : void ApplyAttributesToDictionary(Isolate* isolate, ReadOnlyRoots roots,
    8689             :                                  Handle<Dictionary> dictionary,
    8690             :                                  const PropertyAttributes attributes) {
    8691        6693 :   int capacity = dictionary->Capacity();
    8692       78693 :   for (int i = 0; i < capacity; i++) {
    8693       72000 :     Object k;
    8694      111881 :     if (!dictionary->ToKey(roots, i, &k)) continue;
    8695       32137 :     if (k->FilterKey(ALL_PROPERTIES)) continue;
    8696       32119 :     PropertyDetails details = dictionary->DetailsAt(i);
    8697       32119 :     int attrs = attributes;
    8698             :     // READ_ONLY is an invalid attribute for JS setters/getters.
    8699       62375 :     if ((attributes & READ_ONLY) && details.kind() == kAccessor) {
    8700          54 :       Object v = dictionary->ValueAt(i);
    8701          45 :       if (v->IsAccessorPair()) attrs &= ~READ_ONLY;
    8702             :     }
    8703             :     details = details.CopyAddAttributes(static_cast<PropertyAttributes>(attrs));
    8704       32119 :     dictionary->DetailsAtPut(isolate, i, details);
    8705             :   }
    8706        6693 : }
    8707             : 
    8708             : }  // namespace
    8709             : 
    8710             : template <PropertyAttributes attrs>
    8711      251526 : Maybe<bool> JSObject::PreventExtensionsWithTransition(
    8712             :     Handle<JSObject> object, ShouldThrow should_throw) {
    8713             :   STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN);
    8714             : 
    8715             :   // Sealing/freezing sloppy arguments or namespace objects should be handled
    8716             :   // elsewhere.
    8717             :   DCHECK(!object->HasSloppyArgumentsElements());
    8718             :   DCHECK_IMPLIES(object->IsJSModuleNamespace(), attrs == NONE);
    8719             : 
    8720             :   Isolate* isolate = object->GetIsolate();
    8721      503089 :   if (object->IsAccessCheckNeeded() &&
    8722          25 :       !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
    8723          20 :     isolate->ReportFailedAccessCheck(object);
    8724          20 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    8725           0 :     RETURN_FAILURE(isolate, should_throw,
    8726             :                    NewTypeError(MessageTemplate::kNoAccess));
    8727             :   }
    8728             : 
    8729        4435 :   if (attrs == NONE && !object->map()->is_extensible()) return Just(true);
    8730             : 
    8731      502868 :   if (object->IsJSGlobalProxy()) {
    8732          90 :     PrototypeIterator iter(isolate, object);
    8733          90 :     if (iter.IsAtEnd()) return Just(true);
    8734             :     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
    8735             :     return PreventExtensionsWithTransition<attrs>(
    8736          90 :         PrototypeIterator::GetCurrent<JSObject>(iter), should_throw);
    8737             :   }
    8738             : 
    8739      502683 :   if (object->map()->has_named_interceptor() ||
    8740             :       object->map()->has_indexed_interceptor()) {
    8741             :     MessageTemplate message = MessageTemplate::kNone;
    8742             :     switch (attrs) {
    8743             :       case NONE:
    8744             :         message = MessageTemplate::kCannotPreventExt;
    8745             :         break;
    8746             : 
    8747             :       case SEALED:
    8748             :         message = MessageTemplate::kCannotSeal;
    8749             :         break;
    8750             : 
    8751             :       case FROZEN:
    8752             :         message = MessageTemplate::kCannotFreeze;
    8753             :         break;
    8754             :     }
    8755           3 :     RETURN_FAILURE(isolate, should_throw, NewTypeError(message));
    8756             :   }
    8757             : 
    8758             :   Handle<NumberDictionary> new_element_dictionary;
    8759     1005011 :   if (!object->HasFixedTypedArrayElements() &&
    8760      502625 :       !object->HasDictionaryElements() &&
    8761      502398 :       !object->HasSlowStringWrapperElements()) {
    8762      502120 :     int length = object->IsJSArray()
    8763      264492 :                      ? Smi::ToInt(Handle<JSArray>::cast(object)->length())
    8764      753179 :                      : object->elements()->length();
    8765      502120 :     new_element_dictionary =
    8766             :         length == 0 ? isolate->factory()->empty_slow_element_dictionary()
    8767      271454 :                     : object->GetElementsAccessor()->Normalize(object);
    8768             :   }
    8769             : 
    8770             :   Handle<Symbol> transition_marker;
    8771             :   if (attrs == NONE) {
    8772             :     transition_marker = isolate->factory()->nonextensible_symbol();
    8773             :   } else if (attrs == SEALED) {
    8774             :     transition_marker = isolate->factory()->sealed_symbol();
    8775             :   } else {
    8776             :     DCHECK(attrs == FROZEN);
    8777             :     transition_marker = isolate->factory()->frozen_symbol();
    8778             :   }
    8779             : 
    8780             :   Handle<Map> old_map(object->map(), isolate);
    8781      251341 :   TransitionsAccessor transitions(isolate, old_map);
    8782      251346 :   Map transition = transitions.SearchSpecial(*transition_marker);
    8783      251345 :   if (!transition.is_null()) {
    8784             :     Handle<Map> transition_map(transition, isolate);
    8785             :     DCHECK(transition_map->has_dictionary_elements() ||
    8786             :            transition_map->has_fixed_typed_array_elements() ||
    8787             :            transition_map->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
    8788             :     DCHECK(!transition_map->is_extensible());
    8789       99755 :     JSObject::MigrateToMap(object, transition_map);
    8790      151590 :   } else if (transitions.CanHaveMoreTransitions()) {
    8791             :     // Create a new descriptor array with the appropriate property attributes
    8792             :     Handle<Map> new_map = Map::CopyForPreventExtensions(
    8793      150804 :         isolate, old_map, attrs, transition_marker, "CopyForPreventExtensions");
    8794      150801 :     JSObject::MigrateToMap(object, new_map);
    8795             :   } else {
    8796             :     DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map());
    8797             :     // Slow path: need to normalize properties for safety
    8798         788 :     NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0,
    8799             :                         "SlowPreventExtensions");
    8800             : 
    8801             :     // Create a new map, since other objects with this map may be extensible.
    8802             :     // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
    8803             :     Handle<Map> new_map = Map::Copy(isolate, handle(object->map(), isolate),
    8804         788 :                                     "SlowCopyForPreventExtensions");
    8805             :     new_map->set_is_extensible(false);
    8806         788 :     if (!new_element_dictionary.is_null()) {
    8807             :       ElementsKind new_kind =
    8808             :           IsStringWrapperElementsKind(old_map->elements_kind())
    8809             :               ? SLOW_STRING_WRAPPER_ELEMENTS
    8810         788 :               : DICTIONARY_ELEMENTS;
    8811        1576 :       new_map->set_elements_kind(new_kind);
    8812             :     }
    8813         788 :     JSObject::MigrateToMap(object, new_map);
    8814             : 
    8815             :     if (attrs != NONE) {
    8816             :       ReadOnlyRoots roots(isolate);
    8817         308 :       if (object->IsJSGlobalObject()) {
    8818             :         Handle<GlobalDictionary> dictionary(
    8819         162 :             JSGlobalObject::cast(*object)->global_dictionary(), isolate);
    8820          81 :         ApplyAttributesToDictionary(isolate, roots, dictionary, attrs);
    8821             :       } else {
    8822         146 :         Handle<NameDictionary> dictionary(object->property_dictionary(),
    8823          73 :                                           isolate);
    8824          73 :         ApplyAttributesToDictionary(isolate, roots, dictionary, attrs);
    8825             :       }
    8826             :     }
    8827             :   }
    8828             : 
    8829             :   // Both seal and preventExtensions always go through without modifications to
    8830             :   // typed array elements. Freeze works only if there are no actual elements.
    8831      251344 :   if (object->HasFixedTypedArrayElements()) {
    8832          36 :     if (attrs == FROZEN &&
    8833             :         JSArrayBufferView::cast(*object)->byte_length() > 0) {
    8834          27 :       isolate->Throw(*isolate->factory()->NewTypeError(
    8835          54 :           MessageTemplate::kCannotFreezeArrayBufferView));
    8836             :       return Nothing<bool>();
    8837             :     }
    8838             :     return Just(true);
    8839             :   }
    8840             : 
    8841             :   DCHECK(object->map()->has_dictionary_elements() ||
    8842             :          object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
    8843      251286 :   if (!new_element_dictionary.is_null()) {
    8844      502120 :     object->set_elements(*new_element_dictionary);
    8845             :   }
    8846             : 
    8847      502563 :   if (object->elements() !=
    8848             :       ReadOnlyRoots(isolate).empty_slow_element_dictionary()) {
    8849       14014 :     Handle<NumberDictionary> dictionary(object->element_dictionary(), isolate);
    8850             :     // Make sure we never go back to the fast case
    8851        7007 :     object->RequireSlowElements(*dictionary);
    8852             :     if (attrs != NONE) {
    8853        6539 :       ApplyAttributesToDictionary(isolate, ReadOnlyRoots(isolate), dictionary,
    8854        6539 :                                   attrs);
    8855             :     }
    8856             :   }
    8857             : 
    8858             :   return Just(true);
    8859             : }
    8860             : 
    8861             : 
    8862     6897117 : Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
    8863             :                                         Representation representation,
    8864             :                                         FieldIndex index) {
    8865             :   Isolate* isolate = object->GetIsolate();
    8866     6897129 :   if (object->IsUnboxedDoubleField(index)) {
    8867             :     double value = object->RawFastDoublePropertyAt(index);
    8868       19998 :     return isolate->factory()->NewHeapNumber(value);
    8869             :   }
    8870    13754254 :   Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
    8871     6877132 :   return Object::WrapForRead(isolate, raw_value, representation);
    8872             : }
    8873             : 
    8874             : // static
    8875     5507131 : MaybeHandle<Object> JSReceiver::ToPrimitive(Handle<JSReceiver> receiver,
    8876             :                                             ToPrimitiveHint hint) {
    8877             :   Isolate* const isolate = receiver->GetIsolate();
    8878             :   Handle<Object> exotic_to_prim;
    8879    11014262 :   ASSIGN_RETURN_ON_EXCEPTION(
    8880             :       isolate, exotic_to_prim,
    8881             :       Object::GetMethod(receiver, isolate->factory()->to_primitive_symbol()),
    8882             :       Object);
    8883    11014252 :   if (!exotic_to_prim->IsUndefined(isolate)) {
    8884             :     Handle<Object> hint_string =
    8885        6822 :         isolate->factory()->ToPrimitiveHintString(hint);
    8886             :     Handle<Object> result;
    8887       13644 :     ASSIGN_RETURN_ON_EXCEPTION(
    8888             :         isolate, result,
    8889             :         Execution::Call(isolate, exotic_to_prim, receiver, 1, &hint_string),
    8890             :         Object);
    8891       13338 :     if (result->IsPrimitive()) return result;
    8892           0 :     THROW_NEW_ERROR(isolate,
    8893             :                     NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
    8894             :                     Object);
    8895             :   }
    8896             :   return OrdinaryToPrimitive(receiver, (hint == ToPrimitiveHint::kString)
    8897             :                                            ? OrdinaryToPrimitiveHint::kString
    8898     5500304 :                                            : OrdinaryToPrimitiveHint::kNumber);
    8899             : }
    8900             : 
    8901             : 
    8902             : // static
    8903     5500304 : MaybeHandle<Object> JSReceiver::OrdinaryToPrimitive(
    8904             :     Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint) {
    8905             :   Isolate* const isolate = receiver->GetIsolate();
    8906    16500912 :   Handle<String> method_names[2];
    8907     5500304 :   switch (hint) {
    8908             :     case OrdinaryToPrimitiveHint::kNumber:
    8909        6152 :       method_names[0] = isolate->factory()->valueOf_string();
    8910        6152 :       method_names[1] = isolate->factory()->toString_string();
    8911        6152 :       break;
    8912             :     case OrdinaryToPrimitiveHint::kString:
    8913     5494152 :       method_names[0] = isolate->factory()->toString_string();
    8914     5494152 :       method_names[1] = isolate->factory()->valueOf_string();
    8915     5494152 :       break;
    8916             :   }
    8917     5504247 :   for (Handle<String> name : method_names) {
    8918             :     Handle<Object> method;
    8919    11004416 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, method,
    8920             :                                JSReceiver::GetProperty(isolate, receiver, name),
    8921             :                                Object);
    8922    11004380 :     if (method->IsCallable()) {
    8923             :       Handle<Object> result;
    8924    11003480 :       ASSIGN_RETURN_ON_EXCEPTION(
    8925             :           isolate, result,
    8926             :           Execution::Call(isolate, method, receiver, 0, nullptr), Object);
    8927    10985084 :       if (result->IsPrimitive()) return result;
    8928             :     }
    8929             :   }
    8930         135 :   THROW_NEW_ERROR(isolate,
    8931             :                   NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
    8932             :                   Object);
    8933             : }
    8934             : 
    8935             : 
    8936             : // TODO(cbruni/jkummerow): Consider moving this into elements.cc.
    8937      144303 : bool JSObject::HasEnumerableElements() {
    8938             :   // TODO(cbruni): cleanup
    8939      144303 :   JSObject object = *this;
    8940      144303 :   switch (object->GetElementsKind()) {
    8941             :     case PACKED_SMI_ELEMENTS:
    8942             :     case PACKED_ELEMENTS:
    8943             :     case PACKED_DOUBLE_ELEMENTS: {
    8944             :       int length = object->IsJSArray()
    8945       89496 :                        ? Smi::ToInt(JSArray::cast(object)->length())
    8946       89550 :                        : object->elements()->length();
    8947       29850 :       return length > 0;
    8948             :     }
    8949             :     case HOLEY_SMI_ELEMENTS:
    8950             :     case HOLEY_ELEMENTS: {
    8951      228222 :       FixedArray elements = FixedArray::cast(object->elements());
    8952             :       int length = object->IsJSArray()
    8953      231465 :                        ? Smi::ToInt(JSArray::cast(object)->length())
    8954      228222 :                        : elements->length();
    8955             :       Isolate* isolate = GetIsolate();
    8956     2566764 :       for (int i = 0; i < length; i++) {
    8957     2463786 :         if (!elements->is_the_hole(isolate, i)) return true;
    8958             :       }
    8959             :       return false;
    8960             :     }
    8961             :     case HOLEY_DOUBLE_ELEMENTS: {
    8962             :       int length = object->IsJSArray()
    8963         135 :                        ? Smi::ToInt(JSArray::cast(object)->length())
    8964         135 :                        : object->elements()->length();
    8965             :       // Zero-length arrays would use the empty FixedArray...
    8966          45 :       if (length == 0) return false;
    8967             :       // ...so only cast to FixedDoubleArray otherwise.
    8968          90 :       FixedDoubleArray elements = FixedDoubleArray::cast(object->elements());
    8969          45 :       for (int i = 0; i < length; i++) {
    8970          45 :         if (!elements->is_the_hole(i)) return true;
    8971             :       }
    8972             :       return false;
    8973             :     }
    8974             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
    8975             : 
    8976             :       TYPED_ARRAYS(TYPED_ARRAY_CASE)
    8977             : #undef TYPED_ARRAY_CASE
    8978             :       {
    8979           0 :         int length = object->elements()->length();
    8980           0 :         return length > 0;
    8981             :       }
    8982             :     case DICTIONARY_ELEMENTS: {
    8983         432 :       NumberDictionary elements = NumberDictionary::cast(object->elements());
    8984         216 :       return elements->NumberOfEnumerableProperties() > 0;
    8985             :     }
    8986             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    8987             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    8988             :       // We're approximating non-empty arguments objects here.
    8989             :       return true;
    8990             :     case FAST_STRING_WRAPPER_ELEMENTS:
    8991             :     case SLOW_STRING_WRAPPER_ELEMENTS:
    8992           0 :       if (String::cast(JSValue::cast(object)->value())->length() > 0) {
    8993             :         return true;
    8994             :       }
    8995           0 :       return object->elements()->length() > 0;
    8996             :     case NO_ELEMENTS:
    8997           0 :       return false;
    8998             :   }
    8999           0 :   UNREACHABLE();
    9000             : }
    9001             : 
    9002      169299 : int Map::NumberOfEnumerableProperties() const {
    9003             :   int result = 0;
    9004      169299 :   DescriptorArray descs = instance_descriptors();
    9005             :   int limit = NumberOfOwnDescriptors();
    9006      805006 :   for (int i = 0; i < limit; i++) {
    9007     2236971 :     if ((descs->GetDetails(i).attributes() & ONLY_ENUMERABLE) == 0 &&
    9008      965557 :         !descs->GetKey(i)->FilterKey(ENUMERABLE_STRINGS)) {
    9009      328059 :       result++;
    9010             :     }
    9011             :   }
    9012      169299 :   return result;
    9013             : }
    9014             : 
    9015    53893637 : int Map::NextFreePropertyIndex() const {
    9016             :   int free_index = 0;
    9017             :   int number_of_own_descriptors = NumberOfOwnDescriptors();
    9018    53893637 :   DescriptorArray descs = instance_descriptors();
    9019   471448374 :   for (int i = 0; i < number_of_own_descriptors; i++) {
    9020   417554671 :     PropertyDetails details = descs->GetDetails(i);
    9021   417554671 :     if (details.location() == kField) {
    9022   281659766 :       int candidate = details.field_index() + details.field_width_in_words();
    9023   281659766 :       if (candidate > free_index) free_index = candidate;
    9024             :     }
    9025             :   }
    9026    53893703 :   return free_index;
    9027             : }
    9028             : 
    9029       81558 : bool Map::OnlyHasSimpleProperties() const {
    9030             :   // Wrapped string elements aren't explicitly stored in the elements backing
    9031             :   // store, but are loaded indirectly from the underlying string.
    9032       79453 :   return !IsStringWrapperElementsKind(elements_kind()) &&
    9033      202328 :          !IsSpecialReceiverMap() && !has_hidden_prototype() &&
    9034      141943 :          !is_dictionary_map();
    9035             : }
    9036             : 
    9037        1431 : V8_WARN_UNUSED_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
    9038             :     Isolate* isolate, Handle<JSReceiver> receiver, bool get_entries,
    9039             :     Handle<FixedArray>* result) {
    9040             :   Handle<Map> map(JSReceiver::cast(*receiver)->map(), isolate);
    9041             : 
    9042        1431 :   if (!map->IsJSObjectMap()) return Just(false);
    9043        1431 :   if (!map->OnlyHasSimpleProperties()) return Just(false);
    9044             : 
    9045             :   Handle<JSObject> object(JSObject::cast(*receiver), isolate);
    9046             : 
    9047        2862 :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    9048             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9049             :   int number_of_own_elements =
    9050        5724 :       object->GetElementsAccessor()->GetCapacity(*object, object->elements());
    9051             :   Handle<FixedArray> values_or_entries = isolate->factory()->NewFixedArray(
    9052        1431 :       number_of_own_descriptors + number_of_own_elements);
    9053        1431 :   int count = 0;
    9054             : 
    9055        2862 :   if (object->elements() != ReadOnlyRoots(isolate).empty_fixed_array()) {
    9056        2016 :     MAYBE_RETURN(object->GetElementsAccessor()->CollectValuesOrEntries(
    9057             :                      isolate, object, values_or_entries, get_entries, &count,
    9058             :                      ENUMERABLE_STRINGS),
    9059             :                  Nothing<bool>());
    9060             :   }
    9061             : 
    9062             :   bool stable = object->map() == *map;
    9063             : 
    9064        3429 :   for (int index = 0; index < number_of_own_descriptors; index++) {
    9065        3996 :     Handle<Name> next_key(descriptors->GetKey(index), isolate);
    9066        3996 :     if (!next_key->IsString()) continue;
    9067             :     Handle<Object> prop_value;
    9068             : 
    9069             :     // Directly decode from the descriptor array if |from| did not change shape.
    9070        1818 :     if (stable) {
    9071        1728 :       PropertyDetails details = descriptors->GetDetails(index);
    9072        1728 :       if (!details.IsEnumerable()) continue;
    9073        1233 :       if (details.kind() == kData) {
    9074        1197 :         if (details.location() == kDescriptor) {
    9075           0 :           prop_value = handle(descriptors->GetStrongValue(index), isolate);
    9076             :         } else {
    9077        1197 :           Representation representation = details.representation();
    9078        1197 :           FieldIndex field_index = FieldIndex::ForDescriptor(*map, index);
    9079             :           prop_value =
    9080        1197 :               JSObject::FastPropertyAt(object, representation, field_index);
    9081             :         }
    9082             :       } else {
    9083          72 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    9084             :             isolate, prop_value,
    9085             :             JSReceiver::GetProperty(isolate, object, next_key),
    9086             :             Nothing<bool>());
    9087             :         stable = object->map() == *map;
    9088             :       }
    9089             :     } else {
    9090             :       // If the map did change, do a slower lookup. We are still guaranteed that
    9091             :       // the object has a simple shape, and that the key is a name.
    9092             :       LookupIterator it(isolate, object, next_key,
    9093          90 :                         LookupIterator::OWN_SKIP_INTERCEPTOR);
    9094         162 :       if (!it.IsFound()) continue;
    9095             :       DCHECK(it.state() == LookupIterator::DATA ||
    9096             :              it.state() == LookupIterator::ACCESSOR);
    9097          54 :       if (!it.IsEnumerable()) continue;
    9098          36 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    9099             :           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
    9100             :     }
    9101             : 
    9102        1251 :     if (get_entries) {
    9103         837 :       prop_value = MakeEntryPair(isolate, next_key, prop_value);
    9104             :     }
    9105             : 
    9106        2502 :     values_or_entries->set(count, *prop_value);
    9107        1251 :     count++;
    9108             :   }
    9109             : 
    9110             :   DCHECK_LE(count, values_or_entries->length());
    9111        1431 :   *result = FixedArray::ShrinkOrEmpty(isolate, values_or_entries, count);
    9112             :   return Just(true);
    9113             : }
    9114             : 
    9115        2178 : MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
    9116             :                                               Handle<JSReceiver> object,
    9117             :                                               PropertyFilter filter,
    9118             :                                               bool try_fast_path,
    9119             :                                               bool get_entries) {
    9120             :   Handle<FixedArray> values_or_entries;
    9121        2178 :   if (try_fast_path && filter == ENUMERABLE_STRINGS) {
    9122             :     Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries(
    9123        1431 :         isolate, object, get_entries, &values_or_entries);
    9124        1431 :     if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>();
    9125        1431 :     if (fast_values_or_entries.FromJust()) return values_or_entries;
    9126             :   }
    9127             : 
    9128             :   PropertyFilter key_filter =
    9129         747 :       static_cast<PropertyFilter>(filter & ~ONLY_ENUMERABLE);
    9130             : 
    9131             :   Handle<FixedArray> keys;
    9132        1494 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    9133             :       isolate, keys,
    9134             :       KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, key_filter,
    9135             :                               GetKeysConversion::kConvertToString),
    9136             :       MaybeHandle<FixedArray>());
    9137             : 
    9138         747 :   values_or_entries = isolate->factory()->NewFixedArray(keys->length());
    9139             :   int length = 0;
    9140             : 
    9141        6288 :   for (int i = 0; i < keys->length(); ++i) {
    9142        2433 :     Handle<Name> key = Handle<Name>::cast(handle(keys->get(i), isolate));
    9143             : 
    9144        2433 :     if (filter & ONLY_ENUMERABLE) {
    9145             :       PropertyDescriptor descriptor;
    9146             :       Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
    9147        2433 :           isolate, object, key, &descriptor);
    9148        2433 :       MAYBE_RETURN(did_get_descriptor, MaybeHandle<FixedArray>());
    9149        4737 :       if (!did_get_descriptor.FromJust() || !descriptor.enumerable()) continue;
    9150             :     }
    9151             : 
    9152             :     Handle<Object> value;
    9153        3168 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    9154             :         isolate, value, Object::GetPropertyOrElement(isolate, object, key),
    9155             :         MaybeHandle<FixedArray>());
    9156             : 
    9157        1584 :     if (get_entries) {
    9158             :       Handle<FixedArray> entry_storage =
    9159        1053 :           isolate->factory()->NewUninitializedFixedArray(2);
    9160        2106 :       entry_storage->set(0, *key);
    9161        1053 :       entry_storage->set(1, *value);
    9162             :       value = isolate->factory()->NewJSArrayWithElements(entry_storage,
    9163        1053 :                                                          PACKED_ELEMENTS, 2);
    9164             :     }
    9165             : 
    9166        1584 :     values_or_entries->set(length, *value);
    9167        1584 :     length++;
    9168             :   }
    9169             :   DCHECK_LE(length, values_or_entries->length());
    9170         711 :   return FixedArray::ShrinkOrEmpty(isolate, values_or_entries, length);
    9171             : }
    9172             : 
    9173         909 : MaybeHandle<FixedArray> JSReceiver::GetOwnValues(Handle<JSReceiver> object,
    9174             :                                                  PropertyFilter filter,
    9175             :                                                  bool try_fast_path) {
    9176             :   return GetOwnValuesOrEntries(object->GetIsolate(), object, filter,
    9177        1818 :                                try_fast_path, false);
    9178             : }
    9179             : 
    9180        1269 : MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object,
    9181             :                                                   PropertyFilter filter,
    9182             :                                                   bool try_fast_path) {
    9183             :   return GetOwnValuesOrEntries(object->GetIsolate(), object, filter,
    9184        2538 :                                try_fast_path, true);
    9185             : }
    9186             : 
    9187        4698 : Handle<FixedArray> JSReceiver::GetOwnElementIndices(Isolate* isolate,
    9188             :                                                     Handle<JSReceiver> receiver,
    9189             :                                                     Handle<JSObject> object) {
    9190             :   KeyAccumulator accumulator(isolate, KeyCollectionMode::kOwnOnly,
    9191             :                              ALL_PROPERTIES);
    9192        4698 :   accumulator.CollectOwnElementIndices(receiver, object);
    9193             :   Handle<FixedArray> keys =
    9194        4698 :       accumulator.GetKeys(GetKeysConversion::kKeepNumbers);
    9195             :   DCHECK(keys->ContainsSortedNumbers());
    9196        4698 :   return keys;
    9197             : }
    9198             : 
    9199       60996 : bool Map::DictionaryElementsInPrototypeChainOnly(Isolate* isolate) {
    9200       60996 :   if (IsDictionaryElementsKind(elements_kind())) {
    9201             :     return false;
    9202             :   }
    9203             : 
    9204      250656 :   for (PrototypeIterator iter(isolate, *this); !iter.IsAtEnd();
    9205      132118 :        iter.Advance()) {
    9206             :     // Be conservative, don't walk into proxies.
    9207      278711 :     if (iter.GetCurrent()->IsJSProxy()) return true;
    9208             :     // String wrappers have non-configurable, non-writable elements.
    9209      273886 :     if (iter.GetCurrent()->IsStringWrapper()) return true;
    9210      136925 :     JSObject current = iter.GetCurrent<JSObject>();
    9211             : 
    9212      410775 :     if (current->HasDictionaryElements() &&
    9213      146557 :         current->element_dictionary()->requires_slow_elements()) {
    9214             :       return true;
    9215             :     }
    9216             : 
    9217      132118 :     if (current->HasSlowArgumentsElements()) {
    9218           0 :       FixedArray parameter_map = FixedArray::cast(current->elements());
    9219             :       Object arguments = parameter_map->get(1);
    9220           0 :       if (NumberDictionary::cast(arguments)->requires_slow_elements()) {
    9221             :         return true;
    9222             :       }
    9223             :     }
    9224             :   }
    9225             : 
    9226       54444 :   return false;
    9227             : }
    9228             : 
    9229             : 
    9230      572653 : MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
    9231             :                                              Handle<Name> name,
    9232             :                                              Handle<Object> getter,
    9233             :                                              Handle<Object> setter,
    9234             :                                              PropertyAttributes attributes) {
    9235             :   Isolate* isolate = object->GetIsolate();
    9236             : 
    9237             :   LookupIterator it = LookupIterator::PropertyOrElement(
    9238      572654 :       isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    9239      572653 :   return DefineAccessor(&it, getter, setter, attributes);
    9240             : }
    9241             : 
    9242             : 
    9243     2306359 : MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
    9244             :                                              Handle<Object> getter,
    9245             :                                              Handle<Object> setter,
    9246             :                                              PropertyAttributes attributes) {
    9247             :   Isolate* isolate = it->isolate();
    9248             : 
    9249      768788 :   it->UpdateProtector();
    9250             : 
    9251      768788 :   if (it->state() == LookupIterator::ACCESS_CHECK) {
    9252        1728 :     if (!it->HasAccess()) {
    9253           5 :       isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    9254           5 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    9255           0 :       return isolate->factory()->undefined_value();
    9256             :     }
    9257        1723 :     it->Next();
    9258             :   }
    9259             : 
    9260      768783 :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    9261             :   // Ignore accessors on typed arrays.
    9262      796345 :   if (it->IsElement() && object->HasFixedTypedArrayElements()) {
    9263           0 :     return it->factory()->undefined_value();
    9264             :   }
    9265             : 
    9266             :   DCHECK(getter->IsCallable() || getter->IsUndefined(isolate) ||
    9267             :          getter->IsNull(isolate) || getter->IsFunctionTemplateInfo());
    9268             :   DCHECK(setter->IsCallable() || setter->IsUndefined(isolate) ||
    9269             :          setter->IsNull(isolate) || setter->IsFunctionTemplateInfo());
    9270      768783 :   it->TransitionToAccessorProperty(getter, setter, attributes);
    9271             : 
    9272      768784 :   return isolate->factory()->undefined_value();
    9273             : }
    9274             : 
    9275       60341 : MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
    9276             :                                           Handle<Name> name,
    9277             :                                           Handle<AccessorInfo> info,
    9278             :                                           PropertyAttributes attributes) {
    9279             :   Isolate* isolate = object->GetIsolate();
    9280             : 
    9281             :   LookupIterator it = LookupIterator::PropertyOrElement(
    9282       60341 :       isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    9283             : 
    9284             :   // Duplicate ACCESS_CHECK outside of GetPropertyAttributes for the case that
    9285             :   // the FailedAccessCheckCallbackFunction doesn't throw an exception.
    9286             :   //
    9287             :   // TODO(verwaest): Force throw an exception if the callback doesn't, so we can
    9288             :   // remove reliance on default return values.
    9289       60341 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    9290        7780 :     if (!it.HasAccess()) {
    9291           5 :       isolate->ReportFailedAccessCheck(object);
    9292           5 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    9293           0 :       return it.factory()->undefined_value();
    9294             :     }
    9295        7775 :     it.Next();
    9296             :   }
    9297             : 
    9298             :   // Ignore accessors on typed arrays.
    9299       60348 :   if (it.IsElement() && object->HasFixedTypedArrayElements()) {
    9300           0 :     return it.factory()->undefined_value();
    9301             :   }
    9302             : 
    9303       60336 :   CHECK(GetPropertyAttributes(&it).IsJust());
    9304             : 
    9305             :   // ES5 forbids turning a property into an accessor if it's not
    9306             :   // configurable. See 8.6.1 (Table 5).
    9307       60397 :   if (it.IsFound() && !it.IsConfigurable()) {
    9308          50 :     return it.factory()->undefined_value();
    9309             :   }
    9310             : 
    9311       60311 :   it.TransitionToAccessorPair(info, attributes);
    9312             : 
    9313       60311 :   return object;
    9314             : }
    9315             : 
    9316         117 : Object JSObject::SlowReverseLookup(Object value) {
    9317         117 :   if (HasFastProperties()) {
    9318             :     int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
    9319          90 :     DescriptorArray descs = map()->instance_descriptors();
    9320             :     bool value_is_number = value->IsNumber();
    9321         513 :     for (int i = 0; i < number_of_own_descriptors; i++) {
    9322         432 :       PropertyDetails details = descs->GetDetails(i);
    9323         432 :       if (details.location() == kField) {
    9324             :         DCHECK_EQ(kData, details.kind());
    9325           0 :         FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
    9326           0 :         if (IsUnboxedDoubleField(field_index)) {
    9327           0 :           if (value_is_number) {
    9328             :             double property = RawFastDoublePropertyAt(field_index);
    9329           0 :             if (property == value->Number()) {
    9330           0 :               return descs->GetKey(i);
    9331             :             }
    9332             :           }
    9333             :         } else {
    9334           0 :           Object property = RawFastPropertyAt(field_index);
    9335           0 :           if (field_index.is_double()) {
    9336             :             DCHECK(property->IsMutableHeapNumber());
    9337           0 :             if (value_is_number && property->Number() == value->Number()) {
    9338           0 :               return descs->GetKey(i);
    9339             :             }
    9340           0 :           } else if (property == value) {
    9341           0 :             return descs->GetKey(i);
    9342             :           }
    9343             :         }
    9344             :       } else {
    9345             :         DCHECK_EQ(kDescriptor, details.location());
    9346         432 :         if (details.kind() == kData) {
    9347         810 :           if (descs->GetStrongValue(i) == value) {
    9348           9 :             return descs->GetKey(i);
    9349             :           }
    9350             :         }
    9351             :       }
    9352             :     }
    9353         162 :     return GetReadOnlyRoots().undefined_value();
    9354          54 :   } else if (IsJSGlobalObject()) {
    9355          54 :     return JSGlobalObject::cast(*this)->global_dictionary()->SlowReverseLookup(
    9356          27 :         value);
    9357             :   } else {
    9358           0 :     return property_dictionary()->SlowReverseLookup(value);
    9359             :   }
    9360             : }
    9361             : 
    9362    24895461 : Handle<Map> Map::RawCopy(Isolate* isolate, Handle<Map> map, int instance_size,
    9363             :                          int inobject_properties) {
    9364             :   Handle<Map> result = isolate->factory()->NewMap(
    9365             :       map->instance_type(), instance_size, TERMINAL_FAST_ELEMENTS_KIND,
    9366    24895475 :       inobject_properties);
    9367             :   Handle<Object> prototype(map->prototype(), isolate);
    9368    24895450 :   Map::SetPrototype(isolate, result, prototype);
    9369    49790942 :   result->set_constructor_or_backpointer(map->GetConstructor());
    9370             :   result->set_bit_field(map->bit_field());
    9371             :   result->set_bit_field2(map->bit_field2());
    9372             :   int new_bit_field3 = map->bit_field3();
    9373             :   new_bit_field3 = OwnsDescriptorsBit::update(new_bit_field3, true);
    9374             :   new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
    9375             :   new_bit_field3 = EnumLengthBits::update(new_bit_field3,
    9376             :                                           kInvalidEnumCacheSentinel);
    9377    24895475 :   new_bit_field3 = IsDeprecatedBit::update(new_bit_field3, false);
    9378    24895463 :   if (!map->is_dictionary_map()) {
    9379    23917123 :     new_bit_field3 = IsUnstableBit::update(new_bit_field3, false);
    9380             :   }
    9381    49790939 :   result->set_bit_field3(new_bit_field3);
    9382    24895476 :   return result;
    9383             : }
    9384             : 
    9385      679572 : Handle<Map> Map::Normalize(Isolate* isolate, Handle<Map> fast_map,
    9386             :                            PropertyNormalizationMode mode, const char* reason) {
    9387             :   DCHECK(!fast_map->is_dictionary_map());
    9388             : 
    9389     2037455 :   Handle<Object> maybe_cache(isolate->native_context()->normalized_map_cache(),
    9390      679153 :                              isolate);
    9391             :   bool use_cache =
    9392     1873325 :       !fast_map->is_prototype_map() && !maybe_cache->IsUndefined(isolate);
    9393             :   Handle<NormalizedMapCache> cache;
    9394      679153 :   if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache);
    9395             : 
    9396             :   Handle<Map> new_map;
    9397     1873103 :   if (use_cache && cache->Get(fast_map, mode).ToHandle(&new_map)) {
    9398             : #ifdef VERIFY_HEAP
    9399             :     if (FLAG_verify_heap) new_map->DictionaryMapVerify(isolate);
    9400             : #endif
    9401             : #ifdef ENABLE_SLOW_DCHECKS
    9402             :     if (FLAG_enable_slow_asserts) {
    9403             :       // The cached map should match newly created normalized map bit-by-bit,
    9404             :       // except for the code cache, which can contain some ICs which can be
    9405             :       // applied to the shared map, dependent code and weak cell cache.
    9406             :       Handle<Map> fresh = Map::CopyNormalized(isolate, fast_map, mode);
    9407             : 
    9408             :       if (new_map->is_prototype_map()) {
    9409             :         // For prototype maps, the PrototypeInfo is not copied.
    9410             :         DCHECK_EQ(0, memcmp(reinterpret_cast<void*>(fresh->address()),
    9411             :                             reinterpret_cast<void*>(new_map->address()),
    9412             :                             kTransitionsOrPrototypeInfoOffset));
    9413             :         DCHECK_EQ(fresh->raw_transitions(),
    9414             :                   MaybeObject::FromObject(Smi::kZero));
    9415             :         STATIC_ASSERT(kDescriptorsOffset ==
    9416             :                       kTransitionsOrPrototypeInfoOffset + kTaggedSize);
    9417             :         DCHECK_EQ(
    9418             :             0,
    9419             :             memcmp(
    9420             :                 HeapObject::RawField(*fresh, kDescriptorsOffset).ToVoidPtr(),
    9421             :                 HeapObject::RawField(*new_map, kDescriptorsOffset).ToVoidPtr(),
    9422             :                 kDependentCodeOffset - kDescriptorsOffset));
    9423             :       } else {
    9424             :         DCHECK_EQ(0, memcmp(reinterpret_cast<void*>(fresh->address()),
    9425             :                             reinterpret_cast<void*>(new_map->address()),
    9426             :                             Map::kDependentCodeOffset));
    9427             :       }
    9428             :       STATIC_ASSERT(Map::kPrototypeValidityCellOffset ==
    9429             :                     Map::kDependentCodeOffset + kTaggedSize);
    9430             :       int offset = Map::kPrototypeValidityCellOffset + kTaggedSize;
    9431             :       DCHECK_EQ(0, memcmp(reinterpret_cast<void*>(fresh->address() + offset),
    9432             :                           reinterpret_cast<void*>(new_map->address() + offset),
    9433             :                           Map::kSize - offset));
    9434             :     }
    9435             : #endif
    9436             :   } else {
    9437      244051 :     new_map = Map::CopyNormalized(isolate, fast_map, mode);
    9438      244052 :     if (use_cache) {
    9439      161873 :       cache->Set(fast_map, new_map);
    9440      161873 :       isolate->counters()->maps_normalized()->Increment();
    9441             :     }
    9442      244052 :     if (FLAG_trace_maps) {
    9443         844 :       LOG(isolate, MapEvent("Normalize", *fast_map, *new_map, reason));
    9444             :     }
    9445             :   }
    9446      679153 :   fast_map->NotifyLeafMapLayoutChange(isolate);
    9447      679154 :   return new_map;
    9448             : }
    9449             : 
    9450      244160 : Handle<Map> Map::CopyNormalized(Isolate* isolate, Handle<Map> map,
    9451             :                                 PropertyNormalizationMode mode) {
    9452             :   int new_instance_size = map->instance_size();
    9453      244161 :   if (mode == CLEAR_INOBJECT_PROPERTIES) {
    9454       67784 :     new_instance_size -= map->GetInObjectProperties() * kTaggedSize;
    9455             :   }
    9456             : 
    9457             :   Handle<Map> result = RawCopy(
    9458             :       isolate, map, new_instance_size,
    9459      420538 :       mode == CLEAR_INOBJECT_PROPERTIES ? 0 : map->GetInObjectProperties());
    9460             :   // Clear the unused_property_fields explicitly as this field should not
    9461             :   // be accessed for normalized maps.
    9462      244162 :   result->SetInObjectUnusedPropertyFields(0);
    9463      244162 :   result->set_is_dictionary_map(true);
    9464      244163 :   result->set_is_migration_target(false);
    9465      244161 :   result->set_may_have_interesting_symbols(true);
    9466      244163 :   result->set_construction_counter(kNoSlackTracking);
    9467             : 
    9468             : #ifdef VERIFY_HEAP
    9469             :   if (FLAG_verify_heap) result->DictionaryMapVerify(isolate);
    9470             : #endif
    9471             : 
    9472      244163 :   return result;
    9473             : }
    9474             : 
    9475             : // Return an immutable prototype exotic object version of the input map.
    9476             : // Never even try to cache it in the transition tree, as it is intended
    9477             : // for the global object and its prototype chain, and excluding it saves
    9478             : // memory on the map transition tree.
    9479             : 
    9480             : // static
    9481           6 : Handle<Map> Map::TransitionToImmutableProto(Isolate* isolate, Handle<Map> map) {
    9482           6 :   Handle<Map> new_map = Map::Copy(isolate, map, "ImmutablePrototype");
    9483           6 :   new_map->set_is_immutable_proto(true);
    9484           6 :   return new_map;
    9485             : }
    9486             : 
    9487             : namespace {
    9488             : void EnsureInitialMap(Isolate* isolate, Handle<Map> map) {
    9489             : #ifdef DEBUG
    9490             :   // Strict function maps have Function as a constructor but the
    9491             :   // Function's initial map is a sloppy function map. Same holds for
    9492             :   // GeneratorFunction / AsyncFunction and its initial map.
    9493             :   Object constructor = map->GetConstructor();
    9494             :   DCHECK(constructor->IsJSFunction());
    9495             :   DCHECK(*map == JSFunction::cast(constructor)->initial_map() ||
    9496             :          *map == *isolate->strict_function_map() ||
    9497             :          *map == *isolate->strict_function_with_name_map() ||
    9498             :          *map == *isolate->generator_function_map() ||
    9499             :          *map == *isolate->generator_function_with_name_map() ||
    9500             :          *map == *isolate->generator_function_with_home_object_map() ||
    9501             :          *map == *isolate->generator_function_with_name_and_home_object_map() ||
    9502             :          *map == *isolate->async_function_map() ||
    9503             :          *map == *isolate->async_function_with_name_map() ||
    9504             :          *map == *isolate->async_function_with_home_object_map() ||
    9505             :          *map == *isolate->async_function_with_name_and_home_object_map());
    9506             : #endif
    9507             :   // Initial maps must always own their descriptors and it's descriptor array
    9508             :   // does not contain descriptors that do not belong to the map.
    9509             :   DCHECK(map->owns_descriptors());
    9510             :   DCHECK_EQ(map->NumberOfOwnDescriptors(),
    9511             :             map->instance_descriptors()->number_of_descriptors());
    9512             : }
    9513             : }  // namespace
    9514             : 
    9515             : // static
    9516         111 : Handle<Map> Map::CopyInitialMapNormalized(Isolate* isolate, Handle<Map> map,
    9517             :                                           PropertyNormalizationMode mode) {
    9518             :   EnsureInitialMap(isolate, map);
    9519         111 :   return CopyNormalized(isolate, map, mode);
    9520             : }
    9521             : 
    9522             : // static
    9523      461357 : Handle<Map> Map::CopyInitialMap(Isolate* isolate, Handle<Map> map,
    9524             :                                 int instance_size, int inobject_properties,
    9525             :                                 int unused_property_fields) {
    9526             :   EnsureInitialMap(isolate, map);
    9527             :   Handle<Map> result =
    9528      461357 :       RawCopy(isolate, map, instance_size, inobject_properties);
    9529             : 
    9530             :   // Please note instance_type and instance_size are set when allocated.
    9531      461364 :   result->SetInObjectUnusedPropertyFields(unused_property_fields);
    9532             : 
    9533             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9534      461362 :   if (number_of_own_descriptors > 0) {
    9535             :     // The copy will use the same descriptors array.
    9536             :     result->UpdateDescriptors(isolate, map->instance_descriptors(),
    9537             :                               map->GetLayoutDescriptor(),
    9538       12726 :                               number_of_own_descriptors);
    9539             : 
    9540             :     DCHECK_EQ(result->NumberOfFields(),
    9541             :               result->GetInObjectProperties() - result->UnusedPropertyFields());
    9542             :   }
    9543             : 
    9544      461363 :   return result;
    9545             : }
    9546             : 
    9547    24189923 : Handle<Map> Map::CopyDropDescriptors(Isolate* isolate, Handle<Map> map) {
    9548             :   Handle<Map> result =
    9549             :       RawCopy(isolate, map, map->instance_size(),
    9550    72569616 :               map->IsJSObjectMap() ? map->GetInObjectProperties() : 0);
    9551             : 
    9552             :   // Please note instance_type and instance_size are set when allocated.
    9553    24189953 :   if (map->IsJSObjectMap()) {
    9554    24189731 :     result->CopyUnusedPropertyFields(*map);
    9555             :   }
    9556    24189942 :   map->NotifyLeafMapLayoutChange(isolate);
    9557    24189951 :   return result;
    9558             : }
    9559             : 
    9560     5292489 : Handle<Map> Map::ShareDescriptor(Isolate* isolate, Handle<Map> map,
    9561             :                                  Handle<DescriptorArray> descriptors,
    9562             :                                  Descriptor* descriptor) {
    9563             :   // Sanity check. This path is only to be taken if the map owns its descriptor
    9564             :   // array, implying that its NumberOfOwnDescriptors equals the number of
    9565             :   // descriptors in the descriptor array.
    9566             :   DCHECK_EQ(map->NumberOfOwnDescriptors(),
    9567             :             map->instance_descriptors()->number_of_descriptors());
    9568             : 
    9569     5292489 :   Handle<Map> result = CopyDropDescriptors(isolate, map);
    9570             :   Handle<Name> name = descriptor->GetKey();
    9571             : 
    9572             :   // Properly mark the {result} if the {name} is an "interesting symbol".
    9573     5292493 :   if (name->IsInterestingSymbol()) {
    9574          64 :     result->set_may_have_interesting_symbols(true);
    9575             :   }
    9576             : 
    9577             :   // Ensure there's space for the new descriptor in the shared descriptor array.
    9578     5292493 :   if (descriptors->number_of_slack_descriptors() == 0) {
    9579     2272874 :     int old_size = descriptors->number_of_descriptors();
    9580     2272874 :     if (old_size == 0) {
    9581             :       descriptors = DescriptorArray::Allocate(isolate, 0, 1);
    9582             :     } else {
    9583     2272504 :       int slack = SlackForArraySize(old_size, kMaxNumberOfDescriptors);
    9584     2272504 :       EnsureDescriptorSlack(isolate, map, slack);
    9585     4545014 :       descriptors = handle(map->instance_descriptors(), isolate);
    9586             :     }
    9587             :   }
    9588             : 
    9589             :   Handle<LayoutDescriptor> layout_descriptor =
    9590             :       FLAG_unbox_double_fields
    9591             :           ? LayoutDescriptor::ShareAppend(isolate, map,
    9592             :                                           descriptor->GetDetails())
    9593     5292494 :           : handle(LayoutDescriptor::FastPointerLayout(), isolate);
    9594             : 
    9595             :   {
    9596             :     DisallowHeapAllocation no_gc;
    9597     5292490 :     descriptors->Append(descriptor);
    9598     5292494 :     result->InitializeDescriptors(isolate, *descriptors, *layout_descriptor);
    9599             :   }
    9600             : 
    9601             :   DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
    9602     5292492 :   ConnectTransition(isolate, map, result, name, SIMPLE_PROPERTY_TRANSITION);
    9603             : 
    9604     5292491 :   return result;
    9605             : }
    9606             : 
    9607    14039561 : void Map::ConnectTransition(Isolate* isolate, Handle<Map> parent,
    9608             :                             Handle<Map> child, Handle<Name> name,
    9609             :                             SimpleTransitionFlag flag) {
    9610             :   DCHECK_IMPLIES(name->IsInterestingSymbol(),
    9611             :                  child->may_have_interesting_symbols());
    9612             :   DCHECK_IMPLIES(parent->may_have_interesting_symbols(),
    9613             :                  child->may_have_interesting_symbols());
    9614             :   // Do not track transitions during bootstrap except for element transitions.
    9615    21586529 :   if (isolate->bootstrapper()->IsActive() &&
    9616             :       !name.is_identical_to(isolate->factory()->elements_transition_symbol())) {
    9617     7548603 :     if (FLAG_trace_maps) {
    9618        4900 :       LOG(isolate,
    9619             :           MapEvent("Transition", *parent, *child,
    9620             :                    child->is_prototype_map() ? "prototype" : "", *name));
    9621             :     }
    9622    14036708 :     return;
    9623             :   }
    9624    12976224 :   if (!parent->GetBackPointer()->IsUndefined(isolate)) {
    9625     5529598 :     parent->set_owns_descriptors(false);
    9626             :   } else {
    9627             :     // |parent| is initial map and it must keep the ownership, there must be no
    9628             :     // descriptors in the descriptors array that do not belong to the map.
    9629             :     DCHECK(parent->owns_descriptors());
    9630             :     DCHECK_EQ(parent->NumberOfOwnDescriptors(),
    9631             :               parent->instance_descriptors()->number_of_descriptors());
    9632             :   }
    9633     6488118 :   if (parent->is_prototype_map()) {
    9634             :     DCHECK(child->is_prototype_map());
    9635           0 :     if (FLAG_trace_maps) {
    9636           0 :       LOG(isolate, MapEvent("Transition", *parent, *child, "prototype", *name));
    9637             :     }
    9638             :   } else {
    9639     6488118 :     TransitionsAccessor(isolate, parent).Insert(name, child, flag);
    9640     6488105 :     if (FLAG_trace_maps) {
    9641        4887 :       LOG(isolate, MapEvent("Transition", *parent, *child, "", *name));
    9642             :     }
    9643             :   }
    9644             : }
    9645             : 
    9646    18225476 : Handle<Map> Map::CopyReplaceDescriptors(
    9647        1408 :     Isolate* isolate, Handle<Map> map, Handle<DescriptorArray> descriptors,
    9648             :     Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
    9649             :     MaybeHandle<Name> maybe_name, const char* reason,
    9650             :     SimpleTransitionFlag simple_flag) {
    9651             :   DCHECK(descriptors->IsSortedNoDuplicates());
    9652             : 
    9653    18225476 :   Handle<Map> result = CopyDropDescriptors(isolate, map);
    9654             : 
    9655             :   // Properly mark the {result} if the {name} is an "interesting symbol".
    9656             :   Handle<Name> name;
    9657    30641025 :   if (maybe_name.ToHandle(&name) && name->IsInterestingSymbol()) {
    9658     1024987 :     result->set_may_have_interesting_symbols(true);
    9659             :   }
    9660             : 
    9661    18225498 :   if (!map->is_prototype_map()) {
    9662    43011863 :     if (flag == INSERT_TRANSITION &&
    9663    31541755 :         TransitionsAccessor(isolate, map).CanHaveMoreTransitions()) {
    9664     8602233 :       result->InitializeDescriptors(isolate, *descriptors, *layout_descriptor);
    9665             : 
    9666             :       DCHECK(!maybe_name.is_null());
    9667     8602243 :       ConnectTransition(isolate, map, result, name, simple_flag);
    9668             :     } else {
    9669     5735055 :       descriptors->GeneralizeAllFields();
    9670             :       result->InitializeDescriptors(isolate, *descriptors,
    9671     5735068 :                                     LayoutDescriptor::FastPointerLayout());
    9672             :     }
    9673             :   } else {
    9674     3888207 :     result->InitializeDescriptors(isolate, *descriptors, *layout_descriptor);
    9675             :   }
    9676    36454901 :   if (FLAG_trace_maps &&
    9677             :       // Mirror conditions above that did not call ConnectTransition().
    9678        3255 :       (map->is_prototype_map() ||
    9679             :        !(flag == INSERT_TRANSITION &&
    9680        2551 :          TransitionsAccessor(isolate, map).CanHaveMoreTransitions()))) {
    9681        3520 :     LOG(isolate, MapEvent("ReplaceDescriptors", *map, *result, reason,
    9682             :                           maybe_name.is_null() ? Name() : *name));
    9683             :   }
    9684    18225471 :   return result;
    9685             : }
    9686             : 
    9687             : 
    9688             : // Creates transition tree starting from |split_map| and adding all descriptors
    9689             : // starting from descriptor with index |split_map|.NumberOfOwnDescriptors().
    9690             : // The way how it is done is tricky because of GC and special descriptors
    9691             : // marking logic.
    9692       20791 : Handle<Map> Map::AddMissingTransitions(
    9693             :     Isolate* isolate, Handle<Map> split_map,
    9694             :     Handle<DescriptorArray> descriptors,
    9695             :     Handle<LayoutDescriptor> full_layout_descriptor) {
    9696             :   DCHECK(descriptors->IsSortedNoDuplicates());
    9697             :   int split_nof = split_map->NumberOfOwnDescriptors();
    9698       20791 :   int nof_descriptors = descriptors->number_of_descriptors();
    9699             :   DCHECK_LT(split_nof, nof_descriptors);
    9700             : 
    9701             :   // Start with creating last map which will own full descriptors array.
    9702             :   // This is necessary to guarantee that GC will mark the whole descriptor
    9703             :   // array if any of the allocations happening below fail.
    9704             :   // Number of unused properties is temporarily incorrect and the layout
    9705             :   // descriptor could unnecessarily be in slow mode but we will fix after
    9706             :   // all the other intermediate maps are created.
    9707             :   // Also the last map might have interesting symbols, we temporarily set
    9708             :   // the flag and clear it right before the descriptors are installed. This
    9709             :   // makes heap verification happy and ensures the flag ends up accurate.
    9710       20791 :   Handle<Map> last_map = CopyDropDescriptors(isolate, split_map);
    9711             :   last_map->InitializeDescriptors(isolate, *descriptors,
    9712       20791 :                                   *full_layout_descriptor);
    9713       20791 :   last_map->SetInObjectUnusedPropertyFields(0);
    9714       20791 :   last_map->set_may_have_interesting_symbols(true);
    9715             : 
    9716             :   // During creation of intermediate maps we violate descriptors sharing
    9717             :   // invariant since the last map is not yet connected to the transition tree
    9718             :   // we create here. But it is safe because GC never trims map's descriptors
    9719             :   // if there are no dead transitions from that map and this is exactly the
    9720             :   // case for all the intermediate maps we create here.
    9721             :   Handle<Map> map = split_map;
    9722       51422 :   for (int i = split_nof; i < nof_descriptors - 1; ++i) {
    9723       30631 :     Handle<Map> new_map = CopyDropDescriptors(isolate, map);
    9724             :     InstallDescriptors(isolate, map, new_map, i, descriptors,
    9725       30631 :                        full_layout_descriptor);
    9726             : 
    9727       30631 :     map = new_map;
    9728             :   }
    9729       20791 :   map->NotifyLeafMapLayoutChange(isolate);
    9730       20791 :   last_map->set_may_have_interesting_symbols(false);
    9731             :   InstallDescriptors(isolate, map, last_map, nof_descriptors - 1, descriptors,
    9732       20791 :                      full_layout_descriptor);
    9733       20791 :   return last_map;
    9734             : }
    9735             : 
    9736             : 
    9737             : // Since this method is used to rewrite an existing transition tree, it can
    9738             : // always insert transitions without checking.
    9739       51422 : void Map::InstallDescriptors(Isolate* isolate, Handle<Map> parent,
    9740             :                              Handle<Map> child, int new_descriptor,
    9741             :                              Handle<DescriptorArray> descriptors,
    9742             :                              Handle<LayoutDescriptor> full_layout_descriptor) {
    9743             :   DCHECK(descriptors->IsSortedNoDuplicates());
    9744             : 
    9745      102844 :   child->SetInstanceDescriptors(isolate, *descriptors, new_descriptor + 1);
    9746       51422 :   child->CopyUnusedPropertyFields(*parent);
    9747       51422 :   PropertyDetails details = descriptors->GetDetails(new_descriptor);
    9748       51422 :   if (details.location() == kField) {
    9749       49538 :     child->AccountAddedPropertyField();
    9750             :   }
    9751             : 
    9752             :   if (FLAG_unbox_double_fields) {
    9753             :     Handle<LayoutDescriptor> layout_descriptor =
    9754             :         LayoutDescriptor::AppendIfFastOrUseFull(isolate, parent, details,
    9755       51422 :                                                 full_layout_descriptor);
    9756       51422 :     child->set_layout_descriptor(*layout_descriptor);
    9757             : #ifdef VERIFY_HEAP
    9758             :     // TODO(ishell): remove these checks from VERIFY_HEAP mode.
    9759             :     if (FLAG_verify_heap) {
    9760             :       CHECK(child->layout_descriptor()->IsConsistentWithMap(*child));
    9761             :     }
    9762             : #else
    9763             :     SLOW_DCHECK(child->layout_descriptor()->IsConsistentWithMap(*child));
    9764             : #endif
    9765      102844 :     child->set_visitor_id(Map::GetVisitorId(*child));
    9766             :   }
    9767             : 
    9768      102844 :   Handle<Name> name = handle(descriptors->GetKey(new_descriptor), isolate);
    9769      102781 :   if (parent->may_have_interesting_symbols() || name->IsInterestingSymbol()) {
    9770         300 :     child->set_may_have_interesting_symbols(true);
    9771             :   }
    9772       51422 :   ConnectTransition(isolate, parent, child, name, SIMPLE_PROPERTY_TRANSITION);
    9773       51422 : }
    9774             : 
    9775      173297 : Handle<Map> Map::CopyAsElementsKind(Isolate* isolate, Handle<Map> map,
    9776             :                                     ElementsKind kind, TransitionFlag flag) {
    9777             :   // Only certain objects are allowed to have non-terminal fast transitional
    9778             :   // elements kinds.
    9779             :   DCHECK(map->IsJSObjectMap());
    9780             :   DCHECK_IMPLIES(
    9781             :       !map->CanHaveFastTransitionableElementsKind(),
    9782             :       IsDictionaryElementsKind(kind) || IsTerminalElementsKind(kind));
    9783             : 
    9784             :   Map maybe_elements_transition_map;
    9785      173297 :   if (flag == INSERT_TRANSITION) {
    9786             :     // Ensure we are requested to add elements kind transition "near the root".
    9787             :     DCHECK_EQ(map->FindRootMap(isolate)->NumberOfOwnDescriptors(),
    9788             :               map->NumberOfOwnDescriptors());
    9789             : 
    9790      171483 :     maybe_elements_transition_map = map->ElementsTransitionMap();
    9791             :     DCHECK(maybe_elements_transition_map.is_null() ||
    9792             :            (maybe_elements_transition_map->elements_kind() ==
    9793             :                 DICTIONARY_ELEMENTS &&
    9794             :             kind == DICTIONARY_ELEMENTS));
    9795             :     DCHECK(!IsFastElementsKind(kind) ||
    9796             :            IsMoreGeneralElementsKindTransition(map->elements_kind(), kind));
    9797             :     DCHECK(kind != map->elements_kind());
    9798             :   }
    9799             : 
    9800             :   bool insert_transition =
    9801      171483 :       flag == INSERT_TRANSITION &&
    9802      435227 :       TransitionsAccessor(isolate, map).CanHaveMoreTransitions() &&
    9803        1814 :       maybe_elements_transition_map.is_null();
    9804             : 
    9805      173297 :   if (insert_transition) {
    9806       90447 :     Handle<Map> new_map = CopyForElementsTransition(isolate, map);
    9807      180894 :     new_map->set_elements_kind(kind);
    9808             : 
    9809             :     Handle<Name> name = isolate->factory()->elements_transition_symbol();
    9810       90447 :     ConnectTransition(isolate, map, new_map, name, SPECIAL_TRANSITION);
    9811       90447 :     return new_map;
    9812             :   }
    9813             : 
    9814             :   // Create a new free-floating map only if we are not allowed to store it.
    9815       82850 :   Handle<Map> new_map = Copy(isolate, map, "CopyAsElementsKind");
    9816      165700 :   new_map->set_elements_kind(kind);
    9817       82850 :   return new_map;
    9818             : }
    9819             : 
    9820         671 : Handle<Map> Map::AsLanguageMode(Isolate* isolate, Handle<Map> initial_map,
    9821             :                                 Handle<SharedFunctionInfo> shared_info) {
    9822             :   DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
    9823             :   // Initial map for sloppy mode function is stored in the function
    9824             :   // constructor. Initial maps for strict mode are cached as special transitions
    9825             :   // using |strict_function_transition_symbol| as a key.
    9826         671 :   if (is_sloppy(shared_info->language_mode())) return initial_map;
    9827             : 
    9828         459 :   Handle<Map> function_map(Map::cast(isolate->native_context()->get(
    9829             :                                shared_info->function_map_index())),
    9830         306 :                            isolate);
    9831             : 
    9832             :   STATIC_ASSERT(LanguageModeSize == 2);
    9833             :   DCHECK_EQ(LanguageMode::kStrict, shared_info->language_mode());
    9834             :   Handle<Symbol> transition_symbol =
    9835             :       isolate->factory()->strict_function_transition_symbol();
    9836             :   Map maybe_transition = TransitionsAccessor(isolate, initial_map)
    9837         153 :                              .SearchSpecial(*transition_symbol);
    9838         153 :   if (!maybe_transition.is_null()) {
    9839             :     return handle(maybe_transition, isolate);
    9840             :   }
    9841         117 :   initial_map->NotifyLeafMapLayoutChange(isolate);
    9842             : 
    9843             :   // Create new map taking descriptors from the |function_map| and all
    9844             :   // the other details from the |initial_map|.
    9845             :   Handle<Map> map =
    9846             :       Map::CopyInitialMap(isolate, function_map, initial_map->instance_size(),
    9847             :                           initial_map->GetInObjectProperties(),
    9848         351 :                           initial_map->UnusedPropertyFields());
    9849         234 :   map->SetConstructor(initial_map->GetConstructor());
    9850         117 :   map->set_prototype(initial_map->prototype());
    9851         117 :   map->set_construction_counter(initial_map->construction_counter());
    9852             : 
    9853         117 :   if (TransitionsAccessor(isolate, initial_map).CanHaveMoreTransitions()) {
    9854             :     Map::ConnectTransition(isolate, initial_map, map, transition_symbol,
    9855         117 :                            SPECIAL_TRANSITION);
    9856             :   }
    9857         117 :   return map;
    9858             : }
    9859             : 
    9860       90447 : Handle<Map> Map::CopyForElementsTransition(Isolate* isolate, Handle<Map> map) {
    9861             :   DCHECK(!map->is_prototype_map());
    9862       90447 :   Handle<Map> new_map = CopyDropDescriptors(isolate, map);
    9863             : 
    9864       90447 :   if (map->owns_descriptors()) {
    9865             :     // In case the map owned its own descriptors, share the descriptors and
    9866             :     // transfer ownership to the new map.
    9867             :     // The properties did not change, so reuse descriptors.
    9868             :     new_map->InitializeDescriptors(isolate, map->instance_descriptors(),
    9869      271167 :                                    map->GetLayoutDescriptor());
    9870             :   } else {
    9871             :     // In case the map did not own its own descriptors, a split is forced by
    9872             :     // copying the map; creating a new descriptor array cell.
    9873         116 :     Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    9874             :     int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9875             :     Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
    9876             :         isolate, descriptors, number_of_own_descriptors);
    9877             :     Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9878         116 :                                                    isolate);
    9879             :     new_map->InitializeDescriptors(isolate, *new_descriptors,
    9880          58 :                                    *new_layout_descriptor);
    9881             :   }
    9882       90447 :   return new_map;
    9883             : }
    9884             : 
    9885     5788758 : Handle<Map> Map::Copy(Isolate* isolate, Handle<Map> map, const char* reason) {
    9886    11577535 :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    9887             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9888             :   Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
    9889     5788757 :       isolate, descriptors, number_of_own_descriptors);
    9890             :   Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9891    11577525 :                                                  isolate);
    9892             :   return CopyReplaceDescriptors(
    9893             :       isolate, map, new_descriptors, new_layout_descriptor, OMIT_TRANSITION,
    9894     5788763 :       MaybeHandle<Name>(), reason, SPECIAL_TRANSITION);
    9895             : }
    9896             : 
    9897             : 
    9898       94202 : Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
    9899             :   Handle<Map> copy =
    9900      188407 :       Copy(isolate, handle(isolate->object_function()->initial_map(), isolate),
    9901      188408 :            "MapCreate");
    9902             : 
    9903             :   // Check that we do not overflow the instance size when adding the extra
    9904             :   // inobject properties. If the instance size overflows, we allocate as many
    9905             :   // properties as we can as inobject properties.
    9906       94205 :   if (inobject_properties > JSObject::kMaxInObjectProperties) {
    9907             :     inobject_properties = JSObject::kMaxInObjectProperties;
    9908             :   }
    9909             : 
    9910             :   int new_instance_size =
    9911       94205 :       JSObject::kHeaderSize + kTaggedSize * inobject_properties;
    9912             : 
    9913             :   // Adjust the map with the extra inobject properties.
    9914       94205 :   copy->set_instance_size(new_instance_size);
    9915       94205 :   copy->SetInObjectPropertiesStartInWords(JSObject::kHeaderSize / kTaggedSize);
    9916             :   DCHECK_EQ(copy->GetInObjectProperties(), inobject_properties);
    9917       94205 :   copy->SetInObjectUnusedPropertyFields(inobject_properties);
    9918      188410 :   copy->set_visitor_id(Map::GetVisitorId(*copy));
    9919       94204 :   return copy;
    9920             : }
    9921             : 
    9922      150805 : Handle<Map> Map::CopyForPreventExtensions(Isolate* isolate, Handle<Map> map,
    9923             :                                           PropertyAttributes attrs_to_add,
    9924             :                                           Handle<Symbol> transition_marker,
    9925             :                                           const char* reason) {
    9926             :   int num_descriptors = map->NumberOfOwnDescriptors();
    9927             :   Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
    9928             :       isolate, handle(map->instance_descriptors(), isolate), num_descriptors,
    9929      301625 :       attrs_to_add);
    9930             :   Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9931      301621 :                                                  isolate);
    9932             :   Handle<Map> new_map = CopyReplaceDescriptors(
    9933             :       isolate, map, new_desc, new_layout_descriptor, INSERT_TRANSITION,
    9934      150807 :       transition_marker, reason, SPECIAL_TRANSITION);
    9935             :   new_map->set_is_extensible(false);
    9936      150814 :   if (!IsFixedTypedArrayElementsKind(map->elements_kind())) {
    9937             :     ElementsKind new_kind = IsStringWrapperElementsKind(map->elements_kind())
    9938             :                                 ? SLOW_STRING_WRAPPER_ELEMENTS
    9939      150764 :                                 : DICTIONARY_ELEMENTS;
    9940      301524 :     new_map->set_elements_kind(new_kind);
    9941             :   }
    9942      150810 :   return new_map;
    9943             : }
    9944             : 
    9945             : namespace {
    9946             : 
    9947     6519392 : bool CanHoldValue(DescriptorArray descriptors, int descriptor,
    9948             :                   PropertyConstness constness, Object value) {
    9949     6519392 :   PropertyDetails details = descriptors->GetDetails(descriptor);
    9950     6519392 :   if (details.location() == kField) {
    9951     6503570 :     if (details.kind() == kData) {
    9952     6503569 :       return IsGeneralizableTo(constness, details.constness()) &&
    9953    19286655 :              value->FitsRepresentation(details.representation()) &&
    9954    12783086 :              descriptors->GetFieldType(descriptor)->NowContains(value);
    9955             :     } else {
    9956             :       DCHECK_EQ(kAccessor, details.kind());
    9957             :       return false;
    9958             :     }
    9959             : 
    9960             :   } else {
    9961             :     DCHECK_EQ(kDescriptor, details.location());
    9962             :     DCHECK_EQ(PropertyConstness::kConst, details.constness());
    9963       15822 :     if (details.kind() == kData) {
    9964             :       DCHECK(!FLAG_track_constant_fields);
    9965             :       DCHECK(descriptors->GetStrongValue(descriptor) != value ||
    9966             :              value->FitsRepresentation(details.representation()));
    9967       31644 :       return descriptors->GetStrongValue(descriptor) == value;
    9968             :     } else {
    9969             :       DCHECK_EQ(kAccessor, details.kind());
    9970             :       return false;
    9971             :     }
    9972             :   }
    9973             :   UNREACHABLE();
    9974             : }
    9975             : 
    9976     6519392 : Handle<Map> UpdateDescriptorForValue(Isolate* isolate, Handle<Map> map,
    9977             :                                      int descriptor,
    9978             :                                      PropertyConstness constness,
    9979             :                                      Handle<Object> value) {
    9980    13038789 :   if (CanHoldValue(map->instance_descriptors(), descriptor, constness,
    9981    13038788 :                    *value)) {
    9982     6256620 :     return map;
    9983             :   }
    9984             : 
    9985             :   PropertyAttributes attributes =
    9986      525548 :       map->instance_descriptors()->GetDetails(descriptor).attributes();
    9987      262774 :   Representation representation = value->OptimalRepresentation();
    9988      262776 :   Handle<FieldType> type = value->OptimalType(isolate, representation);
    9989             : 
    9990      262774 :   MapUpdater mu(isolate, map);
    9991             :   return mu.ReconfigureToDataField(descriptor, attributes, constness,
    9992      262777 :                                    representation, type);
    9993             : }
    9994             : 
    9995             : }  // namespace
    9996             : 
    9997             : // static
    9998     1218767 : Handle<Map> Map::PrepareForDataProperty(Isolate* isolate, Handle<Map> map,
    9999             :                                         int descriptor,
   10000             :                                         PropertyConstness constness,
   10001             :                                         Handle<Object> value) {
   10002             :   // Dictionaries can store any property value.
   10003             :   DCHECK(!map->is_dictionary_map());
   10004             :   // Update to the newest map before storing the property.
   10005             :   return UpdateDescriptorForValue(isolate, Update(isolate, map), descriptor,
   10006     1218767 :                                   constness, value);
   10007             : }
   10008             : 
   10009    22368830 : Handle<Map> Map::TransitionToDataProperty(Isolate* isolate, Handle<Map> map,
   10010             :                                           Handle<Name> name,
   10011             :                                           Handle<Object> value,
   10012             :                                           PropertyAttributes attributes,
   10013             :                                           PropertyConstness constness,
   10014             :                                           StoreOrigin store_origin) {
   10015             :   RuntimeCallTimerScope stats_scope(
   10016             :       isolate, *map,
   10017             :       map->is_prototype_map()
   10018             :           ? RuntimeCallCounterId::kPrototypeMap_TransitionToDataProperty
   10019    22368839 :           : RuntimeCallCounterId::kMap_TransitionToDataProperty);
   10020             : 
   10021             :   DCHECK(name->IsUniqueName());
   10022             :   DCHECK(!map->is_dictionary_map());
   10023             : 
   10024             :   // Migrate to the newest map before storing the property.
   10025    22368828 :   map = Update(isolate, map);
   10026             : 
   10027             :   Map maybe_transition = TransitionsAccessor(isolate, map)
   10028    22368836 :                              .SearchTransition(*name, kData, attributes);
   10029    22368834 :   if (!maybe_transition.is_null()) {
   10030             :     Handle<Map> transition(maybe_transition, isolate);
   10031     5300628 :     int descriptor = transition->LastAdded();
   10032             : 
   10033             :     DCHECK_EQ(attributes, transition->instance_descriptors()
   10034             :                               ->GetDetails(descriptor)
   10035             :                               .attributes());
   10036             : 
   10037             :     return UpdateDescriptorForValue(isolate, transition, descriptor, constness,
   10038     5300628 :                                     value);
   10039             :   }
   10040             : 
   10041             :   TransitionFlag flag = INSERT_TRANSITION;
   10042             :   MaybeHandle<Map> maybe_map;
   10043    17068203 :   if (!map->TooManyFastProperties(store_origin)) {
   10044    34085399 :     if (!FLAG_track_constant_fields && value->IsJSFunction()) {
   10045             :       maybe_map =
   10046     9768746 :           Map::CopyWithConstant(isolate, map, name, value, attributes, flag);
   10047             :     } else {
   10048     7273953 :       Representation representation = value->OptimalRepresentation();
   10049     7273951 :       Handle<FieldType> type = value->OptimalType(isolate, representation);
   10050             :       maybe_map = Map::CopyWithField(isolate, map, name, type, attributes,
   10051     7273942 :                                      constness, representation, flag);
   10052             :     }
   10053             :   }
   10054             : 
   10055             :   Handle<Map> result;
   10056    17068192 :   if (!maybe_map.ToHandle(&result)) {
   10057             :     const char* reason = "TooManyFastProperties";
   10058             : #if V8_TRACE_MAPS
   10059             :     std::unique_ptr<ScopedVector<char>> buffer;
   10060             :     if (FLAG_trace_maps) {
   10061             :       ScopedVector<char> name_buffer(100);
   10062             :       name->NameShortPrint(name_buffer);
   10063             :       buffer.reset(new ScopedVector<char>(128));
   10064             :       SNPrintF(*buffer, "TooManyFastProperties %s", name_buffer.start());
   10065             :       reason = buffer->start();
   10066             :     }
   10067             : #endif
   10068       51230 :     Handle<Object> maybe_constructor(map->GetConstructor(), isolate);
   10069       25615 :     if (FLAG_feedback_normalization && map->new_target_is_base() &&
   10070       51230 :         maybe_constructor->IsJSFunction() &&
   10071       25615 :         !JSFunction::cast(*maybe_constructor)->shared()->native()) {
   10072             :       Handle<JSFunction> constructor =
   10073           0 :           Handle<JSFunction>::cast(maybe_constructor);
   10074             :       DCHECK_NE(*constructor,
   10075             :                 constructor->context()->native_context()->object_function());
   10076           0 :       Handle<Map> initial_map(constructor->initial_map(), isolate);
   10077             :       result = Map::Normalize(isolate, initial_map, CLEAR_INOBJECT_PROPERTIES,
   10078           0 :                               reason);
   10079           0 :       initial_map->DeprecateTransitionTree(isolate);
   10080             :       Handle<Object> prototype(result->prototype(), isolate);
   10081           0 :       JSFunction::SetInitialMap(constructor, result, prototype);
   10082             : 
   10083             :       // Deoptimize all code that embeds the previous initial map.
   10084           0 :       initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
   10085           0 :           isolate, DependentCode::kInitialMapChangedGroup);
   10086           0 :       if (!result->EquivalentToForNormalization(*map,
   10087           0 :                                                 CLEAR_INOBJECT_PROPERTIES)) {
   10088             :         result =
   10089           0 :             Map::Normalize(isolate, map, CLEAR_INOBJECT_PROPERTIES, reason);
   10090             :       }
   10091             :     } else {
   10092       25615 :       result = Map::Normalize(isolate, map, CLEAR_INOBJECT_PROPERTIES, reason);
   10093             :     }
   10094             :   }
   10095             : 
   10096    17068192 :   return result;
   10097             : }
   10098             : 
   10099       16455 : Handle<Map> Map::ReconfigureExistingProperty(Isolate* isolate, Handle<Map> map,
   10100             :                                              int descriptor, PropertyKind kind,
   10101             :                                              PropertyAttributes attributes) {
   10102             :   // Dictionaries have to be reconfigured in-place.
   10103             :   DCHECK(!map->is_dictionary_map());
   10104             : 
   10105       32910 :   if (!map->GetBackPointer()->IsMap()) {
   10106             :     // There is no benefit from reconstructing transition tree for maps without
   10107             :     // back pointers.
   10108             :     return CopyGeneralizeAllFields(isolate, map, map->elements_kind(),
   10109             :                                    descriptor, kind, attributes,
   10110        1242 :                                    "GenAll_AttributesMismatchProtoMap");
   10111             :   }
   10112             : 
   10113       15213 :   if (FLAG_trace_generalization) {
   10114           0 :     map->PrintReconfiguration(isolate, stdout, descriptor, kind, attributes);
   10115             :   }
   10116             : 
   10117       15213 :   MapUpdater mu(isolate, map);
   10118             :   DCHECK_EQ(kData, kind);  // Only kData case is supported so far.
   10119             :   Handle<Map> new_map = mu.ReconfigureToDataField(
   10120             :       descriptor, attributes, kDefaultFieldConstness, Representation::None(),
   10121       15213 :       FieldType::None(isolate));
   10122       15213 :   return new_map;
   10123             : }
   10124             : 
   10125      727735 : Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
   10126             :                                               Handle<Name> name, int descriptor,
   10127             :                                               Handle<Object> getter,
   10128             :                                               Handle<Object> setter,
   10129             :                                               PropertyAttributes attributes) {
   10130             :   RuntimeCallTimerScope stats_scope(
   10131             :       isolate,
   10132             :       map->is_prototype_map()
   10133             :           ? RuntimeCallCounterId::kPrototypeMap_TransitionToAccessorProperty
   10134      727735 :           : RuntimeCallCounterId::kMap_TransitionToAccessorProperty);
   10135             : 
   10136             :   // At least one of the accessors needs to be a new value.
   10137             :   DCHECK(!getter->IsNull(isolate) || !setter->IsNull(isolate));
   10138             :   DCHECK(name->IsUniqueName());
   10139             : 
   10140             :   // Dictionary maps can always have additional data properties.
   10141      727735 :   if (map->is_dictionary_map()) return map;
   10142             : 
   10143             :   // Migrate to the newest map before transitioning to the new property.
   10144      727735 :   map = Update(isolate, map);
   10145             : 
   10146             :   PropertyNormalizationMode mode = map->is_prototype_map()
   10147             :                                        ? KEEP_INOBJECT_PROPERTIES
   10148      727736 :                                        : CLEAR_INOBJECT_PROPERTIES;
   10149             : 
   10150             :   Map maybe_transition = TransitionsAccessor(isolate, map)
   10151      727736 :                              .SearchTransition(*name, kAccessor, attributes);
   10152      727735 :   if (!maybe_transition.is_null()) {
   10153             :     Handle<Map> transition(maybe_transition, isolate);
   10154       12135 :     DescriptorArray descriptors = transition->instance_descriptors();
   10155       12135 :     int descriptor = transition->LastAdded();
   10156             :     DCHECK(descriptors->GetKey(descriptor)->Equals(*name));
   10157             : 
   10158             :     DCHECK_EQ(kAccessor, descriptors->GetDetails(descriptor).kind());
   10159             :     DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes());
   10160             : 
   10161       12135 :     Handle<Object> maybe_pair(descriptors->GetStrongValue(descriptor), isolate);
   10162       24270 :     if (!maybe_pair->IsAccessorPair()) {
   10163             :       return Map::Normalize(isolate, map, mode,
   10164           0 :                             "TransitionToAccessorFromNonPair");
   10165             :     }
   10166             : 
   10167       12135 :     Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair);
   10168       12135 :     if (!pair->Equals(*getter, *setter)) {
   10169             :       return Map::Normalize(isolate, map, mode,
   10170       11602 :                             "TransitionToDifferentAccessor");
   10171             :     }
   10172             : 
   10173         533 :     return transition;
   10174             :   }
   10175             : 
   10176             :   Handle<AccessorPair> pair;
   10177      715600 :   DescriptorArray old_descriptors = map->instance_descriptors();
   10178      715600 :   if (descriptor != DescriptorArray::kNotFound) {
   10179      219444 :     if (descriptor != map->LastAdded()) {
   10180      117369 :       return Map::Normalize(isolate, map, mode, "AccessorsOverwritingNonLast");
   10181             :     }
   10182      102075 :     PropertyDetails old_details = old_descriptors->GetDetails(descriptor);
   10183      102075 :     if (old_details.kind() != kAccessor) {
   10184             :       return Map::Normalize(isolate, map, mode,
   10185      100395 :                             "AccessorsOverwritingNonAccessors");
   10186             :     }
   10187             : 
   10188        1680 :     if (old_details.attributes() != attributes) {
   10189          81 :       return Map::Normalize(isolate, map, mode, "AccessorsWithAttributes");
   10190             :     }
   10191             : 
   10192             :     Handle<Object> maybe_pair(old_descriptors->GetStrongValue(descriptor),
   10193        1599 :                               isolate);
   10194        3198 :     if (!maybe_pair->IsAccessorPair()) {
   10195          24 :       return Map::Normalize(isolate, map, mode, "AccessorsOverwritingNonPair");
   10196             :     }
   10197             : 
   10198        1575 :     Handle<AccessorPair> current_pair = Handle<AccessorPair>::cast(maybe_pair);
   10199        1575 :     if (current_pair->Equals(*getter, *setter)) return map;
   10200             : 
   10201             :     bool overwriting_accessor = false;
   10202        4711 :     if (!getter->IsNull(isolate) &&
   10203        6182 :         !current_pair->get(ACCESSOR_GETTER)->IsNull(isolate) &&
   10204        3046 :         current_pair->get(ACCESSOR_GETTER) != *getter) {
   10205             :       overwriting_accessor = true;
   10206             :     }
   10207        4716 :     if (!setter->IsNull(isolate) &&
   10208        5892 :         !current_pair->get(ACCESSOR_SETTER)->IsNull(isolate) &&
   10209        2751 :         current_pair->get(ACCESSOR_SETTER) != *setter) {
   10210             :       overwriting_accessor = true;
   10211             :     }
   10212        1575 :     if (overwriting_accessor) {
   10213             :       return Map::Normalize(isolate, map, mode,
   10214        1392 :                             "AccessorsOverwritingAccessors");
   10215             :     }
   10216             : 
   10217         183 :     pair = AccessorPair::Copy(isolate, Handle<AccessorPair>::cast(maybe_pair));
   10218     1488470 :   } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors ||
   10219      992313 :              map->TooManyFastProperties(StoreOrigin::kNamed)) {
   10220             :     return Map::Normalize(isolate, map, CLEAR_INOBJECT_PROPERTIES,
   10221           0 :                           "TooManyAccessors");
   10222             :   } else {
   10223      496157 :     pair = isolate->factory()->NewAccessorPair();
   10224             :   }
   10225             : 
   10226      496340 :   pair->SetComponents(*getter, *setter);
   10227             : 
   10228             :   TransitionFlag flag = INSERT_TRANSITION;
   10229      496340 :   Descriptor d = Descriptor::AccessorConstant(name, pair, attributes);
   10230      496339 :   return Map::CopyInsertDescriptor(isolate, map, &d, flag);
   10231             : }
   10232             : 
   10233    17557024 : Handle<Map> Map::CopyAddDescriptor(Isolate* isolate, Handle<Map> map,
   10234             :                                    Descriptor* descriptor,
   10235             :                                    TransitionFlag flag) {
   10236    35114067 :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
   10237             : 
   10238             :   // Share descriptors only if map owns descriptors and it not an initial map.
   10239    52622625 :   if (flag == INSERT_TRANSITION && map->owns_descriptors() &&
   10240    57915316 :       !map->GetBackPointer()->IsUndefined(isolate) &&
   10241    22849537 :       TransitionsAccessor(isolate, map).CanHaveMoreTransitions()) {
   10242     5292494 :     return ShareDescriptor(isolate, map, descriptors, descriptor);
   10243             :   }
   10244             : 
   10245             :   int nof = map->NumberOfOwnDescriptors();
   10246             :   Handle<DescriptorArray> new_descriptors =
   10247             :       DescriptorArray::CopyUpTo(isolate, descriptors, nof, 1);
   10248    12264545 :   new_descriptors->Append(descriptor);
   10249             : 
   10250             :   Handle<LayoutDescriptor> new_layout_descriptor =
   10251             :       FLAG_unbox_double_fields
   10252    12264560 :           ? LayoutDescriptor::New(isolate, map, new_descriptors, nof + 1)
   10253    12264560 :           : handle(LayoutDescriptor::FastPointerLayout(), isolate);
   10254             : 
   10255             :   return CopyReplaceDescriptors(
   10256             :       isolate, map, new_descriptors, new_layout_descriptor, flag,
   10257    12264556 :       descriptor->GetKey(), "CopyAddDescriptor", SIMPLE_PROPERTY_TRANSITION);
   10258             : }
   10259             : 
   10260      496379 : Handle<Map> Map::CopyInsertDescriptor(Isolate* isolate, Handle<Map> map,
   10261             :                                       Descriptor* descriptor,
   10262             :                                       TransitionFlag flag) {
   10263      992758 :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
   10264             : 
   10265             :   // We replace the key if it is already present.
   10266             :   int index =
   10267      992758 :       old_descriptors->SearchWithCache(isolate, *descriptor->GetKey(), *map);
   10268      496379 :   if (index != DescriptorArray::kNotFound) {
   10269             :     return CopyReplaceDescriptor(isolate, map, old_descriptors, descriptor,
   10270         183 :                                  index, flag);
   10271             :   }
   10272      496196 :   return CopyAddDescriptor(isolate, map, descriptor, flag);
   10273             : }
   10274             : 
   10275           0 : Handle<DescriptorArray> DescriptorArray::CopyUpTo(Isolate* isolate,
   10276             :                                                   Handle<DescriptorArray> desc,
   10277             :                                                   int enumeration_index,
   10278             :                                                   int slack) {
   10279             :   return DescriptorArray::CopyUpToAddAttributes(isolate, desc,
   10280    20351929 :                                                 enumeration_index, NONE, slack);
   10281             : }
   10282             : 
   10283    20502704 : Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
   10284             :     Isolate* isolate, Handle<DescriptorArray> desc, int enumeration_index,
   10285             :     PropertyAttributes attributes, int slack) {
   10286    20502704 :   if (enumeration_index + slack == 0) {
   10287             :     return isolate->factory()->empty_descriptor_array();
   10288             :   }
   10289             : 
   10290             :   int size = enumeration_index;
   10291             : 
   10292             :   Handle<DescriptorArray> descriptors =
   10293             :       DescriptorArray::Allocate(isolate, size, slack);
   10294             : 
   10295    19031287 :   if (attributes != NONE) {
   10296      245838 :     for (int i = 0; i < size; ++i) {
   10297      491671 :       MaybeObject value_or_field_type = desc->GetValue(i);
   10298      245836 :       Name key = desc->GetKey(i);
   10299      245834 :       PropertyDetails details = desc->GetDetails(i);
   10300             :       // Bulk attribute changes never affect private properties.
   10301      245836 :       if (!key->IsPrivate()) {
   10302             :         int mask = DONT_DELETE | DONT_ENUM;
   10303             :         // READ_ONLY is an invalid attribute for JS setters/getters.
   10304      245801 :         HeapObject heap_object;
   10305      492564 :         if (details.kind() != kAccessor ||
   10306         962 :             !(value_or_field_type->GetHeapObjectIfStrong(&heap_object) &&
   10307         962 :               heap_object->IsAccessorPair())) {
   10308             :           mask |= READ_ONLY;
   10309             :         }
   10310             :         details = details.CopyAddAttributes(
   10311      245801 :             static_cast<PropertyAttributes>(attributes & mask));
   10312             :       }
   10313      245838 :       descriptors->Set(i, key, value_or_field_type, details);
   10314             :     }
   10315             :   } else {
   10316   119354566 :     for (int i = 0; i < size; ++i) {
   10317   119354509 :       descriptors->CopyFrom(i, *desc);
   10318             :     }
   10319             :   }
   10320             : 
   10321    19083527 :   if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort();
   10322             : 
   10323    19031305 :   return descriptors;
   10324             : }
   10325             : 
   10326             : // Create a new descriptor array with only enumerable, configurable, writeable
   10327             : // data properties, but identical field locations.
   10328         261 : Handle<DescriptorArray> DescriptorArray::CopyForFastObjectClone(
   10329             :     Isolate* isolate, Handle<DescriptorArray> src, int enumeration_index,
   10330             :     int slack) {
   10331         261 :   if (enumeration_index + slack == 0) {
   10332             :     return isolate->factory()->empty_descriptor_array();
   10333             :   }
   10334             : 
   10335             :   int size = enumeration_index;
   10336             :   Handle<DescriptorArray> descriptors =
   10337             :       DescriptorArray::Allocate(isolate, size, slack);
   10338             : 
   10339         711 :   for (int i = 0; i < size; ++i) {
   10340         450 :     Name key = src->GetKey(i);
   10341         450 :     PropertyDetails details = src->GetDetails(i);
   10342             : 
   10343             :     DCHECK(!key->IsPrivateName());
   10344             :     DCHECK(details.IsEnumerable());
   10345             :     DCHECK_EQ(details.kind(), kData);
   10346             : 
   10347             :     // Ensure the ObjectClone property details are NONE, and that all source
   10348             :     // details did not contain DONT_ENUM.
   10349             :     PropertyDetails new_details(kData, NONE, details.location(),
   10350             :                                 details.constness(), details.representation(),
   10351             :                                 details.field_index());
   10352             :     // Do not propagate the field type of normal object fields from the
   10353             :     // original descriptors since FieldType changes don't create new maps.
   10354         900 :     MaybeObject type = src->GetValue(i);
   10355         450 :     if (details.location() == PropertyLocation::kField) {
   10356         414 :       type = MaybeObject::FromObject(FieldType::Any());
   10357             :     }
   10358         450 :     descriptors->Set(i, key, type, new_details);
   10359             :   }
   10360             : 
   10361         261 :   descriptors->Sort();
   10362             : 
   10363         261 :   return descriptors;
   10364             : }
   10365             : 
   10366        2012 : bool DescriptorArray::IsEqualUpTo(DescriptorArray desc, int nof_descriptors) {
   10367       26977 :   for (int i = 0; i < nof_descriptors; i++) {
   10368       74895 :     if (GetKey(i) != desc->GetKey(i) || GetValue(i) != desc->GetValue(i)) {
   10369             :       return false;
   10370             :     }
   10371       24965 :     PropertyDetails details = GetDetails(i);
   10372       24965 :     PropertyDetails other_details = desc->GetDetails(i);
   10373       49930 :     if (details.kind() != other_details.kind() ||
   10374       49930 :         details.location() != other_details.location() ||
   10375             :         !details.representation().Equals(other_details.representation())) {
   10376             :       return false;
   10377             :     }
   10378             :   }
   10379             :   return true;
   10380             : }
   10381             : 
   10382         183 : Handle<Map> Map::CopyReplaceDescriptor(Isolate* isolate, Handle<Map> map,
   10383             :                                        Handle<DescriptorArray> descriptors,
   10384             :                                        Descriptor* descriptor,
   10385             :                                        int insertion_index,
   10386             :                                        TransitionFlag flag) {
   10387             :   Handle<Name> key = descriptor->GetKey();
   10388             :   DCHECK_EQ(*key, descriptors->GetKey(insertion_index));
   10389             :   // This function does not support replacing property fields as
   10390             :   // that would break property field counters.
   10391             :   DCHECK_NE(kField, descriptor->GetDetails().location());
   10392             :   DCHECK_NE(kField, descriptors->GetDetails(insertion_index).location());
   10393             : 
   10394             :   Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
   10395             :       isolate, descriptors, map->NumberOfOwnDescriptors());
   10396             : 
   10397         183 :   new_descriptors->Replace(insertion_index, descriptor);
   10398             :   Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New(
   10399         183 :       isolate, map, new_descriptors, new_descriptors->number_of_descriptors());
   10400             : 
   10401             :   SimpleTransitionFlag simple_flag =
   10402         183 :       (insertion_index == descriptors->number_of_descriptors() - 1)
   10403             :           ? SIMPLE_PROPERTY_TRANSITION
   10404         183 :           : PROPERTY_TRANSITION;
   10405             :   return CopyReplaceDescriptors(isolate, map, new_descriptors,
   10406             :                                 new_layout_descriptor, flag, key,
   10407         183 :                                 "CopyReplaceDescriptor", simple_flag);
   10408             : }
   10409             : 
   10410     9873311 : Handle<FixedArray> FixedArray::SetAndGrow(Isolate* isolate,
   10411             :                                           Handle<FixedArray> array, int index,
   10412             :                                           Handle<Object> value,
   10413             :                                           PretenureFlag pretenure) {
   10414     9873311 :   if (index < array->length()) {
   10415     9348246 :     array->set(index, *value);
   10416     9348244 :     return array;
   10417             :   }
   10418             :   int capacity = array->length();
   10419      525065 :   do {
   10420     1050130 :     capacity = JSObject::NewElementsCapacity(capacity);
   10421             :   } while (capacity <= index);
   10422             :   Handle<FixedArray> new_array =
   10423      525065 :       isolate->factory()->NewUninitializedFixedArray(capacity, pretenure);
   10424      525065 :   array->CopyTo(0, *new_array, 0, array->length());
   10425     1050129 :   new_array->FillWithHoles(array->length(), new_array->length());
   10426      525065 :   new_array->set(index, *value);
   10427      525065 :   return new_array;
   10428             : }
   10429             : 
   10430           0 : bool FixedArray::ContainsSortedNumbers() {
   10431           0 :   for (int i = 1; i < length(); ++i) {
   10432           0 :     Object a_obj = get(i - 1);
   10433           0 :     Object b_obj = get(i);
   10434           0 :     if (!a_obj->IsNumber() || !b_obj->IsNumber()) return false;
   10435             : 
   10436           0 :     uint32_t a = NumberToUint32(a_obj);
   10437           0 :     uint32_t b = NumberToUint32(b_obj);
   10438             : 
   10439           0 :     if (a > b) return false;
   10440             :   }
   10441             :   return true;
   10442             : }
   10443             : 
   10444      846686 : Handle<FixedArray> FixedArray::ShrinkOrEmpty(Isolate* isolate,
   10445             :                                              Handle<FixedArray> array,
   10446             :                                              int new_length) {
   10447      846686 :   if (new_length == 0) {
   10448      194782 :     return array->GetReadOnlyRoots().empty_fixed_array_handle();
   10449             :   } else {
   10450      749296 :     array->Shrink(isolate, new_length);
   10451      749296 :     return array;
   10452             :   }
   10453             : }
   10454             : 
   10455     2003377 : void FixedArray::Shrink(Isolate* isolate, int new_length) {
   10456             :   DCHECK(0 < new_length && new_length <= length());
   10457     2003377 :   if (new_length < length()) {
   10458     1362518 :     isolate->heap()->RightTrimFixedArray(*this, length() - new_length);
   10459             :   }
   10460     2003377 : }
   10461             : 
   10462      545297 : void FixedArray::CopyTo(int pos, FixedArray dest, int dest_pos, int len) const {
   10463             :   DisallowHeapAllocation no_gc;
   10464             :   // Return early if len == 0 so that we don't try to read the write barrier off
   10465             :   // a canonical read-only empty fixed array.
   10466     1090598 :   if (len == 0) return;
   10467             :   WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
   10468     9002870 :   for (int index = 0; index < len; index++) {
   10469    16931132 :     dest->set(dest_pos + index, get(pos + index), mode);
   10470             :   }
   10471             : }
   10472             : 
   10473           0 : void JSObject::PrototypeRegistryCompactionCallback(HeapObject value,
   10474             :                                                    int old_index,
   10475             :                                                    int new_index) {
   10476             :   DCHECK(value->IsMap() && Map::cast(value)->is_prototype_map());
   10477             :   Map map = Map::cast(value);
   10478             :   DCHECK(map->prototype_info()->IsPrototypeInfo());
   10479             :   PrototypeInfo proto_info = PrototypeInfo::cast(map->prototype_info());
   10480             :   DCHECK_EQ(old_index, proto_info->registry_slot());
   10481             :   proto_info->set_registry_slot(new_index);
   10482           0 : }
   10483             : 
   10484             : // static
   10485        2310 : Handle<ArrayList> ArrayList::Add(Isolate* isolate, Handle<ArrayList> array,
   10486             :                                  Handle<Object> obj) {
   10487        2310 :   int length = array->Length();
   10488        2310 :   array = EnsureSpace(isolate, array, length + 1);
   10489             :   // Check that GC didn't remove elements from the array.
   10490             :   DCHECK_EQ(array->Length(), length);
   10491        2310 :   array->Set(length, *obj);
   10492        2310 :   array->SetLength(length + 1);
   10493        2310 :   return array;
   10494             : }
   10495             : 
   10496             : // static
   10497           5 : Handle<ArrayList> ArrayList::Add(Isolate* isolate, Handle<ArrayList> array,
   10498             :                                  Handle<Object> obj1, Handle<Object> obj2) {
   10499           5 :   int length = array->Length();
   10500           5 :   array = EnsureSpace(isolate, array, length + 2);
   10501             :   // Check that GC didn't remove elements from the array.
   10502             :   DCHECK_EQ(array->Length(), length);
   10503           5 :   array->Set(length, *obj1);
   10504          10 :   array->Set(length + 1, *obj2);
   10505           5 :   array->SetLength(length + 2);
   10506           5 :   return array;
   10507             : }
   10508             : 
   10509             : // static
   10510         435 : Handle<ArrayList> ArrayList::New(Isolate* isolate, int size) {
   10511             :   Handle<FixedArray> fixed_array =
   10512         435 :       isolate->factory()->NewFixedArray(size + kFirstIndex);
   10513             :   fixed_array->set_map_no_write_barrier(
   10514             :       ReadOnlyRoots(isolate).array_list_map());
   10515         435 :   Handle<ArrayList> result = Handle<ArrayList>::cast(fixed_array);
   10516         435 :   result->SetLength(0);
   10517         435 :   return result;
   10518             : }
   10519             : 
   10520         402 : Handle<FixedArray> ArrayList::Elements(Isolate* isolate,
   10521             :                                        Handle<ArrayList> array) {
   10522         402 :   int length = array->Length();
   10523         402 :   Handle<FixedArray> result = isolate->factory()->NewFixedArray(length);
   10524             :   // Do not copy the first entry, i.e., the length.
   10525         402 :   array->CopyTo(kFirstIndex, *result, 0, length);
   10526         402 :   return result;
   10527             : }
   10528             : 
   10529             : namespace {
   10530             : 
   10531     5115523 : Handle<FixedArray> EnsureSpaceInFixedArray(Isolate* isolate,
   10532             :                                            Handle<FixedArray> array,
   10533             :                                            int length) {
   10534             :   int capacity = array->length();
   10535     5115523 :   if (capacity < length) {
   10536             :     int new_capacity = length;
   10537        5486 :     new_capacity = new_capacity + Max(new_capacity / 2, 2);
   10538        2743 :     int grow_by = new_capacity - capacity;
   10539        2743 :     array = isolate->factory()->CopyFixedArrayAndGrow(array, grow_by);
   10540             :   }
   10541     5115523 :   return array;
   10542             : }
   10543             : 
   10544             : }  // namespace
   10545             : 
   10546             : // static
   10547        2315 : Handle<ArrayList> ArrayList::EnsureSpace(Isolate* isolate,
   10548             :                                          Handle<ArrayList> array, int length) {
   10549             :   const bool empty = (array->length() == 0);
   10550             :   Handle<FixedArray> ret =
   10551        4630 :       EnsureSpaceInFixedArray(isolate, array, kFirstIndex + length);
   10552        2315 :   if (empty) {
   10553          50 :     ret->set_map_no_write_barrier(array->GetReadOnlyRoots().array_list_map());
   10554             : 
   10555          50 :     Handle<ArrayList>::cast(ret)->SetLength(0);
   10556             :   }
   10557        2315 :   return Handle<ArrayList>::cast(ret);
   10558             : }
   10559             : 
   10560             : // static
   10561    14352905 : Handle<WeakArrayList> WeakArrayList::AddToEnd(Isolate* isolate,
   10562             :                                               Handle<WeakArrayList> array,
   10563             :                                               const MaybeObjectHandle& value) {
   10564             :   int length = array->length();
   10565    14352915 :   array = EnsureSpace(isolate, array, length + 1);
   10566             :   // Reload length; GC might have removed elements from the array.
   10567             :   length = array->length();
   10568    28705849 :   array->Set(length, *value);
   10569    14352919 :   array->set_length(length + 1);
   10570    14352921 :   return array;
   10571             : }
   10572             : 
   10573      849539 : bool WeakArrayList::IsFull() { return length() == capacity(); }
   10574             : 
   10575             : // static
   10576    14486442 : Handle<WeakArrayList> WeakArrayList::EnsureSpace(Isolate* isolate,
   10577             :                                                  Handle<WeakArrayList> array,
   10578             :                                                  int length,
   10579             :                                                  PretenureFlag pretenure) {
   10580             :   int capacity = array->capacity();
   10581    14486451 :   if (capacity < length) {
   10582             :     int new_capacity = length;
   10583     3682810 :     new_capacity = new_capacity + Max(new_capacity / 2, 2);
   10584     1841405 :     int grow_by = new_capacity - capacity;
   10585             :     array =
   10586     1841405 :         isolate->factory()->CopyWeakArrayListAndGrow(array, grow_by, pretenure);
   10587             :   }
   10588    14486451 :   return array;
   10589             : }
   10590             : 
   10591         402 : int WeakArrayList::CountLiveWeakReferences() const {
   10592             :   int live_weak_references = 0;
   10593      226668 :   for (int i = 0; i < length(); i++) {
   10594      225864 :     if (Get(i)->IsWeak()) {
   10595      112572 :       ++live_weak_references;
   10596             :     }
   10597             :   }
   10598         402 :   return live_weak_references;
   10599             : }
   10600             : 
   10601     3564483 : bool WeakArrayList::RemoveOne(const MaybeObjectHandle& value) {
   10602     3564491 :   if (length() == 0) return false;
   10603             :   // Optimize for the most recently added element to be removed again.
   10604             :   MaybeObject cleared_weak_ref =
   10605     3564489 :       HeapObjectReference::ClearedValue(GetIsolate());
   10606     3564492 :   int last_index = length() - 1;
   10607     3564512 :   for (int i = last_index; i >= 0; --i) {
   10608     7129016 :     if (Get(i) == *value) {
   10609             :       // Move the last element into the this slot (or no-op, if this is the
   10610             :       // last slot).
   10611     3564489 :       Set(i, Get(last_index));
   10612     3564495 :       Set(last_index, cleared_weak_ref);
   10613             :       set_length(last_index);
   10614     3564497 :       return true;
   10615             :     }
   10616             :   }
   10617             :   return false;
   10618             : }
   10619             : 
   10620             : // static
   10621      500894 : Handle<WeakArrayList> PrototypeUsers::Add(Isolate* isolate,
   10622             :                                           Handle<WeakArrayList> array,
   10623             :                                           Handle<Map> value,
   10624             :                                           int* assigned_index) {
   10625             :   int length = array->length();
   10626      500898 :   if (length == 0) {
   10627             :     // Uninitialized WeakArrayList; need to initialize empty_slot_index.
   10628      118639 :     array = WeakArrayList::EnsureSpace(isolate, array, kFirstIndex + 1);
   10629             :     set_empty_slot_index(*array, kNoEmptySlotsMarker);
   10630      237276 :     array->Set(kFirstIndex, HeapObjectReference::Weak(*value));
   10631             :     array->set_length(kFirstIndex + 1);
   10632      118638 :     if (assigned_index != nullptr) *assigned_index = kFirstIndex;
   10633      118638 :     return array;
   10634             :   }
   10635             : 
   10636             :   // If the array has unfilled space at the end, use it.
   10637      382258 :   if (!array->IsFull()) {
   10638      539362 :     array->Set(length, HeapObjectReference::Weak(*value));
   10639      269682 :     array->set_length(length + 1);
   10640      269681 :     if (assigned_index != nullptr) *assigned_index = length;
   10641      269681 :     return array;
   10642             :   }
   10643             : 
   10644             :   // If there are empty slots, use one of them.
   10645      112578 :   int empty_slot = Smi::ToInt(empty_slot_index(*array));
   10646      112578 :   if (empty_slot != kNoEmptySlotsMarker) {
   10647             :     DCHECK_GE(empty_slot, kFirstIndex);
   10648       97798 :     CHECK_LT(empty_slot, array->length());
   10649      195596 :     int next_empty_slot = array->Get(empty_slot).ToSmi().value();
   10650             : 
   10651      195596 :     array->Set(empty_slot, HeapObjectReference::Weak(*value));
   10652       97798 :     if (assigned_index != nullptr) *assigned_index = empty_slot;
   10653             : 
   10654             :     set_empty_slot_index(*array, next_empty_slot);
   10655       97798 :     return array;
   10656             :   } else {
   10657             :     DCHECK_EQ(empty_slot, kNoEmptySlotsMarker);
   10658             :   }
   10659             : 
   10660             :   // Array full and no empty slots. Grow the array.
   10661       14780 :   array = WeakArrayList::EnsureSpace(isolate, array, length + 1);
   10662       29560 :   array->Set(length, HeapObjectReference::Weak(*value));
   10663             :   array->set_length(length + 1);
   10664       14780 :   if (assigned_index != nullptr) *assigned_index = length;
   10665       14780 :   return array;
   10666             : }
   10667             : 
   10668          30 : WeakArrayList PrototypeUsers::Compact(Handle<WeakArrayList> array, Heap* heap,
   10669             :                                       CompactionCallback callback,
   10670             :                                       PretenureFlag pretenure) {
   10671          30 :   if (array->length() == 0) {
   10672             :     return *array;
   10673             :   }
   10674          30 :   int new_length = kFirstIndex + array->CountLiveWeakReferences();
   10675          30 :   if (new_length == array->length()) {
   10676             :     return *array;
   10677             :   }
   10678             : 
   10679             :   Handle<WeakArrayList> new_array = WeakArrayList::EnsureSpace(
   10680             :       heap->isolate(),
   10681             :       handle(ReadOnlyRoots(heap).empty_weak_array_list(), heap->isolate()),
   10682           5 :       new_length, pretenure);
   10683             :   // Allocation might have caused GC and turned some of the elements into
   10684             :   // cleared weak heap objects. Count the number of live objects again.
   10685             :   int copy_to = kFirstIndex;
   10686          40 :   for (int i = kFirstIndex; i < array->length(); i++) {
   10687          15 :     MaybeObject element = array->Get(i);
   10688          15 :     HeapObject value;
   10689          15 :     if (element->GetHeapObjectIfWeak(&value)) {
   10690           5 :       callback(value, i, copy_to);
   10691          10 :       new_array->Set(copy_to++, element);
   10692             :     } else {
   10693             :       DCHECK(element->IsCleared() || element->IsSmi());
   10694             :     }
   10695             :   }
   10696             :   new_array->set_length(copy_to);
   10697             :   set_empty_slot_index(*new_array, kNoEmptySlotsMarker);
   10698             :   return *new_array;
   10699             : }
   10700             : 
   10701      181946 : Handle<RegExpMatchInfo> RegExpMatchInfo::ReserveCaptures(
   10702             :     Isolate* isolate, Handle<RegExpMatchInfo> match_info, int capture_count) {
   10703             :   DCHECK_GE(match_info->length(), kLastMatchOverhead);
   10704      181946 :   const int required_length = kFirstCaptureIndex + capture_count;
   10705             :   return Handle<RegExpMatchInfo>::cast(
   10706      181946 :       EnsureSpaceInFixedArray(isolate, match_info, required_length));
   10707             : }
   10708             : 
   10709             : // static
   10710     4756622 : Handle<FrameArray> FrameArray::AppendJSFrame(Handle<FrameArray> in,
   10711             :                                              Handle<Object> receiver,
   10712             :                                              Handle<JSFunction> function,
   10713             :                                              Handle<AbstractCode> code,
   10714             :                                              int offset, int flags) {
   10715     4756622 :   const int frame_count = in->FrameCount();
   10716     4756622 :   const int new_length = LengthFor(frame_count + 1);
   10717             :   Handle<FrameArray> array =
   10718     4756622 :       EnsureSpace(function->GetIsolate(), in, new_length);
   10719     9513244 :   array->SetReceiver(frame_count, *receiver);
   10720     9513244 :   array->SetFunction(frame_count, *function);
   10721     9513244 :   array->SetCode(frame_count, *code);
   10722     4756622 :   array->SetOffset(frame_count, Smi::FromInt(offset));
   10723     4756622 :   array->SetFlags(frame_count, Smi::FromInt(flags));
   10724             :   array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1));
   10725     4756622 :   return array;
   10726             : }
   10727             : 
   10728             : // static
   10729      174640 : Handle<FrameArray> FrameArray::AppendWasmFrame(
   10730             :     Handle<FrameArray> in, Handle<WasmInstanceObject> wasm_instance,
   10731             :     int wasm_function_index, wasm::WasmCode* code, int offset, int flags) {
   10732             :   Isolate* isolate = wasm_instance->GetIsolate();
   10733      174640 :   const int frame_count = in->FrameCount();
   10734      174640 :   const int new_length = LengthFor(frame_count + 1);
   10735      174640 :   Handle<FrameArray> array = EnsureSpace(isolate, in, new_length);
   10736             :   // The {code} will be {nullptr} for interpreted wasm frames.
   10737             :   Handle<Foreign> code_foreign =
   10738      174640 :       isolate->factory()->NewForeign(reinterpret_cast<Address>(code));
   10739      349280 :   array->SetWasmInstance(frame_count, *wasm_instance);
   10740      174640 :   array->SetWasmFunctionIndex(frame_count, Smi::FromInt(wasm_function_index));
   10741      349280 :   array->SetWasmCodeObject(frame_count, *code_foreign);
   10742      174640 :   array->SetOffset(frame_count, Smi::FromInt(offset));
   10743      174640 :   array->SetFlags(frame_count, Smi::FromInt(flags));
   10744             :   array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1));
   10745      174640 :   return array;
   10746             : }
   10747             : 
   10748     1253133 : void FrameArray::ShrinkToFit(Isolate* isolate) {
   10749     2506266 :   Shrink(isolate, LengthFor(FrameCount()));
   10750     1253133 : }
   10751             : 
   10752             : // static
   10753     4931262 : Handle<FrameArray> FrameArray::EnsureSpace(Isolate* isolate,
   10754             :                                            Handle<FrameArray> array,
   10755             :                                            int length) {
   10756             :   return Handle<FrameArray>::cast(
   10757     4931262 :       EnsureSpaceInFixedArray(isolate, array, length));
   10758             : }
   10759             : 
   10760      192938 : Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
   10761             :                                                   int nof_descriptors,
   10762             :                                                   int slack,
   10763             :                                                   PretenureFlag pretenure) {
   10764      192938 :   return nof_descriptors + slack == 0
   10765             :              ? isolate->factory()->empty_descriptor_array()
   10766             :              : isolate->factory()->NewDescriptorArray(nof_descriptors, slack,
   10767    38991774 :                                                       pretenure);
   10768             : }
   10769             : 
   10770    19496111 : void DescriptorArray::Initialize(EnumCache enum_cache,
   10771             :                                  HeapObject undefined_value,
   10772             :                                  int nof_descriptors, int slack) {
   10773             :   DCHECK_GE(nof_descriptors, 0);
   10774             :   DCHECK_GE(slack, 0);
   10775             :   DCHECK_LE(nof_descriptors + slack, kMaxNumberOfDescriptors);
   10776    19496111 :   set_number_of_all_descriptors(nof_descriptors + slack);
   10777    19496111 :   set_number_of_descriptors(nof_descriptors);
   10778             :   set_raw_number_of_marked_descriptors(0);
   10779             :   set_filler16bits(0);
   10780    19496111 :   set_enum_cache(enum_cache);
   10781             :   MemsetTagged(GetDescriptorSlot(0), undefined_value,
   10782    19496122 :                number_of_all_descriptors() * kEntrySize);
   10783    19496114 : }
   10784             : 
   10785          62 : void DescriptorArray::ClearEnumCache() {
   10786         124 :   set_enum_cache(GetReadOnlyRoots().empty_enum_cache());
   10787          62 : }
   10788             : 
   10789      239133 : void DescriptorArray::Replace(int index, Descriptor* descriptor) {
   10790             :   descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index));
   10791      239134 :   Set(index, descriptor);
   10792      239136 : }
   10793             : 
   10794             : // static
   10795       47976 : void DescriptorArray::InitializeOrChangeEnumCache(
   10796             :     Handle<DescriptorArray> descriptors, Isolate* isolate,
   10797             :     Handle<FixedArray> keys, Handle<FixedArray> indices) {
   10798       47976 :   EnumCache enum_cache = descriptors->enum_cache();
   10799       47976 :   if (enum_cache == ReadOnlyRoots(isolate).empty_enum_cache()) {
   10800       94408 :     enum_cache = *isolate->factory()->NewEnumCache(keys, indices);
   10801       47204 :     descriptors->set_enum_cache(enum_cache);
   10802             :   } else {
   10803         772 :     enum_cache->set_keys(*keys);
   10804         772 :     enum_cache->set_indices(*indices);
   10805             :   }
   10806       47976 : }
   10807             : 
   10808   119354516 : void DescriptorArray::CopyFrom(int index, DescriptorArray src) {
   10809   119354516 :   PropertyDetails details = src->GetDetails(index);
   10810   119354523 :   Set(index, src->GetKey(index), src->GetValue(index), details);
   10811   119354562 : }
   10812             : 
   10813    14208666 : void DescriptorArray::Sort() {
   10814             :   // In-place heap sort.
   10815    14208666 :   int len = number_of_descriptors();
   10816             :   // Reset sorting since the descriptor array might contain invalid pointers.
   10817    14208666 :   for (int i = 0; i < len; ++i) SetSortedKey(i, i);
   10818             :   // Bottom-up max-heap construction.
   10819             :   // Index of the last node with children
   10820    14208675 :   const int max_parent_index = (len / 2) - 1;
   10821    57328033 :   for (int i = max_parent_index; i >= 0; --i) {
   10822             :     int parent_index = i;
   10823    43119411 :     const uint32_t parent_hash = GetSortedKey(i)->Hash();
   10824   127147172 :     while (parent_index <= max_parent_index) {
   10825    63757077 :       int child_index = 2 * parent_index + 1;
   10826    63757077 :       uint32_t child_hash = GetSortedKey(child_index)->Hash();
   10827    63756994 :       if (child_index + 1 < len) {
   10828    50818908 :         uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
   10829    50818887 :         if (right_child_hash > child_hash) {
   10830             :           child_index++;
   10831             :           child_hash = right_child_hash;
   10832             :         }
   10833             :       }
   10834    63756973 :       if (child_hash <= parent_hash) break;
   10835    40908365 :       SwapSortedKeys(parent_index, child_index);
   10836             :       // Now element at child_index could be < its children.
   10837             :       parent_index = child_index;  // parent_hash remains correct.
   10838             :     }
   10839             :   }
   10840             : 
   10841             :   // Extract elements and create sorted array.
   10842    92272565 :   for (int i = len - 1; i > 0; --i) {
   10843             :     // Put max element at the back of the array.
   10844    78063964 :     SwapSortedKeys(0, i);
   10845             :     // Shift down the new top element.
   10846             :     int parent_index = 0;
   10847    78063729 :     const uint32_t parent_hash = GetSortedKey(parent_index)->Hash();
   10848    78063688 :     const int max_parent_index = (i / 2) - 1;
   10849   281046868 :     while (parent_index <= max_parent_index) {
   10850   137496349 :       int child_index = parent_index * 2 + 1;
   10851   137496349 :       uint32_t child_hash = GetSortedKey(child_index)->Hash();
   10852   137496307 :       if (child_index + 1 < i) {
   10853   119131967 :         uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
   10854   119131859 :         if (right_child_hash > child_hash) {
   10855             :           child_index++;
   10856             :           child_hash = right_child_hash;
   10857             :         }
   10858             :       }
   10859   137496199 :       if (child_hash <= parent_hash) break;
   10860   124919087 :       SwapSortedKeys(parent_index, child_index);
   10861             :       parent_index = child_index;
   10862             :     }
   10863             :   }
   10864             :   DCHECK(IsSortedNoDuplicates());
   10865    14208601 : }
   10866             : 
   10867    38596690 : int16_t DescriptorArray::UpdateNumberOfMarkedDescriptors(
   10868             :     unsigned mark_compact_epoch, int16_t new_marked) {
   10869             :   STATIC_ASSERT(kMaxNumberOfDescriptors <=
   10870             :                 NumberOfMarkedDescriptors::kMaxNumberOfMarkedDescriptors);
   10871             :   int16_t old_raw_marked = raw_number_of_marked_descriptors();
   10872             :   int16_t old_marked =
   10873             :       NumberOfMarkedDescriptors::decode(mark_compact_epoch, old_raw_marked);
   10874             :   int16_t new_raw_marked =
   10875             :       NumberOfMarkedDescriptors::encode(mark_compact_epoch, new_marked);
   10876    77193387 :   while (old_marked < new_marked) {
   10877             :     int16_t actual_raw_marked = CompareAndSwapRawNumberOfMarkedDescriptors(
   10878    24697599 :         old_raw_marked, new_raw_marked);
   10879    24737481 :     if (actual_raw_marked == old_raw_marked) {
   10880             :       break;
   10881             :     }
   10882             :     old_raw_marked = actual_raw_marked;
   10883             :     old_marked =
   10884             :         NumberOfMarkedDescriptors::decode(mark_compact_epoch, old_raw_marked);
   10885             :   }
   10886    38636572 :   return old_marked;
   10887             : }
   10888             : 
   10889       15548 : Handle<AccessorPair> AccessorPair::Copy(Isolate* isolate,
   10890             :                                         Handle<AccessorPair> pair) {
   10891       15548 :   Handle<AccessorPair> copy = isolate->factory()->NewAccessorPair();
   10892       31096 :   copy->set_getter(pair->getter());
   10893       31096 :   copy->set_setter(pair->setter());
   10894       15548 :   return copy;
   10895             : }
   10896             : 
   10897       90809 : Handle<Object> AccessorPair::GetComponent(Isolate* isolate,
   10898             :                                           Handle<AccessorPair> accessor_pair,
   10899             :                                           AccessorComponent component) {
   10900       90809 :   Object accessor = accessor_pair->get(component);
   10901       90809 :   if (accessor->IsFunctionTemplateInfo()) {
   10902             :     return ApiNatives::InstantiateFunction(
   10903         178 :                handle(FunctionTemplateInfo::cast(accessor), isolate))
   10904         178 :         .ToHandleChecked();
   10905             :   }
   10906       90720 :   if (accessor->IsNull(isolate)) {
   10907        4376 :     return isolate->factory()->undefined_value();
   10908             :   }
   10909             :   return handle(accessor, isolate);
   10910             : }
   10911             : 
   10912      455962 : Handle<DeoptimizationData> DeoptimizationData::New(Isolate* isolate,
   10913             :                                                    int deopt_entry_count,
   10914             :                                                    PretenureFlag pretenure) {
   10915             :   return Handle<DeoptimizationData>::cast(isolate->factory()->NewFixedArray(
   10916      455962 :       LengthFor(deopt_entry_count), pretenure));
   10917             : }
   10918             : 
   10919     1744276 : Handle<DeoptimizationData> DeoptimizationData::Empty(Isolate* isolate) {
   10920             :   return Handle<DeoptimizationData>::cast(
   10921     1744276 :       isolate->factory()->empty_fixed_array());
   10922             : }
   10923             : 
   10924          86 : SharedFunctionInfo DeoptimizationData::GetInlinedFunction(int index) {
   10925          86 :   if (index == -1) {
   10926           0 :     return SharedFunctionInfo::cast(SharedFunctionInfo());
   10927             :   } else {
   10928         172 :     return SharedFunctionInfo::cast(LiteralArray()->get(index));
   10929             :   }
   10930             : }
   10931             : 
   10932             : #ifdef DEBUG
   10933             : bool DescriptorArray::IsEqualTo(DescriptorArray other) {
   10934             :   if (number_of_all_descriptors() != other->number_of_all_descriptors()) {
   10935             :     return false;
   10936             :   }
   10937             :   for (int i = 0; i < number_of_all_descriptors(); ++i) {
   10938             :     if (get(i) != other->get(i)) return false;
   10939             :   }
   10940             :   return true;
   10941             : }
   10942             : #endif
   10943             : 
   10944             : // static
   10945          36 : Handle<String> String::Trim(Isolate* isolate, Handle<String> string,
   10946             :                             TrimMode mode) {
   10947          36 :   string = String::Flatten(isolate, string);
   10948             :   int const length = string->length();
   10949             : 
   10950             :   // Perform left trimming if requested.
   10951             :   int left = 0;
   10952          36 :   if (mode == kTrim || mode == kTrimStart) {
   10953        2412 :     while (left < length && IsWhiteSpaceOrLineTerminator(string->Get(left))) {
   10954         567 :       left++;
   10955             :     }
   10956             :   }
   10957             : 
   10958             :   // Perform right trimming if requested.
   10959             :   int right = length;
   10960          36 :   if (mode == kTrim || mode == kTrimEnd) {
   10961         108 :     while (right > left &&
   10962         180 :            IsWhiteSpaceOrLineTerminator(string->Get(right - 1))) {
   10963           0 :       right--;
   10964             :     }
   10965             :   }
   10966             : 
   10967          36 :   return isolate->factory()->NewSubString(string, left, right);
   10968             : }
   10969             : 
   10970     3684507 : bool String::LooksValid() {
   10971             :   // TODO(leszeks): Maybe remove this check entirely, Heap::Contains uses
   10972             :   // basically the same logic as the way we access the heap in the first place.
   10973     1929964 :   MemoryChunk* chunk = MemoryChunk::FromHeapObject(*this);
   10974             :   // RO_SPACE objects should always be valid.
   10975     3684507 :   if (chunk->owner()->identity() == RO_SPACE) return true;
   10976     1929964 :   if (chunk->heap() == nullptr) return false;
   10977     1929964 :   return chunk->heap()->Contains(*this);
   10978             : }
   10979             : 
   10980             : // static
   10981      620972 : MaybeHandle<String> Name::ToFunctionName(Isolate* isolate, Handle<Name> name) {
   10982     1241944 :   if (name->IsString()) return Handle<String>::cast(name);
   10983             :   // ES6 section 9.2.11 SetFunctionName, step 4.
   10984       17310 :   Handle<Object> description(Handle<Symbol>::cast(name)->name(), isolate);
   10985       11540 :   if (description->IsUndefined(isolate)) {
   10986          81 :     return isolate->factory()->empty_string();
   10987             :   }
   10988        5689 :   IncrementalStringBuilder builder(isolate);
   10989             :   builder.AppendCharacter('[');
   10990        5689 :   builder.AppendString(Handle<String>::cast(description));
   10991             :   builder.AppendCharacter(']');
   10992        5689 :   return builder.Finish();
   10993             : }
   10994             : 
   10995             : // static
   10996      560452 : MaybeHandle<String> Name::ToFunctionName(Isolate* isolate, Handle<Name> name,
   10997             :                                          Handle<String> prefix) {
   10998             :   Handle<String> name_string;
   10999     1120904 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, name_string,
   11000             :                              ToFunctionName(isolate, name), String);
   11001      560452 :   IncrementalStringBuilder builder(isolate);
   11002      560453 :   builder.AppendString(prefix);
   11003             :   builder.AppendCharacter(' ');
   11004      560454 :   builder.AppendString(name_string);
   11005      560454 :   return builder.Finish();
   11006             : }
   11007             : 
   11008             : namespace {
   11009             : 
   11010             : bool AreDigits(const uint8_t* s, int from, int to) {
   11011       34838 :   for (int i = from; i < to; i++) {
   11012       59817 :     if (s[i] < '0' || s[i] > '9') return false;
   11013             :   }
   11014             : 
   11015             :   return true;
   11016             : }
   11017             : 
   11018             : 
   11019             : int ParseDecimalInteger(const uint8_t* s, int from, int to) {
   11020             :   DCHECK_LT(to - from, 10);  // Overflow is not possible.
   11021             :   DCHECK(from < to);
   11022        1561 :   int d = s[from] - '0';
   11023             : 
   11024        1930 :   for (int i = from + 1; i < to; i++) {
   11025         369 :     d = 10 * d + (s[i] - '0');
   11026             :   }
   11027             : 
   11028             :   return d;
   11029             : }
   11030             : 
   11031             : }  // namespace
   11032             : 
   11033             : // static
   11034     3766110 : Handle<Object> String::ToNumber(Isolate* isolate, Handle<String> subject) {
   11035             :   // Flatten {subject} string first.
   11036     3766110 :   subject = String::Flatten(isolate, subject);
   11037             : 
   11038             :   // Fast array index case.
   11039             :   uint32_t index;
   11040     3766110 :   if (subject->AsArrayIndex(&index)) {
   11041        2233 :     return isolate->factory()->NewNumberFromUint(index);
   11042             :   }
   11043             : 
   11044             :   // Fast case: short integer or some sorts of junk values.
   11045     7527754 :   if (subject->IsSeqOneByteString()) {
   11046             :     int len = subject->length();
   11047     2582151 :     if (len == 0) return handle(Smi::kZero, isolate);
   11048             : 
   11049             :     DisallowHeapAllocation no_gc;
   11050             :     uint8_t const* data =
   11051     5123998 :         Handle<SeqOneByteString>::cast(subject)->GetChars(no_gc);
   11052     2561999 :     bool minus = (data[0] == '-');
   11053     2561999 :     int start_pos = (minus ? 1 : 0);
   11054             : 
   11055     2561999 :     if (start_pos == len) {
   11056           0 :       return isolate->factory()->nan_value();
   11057     2561999 :     } else if (data[start_pos] > '9') {
   11058             :       // Fast check for a junk value. A valid string may start from a
   11059             :       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
   11060             :       // or the 'I' character ('Infinity'). All of that have codes not greater
   11061             :       // than '9' except 'I' and &nbsp;.
   11062     2412523 :       if (data[start_pos] != 'I' && data[start_pos] != 0xA0) {
   11063     2406103 :         return isolate->factory()->nan_value();
   11064             :       }
   11065      176016 :     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
   11066             :       // The maximal/minimal smi has 10 digits. If the string has less digits
   11067             :       // we know it will fit into the smi-data type.
   11068             :       int d = ParseDecimalInteger(data, start_pos, len);
   11069        1561 :       if (minus) {
   11070        1768 :         if (d == 0) return isolate->factory()->minus_zero_value();
   11071        1246 :         d = -d;
   11072         108 :       } else if (!subject->HasHashCode() && len <= String::kMaxArrayIndexSize &&
   11073           0 :                  (len == 1 || data[0] != '0')) {
   11074             :         // String hash is not calculated yet but all the data are present.
   11075             :         // Update the hash field to speed up sequential convertions.
   11076           0 :         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
   11077             : #ifdef DEBUG
   11078             :         subject->Hash();  // Force hash calculation.
   11079             :         DCHECK_EQ(static_cast<int>(subject->hash_field()),
   11080             :                   static_cast<int>(hash));
   11081             : #endif
   11082             :         subject->set_hash_field(hash);
   11083             :       }
   11084        1300 :       return handle(Smi::FromInt(d), isolate);
   11085             :     }
   11086             :   }
   11087             : 
   11088             :   // Slower case.
   11089             :   int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
   11090     1336061 :   return isolate->factory()->NewNumber(StringToDouble(isolate, subject, flags));
   11091             : }
   11092             : 
   11093   148240895 : String::FlatContent String::GetFlatContent(
   11094             :     const DisallowHeapAllocation& no_gc) {
   11095             :   USE(no_gc);
   11096             :   int length = this->length();
   11097             :   StringShape shape(*this);
   11098   148240895 :   String string = *this;
   11099             :   int offset = 0;
   11100   148240895 :   if (shape.representation_tag() == kConsStringTag) {
   11101           0 :     ConsString cons = ConsString::cast(string);
   11102           0 :     if (cons->second()->length() != 0) {
   11103           0 :       return FlatContent();
   11104             :     }
   11105           0 :     string = cons->first();
   11106             :     shape = StringShape(string);
   11107   148240895 :   } else if (shape.representation_tag() == kSlicedStringTag) {
   11108     1097732 :     SlicedString slice = SlicedString::cast(string);
   11109             :     offset = slice->offset();
   11110     1097732 :     string = slice->parent();
   11111             :     shape = StringShape(string);
   11112             :     DCHECK(shape.representation_tag() != kConsStringTag &&
   11113             :            shape.representation_tag() != kSlicedStringTag);
   11114             :   }
   11115   148240895 :   if (shape.representation_tag() == kThinStringTag) {
   11116          23 :     ThinString thin = ThinString::cast(string);
   11117          23 :     string = thin->actual();
   11118             :     shape = StringShape(string);
   11119             :     DCHECK(!shape.IsCons());
   11120             :     DCHECK(!shape.IsSliced());
   11121             :   }
   11122   148240895 :   if (shape.encoding_tag() == kOneByteStringTag) {
   11123             :     const uint8_t* start;
   11124   143255149 :     if (shape.representation_tag() == kSeqStringTag) {
   11125             :       start = SeqOneByteString::cast(string)->GetChars(no_gc);
   11126             :     } else {
   11127             :       start = ExternalOneByteString::cast(string)->GetChars();
   11128             :     }
   11129   143255141 :     return FlatContent(start + offset, length);
   11130             :   } else {
   11131             :     DCHECK_EQ(shape.encoding_tag(), kTwoByteStringTag);
   11132             :     const uc16* start;
   11133     4985746 :     if (shape.representation_tag() == kSeqStringTag) {
   11134             :       start = SeqTwoByteString::cast(string)->GetChars(no_gc);
   11135             :     } else {
   11136             :       start = ExternalTwoByteString::cast(string)->GetChars();
   11137             :     }
   11138     4985746 :     return FlatContent(start + offset, length);
   11139             :   }
   11140             : }
   11141             : 
   11142     5130559 : std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls,
   11143             :                                           RobustnessFlag robust_flag,
   11144             :                                           int offset, int length,
   11145             :                                           int* length_return) {
   11146     5130559 :   if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
   11147             :     return std::unique_ptr<char[]>();
   11148             :   }
   11149             :   // Negative length means the to the end of the string.
   11150     5130559 :   if (length < 0) length = kMaxInt - offset;
   11151             : 
   11152             :   // Compute the size of the UTF-8 string. Start at the specified offset.
   11153     5130559 :   StringCharacterStream stream(*this, offset);
   11154             :   int character_position = offset;
   11155             :   int utf8_bytes = 0;
   11156             :   int last = unibrow::Utf16::kNoPreviousCharacter;
   11157    38511494 :   while (stream.HasMore() && character_position++ < offset + length) {
   11158    28250357 :     uint16_t character = stream.GetNext();
   11159    56500708 :     utf8_bytes += unibrow::Utf8::Length(character, last);
   11160    28250354 :     last = character;
   11161             :   }
   11162             : 
   11163     5130571 :   if (length_return) {
   11164     3612115 :     *length_return = utf8_bytes;
   11165             :   }
   11166             : 
   11167     5130571 :   char* result = NewArray<char>(utf8_bytes + 1);
   11168             : 
   11169             :   // Convert the UTF-16 string to a UTF-8 buffer. Start at the specified offset.
   11170     5130578 :   stream.Reset(*this, offset);
   11171             :   character_position = offset;
   11172             :   int utf8_byte_position = 0;
   11173             :   last = unibrow::Utf16::kNoPreviousCharacter;
   11174    38511515 :   while (stream.HasMore() && character_position++ < offset + length) {
   11175    28250365 :     uint16_t character = stream.GetNext();
   11176    28250366 :     if (allow_nulls == DISALLOW_NULLS && character == 0) {
   11177             :       character = ' ';
   11178             :     }
   11179             :     utf8_byte_position +=
   11180    28250366 :         unibrow::Utf8::Encode(result + utf8_byte_position, character, last);
   11181    28250361 :     last = character;
   11182             :   }
   11183     5130571 :   result[utf8_byte_position] = 0;
   11184             :   return std::unique_ptr<char[]>(result);
   11185             : }
   11186             : 
   11187      589581 : std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls,
   11188             :                                           RobustnessFlag robust_flag,
   11189             :                                           int* length_return) {
   11190     1519061 :   return ToCString(allow_nulls, robust_flag, 0, -1, length_return);
   11191             : }
   11192             : 
   11193             : 
   11194      107086 : void Relocatable::PostGarbageCollectionProcessing(Isolate* isolate) {
   11195             :   Relocatable* current = isolate->relocatable_top();
   11196      245240 :   while (current != nullptr) {
   11197       31068 :     current->PostGarbageCollection();
   11198       31068 :     current = current->prev_;
   11199             :   }
   11200      107086 : }
   11201             : 
   11202             : 
   11203             : // Reserve space for statics needing saving and restoring.
   11204        1111 : int Relocatable::ArchiveSpacePerThread() {
   11205        1111 :   return sizeof(Relocatable*);  // NOLINT
   11206             : }
   11207             : 
   11208             : 
   11209             : // Archive statics that are thread-local.
   11210       24256 : char* Relocatable::ArchiveState(Isolate* isolate, char* to) {
   11211       24256 :   *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top();
   11212             :   isolate->set_relocatable_top(nullptr);
   11213       24256 :   return to + ArchiveSpacePerThread();
   11214             : }
   11215             : 
   11216             : 
   11217             : // Restore statics that are thread-local.
   11218       24256 : char* Relocatable::RestoreState(Isolate* isolate, char* from) {
   11219       24256 :   isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from));
   11220       24256 :   return from + ArchiveSpacePerThread();
   11221             : }
   11222             : 
   11223        6344 : char* Relocatable::Iterate(RootVisitor* v, char* thread_storage) {
   11224        6344 :   Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage);
   11225             :   Iterate(v, top);
   11226        6344 :   return thread_storage + ArchiveSpacePerThread();
   11227             : }
   11228             : 
   11229      307250 : void Relocatable::Iterate(Isolate* isolate, RootVisitor* v) {
   11230             :   Iterate(v, isolate->relocatable_top());
   11231      307250 : }
   11232             : 
   11233           0 : void Relocatable::Iterate(RootVisitor* v, Relocatable* top) {
   11234             :   Relocatable* current = top;
   11235      379134 :   while (current != nullptr) {
   11236       65540 :     current->IterateInstance(v);
   11237       65540 :     current = current->prev_;
   11238             :   }
   11239           0 : }
   11240             : 
   11241             : 
   11242     1606028 : FlatStringReader::FlatStringReader(Isolate* isolate, Handle<String> str)
   11243             :     : Relocatable(isolate),
   11244             :       str_(str.location()),
   11245     4818084 :       length_(str->length()) {
   11246     1606028 :   PostGarbageCollection();
   11247     1606028 : }
   11248             : 
   11249        1345 : FlatStringReader::FlatStringReader(Isolate* isolate, Vector<const char> input)
   11250             :     : Relocatable(isolate),
   11251             :       str_(nullptr),
   11252             :       is_one_byte_(true),
   11253        1345 :       length_(input.length()),
   11254        4035 :       start_(input.start()) {}
   11255             : 
   11256     1606406 : void FlatStringReader::PostGarbageCollection() {
   11257     1606406 :   if (str_ == nullptr) return;
   11258             :   Handle<String> str(str_);
   11259             :   DCHECK(str->IsFlat());
   11260             :   DisallowHeapAllocation no_gc;
   11261             :   // This does not actually prevent the vector from being relocated later.
   11262     1606406 :   String::FlatContent content = str->GetFlatContent(no_gc);
   11263             :   DCHECK(content.IsFlat());
   11264     3212812 :   is_one_byte_ = content.IsOneByte();
   11265     1606406 :   if (is_one_byte_) {
   11266     1468427 :     start_ = content.ToOneByteVector().start();
   11267             :   } else {
   11268      137979 :     start_ = content.ToUC16Vector().start();
   11269             :   }
   11270             : }
   11271             : 
   11272       42896 : void ConsStringIterator::Initialize(ConsString cons_string, int offset) {
   11273             :   DCHECK(!cons_string.is_null());
   11274      138960 :   root_ = cons_string;
   11275      138960 :   consumed_ = offset;
   11276             :   // Force stack blown condition to trigger restart.
   11277      138960 :   depth_ = 1;
   11278      138960 :   maximum_depth_ = kStackSize + depth_;
   11279             :   DCHECK(StackBlown());
   11280       42896 : }
   11281             : 
   11282    10637895 : String ConsStringIterator::Continue(int* offset_out) {
   11283             :   DCHECK_NE(depth_, 0);
   11284             :   DCHECK_EQ(0, *offset_out);
   11285    10637895 :   bool blew_stack = StackBlown();
   11286             :   String string;
   11287             :   // Get the next leaf if there is one.
   11288    10637895 :   if (!blew_stack) string = NextLeaf(&blew_stack);
   11289             :   // Restart search from root.
   11290    10637895 :   if (blew_stack) {
   11291             :     DCHECK(string.is_null());
   11292      163335 :     string = Search(offset_out);
   11293             :   }
   11294             :   // Ensure future calls return null immediately.
   11295    10637895 :   if (string.is_null()) Reset(ConsString());
   11296    10637895 :   return string;
   11297             : }
   11298             : 
   11299      326525 : String ConsStringIterator::Search(int* offset_out) {
   11300      163335 :   ConsString cons_string = root_;
   11301             :   // Reset the stack, pushing the root string.
   11302      163335 :   depth_ = 1;
   11303      163335 :   maximum_depth_ = 1;
   11304      163335 :   frames_[0] = cons_string;
   11305      163335 :   const int consumed = consumed_;
   11306             :   int offset = 0;
   11307             :   while (true) {
   11308             :     // Loop until the string is found which contains the target offset.
   11309    34906904 :     String string = cons_string->first();
   11310             :     int length = string->length();
   11311             :     int32_t type;
   11312    34906904 :     if (consumed < offset + length) {
   11313             :       // Target offset is in the left branch.
   11314             :       // Keep going if we're still in a ConString.
   11315             :       type = string->map()->instance_type();
   11316    33585879 :       if ((type & kStringRepresentationMask) == kConsStringTag) {
   11317    33452624 :         cons_string = ConsString::cast(string);
   11318             :         PushLeft(cons_string);
   11319             :         continue;
   11320             :       }
   11321             :       // Tell the stack we're done descending.
   11322             :       AdjustMaximumDepth();
   11323             :     } else {
   11324             :       // Descend right.
   11325             :       // Update progress through the string.
   11326             :       offset += length;
   11327             :       // Keep going if we're still in a ConString.
   11328     1321025 :       string = cons_string->second();
   11329             :       type = string->map()->instance_type();
   11330     1321025 :       if ((type & kStringRepresentationMask) == kConsStringTag) {
   11331     1290945 :         cons_string = ConsString::cast(string);
   11332             :         PushRight(cons_string);
   11333             :         continue;
   11334             :       }
   11335             :       // Need this to be updated for the current string.
   11336             :       length = string->length();
   11337             :       // Account for the possibility of an empty right leaf.
   11338             :       // This happens only if we have asked for an offset outside the string.
   11339       30080 :       if (length == 0) {
   11340             :         // Reset so future operations will return null immediately.
   11341             :         Reset(ConsString());
   11342         145 :         return String();
   11343             :       }
   11344             :       // Tell the stack we're done descending.
   11345             :       AdjustMaximumDepth();
   11346             :       // Pop stack so next iteration is in correct place.
   11347             :       Pop();
   11348             :     }
   11349             :     DCHECK_NE(length, 0);
   11350             :     // Adjust return values and exit.
   11351      163190 :     consumed_ = offset + length;
   11352      163190 :     *offset_out = consumed - offset;
   11353      163190 :     return string;
   11354             :   }
   11355             :   UNREACHABLE();
   11356             : }
   11357             : 
   11358    26414291 : String ConsStringIterator::NextLeaf(bool* blew_stack) {
   11359             :   while (true) {
   11360             :     // Tree traversal complete.
   11361    10893404 :     if (depth_ == 0) {
   11362       35344 :       *blew_stack = false;
   11363       35344 :       return String();
   11364             :     }
   11365             :     // We've lost track of higher nodes.
   11366    10858060 :     if (StackBlown()) {
   11367         695 :       *blew_stack = true;
   11368         695 :       return String();
   11369             :     }
   11370             :     // Go right.
   11371    21714730 :     ConsString cons_string = frames_[OffsetForDepth(depth_ - 1)];
   11372    10857365 :     String string = cons_string->second();
   11373             :     int32_t type = string->map()->instance_type();
   11374    10857365 :     if ((type & kStringRepresentationMask) != kConsStringTag) {
   11375             :       // Pop stack so next iteration is in correct place.
   11376             :       Pop();
   11377             :       int length = string->length();
   11378             :       // Could be a flattened ConsString.
   11379     6194538 :       if (length == 0) continue;
   11380     5358240 :       consumed_ += length;
   11381     5358240 :       return string;
   11382             :     }
   11383     5080976 :     cons_string = ConsString::cast(string);
   11384             :     PushRight(cons_string);
   11385             :     // Need to traverse all the way left.
   11386             :     while (true) {
   11387             :       // Continue left.
   11388    10119811 :       string = cons_string->first();
   11389             :       type = string->map()->instance_type();
   11390    10119811 :       if ((type & kStringRepresentationMask) != kConsStringTag) {
   11391             :         AdjustMaximumDepth();
   11392             :         int length = string->length();
   11393     5080976 :         if (length == 0) break;  // Skip empty left-hand sides of ConsStrings.
   11394     5080976 :         consumed_ += length;
   11395     5080976 :         return string;
   11396             :       }
   11397     5038835 :       cons_string = ConsString::cast(string);
   11398             :       PushLeft(cons_string);
   11399             :     }
   11400             :   }
   11401             :   UNREACHABLE();
   11402             : }
   11403             : 
   11404      273526 : uint16_t ConsString::ConsStringGet(int index) {
   11405             :   DCHECK(index >= 0 && index < this->length());
   11406             : 
   11407             :   // Check for a flattened cons string
   11408      547052 :   if (second()->length() == 0) {
   11409       77526 :     String left = first();
   11410             :     return left->Get(index);
   11411             :   }
   11412             : 
   11413      196000 :   String string = String::cast(*this);
   11414             : 
   11415             :   while (true) {
   11416     1122445 :     if (StringShape(string).IsCons()) {
   11417      926445 :       ConsString cons_string = ConsString::cast(string);
   11418      926445 :       String left = cons_string->first();
   11419      926445 :       if (left->length() > index) {
   11420      518995 :         string = left;
   11421             :       } else {
   11422      407450 :         index -= left->length();
   11423      407450 :         string = cons_string->second();
   11424             :       }
   11425             :     } else {
   11426      196000 :       return string->Get(index);
   11427             :     }
   11428             :   }
   11429             : 
   11430      926445 :   UNREACHABLE();
   11431             : }
   11432             : 
   11433        5248 : uint16_t ThinString::ThinStringGet(int index) { return actual()->Get(index); }
   11434             : 
   11435     1095402 : uint16_t SlicedString::SlicedStringGet(int index) {
   11436     2190804 :   return parent()->Get(offset() + index);
   11437             : }
   11438             : 
   11439             : template <typename sinkchar>
   11440   131288879 : void String::WriteToFlat(String src, sinkchar* sink, int f, int t) {
   11441             :   DisallowHeapAllocation no_gc;
   11442   131288879 :   String source = src;
   11443             :   int from = f;
   11444             :   int to = t;
   11445             :   while (true) {
   11446             :     DCHECK(0 <= from && from <= to && to <= source->length());
   11447   192652335 :     switch (StringShape(source).full_representation_tag()) {
   11448             :       case kOneByteStringTag | kExternalStringTag: {
   11449             :         CopyChars(sink, ExternalOneByteString::cast(source)->GetChars() + from,
   11450      852134 :                   to - from);
   11451             :         return;
   11452             :       }
   11453             :       case kTwoByteStringTag | kExternalStringTag: {
   11454             :         const uc16* data =
   11455             :             ExternalTwoByteString::cast(source)->GetChars();
   11456             :         CopyChars(sink,
   11457             :                   data + from,
   11458      280345 :                   to - from);
   11459             :         return;
   11460             :       }
   11461             :       case kOneByteStringTag | kSeqStringTag: {
   11462             :         CopyChars(sink, SeqOneByteString::cast(source)->GetChars(no_gc) + from,
   11463   171023086 :                   to - from);
   11464             :         return;
   11465             :       }
   11466             :       case kTwoByteStringTag | kSeqStringTag: {
   11467             :         CopyChars(sink, SeqTwoByteString::cast(source)->GetChars(no_gc) + from,
   11468    12825068 :                   to - from);
   11469             :         return;
   11470             :       }
   11471             :       case kOneByteStringTag | kConsStringTag:
   11472             :       case kTwoByteStringTag | kConsStringTag: {
   11473    98385963 :         ConsString cons_string = ConsString::cast(source);
   11474    98385963 :         String first = cons_string->first();
   11475             :         int boundary = first->length();
   11476    98385963 :         if (to - boundary >= boundary - from) {
   11477             :           // Right hand side is longer.  Recurse over left.
   11478    45206160 :           if (from < boundary) {
   11479    45206160 :             WriteToFlat(first, sink, from, boundary);
   11480    90412320 :             if (from == 0 && cons_string->second() == first) {
   11481    37036955 :               CopyChars(sink + boundary, sink, boundary);
   11482    37036955 :               return;
   11483             :             }
   11484     8169205 :             sink += boundary - from;
   11485             :             from = 0;
   11486             :           } else {
   11487           0 :             from -= boundary;
   11488             :           }
   11489             :           to -= boundary;
   11490     8169205 :           source = cons_string->second();
   11491             :         } else {
   11492             :           // Left hand side is longer.  Recurse over right.
   11493    53179803 :           if (to > boundary) {
   11494    52803976 :             String second = cons_string->second();
   11495             :             // When repeatedly appending to a string, we get a cons string that
   11496             :             // is unbalanced to the left, a list, essentially.  We inline the
   11497             :             // common case of sequential one-byte right child.
   11498    52803977 :             if (to - boundary == 1) {
   11499    34326250 :               sink[boundary - from] = static_cast<sinkchar>(second->Get(0));
   11500    35640852 :             } else if (second->IsSeqOneByteString()) {
   11501    24112139 :               CopyChars(sink + boundary - from,
   11502             :                         SeqOneByteString::cast(second)->GetChars(no_gc),
   11503    48224278 :                         to - boundary);
   11504             :             } else {
   11505    11528713 :               WriteToFlat(second,
   11506    11528713 :                           sink + boundary - from,
   11507             :                           0,
   11508    11528713 :                           to - boundary);
   11509             :             }
   11510             :             to = boundary;
   11511             :           }
   11512    53179804 :           source = first;
   11513             :         }
   11514    61349009 :         break;
   11515             :       }
   11516             :       case kOneByteStringTag | kSlicedStringTag:
   11517             :       case kTwoByteStringTag | kSlicedStringTag: {
   11518     1621437 :         SlicedString slice = SlicedString::cast(source);
   11519     1621437 :         unsigned offset = slice->offset();
   11520     1621437 :         WriteToFlat(slice->parent(), sink, from + offset, to + offset);
   11521             :         return;
   11522             :       }
   11523             :       case kOneByteStringTag | kThinStringTag:
   11524             :       case kTwoByteStringTag | kThinStringTag:
   11525       14447 :         source = ThinString::cast(source)->actual();
   11526       14447 :         break;
   11527             :     }
   11528             :   }
   11529             : }
   11530             : 
   11531             : template <typename SourceChar>
   11532       52700 : static void CalculateLineEndsImpl(Isolate* isolate, std::vector<int>* line_ends,
   11533             :                                   Vector<const SourceChar> src,
   11534             :                                   bool include_ending_line) {
   11535      105400 :   const int src_len = src.length();
   11536   154346830 :   for (int i = 0; i < src_len - 1; i++) {
   11537   308588260 :     SourceChar current = src[i];
   11538   308588260 :     SourceChar next = src[i + 1];
   11539   154294130 :     if (IsLineTerminatorSequence(current, next)) line_ends->push_back(i);
   11540             :   }
   11541             : 
   11542      157530 :   if (src_len > 0 && IsLineTerminatorSequence(src[src_len - 1], 0)) {
   11543       33322 :     line_ends->push_back(src_len - 1);
   11544             :   }
   11545       52700 :   if (include_ending_line) {
   11546             :     // Include one character beyond the end of script. The rewriter uses that
   11547             :     // position for the implicit return statement.
   11548       50268 :     line_ends->push_back(src_len);
   11549             :   }
   11550       52700 : }
   11551             : 
   11552       52700 : Handle<FixedArray> String::CalculateLineEnds(Isolate* isolate,
   11553             :                                              Handle<String> src,
   11554             :                                              bool include_ending_line) {
   11555       52700 :   src = Flatten(isolate, src);
   11556             :   // Rough estimate of line count based on a roughly estimated average
   11557             :   // length of (unpacked) code.
   11558       52700 :   int line_count_estimate = src->length() >> 4;
   11559             :   std::vector<int> line_ends;
   11560       52700 :   line_ends.reserve(line_count_estimate);
   11561             :   { DisallowHeapAllocation no_allocation;  // ensure vectors stay valid.
   11562             :     // Dispatch on type of strings.
   11563       52700 :     String::FlatContent content = src->GetFlatContent(no_allocation);
   11564             :     DCHECK(content.IsFlat());
   11565       52700 :     if (content.IsOneByte()) {
   11566             :       CalculateLineEndsImpl(isolate,
   11567             :                             &line_ends,
   11568             :                             content.ToOneByteVector(),
   11569      105360 :                             include_ending_line);
   11570             :     } else {
   11571             :       CalculateLineEndsImpl(isolate,
   11572             :                             &line_ends,
   11573             :                             content.ToUC16Vector(),
   11574          40 :                             include_ending_line);
   11575             :     }
   11576             :   }
   11577      105400 :   int line_count = static_cast<int>(line_ends.size());
   11578       52700 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
   11579     9701746 :   for (int i = 0; i < line_count; i++) {
   11580    19298092 :     array->set(i, Smi::FromInt(line_ends[i]));
   11581             :   }
   11582      105400 :   return array;
   11583             : }
   11584             : 
   11585             : namespace {
   11586             : 
   11587             : template <typename sinkchar>
   11588      105139 : void WriteFixedArrayToFlat(FixedArray fixed_array, int length, String separator,
   11589             :                            sinkchar* sink, int sink_length) {
   11590             :   DisallowHeapAllocation no_allocation;
   11591      105139 :   CHECK_GT(length, 0);
   11592      105139 :   CHECK_LE(length, fixed_array->length());
   11593             : #ifdef DEBUG
   11594             :   sinkchar* sink_end = sink + sink_length;
   11595             : #endif
   11596             : 
   11597             :   const int separator_length = separator->length();
   11598             :   const bool use_one_byte_separator_fast_path =
   11599             :       separator_length == 1 && sizeof(sinkchar) == 1 &&
   11600      165617 :       StringShape(separator).IsSequentialOneByte();
   11601             :   uint8_t separator_one_char;
   11602      103406 :   if (use_one_byte_separator_fast_path) {
   11603       62211 :     CHECK(StringShape(separator).IsSequentialOneByte());
   11604       62211 :     CHECK_EQ(separator->length(), 1);
   11605       62211 :     separator_one_char =
   11606             :         SeqOneByteString::cast(separator)->GetChars(no_allocation)[0];
   11607             :   }
   11608             : 
   11609      105139 :   uint32_t num_separators = 0;
   11610    31390589 :   for (int i = 0; i < length; i++) {
   11611    31390589 :     Object element = fixed_array->get(i);
   11612             :     const bool element_is_separator_sequence = element->IsSmi();
   11613             : 
   11614             :     // If element is a Smi, it represents the number of separators to write.
   11615    31390589 :     if (V8_UNLIKELY(element_is_separator_sequence)) {
   11616        6774 :       CHECK(element->ToUint32(&num_separators));
   11617             :       // Verify that Smis (number of separators) only occur when necessary:
   11618             :       //   1) at the beginning
   11619             :       //   2) at the end
   11620             :       //   3) when the number of separators > 1
   11621             :       //     - It is assumed that consecutive Strings will have one separator,
   11622             :       //       so there is no need for a Smi.
   11623             :       DCHECK(i == 0 || i == length - 1 || num_separators > 1);
   11624             :     }
   11625             : 
   11626             :     // Write separator(s) if necessary.
   11627    31390589 :     if (num_separators > 0 && separator_length > 0) {
   11628             :       // TODO(pwong): Consider doubling strategy employed by runtime-strings.cc
   11629             :       //              WriteRepeatToFlat().
   11630             :       // Fast path for single character, single byte separators.
   11631    31106525 :       if (use_one_byte_separator_fast_path) {
   11632             :         DCHECK_LE(sink + num_separators, sink_end);
   11633    29487177 :         memset(sink, separator_one_char, num_separators);
   11634             :         DCHECK_EQ(separator_length, 1);
   11635    29487177 :         sink += num_separators;
   11636             :       } else {
   11637     2520944 :         for (uint32_t j = 0; j < num_separators; j++) {
   11638             :           DCHECK_LE(sink + separator_length, sink_end);
   11639     2520944 :           String::WriteToFlat(separator, sink, 0, separator_length);
   11640     2520944 :           sink += separator_length;
   11641             :         }
   11642             :       }
   11643             :     }
   11644             : 
   11645    31390589 :     if (V8_UNLIKELY(element_is_separator_sequence)) {
   11646        6774 :       num_separators = 0;
   11647             :     } else {
   11648             :       DCHECK(element->IsString());
   11649             :       String string = String::cast(element);
   11650             :       const int string_length = string->length();
   11651             : 
   11652             :       DCHECK(string_length == 0 || sink < sink_end);
   11653    31383815 :       String::WriteToFlat(string, sink, 0, string_length);
   11654    31383815 :       sink += string_length;
   11655             : 
   11656             :       // Next string element, needs at least one separator preceding it.
   11657    31383815 :       num_separators = 1;
   11658             :     }
   11659             :   }
   11660             : 
   11661             :   // Verify we have written to the end of the sink.
   11662             :   DCHECK_EQ(sink, sink_end);
   11663      105139 : }
   11664             : 
   11665             : }  // namespace
   11666             : 
   11667             : // static
   11668      105139 : Address JSArray::ArrayJoinConcatToSequentialString(Isolate* isolate,
   11669             :                                                    Address raw_fixed_array,
   11670             :                                                    intptr_t length,
   11671             :                                                    Address raw_separator,
   11672             :                                                    Address raw_dest) {
   11673             :   DisallowHeapAllocation no_allocation;
   11674      105139 :   DisallowJavascriptExecution no_js(isolate);
   11675      105139 :   FixedArray fixed_array = FixedArray::cast(Object(raw_fixed_array));
   11676      105139 :   String separator = String::cast(Object(raw_separator));
   11677             :   String dest = String::cast(Object(raw_dest));
   11678             :   DCHECK(fixed_array->IsFixedArray());
   11679             :   DCHECK(StringShape(dest).IsSequentialOneByte() ||
   11680             :          StringShape(dest).IsSequentialTwoByte());
   11681             : 
   11682      105139 :   if (StringShape(dest).IsSequentialOneByte()) {
   11683             :     WriteFixedArrayToFlat(fixed_array, static_cast<int>(length), separator,
   11684             :                           SeqOneByteString::cast(dest)->GetChars(no_allocation),
   11685      103406 :                           dest->length());
   11686             :   } else {
   11687             :     DCHECK(StringShape(dest).IsSequentialTwoByte());
   11688             :     WriteFixedArrayToFlat(fixed_array, static_cast<int>(length), separator,
   11689             :                           SeqTwoByteString::cast(dest)->GetChars(no_allocation),
   11690        1733 :                           dest->length());
   11691             :   }
   11692      105139 :   return dest->ptr();
   11693             : }
   11694             : 
   11695             : // Compares the contents of two strings by reading and comparing
   11696             : // int-sized blocks of characters.
   11697             : template <typename Char>
   11698             : static inline bool CompareRawStringContents(const Char* const a,
   11699             :                                             const Char* const b,
   11700             :                                             int length) {
   11701    19112538 :   return CompareChars(a, b, length) == 0;
   11702             : }
   11703             : 
   11704             : 
   11705             : template<typename Chars1, typename Chars2>
   11706             : class RawStringComparator : public AllStatic {
   11707             :  public:
   11708             :   static inline bool compare(const Chars1* a, const Chars2* b, int len) {
   11709             :     DCHECK(sizeof(Chars1) != sizeof(Chars2));
   11710         933 :     for (int i = 0; i < len; i++) {
   11711         933 :       if (a[i] != b[i]) {
   11712             :         return false;
   11713             :       }
   11714             :     }
   11715             :     return true;
   11716             :   }
   11717             : };
   11718             : 
   11719             : 
   11720             : template<>
   11721             : class RawStringComparator<uint16_t, uint16_t> {
   11722             :  public:
   11723             :   static inline bool compare(const uint16_t* a, const uint16_t* b, int len) {
   11724             :     return CompareRawStringContents(a, b, len);
   11725             :   }
   11726             : };
   11727             : 
   11728             : 
   11729             : template<>
   11730             : class RawStringComparator<uint8_t, uint8_t> {
   11731             :  public:
   11732             :   static inline bool compare(const uint8_t* a, const uint8_t* b, int len) {
   11733             :     return CompareRawStringContents(a, b, len);
   11734             :   }
   11735             : };
   11736             : 
   11737             : 
   11738             : class StringComparator {
   11739             :   class State {
   11740             :    public:
   11741      124684 :     State() : is_one_byte_(true), length_(0), buffer8_(nullptr) {}
   11742             : 
   11743      124684 :     void Init(String string) {
   11744      124684 :       ConsString cons_string = String::VisitFlat(this, string);
   11745             :       iter_.Reset(cons_string);
   11746      124684 :       if (!cons_string.is_null()) {
   11747             :         int offset;
   11748          90 :         string = iter_.Next(&offset);
   11749          45 :         String::VisitFlat(this, string, offset);
   11750             :       }
   11751      124684 :     }
   11752             : 
   11753             :     inline void VisitOneByteString(const uint8_t* chars, int length) {
   11754        2382 :       is_one_byte_ = true;
   11755        2382 :       buffer8_ = chars;
   11756        2382 :       length_ = length;
   11757             :     }
   11758             : 
   11759             :     inline void VisitTwoByteString(const uint16_t* chars, int length) {
   11760      122652 :       is_one_byte_ = false;
   11761      122652 :       buffer16_ = chars;
   11762      122652 :       length_ = length;
   11763             :     }
   11764             : 
   11765         700 :     void Advance(int consumed) {
   11766             :       DCHECK(consumed <= length_);
   11767             :       // Still in buffer.
   11768         700 :       if (length_ != consumed) {
   11769         350 :         if (is_one_byte_) {
   11770         350 :           buffer8_ += consumed;
   11771             :         } else {
   11772           0 :           buffer16_ += consumed;
   11773             :         }
   11774         350 :         length_ -= consumed;
   11775        1050 :         return;
   11776             :       }
   11777             :       // Advance state.
   11778             :       int offset;
   11779         700 :       String next = iter_.Next(&offset);
   11780             :       DCHECK_EQ(0, offset);
   11781             :       DCHECK(!next.is_null());
   11782         350 :       String::VisitFlat(this, next);
   11783             :     }
   11784             : 
   11785             :     ConsStringIterator iter_;
   11786             :     bool is_one_byte_;
   11787             :     int length_;
   11788             :     union {
   11789             :       const uint8_t* buffer8_;
   11790             :       const uint16_t* buffer16_;
   11791             :     };
   11792             : 
   11793             :    private:
   11794             :     DISALLOW_COPY_AND_ASSIGN(State);
   11795             :   };
   11796             : 
   11797             :  public:
   11798      124684 :   inline StringComparator() = default;
   11799             : 
   11800             :   template<typename Chars1, typename Chars2>
   11801             :   static inline bool Equals(State* state_1, State* state_2, int to_check) {
   11802             :     const Chars1* a = reinterpret_cast<const Chars1*>(state_1->buffer8_);
   11803             :     const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_);
   11804             :     return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check);
   11805             :   }
   11806             : 
   11807       62342 :   bool Equals(String string_1, String string_2) {
   11808             :     int length = string_1->length();
   11809      125034 :     state_1_.Init(string_1);
   11810      125034 :     state_2_.Init(string_2);
   11811             :     while (true) {
   11812       62692 :       int to_check = Min(state_1_.length_, state_2_.length_);
   11813             :       DCHECK(to_check > 0 && to_check <= length);
   11814             :       bool is_equal;
   11815       62692 :       if (state_1_.is_one_byte_) {
   11816        1281 :         if (state_2_.is_one_byte_) {
   11817             :           is_equal = Equals<uint8_t, uint8_t>(&state_1_, &state_2_, to_check);
   11818             :         } else {
   11819             :           is_equal = Equals<uint8_t, uint16_t>(&state_1_, &state_2_, to_check);
   11820             :         }
   11821             :       } else {
   11822       61411 :         if (state_2_.is_one_byte_) {
   11823             :           is_equal = Equals<uint16_t, uint8_t>(&state_1_, &state_2_, to_check);
   11824             :         } else {
   11825             :           is_equal = Equals<uint16_t, uint16_t>(&state_1_, &state_2_, to_check);
   11826             :         }
   11827             :       }
   11828             :       // Looping done.
   11829       62692 :       if (!is_equal) return false;
   11830       62692 :       length -= to_check;
   11831             :       // Exit condition. Strings are equal.
   11832       62692 :       if (length == 0) return true;
   11833         350 :       state_1_.Advance(to_check);
   11834         350 :       state_2_.Advance(to_check);
   11835         350 :     }
   11836             :   }
   11837             : 
   11838             :  private:
   11839             :   State state_1_;
   11840             :   State state_2_;
   11841             : 
   11842             :   DISALLOW_COPY_AND_ASSIGN(StringComparator);
   11843             : };
   11844             : 
   11845    17204529 : bool String::SlowEquals(String other) {
   11846             :   DisallowHeapAllocation no_gc;
   11847             :   // Fast check: negative check with lengths.
   11848             :   int len = length();
   11849    17204529 :   if (len != other->length()) return false;
   11850     9421112 :   if (len == 0) return true;
   11851             : 
   11852             :   // Fast check: if at least one ThinString is involved, dereference it/them
   11853             :   // and restart.
   11854    28253070 :   if (this->IsThinString() || other->IsThinString()) {
   11855       10258 :     if (other->IsThinString()) other = ThinString::cast(other)->actual();
   11856       10258 :     if (this->IsThinString()) {
   11857       10258 :       return ThinString::cast(*this)->actual()->Equals(other);
   11858             :     } else {
   11859           0 :       return this->Equals(other);
   11860             :     }
   11861             :   }
   11862             : 
   11863             :   // Fast check: if hash code is computed for both strings
   11864             :   // a fast negative check can be performed.
   11865    18821189 :   if (HasHashCode() && other->HasHashCode()) {
   11866             : #ifdef ENABLE_SLOW_DCHECKS
   11867             :     if (FLAG_enable_slow_asserts) {
   11868             :       if (Hash() != other->Hash()) {
   11869             :         bool found_difference = false;
   11870             :         for (int i = 0; i < len; i++) {
   11871             :           if (Get(i) != other->Get(i)) {
   11872             :             found_difference = true;
   11873             :             break;
   11874             :           }
   11875             :         }
   11876             :         DCHECK(found_difference);
   11877             :       }
   11878             :     }
   11879             : #endif
   11880     9390982 :     if (Hash() != other->Hash()) return false;
   11881             :   }
   11882             : 
   11883             :   // We know the strings are both non-empty. Compare the first chars
   11884             :   // before we try to flatten the strings.
   11885     7323147 :   if (this->Get(0) != other->Get(0)) return false;
   11886             : 
   11887    14569601 :   if (IsSeqOneByteString() && other->IsSeqOneByteString()) {
   11888             :     const uint8_t* str1 = SeqOneByteString::cast(*this)->GetChars(no_gc);
   11889             :     const uint8_t* str2 = SeqOneByteString::cast(other)->GetChars(no_gc);
   11890     7253603 :     return CompareRawStringContents(str1, str2, len);
   11891             :   }
   11892             : 
   11893       62342 :   StringComparator comparator;
   11894       62342 :   return comparator.Equals(*this, other);
   11895             : }
   11896             : 
   11897      742191 : bool String::SlowEquals(Isolate* isolate, Handle<String> one,
   11898             :                         Handle<String> two) {
   11899             :   // Fast check: negative check with lengths.
   11900             :   int one_length = one->length();
   11901      742191 :   if (one_length != two->length()) return false;
   11902      732826 :   if (one_length == 0) return true;
   11903             : 
   11904             :   // Fast check: if at least one ThinString is involved, dereference it/them
   11905             :   // and restart.
   11906     2931304 :   if (one->IsThinString() || two->IsThinString()) {
   11907          46 :     if (one->IsThinString())
   11908           0 :       one = handle(ThinString::cast(*one)->actual(), isolate);
   11909          46 :     if (two->IsThinString())
   11910          46 :       two = handle(ThinString::cast(*two)->actual(), isolate);
   11911          23 :     return String::Equals(isolate, one, two);
   11912             :   }
   11913             : 
   11914             :   // Fast check: if hash code is computed for both strings
   11915             :   // a fast negative check can be performed.
   11916      744102 :   if (one->HasHashCode() && two->HasHashCode()) {
   11917             : #ifdef ENABLE_SLOW_DCHECKS
   11918             :     if (FLAG_enable_slow_asserts) {
   11919             :       if (one->Hash() != two->Hash()) {
   11920             :         bool found_difference = false;
   11921             :         for (int i = 0; i < one_length; i++) {
   11922             :           if (one->Get(i) != two->Get(i)) {
   11923             :             found_difference = true;
   11924             :             break;
   11925             :           }
   11926             :         }
   11927             :         DCHECK(found_difference);
   11928             :       }
   11929             :     }
   11930             : #endif
   11931       13002 :     if (one->Hash() != two->Hash()) return false;
   11932             :   }
   11933             : 
   11934             :   // We know the strings are both non-empty. Compare the first chars
   11935             :   // before we try to flatten the strings.
   11936     2198334 :   if (one->Get(0) != two->Get(0)) return false;
   11937             : 
   11938      732621 :   one = String::Flatten(isolate, one);
   11939      732621 :   two = String::Flatten(isolate, two);
   11940             : 
   11941             :   DisallowHeapAllocation no_gc;
   11942      732621 :   String::FlatContent flat1 = one->GetFlatContent(no_gc);
   11943      732621 :   String::FlatContent flat2 = two->GetFlatContent(no_gc);
   11944             : 
   11945      732621 :   if (flat1.IsOneByte() && flat2.IsOneByte()) {
   11946             :       return CompareRawStringContents(flat1.ToOneByteVector().start(),
   11947             :                                       flat2.ToOneByteVector().start(),
   11948             :                                       one_length);
   11949             :   } else {
   11950     7643751 :     for (int i = 0; i < one_length; i++) {
   11951     7643751 :       if (flat1.Get(i) != flat2.Get(i)) return false;
   11952             :     }
   11953             :     return true;
   11954             :   }
   11955             : }
   11956             : 
   11957             : 
   11958             : // static
   11959     4806180 : ComparisonResult String::Compare(Isolate* isolate, Handle<String> x,
   11960             :                                  Handle<String> y) {
   11961             :   // A few fast case tests before we flatten.
   11962     4806180 :   if (x.is_identical_to(y)) {
   11963             :     return ComparisonResult::kEqual;
   11964     4806180 :   } else if (y->length() == 0) {
   11965             :     return x->length() == 0 ? ComparisonResult::kEqual
   11966           0 :                             : ComparisonResult::kGreaterThan;
   11967     4806180 :   } else if (x->length() == 0) {
   11968             :     return ComparisonResult::kLessThan;
   11969             :   }
   11970             : 
   11971    19224720 :   int const d = x->Get(0) - y->Get(0);
   11972     4806180 :   if (d < 0) {
   11973             :     return ComparisonResult::kLessThan;
   11974     3878046 :   } else if (d > 0) {
   11975             :     return ComparisonResult::kGreaterThan;
   11976             :   }
   11977             : 
   11978             :   // Slow case.
   11979      384688 :   x = String::Flatten(isolate, x);
   11980      384688 :   y = String::Flatten(isolate, y);
   11981             : 
   11982             :   DisallowHeapAllocation no_gc;
   11983             :   ComparisonResult result = ComparisonResult::kEqual;
   11984             :   int prefix_length = x->length();
   11985      384688 :   if (y->length() < prefix_length) {
   11986             :     prefix_length = y->length();
   11987             :     result = ComparisonResult::kGreaterThan;
   11988      337806 :   } else if (y->length() > prefix_length) {
   11989             :     result = ComparisonResult::kLessThan;
   11990             :   }
   11991             :   int r;
   11992      384688 :   String::FlatContent x_content = x->GetFlatContent(no_gc);
   11993      384688 :   String::FlatContent y_content = y->GetFlatContent(no_gc);
   11994      384688 :   if (x_content.IsOneByte()) {
   11995             :     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
   11996      380089 :     if (y_content.IsOneByte()) {
   11997             :       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   11998      380071 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11999             :     } else {
   12000             :       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   12001          18 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   12002             :     }
   12003             :   } else {
   12004             :     Vector<const uc16> x_chars = x_content.ToUC16Vector();
   12005        4599 :     if (y_content.IsOneByte()) {
   12006             :       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   12007          18 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   12008             :     } else {
   12009             :       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   12010        4581 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   12011             :     }
   12012             :   }
   12013      384688 :   if (r < 0) {
   12014             :     result = ComparisonResult::kLessThan;
   12015      156682 :   } else if (r > 0) {
   12016             :     result = ComparisonResult::kGreaterThan;
   12017             :   }
   12018      384688 :   return result;
   12019             : }
   12020             : 
   12021         799 : Object String::IndexOf(Isolate* isolate, Handle<Object> receiver,
   12022             :                        Handle<Object> search, Handle<Object> position) {
   12023        1598 :   if (receiver->IsNullOrUndefined(isolate)) {
   12024         540 :     THROW_NEW_ERROR_RETURN_FAILURE(
   12025             :         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
   12026             :                               isolate->factory()->NewStringFromAsciiChecked(
   12027             :                                   "String.prototype.indexOf")));
   12028             :   }
   12029             :   Handle<String> receiver_string;
   12030        1238 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_string,
   12031             :                                      Object::ToString(isolate, receiver));
   12032             : 
   12033             :   Handle<String> search_string;
   12034        1238 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, search_string,
   12035             :                                      Object::ToString(isolate, search));
   12036             : 
   12037        1247 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   12038             :                                      Object::ToInteger(isolate, position));
   12039             : 
   12040             :   uint32_t index = receiver_string->ToValidIndex(*position);
   12041             :   return Smi::FromInt(
   12042        1220 :       String::IndexOf(isolate, receiver_string, search_string, index));
   12043             : }
   12044             : 
   12045             : namespace {
   12046             : 
   12047             : template <typename T>
   12048     1052751 : int SearchString(Isolate* isolate, String::FlatContent receiver_content,
   12049             :                  Vector<T> pat_vector, int start_index) {
   12050     1052751 :   if (receiver_content.IsOneByte()) {
   12051             :     return SearchString(isolate, receiver_content.ToOneByteVector(), pat_vector,
   12052     1048881 :                         start_index);
   12053             :   }
   12054             :   return SearchString(isolate, receiver_content.ToUC16Vector(), pat_vector,
   12055        3870 :                       start_index);
   12056             : }
   12057             : 
   12058             : }  // namespace
   12059             : 
   12060     1055850 : int String::IndexOf(Isolate* isolate, Handle<String> receiver,
   12061             :                     Handle<String> search, int start_index) {
   12062             :   DCHECK_LE(0, start_index);
   12063             :   DCHECK(start_index <= receiver->length());
   12064             : 
   12065     1055850 :   uint32_t search_length = search->length();
   12066     1055850 :   if (search_length == 0) return start_index;
   12067             : 
   12068     1055805 :   uint32_t receiver_length = receiver->length();
   12069     1055805 :   if (start_index + search_length > receiver_length) return -1;
   12070             : 
   12071     1052751 :   receiver = String::Flatten(isolate, receiver);
   12072     1052751 :   search = String::Flatten(isolate, search);
   12073             : 
   12074             :   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   12075             :   // Extract flattened substrings of cons strings before getting encoding.
   12076     1052751 :   String::FlatContent receiver_content = receiver->GetFlatContent(no_gc);
   12077     1052751 :   String::FlatContent search_content = search->GetFlatContent(no_gc);
   12078             : 
   12079             :   // dispatch on type of strings
   12080     1052751 :   if (search_content.IsOneByte()) {
   12081     1050996 :     Vector<const uint8_t> pat_vector = search_content.ToOneByteVector();
   12082             :     return SearchString<const uint8_t>(isolate, receiver_content, pat_vector,
   12083     1050996 :                                        start_index);
   12084             :   }
   12085        1755 :   Vector<const uc16> pat_vector = search_content.ToUC16Vector();
   12086             :   return SearchString<const uc16>(isolate, receiver_content, pat_vector,
   12087        1755 :                                   start_index);
   12088             : }
   12089             : 
   12090        3894 : MaybeHandle<String> String::GetSubstitution(Isolate* isolate, Match* match,
   12091             :                                             Handle<String> replacement,
   12092             :                                             int start_index) {
   12093             :   DCHECK_GE(start_index, 0);
   12094             : 
   12095             :   Factory* factory = isolate->factory();
   12096             : 
   12097             :   const int replacement_length = replacement->length();
   12098        3894 :   const int captures_length = match->CaptureCount();
   12099             : 
   12100        3894 :   replacement = String::Flatten(isolate, replacement);
   12101             : 
   12102             :   Handle<String> dollar_string =
   12103        3894 :       factory->LookupSingleCharacterStringFromCode('$');
   12104             :   int next_dollar_ix =
   12105        3894 :       String::IndexOf(isolate, replacement, dollar_string, start_index);
   12106        3894 :   if (next_dollar_ix < 0) {
   12107         153 :     return replacement;
   12108             :   }
   12109             : 
   12110        3741 :   IncrementalStringBuilder builder(isolate);
   12111             : 
   12112        3741 :   if (next_dollar_ix > 0) {
   12113         279 :     builder.AppendString(factory->NewSubString(replacement, 0, next_dollar_ix));
   12114             :   }
   12115             : 
   12116             :   while (true) {
   12117        7962 :     const int peek_ix = next_dollar_ix + 1;
   12118        7962 :     if (peek_ix >= replacement_length) {
   12119             :       builder.AppendCharacter('$');
   12120          18 :       return builder.Finish();
   12121             :     }
   12122             : 
   12123             :     int continue_from_ix = -1;
   12124       15888 :     const uint16_t peek = replacement->Get(peek_ix);
   12125        7944 :     switch (peek) {
   12126             :       case '$':  // $$
   12127             :         builder.AppendCharacter('$');
   12128          54 :         continue_from_ix = peek_ix + 1;
   12129          54 :         break;
   12130             :       case '&':  // $& - match
   12131          54 :         builder.AppendString(match->GetMatch());
   12132          54 :         continue_from_ix = peek_ix + 1;
   12133          54 :         break;
   12134             :       case '`':  // $` - prefix
   12135          36 :         builder.AppendString(match->GetPrefix());
   12136          36 :         continue_from_ix = peek_ix + 1;
   12137          36 :         break;
   12138             :       case '\'':  // $' - suffix
   12139          36 :         builder.AppendString(match->GetSuffix());
   12140          36 :         continue_from_ix = peek_ix + 1;
   12141          36 :         break;
   12142             :       case '0':
   12143             :       case '1':
   12144             :       case '2':
   12145             :       case '3':
   12146             :       case '4':
   12147             :       case '5':
   12148             :       case '6':
   12149             :       case '7':
   12150             :       case '8':
   12151             :       case '9': {
   12152             :         // Valid indices are $1 .. $9, $01 .. $09 and $10 .. $99
   12153        7278 :         int scaled_index = (peek - '0');
   12154             :         int advance = 1;
   12155             : 
   12156        7278 :         if (peek_ix + 1 < replacement_length) {
   12157       12108 :           const uint16_t next_peek = replacement->Get(peek_ix + 1);
   12158        6054 :           if (next_peek >= '0' && next_peek <= '9') {
   12159        1341 :             const int new_scaled_index = scaled_index * 10 + (next_peek - '0');
   12160        1341 :             if (new_scaled_index < captures_length) {
   12161             :               scaled_index = new_scaled_index;
   12162             :               advance = 2;
   12163             :             }
   12164             :           }
   12165             :         }
   12166             : 
   12167        7278 :         if (scaled_index == 0 || scaled_index >= captures_length) {
   12168             :           builder.AppendCharacter('$');
   12169             :           continue_from_ix = peek_ix;
   12170        7368 :           break;
   12171             :         }
   12172             : 
   12173             :         bool capture_exists;
   12174             :         Handle<String> capture;
   12175       14376 :         ASSIGN_RETURN_ON_EXCEPTION(
   12176             :             isolate, capture, match->GetCapture(scaled_index, &capture_exists),
   12177             :             String);
   12178        7188 :         if (capture_exists) builder.AppendString(capture);
   12179        7188 :         continue_from_ix = peek_ix + advance;
   12180        7188 :         break;
   12181             :       }
   12182             :       case '<': {  // $<name> - named capture
   12183             :         typedef String::Match::CaptureState CaptureState;
   12184             : 
   12185         459 :         if (!match->HasNamedCaptures()) {
   12186             :           builder.AppendCharacter('$');
   12187             :           continue_from_ix = peek_ix;
   12188         540 :           break;
   12189             :         }
   12190             : 
   12191             :         Handle<String> bracket_string =
   12192         378 :             factory->LookupSingleCharacterStringFromCode('>');
   12193             :         const int closing_bracket_ix =
   12194         378 :             String::IndexOf(isolate, replacement, bracket_string, peek_ix + 1);
   12195             : 
   12196         378 :         if (closing_bracket_ix == -1) {
   12197             :           // No closing bracket was found, treat '$<' as a string literal.
   12198             :           builder.AppendCharacter('$');
   12199             :           continue_from_ix = peek_ix;
   12200          72 :           break;
   12201             :         }
   12202             : 
   12203             :         Handle<String> capture_name =
   12204         306 :             factory->NewSubString(replacement, peek_ix + 1, closing_bracket_ix);
   12205             :         Handle<String> capture;
   12206             :         CaptureState capture_state;
   12207         612 :         ASSIGN_RETURN_ON_EXCEPTION(
   12208             :             isolate, capture,
   12209             :             match->GetNamedCapture(capture_name, &capture_state), String);
   12210             : 
   12211         306 :         switch (capture_state) {
   12212             :           case CaptureState::INVALID:
   12213             :           case CaptureState::UNMATCHED:
   12214             :             break;
   12215             :           case CaptureState::MATCHED:
   12216         126 :             builder.AppendString(capture);
   12217         126 :             break;
   12218             :         }
   12219             : 
   12220         306 :         continue_from_ix = closing_bracket_ix + 1;
   12221         306 :         break;
   12222             :       }
   12223             :       default:
   12224             :         builder.AppendCharacter('$');
   12225             :         continue_from_ix = peek_ix;
   12226          27 :         break;
   12227             :     }
   12228             : 
   12229             :     // Go the the next $ in the replacement.
   12230             :     // TODO(jgruber): Single-char lookups could be much more efficient.
   12231             :     DCHECK_NE(continue_from_ix, -1);
   12232             :     next_dollar_ix =
   12233        7944 :         String::IndexOf(isolate, replacement, dollar_string, continue_from_ix);
   12234             : 
   12235             :     // Return if there are no more $ characters in the replacement. If we
   12236             :     // haven't reached the end, we need to append the suffix.
   12237        7944 :     if (next_dollar_ix < 0) {
   12238        3723 :       if (continue_from_ix < replacement_length) {
   12239             :         builder.AppendString(factory->NewSubString(
   12240        1311 :             replacement, continue_from_ix, replacement_length));
   12241             :       }
   12242        3723 :       return builder.Finish();
   12243             :     }
   12244             : 
   12245             :     // Append substring between the previous and the next $ character.
   12246        4221 :     if (next_dollar_ix > continue_from_ix) {
   12247             :       builder.AppendString(
   12248          72 :           factory->NewSubString(replacement, continue_from_ix, next_dollar_ix));
   12249             :     }
   12250             :   }
   12251             : 
   12252             :   UNREACHABLE();
   12253             : }
   12254             : 
   12255             : namespace {  // for String.Prototype.lastIndexOf
   12256             : 
   12257             : template <typename schar, typename pchar>
   12258        1313 : int StringMatchBackwards(Vector<const schar> subject,
   12259             :                          Vector<const pchar> pattern, int idx) {
   12260        1313 :   int pattern_length = pattern.length();
   12261             :   DCHECK_GE(pattern_length, 1);
   12262             :   DCHECK(idx + pattern_length <= subject.length());
   12263             : 
   12264             :   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
   12265           0 :     for (int i = 0; i < pattern_length; i++) {
   12266           0 :       uc16 c = pattern[i];
   12267           0 :       if (c > String::kMaxOneByteCharCode) {
   12268             :         return -1;
   12269             :       }
   12270             :     }
   12271             :   }
   12272             : 
   12273        1313 :   pchar pattern_first_char = pattern[0];
   12274        4999 :   for (int i = idx; i >= 0; i--) {
   12275       12354 :     if (subject[i] != pattern_first_char) continue;
   12276             :     int j = 1;
   12277        1869 :     while (j < pattern_length) {
   12278        2073 :       if (pattern[j] != subject[i + j]) {
   12279             :         break;
   12280             :       }
   12281         673 :       j++;
   12282             :     }
   12283        1196 :     if (j == pattern_length) {
   12284             :       return i;
   12285             :     }
   12286             :   }
   12287             :   return -1;
   12288             : }
   12289             : 
   12290             : }  // namespace
   12291             : 
   12292        1727 : Object String::LastIndexOf(Isolate* isolate, Handle<Object> receiver,
   12293             :                            Handle<Object> search, Handle<Object> position) {
   12294        3454 :   if (receiver->IsNullOrUndefined(isolate)) {
   12295         486 :     THROW_NEW_ERROR_RETURN_FAILURE(
   12296             :         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
   12297             :                               isolate->factory()->NewStringFromAsciiChecked(
   12298             :                                   "String.prototype.lastIndexOf")));
   12299             :   }
   12300             :   Handle<String> receiver_string;
   12301        3130 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_string,
   12302             :                                      Object::ToString(isolate, receiver));
   12303             : 
   12304             :   Handle<String> search_string;
   12305        3130 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, search_string,
   12306             :                                      Object::ToString(isolate, search));
   12307             : 
   12308        3130 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   12309             :                                      Object::ToNumber(isolate, position));
   12310             : 
   12311             :   uint32_t start_index;
   12312             : 
   12313        3130 :   if (position->IsNaN()) {
   12314        1088 :     start_index = receiver_string->length();
   12315             :   } else {
   12316         954 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   12317             :                                        Object::ToInteger(isolate, position));
   12318             :     start_index = receiver_string->ToValidIndex(*position);
   12319             :   }
   12320             : 
   12321        1565 :   uint32_t pattern_length = search_string->length();
   12322        1565 :   uint32_t receiver_length = receiver_string->length();
   12323             : 
   12324        1565 :   if (start_index + pattern_length > receiver_length) {
   12325        1160 :     start_index = receiver_length - pattern_length;
   12326             :   }
   12327             : 
   12328        1565 :   if (pattern_length == 0) {
   12329         504 :     return Smi::FromInt(start_index);
   12330             :   }
   12331             : 
   12332        1313 :   receiver_string = String::Flatten(isolate, receiver_string);
   12333        1313 :   search_string = String::Flatten(isolate, search_string);
   12334             : 
   12335             :   int last_index = -1;
   12336             :   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   12337             : 
   12338        1313 :   String::FlatContent receiver_content = receiver_string->GetFlatContent(no_gc);
   12339        1313 :   String::FlatContent search_content = search_string->GetFlatContent(no_gc);
   12340             : 
   12341        1313 :   if (search_content.IsOneByte()) {
   12342        1313 :     Vector<const uint8_t> pat_vector = search_content.ToOneByteVector();
   12343        1313 :     if (receiver_content.IsOneByte()) {
   12344             :       last_index = StringMatchBackwards(receiver_content.ToOneByteVector(),
   12345        1307 :                                         pat_vector, start_index);
   12346             :     } else {
   12347             :       last_index = StringMatchBackwards(receiver_content.ToUC16Vector(),
   12348           6 :                                         pat_vector, start_index);
   12349             :     }
   12350             :   } else {
   12351           0 :     Vector<const uc16> pat_vector = search_content.ToUC16Vector();
   12352           0 :     if (receiver_content.IsOneByte()) {
   12353             :       last_index = StringMatchBackwards(receiver_content.ToOneByteVector(),
   12354           0 :                                         pat_vector, start_index);
   12355             :     } else {
   12356             :       last_index = StringMatchBackwards(receiver_content.ToUC16Vector(),
   12357           0 :                                         pat_vector, start_index);
   12358             :     }
   12359             :   }
   12360        1313 :   return Smi::FromInt(last_index);
   12361             : }
   12362             : 
   12363    20001978 : bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) {
   12364             :   int slen = length();
   12365             :   // Can't check exact length equality, but we can check bounds.
   12366    20001978 :   int str_len = str.length();
   12367    20001978 :   if (!allow_prefix_match &&
   12368    17821493 :       (str_len < slen ||
   12369    17821493 :           str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) {
   12370             :     return false;
   12371             :   }
   12372             : 
   12373             :   int i = 0;
   12374             :   unibrow::Utf8Iterator it = unibrow::Utf8Iterator(str);
   12375   116021797 :   while (i < slen && !it.Done()) {
   12376   204547735 :     if (Get(i++) != *it) return false;
   12377    98339190 :     ++it;
   12378             :   }
   12379             : 
   12380    13747954 :   return (allow_prefix_match || i == slen) && it.Done();
   12381             : }
   12382             : 
   12383             : template <>
   12384         135 : bool String::IsEqualTo(Vector<const uint8_t> str) {
   12385         135 :   return IsOneByteEqualTo(str);
   12386             : }
   12387             : 
   12388             : template <>
   12389           0 : bool String::IsEqualTo(Vector<const uc16> str) {
   12390           0 :   return IsTwoByteEqualTo(str);
   12391             : }
   12392             : 
   12393   110375854 : bool String::IsOneByteEqualTo(Vector<const uint8_t> str) {
   12394             :   int slen = length();
   12395   220751708 :   if (str.length() != slen) return false;
   12396             :   DisallowHeapAllocation no_gc;
   12397    84992055 :   FlatContent content = GetFlatContent(no_gc);
   12398    84992051 :   if (content.IsOneByte()) {
   12399             :     return CompareChars(content.ToOneByteVector().start(),
   12400   169983830 :                         str.start(), slen) == 0;
   12401             :   }
   12402         272 :   return CompareChars(content.ToUC16Vector().start(), str.start(), slen) == 0;
   12403             : }
   12404             : 
   12405             : 
   12406       74479 : bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
   12407             :   int slen = length();
   12408      148958 :   if (str.length() != slen) return false;
   12409             :   DisallowHeapAllocation no_gc;
   12410       19388 :   FlatContent content = GetFlatContent(no_gc);
   12411       19388 :   if (content.IsOneByte()) {
   12412        3972 :     return CompareChars(content.ToOneByteVector().start(), str.start(), slen) ==
   12413        3972 :            0;
   12414             :   }
   12415       30832 :   return CompareChars(content.ToUC16Vector().start(), str.start(), slen) == 0;
   12416             : }
   12417             : 
   12418    71369476 : uint32_t String::ComputeAndSetHash(Isolate* isolate) {
   12419             :   DisallowHeapAllocation no_gc;
   12420             :   // Should only be called if hash code has not yet been computed.
   12421             :   DCHECK(!HasHashCode());
   12422             : 
   12423             :   // Store the hash code in the object.
   12424             :   uint32_t field =
   12425    71369476 :       IteratingStringHasher::Hash(*this, isolate->heap()->HashSeed());
   12426             :   set_hash_field(field);
   12427             : 
   12428             :   // Check the hash code is there.
   12429             :   DCHECK(HasHashCode());
   12430    71369617 :   uint32_t result = field >> kHashShift;
   12431             :   DCHECK_NE(result, 0);  // Ensure that the hash value of 0 is never computed.
   12432    71369617 :   return result;
   12433             : }
   12434             : 
   12435             : 
   12436     1443764 : bool String::ComputeArrayIndex(uint32_t* index) {
   12437             :   int length = this->length();
   12438     1443764 :   if (length == 0 || length > kMaxArrayIndexSize) return false;
   12439      931022 :   StringCharacterStream stream(*this);
   12440      931022 :   return StringToArrayIndex(&stream, index);
   12441             : }
   12442             : 
   12443             : 
   12444     8332243 : bool String::SlowAsArrayIndex(uint32_t* index) {
   12445             :   DisallowHeapAllocation no_gc;
   12446     8332243 :   if (length() <= kMaxCachedArrayIndexLength) {
   12447     6888479 :     Hash();  // force computation of hash code
   12448             :     uint32_t field = hash_field();
   12449     6888491 :     if ((field & kIsNotArrayIndexMask) != 0) return false;
   12450             :     // Isolate the array index form the full hash field.
   12451     2219157 :     *index = ArrayIndexValueBits::decode(field);
   12452     2219157 :     return true;
   12453             :   } else {
   12454     1443764 :     return ComputeArrayIndex(index);
   12455             :   }
   12456             : }
   12457             : 
   12458             : 
   12459    15926355 : Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) {
   12460    21851256 :   if (new_length == 0) return string->GetReadOnlyRoots().empty_string_handle();
   12461             : 
   12462             :   int new_size, old_size;
   12463             :   int old_length = string->length();
   12464    12963905 :   if (old_length <= new_length) return string;
   12465             : 
   12466    23798759 :   if (string->IsSeqOneByteString()) {
   12467             :     old_size = SeqOneByteString::SizeFor(old_length);
   12468             :     new_size = SeqOneByteString::SizeFor(new_length);
   12469             :   } else {
   12470             :     DCHECK(string->IsSeqTwoByteString());
   12471             :     old_size = SeqTwoByteString::SizeFor(old_length);
   12472             :     new_size = SeqTwoByteString::SizeFor(new_length);
   12473             :   }
   12474             : 
   12475    11899379 :   int delta = old_size - new_size;
   12476             : 
   12477             :   Address start_of_string = string->address();
   12478             :   DCHECK_OBJECT_ALIGNED(start_of_string);
   12479             :   DCHECK_OBJECT_ALIGNED(start_of_string + new_size);
   12480             : 
   12481             :   Heap* heap = Heap::FromWritableHeapObject(*string);
   12482             :   // Sizes are pointer size aligned, so that we can use filler objects
   12483             :   // that are a multiple of pointer size.
   12484             :   heap->CreateFillerObjectAt(start_of_string + new_size, delta,
   12485    11899379 :                              ClearRecordedSlots::kNo);
   12486             :   // We are storing the new length using release store after creating a filler
   12487             :   // for the left-over space to avoid races with the sweeper thread.
   12488             :   string->synchronized_set_length(new_length);
   12489             : 
   12490    11899379 :   return string;
   12491             : }
   12492             : 
   12493      324429 : void SeqOneByteString::clear_padding() {
   12494      324429 :   int data_size = SeqString::kHeaderSize + length() * kOneByteSize;
   12495      324429 :   memset(reinterpret_cast<void*>(address() + data_size), 0,
   12496      648858 :          SizeFor(length()) - data_size);
   12497      324429 : }
   12498             : 
   12499           0 : void SeqTwoByteString::clear_padding() {
   12500           0 :   int data_size = SeqString::kHeaderSize + length() * kUC16Size;
   12501           0 :   memset(reinterpret_cast<void*>(address() + data_size), 0,
   12502           0 :          SizeFor(length()) - data_size);
   12503           0 : }
   12504             : 
   12505       88858 : int ExternalString::ExternalPayloadSize() const {
   12506       88858 :   int length_multiplier = IsTwoByteRepresentation() ? i::kShortSize : kCharSize;
   12507       88858 :   return length() * length_multiplier;
   12508             : }
   12509             : 
   12510     6361519 : uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
   12511             :   // For array indexes mix the length into the hash as an array index could
   12512             :   // be zero.
   12513             :   DCHECK_GT(length, 0);
   12514             :   DCHECK_LE(length, String::kMaxArrayIndexSize);
   12515             :   DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) <
   12516             :          (1 << String::kArrayIndexValueBits));
   12517             : 
   12518     7157526 :   value <<= String::ArrayIndexValueBits::kShift;
   12519     7157526 :   value |= length << String::ArrayIndexLengthBits::kShift;
   12520             : 
   12521             :   DCHECK_EQ(value & String::kIsNotArrayIndexMask, 0);
   12522             :   DCHECK_EQ(length <= String::kMaxCachedArrayIndexLength,
   12523             :             Name::ContainsCachedArrayIndex(value));
   12524     6361519 :   return value;
   12525             : }
   12526             : 
   12527             : 
   12528    85901429 : uint32_t StringHasher::GetHashField() {
   12529    85901429 :   if (length_ <= String::kMaxHashCalcLength) {
   12530    85834817 :     if (is_array_index_) {
   12531     1586602 :       return MakeArrayIndexHash(array_index_, length_);
   12532             :     }
   12533   170083032 :     return (GetHashCore(raw_running_hash_) << String::kHashShift) |
   12534    85041516 :            String::kIsNotArrayIndexMask;
   12535             :   } else {
   12536       66612 :     return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask;
   12537             :   }
   12538             : }
   12539             : 
   12540    14534349 : uint32_t StringHasher::ComputeUtf8Hash(Vector<const char> chars, uint64_t seed,
   12541             :                                        int* utf16_length_out) {
   12542    14534349 :   int vector_length = chars.length();
   12543             :   // Handle some edge cases
   12544    14534349 :   if (vector_length <= 1) {
   12545             :     DCHECK(vector_length == 0 ||
   12546             :            static_cast<uint8_t>(chars.start()[0]) <=
   12547             :                unibrow::Utf8::kMaxOneByteChar);
   12548        2559 :     *utf16_length_out = vector_length;
   12549        2559 :     return HashSequentialString(chars.start(), vector_length, seed);
   12550             :   }
   12551             : 
   12552             :   // Start with a fake length which won't affect computation.
   12553             :   // It will be updated later.
   12554             :   StringHasher hasher(String::kMaxArrayIndexSize, seed);
   12555             :   DCHECK(hasher.is_array_index_);
   12556             : 
   12557             :   unibrow::Utf8Iterator it = unibrow::Utf8Iterator(chars);
   12558             :   int utf16_length = 0;
   12559             :   bool is_index = true;
   12560             : 
   12561   134464543 :   while (utf16_length < String::kMaxHashCalcLength && !it.Done()) {
   12562   105400931 :     utf16_length++;
   12563   105400931 :     uint16_t c = *it;
   12564   105400859 :     ++it;
   12565             :     hasher.AddCharacter(c);
   12566   105400912 :     if (is_index) is_index = hasher.UpdateIndex(c);
   12567             :   }
   12568             : 
   12569             :   // Now that hashing is done, we just need to calculate utf16_length
   12570    14531805 :   while (!it.Done()) {
   12571           0 :     ++it;
   12572           0 :     utf16_length++;
   12573             :   }
   12574             : 
   12575    14531805 :   *utf16_length_out = utf16_length;
   12576             :   // Must set length here so that hash computation is correct.
   12577    14531805 :   hasher.length_ = utf16_length;
   12578    14531805 :   return hasher.GetHashField();
   12579             : }
   12580             : 
   12581      124582 : void IteratingStringHasher::VisitConsString(ConsString cons_string) {
   12582             :   // Run small ConsStrings through ConsStringIterator.
   12583      124582 :   if (cons_string->length() < 64) {
   12584             :     ConsStringIterator iter(cons_string);
   12585             :     int offset;
   12586      288331 :     for (String string = iter.Next(&offset); !string.is_null();
   12587             :          string = iter.Next(&offset)) {
   12588             :       DCHECK_EQ(0, offset);
   12589      128749 :       String::VisitFlat(this, string, 0);
   12590             :     }
   12591      124582 :     return;
   12592             :   }
   12593             :   // Slow case.
   12594       44791 :   const int max_length = String::kMaxHashCalcLength;
   12595       89582 :   int length = std::min(cons_string->length(), max_length);
   12596       44791 :   if (cons_string->HasOnlyOneByteChars()) {
   12597       44791 :     uint8_t* buffer = new uint8_t[length];
   12598       44791 :     String::WriteToFlat(cons_string, buffer, 0, length);
   12599       44791 :     AddCharacters(buffer, length);
   12600       44791 :     delete[] buffer;
   12601             :   } else {
   12602           0 :     uint16_t* buffer = new uint16_t[length];
   12603           0 :     String::WriteToFlat(cons_string, buffer, 0, length);
   12604           0 :     AddCharacters(buffer, length);
   12605           0 :     delete[] buffer;
   12606             :   }
   12607             : }
   12608             : 
   12609       41680 : void String::PrintOn(FILE* file) {
   12610             :   int length = this->length();
   12611     3513550 :   for (int i = 0; i < length; i++) {
   12612     3471870 :     PrintF(file, "%c", Get(i));
   12613             :   }
   12614       41680 : }
   12615             : 
   12616             : 
   12617      758848 : int Map::Hash() {
   12618             :   // For performance reasons we only hash the 3 most variable fields of a map:
   12619             :   // constructor, prototype and bit_field2. For predictability reasons we
   12620             :   // use objects' offsets in respective pages for hashing instead of raw
   12621             :   // addresses.
   12622             : 
   12623             :   // Shift away the tag.
   12624     1517696 :   int hash = ObjectAddressForHashing(GetConstructor().ptr()) >> 2;
   12625             : 
   12626             :   // XOR-ing the prototype and constructor directly yields too many zero bits
   12627             :   // when the two pointers are close (which is fairly common).
   12628             :   // To avoid this we shift the prototype bits relatively to the constructor.
   12629      758848 :   hash ^= ObjectAddressForHashing(prototype().ptr()) << (32 - kPageSizeBits);
   12630             : 
   12631     1517696 :   return hash ^ (hash >> 16) ^ bit_field2();
   12632             : }
   12633             : 
   12634             : 
   12635             : namespace {
   12636             : 
   12637      951943 : bool CheckEquivalent(const Map first, const Map second) {
   12638     2822318 :   return first->GetConstructor() == second->GetConstructor() &&
   12639      909992 :          first->prototype() == second->prototype() &&
   12640      909993 :          first->instance_type() == second->instance_type() &&
   12641      909993 :          first->bit_field() == second->bit_field() &&
   12642      909835 :          first->is_extensible() == second->is_extensible() &&
   12643     2771607 :          first->new_target_is_base() == second->new_target_is_base() &&
   12644     1861764 :          first->has_hidden_prototype() == second->has_hidden_prototype();
   12645             : }
   12646             : 
   12647             : }  // namespace
   12648             : 
   12649      424647 : bool Map::EquivalentToForTransition(const Map other) const {
   12650      424647 :   if (!CheckEquivalent(*this, other)) return false;
   12651      424490 :   if (instance_type() == JS_FUNCTION_TYPE) {
   12652             :     // JSFunctions require more checks to ensure that sloppy function is
   12653             :     // not equivalent to strict function.
   12654             :     int nof = Min(NumberOfOwnDescriptors(), other->NumberOfOwnDescriptors());
   12655             :     return instance_descriptors()->IsEqualUpTo(other->instance_descriptors(),
   12656        2012 :                                                nof);
   12657             :   }
   12658             :   return true;
   12659             : }
   12660             : 
   12661           0 : bool Map::EquivalentToForElementsKindTransition(const Map other) const {
   12662       26579 :   if (!EquivalentToForTransition(other)) return false;
   12663             : #ifdef DEBUG
   12664             :   // Ensure that we don't try to generate elements kind transitions from maps
   12665             :   // with fields that may be generalized in-place. This must already be handled
   12666             :   // during addition of a new field.
   12667             :   DescriptorArray descriptors = instance_descriptors();
   12668             :   int nof = NumberOfOwnDescriptors();
   12669             :   for (int i = 0; i < nof; i++) {
   12670             :     PropertyDetails details = descriptors->GetDetails(i);
   12671             :     if (details.location() == kField) {
   12672             :       DCHECK(!IsInplaceGeneralizableField(details.constness(),
   12673             :                                           details.representation(),
   12674             :                                           descriptors->GetFieldType(i)));
   12675             :     }
   12676             :   }
   12677             : #endif
   12678           0 :   return true;
   12679             : }
   12680             : 
   12681      527295 : bool Map::EquivalentToForNormalization(const Map other,
   12682             :                                        PropertyNormalizationMode mode) const {
   12683             :   int properties =
   12684      527295 :       mode == CLEAR_INOBJECT_PROPERTIES ? 0 : other->GetInObjectProperties();
   12685     1497955 :   return CheckEquivalent(*this, other) && bit_field2() == other->bit_field2() &&
   12686     1447727 :          GetInObjectProperties() == properties &&
   12687      435102 :          JSObject::GetEmbedderFieldCount(*this) ==
   12688      962397 :              JSObject::GetEmbedderFieldCount(other);
   12689             : }
   12690             : 
   12691             : 
   12692      485174 : void JSFunction::MarkForOptimization(ConcurrencyMode mode) {
   12693      969982 :   Isolate* isolate = GetIsolate();
   12694      969982 :   if (!isolate->concurrent_recompilation_enabled() ||
   12695      484802 :       isolate->bootstrapper()->IsActive()) {
   12696             :     mode = ConcurrencyMode::kNotConcurrent;
   12697             :   }
   12698             : 
   12699             :   DCHECK(!is_compiled() || IsInterpreted());
   12700             :   DCHECK(shared()->IsInterpreted());
   12701             :   DCHECK(!IsOptimized());
   12702             :   DCHECK(!HasOptimizedCode());
   12703             :   DCHECK(shared()->allows_lazy_compilation() ||
   12704             :          !shared()->optimization_disabled());
   12705             : 
   12706      485180 :   if (mode == ConcurrencyMode::kConcurrent) {
   12707       28894 :     if (IsInOptimizationQueue()) {
   12708           0 :       if (FLAG_trace_concurrent_recompilation) {
   12709           0 :         PrintF("  ** Not marking ");
   12710           0 :         ShortPrint();
   12711           0 :         PrintF(" -- already in optimization queue.\n");
   12712             :       }
   12713      485181 :       return;
   12714             :     }
   12715       28894 :     if (FLAG_trace_concurrent_recompilation) {
   12716           0 :       PrintF("  ** Marking ");
   12717           0 :       ShortPrint();
   12718           0 :       PrintF(" for concurrent recompilation.\n");
   12719             :     }
   12720             :   }
   12721             : 
   12722             :   SetOptimizationMarker(mode == ConcurrencyMode::kConcurrent
   12723             :                             ? OptimizationMarker::kCompileOptimizedConcurrent
   12724      485181 :                             : OptimizationMarker::kCompileOptimized);
   12725             : }
   12726             : 
   12727             : // static
   12728     8434330 : void JSFunction::EnsureFeedbackVector(Handle<JSFunction> function) {
   12729             :   Isolate* const isolate = function->GetIsolate();
   12730             :   DCHECK(function->shared()->is_compiled());
   12731             :   DCHECK(FLAG_lite_mode || function->shared()->HasFeedbackMetadata());
   12732    19944613 :   if (!function->has_feedback_vector() &&
   12733    11510263 :       function->shared()->HasFeedbackMetadata()) {
   12734     6151791 :     Handle<SharedFunctionInfo> shared(function->shared(), isolate);
   12735     3075895 :     if (!shared->HasAsmWasmData()) {
   12736             :       DCHECK(function->shared()->HasBytecodeArray());
   12737             :       Handle<FeedbackVector> feedback_vector =
   12738     3073782 :           FeedbackVector::New(isolate, shared);
   12739     9221345 :       if (function->raw_feedback_cell() ==
   12740     3073781 :           isolate->heap()->many_closures_cell()) {
   12741             :         Handle<FeedbackCell> feedback_cell =
   12742     1524843 :             isolate->factory()->NewOneClosureCell(feedback_vector);
   12743     1524847 :         function->set_raw_feedback_cell(*feedback_cell);
   12744             :       } else {
   12745     3097878 :         function->raw_feedback_cell()->set_value(*feedback_vector);
   12746             :       }
   12747             :     }
   12748             :   }
   12749     8434360 : }
   12750             : 
   12751      371777 : static void GetMinInobjectSlack(Map map, void* data) {
   12752      371777 :   int slack = map->UnusedPropertyFields();
   12753      371779 :   if (*reinterpret_cast<int*>(data) > slack) {
   12754       36627 :     *reinterpret_cast<int*>(data) = slack;
   12755             :   }
   12756      371779 : }
   12757             : 
   12758             : int Map::InstanceSizeFromSlack(int slack) const {
   12759      269814 :   return instance_size() - slack * kTaggedSize;
   12760             : }
   12761             : 
   12762      263470 : static void ShrinkInstanceSize(Map map, void* data) {
   12763      263470 :   int slack = *reinterpret_cast<int*>(data);
   12764             :   DCHECK_GE(slack, 0);
   12765             : #ifdef DEBUG
   12766             :   int old_visitor_id = Map::GetVisitorId(map);
   12767             :   int new_unused = map->UnusedPropertyFields() - slack;
   12768             : #endif
   12769      263470 :   map->set_instance_size(map->InstanceSizeFromSlack(slack));
   12770      263471 :   map->set_construction_counter(Map::kNoSlackTracking);
   12771             :   DCHECK_EQ(old_visitor_id, Map::GetVisitorId(map));
   12772             :   DCHECK_EQ(new_unused, map->UnusedPropertyFields());
   12773      263471 : }
   12774             : 
   12775       95412 : static void StopSlackTracking(Map map, void* data) {
   12776       95412 :   map->set_construction_counter(Map::kNoSlackTracking);
   12777       95412 : }
   12778             : 
   12779      135058 : int Map::ComputeMinObjectSlack(Isolate* isolate) {
   12780             :   DisallowHeapAllocation no_gc;
   12781             :   // Has to be an initial map.
   12782             :   DCHECK(GetBackPointer()->IsUndefined(isolate));
   12783             : 
   12784      135058 :   int slack = UnusedPropertyFields();
   12785             :   TransitionsAccessor transitions(isolate, *this, &no_gc);
   12786             :   transitions.TraverseTransitionTree(&GetMinInobjectSlack, &slack);
   12787      135060 :   return slack;
   12788             : }
   12789             : 
   12790      128714 : void Map::CompleteInobjectSlackTracking(Isolate* isolate) {
   12791             :   DisallowHeapAllocation no_gc;
   12792             :   // Has to be an initial map.
   12793             :   DCHECK(GetBackPointer()->IsUndefined(isolate));
   12794             : 
   12795      128714 :   int slack = ComputeMinObjectSlack(isolate);
   12796             :   TransitionsAccessor transitions(isolate, *this, &no_gc);
   12797      128716 :   if (slack != 0) {
   12798             :     // Resize the initial map and all maps in its transition tree.
   12799             :     transitions.TraverseTransitionTree(&ShrinkInstanceSize, &slack);
   12800             :   } else {
   12801             :     transitions.TraverseTransitionTree(&StopSlackTracking, nullptr);
   12802             :   }
   12803      128717 : }
   12804             : 
   12805    80195626 : void Map::SetInstanceDescriptors(Isolate* isolate, DescriptorArray descriptors,
   12806             :                                  int number_of_own_descriptors) {
   12807    80195626 :   set_synchronized_instance_descriptors(descriptors);
   12808    80195627 :   SetNumberOfOwnDescriptors(number_of_own_descriptors);
   12809             :   MarkingBarrierForDescriptorArray(isolate->heap(), *this, descriptors,
   12810    80195607 :                                    number_of_own_descriptors);
   12811    80195600 : }
   12812             : 
   12813    27434591 : static bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) {
   12814             :   DisallowHeapAllocation no_gc;
   12815    27434599 :   if (!object->HasFastProperties()) return false;
   12816    52456706 :   if (object->IsJSGlobalProxy()) return false;
   12817    26207029 :   if (object->GetIsolate()->bootstrapper()->IsActive()) return false;
   12818     9438501 :   return !object->map()->is_prototype_map() ||
   12819     9438501 :          !object->map()->should_be_fast_prototype_map();
   12820             : }
   12821             : 
   12822             : // static
   12823     4346350 : void JSObject::MakePrototypesFast(Handle<Object> receiver,
   12824             :                                   WhereToStart where_to_start,
   12825             :                                   Isolate* isolate) {
   12826     8692731 :   if (!receiver->IsJSReceiver()) return;
   12827    12082094 :   for (PrototypeIterator iter(isolate, Handle<JSReceiver>::cast(receiver),
   12828     4300363 :                               where_to_start);
   12829    11263164 :        !iter.IsAtEnd(); iter.Advance()) {
   12830             :     Handle<Object> current = PrototypeIterator::GetCurrent(iter);
   12831    19805809 :     if (!current->IsJSObject()) return;
   12832     7756196 :     Handle<JSObject> current_obj = Handle<JSObject>::cast(current);
   12833     7756198 :     Map current_map = current_obj->map();
   12834     7756198 :     if (current_map->is_prototype_map()) {
   12835             :       // If the map is already marked as should be fast, we're done. Its
   12836             :       // prototypes will have been marked already as well.
   12837     9100214 :       if (current_map->should_be_fast_prototype_map()) return;
   12838             :       Handle<Map> map(current_map, isolate);
   12839      550648 :       Map::SetShouldBeFastPrototypeMap(map, true, isolate);
   12840      550646 :       JSObject::OptimizeAsPrototype(current_obj);
   12841             :     }
   12842             :   }
   12843             : }
   12844             : 
   12845             : // static
   12846    27547732 : void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
   12847             :                                    bool enable_setup_mode) {
   12848    82643258 :   if (object->IsJSGlobalObject()) return;
   12849    27449683 :   if (enable_setup_mode && PrototypeBenefitsFromNormalization(object)) {
   12850             :     // First normalize to ensure all JSFunctions are DATA_CONSTANT.
   12851             :     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0,
   12852      328747 :                                   "NormalizeAsPrototype");
   12853             :   }
   12854    27449713 :   if (object->map()->is_prototype_map()) {
   12855    64972240 :     if (object->map()->should_be_fast_prototype_map() &&
   12856    42116570 :         !object->HasFastProperties()) {
   12857      283096 :       JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype");
   12858             :     }
   12859             :   } else {
   12860             :     Handle<Map> new_map = Map::Copy(object->GetIsolate(),
   12861             :                                     handle(object->map(), object->GetIsolate()),
   12862     4594048 :                                     "CopyAsPrototype");
   12863     4594047 :     JSObject::MigrateToMap(object, new_map);
   12864             :     object->map()->set_is_prototype_map(true);
   12865             : 
   12866             :     // Replace the pointer to the exact constructor with the Object function
   12867             :     // from the same context if undetectable from JS. This is to avoid keeping
   12868             :     // memory alive unnecessarily.
   12869     4594053 :     Object maybe_constructor = object->map()->GetConstructor();
   12870     4594047 :     if (maybe_constructor->IsJSFunction()) {
   12871     4593379 :       JSFunction constructor = JSFunction::cast(maybe_constructor);
   12872     4593379 :       if (!constructor->shared()->IsApiFunction()) {
   12873     4538493 :         Context context = constructor->context()->native_context();
   12874     4538494 :         JSFunction object_function = context->object_function();
   12875     4538494 :         object->map()->SetConstructor(object_function);
   12876             :       }
   12877             :     }
   12878             :   }
   12879             : }
   12880             : 
   12881             : 
   12882             : // static
   12883      360091 : void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) {
   12884      360091 :   if (!object->map()->is_prototype_map()) return;
   12885       57570 :   if (!object->map()->should_be_fast_prototype_map()) return;
   12886       39112 :   OptimizeAsPrototype(object);
   12887             : }
   12888             : 
   12889             : 
   12890             : // static
   12891     1734944 : void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
   12892             :   // Contract: In line with InvalidatePrototypeChains()'s requirements,
   12893             :   // leaf maps don't need to register as users, only prototypes do.
   12894             :   DCHECK(user->is_prototype_map());
   12895             : 
   12896     1734944 :   Handle<Map> current_user = user;
   12897             :   Handle<PrototypeInfo> current_user_info =
   12898     1734944 :       Map::GetOrCreatePrototypeInfo(user, isolate);
   12899     4471575 :   for (PrototypeIterator iter(isolate, user); !iter.IsAtEnd(); iter.Advance()) {
   12900             :     // Walk up the prototype chain as far as links haven't been registered yet.
   12901     1599908 :     if (current_user_info->registry_slot() != PrototypeInfo::UNREGISTERED) {
   12902             :       break;
   12903             :     }
   12904             :     Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter);
   12905             :     // Proxies on the prototype chain are not supported. They make it
   12906             :     // impossible to make any assumptions about the prototype chain anyway.
   12907     2737560 :     if (maybe_proto->IsJSProxy()) return;
   12908      500838 :     Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto);
   12909             :     Handle<PrototypeInfo> proto_info =
   12910      500838 :         Map::GetOrCreatePrototypeInfo(proto, isolate);
   12911     1001676 :     Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
   12912             :     Handle<WeakArrayList> registry =
   12913     1001674 :         maybe_registry->IsSmi()
   12914             :             ? handle(ReadOnlyRoots(isolate->heap()).empty_weak_array_list(),
   12915      118629 :                      isolate)
   12916      619466 :             : Handle<WeakArrayList>::cast(maybe_registry);
   12917      500837 :     int slot = 0;
   12918             :     Handle<WeakArrayList> new_array =
   12919      500837 :         PrototypeUsers::Add(isolate, registry, current_user, &slot);
   12920      500838 :     current_user_info->set_registry_slot(slot);
   12921      500838 :     if (!maybe_registry.is_identical_to(new_array)) {
   12922      266808 :       proto_info->set_prototype_users(*new_array);
   12923             :     }
   12924      500839 :     if (FLAG_trace_prototype_users) {
   12925             :       PrintF("Registering %p as a user of prototype %p (map=%p).\n",
   12926             :              reinterpret_cast<void*>(current_user->ptr()),
   12927             :              reinterpret_cast<void*>(proto->ptr()),
   12928           0 :              reinterpret_cast<void*>(proto->map()->ptr()));
   12929             :     }
   12930             : 
   12931             :     current_user = handle(proto->map(), isolate);
   12932             :     current_user_info = proto_info;
   12933             :   }
   12934             : }
   12935             : 
   12936             : 
   12937             : // Can be called regardless of whether |user| was actually registered with
   12938             : // |prototype|. Returns true when there was a registration.
   12939             : // static
   12940     4252986 : bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
   12941             :   DCHECK(user->is_prototype_map());
   12942             :   // If it doesn't have a PrototypeInfo, it was never registered.
   12943     8505976 :   if (!user->prototype_info()->IsPrototypeInfo()) return false;
   12944             :   // If it had no prototype before, see if it had users that might expect
   12945             :   // registration.
   12946     3167925 :   if (!user->prototype()->IsJSObject()) {
   12947             :     Object users =
   12948       69518 :         PrototypeInfo::cast(user->prototype_info())->prototype_users();
   12949             :     return users->IsWeakArrayList();
   12950             :   }
   12951             :   Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate);
   12952             :   Handle<PrototypeInfo> user_info =
   12953     1514445 :       Map::GetOrCreatePrototypeInfo(user, isolate);
   12954             :   int slot = user_info->registry_slot();
   12955     1514445 :   if (slot == PrototypeInfo::UNREGISTERED) return false;
   12956             :   DCHECK(prototype->map()->is_prototype_map());
   12957             :   Object maybe_proto_info = prototype->map()->prototype_info();
   12958             :   // User knows its registry slot, prototype info and user registry must exist.
   12959             :   DCHECK(maybe_proto_info->IsPrototypeInfo());
   12960             :   Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info),
   12961             :                                    isolate);
   12962             :   Handle<WeakArrayList> prototype_users(
   12963      251278 :       WeakArrayList::cast(proto_info->prototype_users()), isolate);
   12964             :   DCHECK_EQ(prototype_users->Get(slot), HeapObjectReference::Weak(*user));
   12965      125639 :   PrototypeUsers::MarkSlotEmpty(*prototype_users, slot);
   12966      125638 :   if (FLAG_trace_prototype_users) {
   12967             :     PrintF("Unregistering %p as a user of prototype %p.\n",
   12968             :            reinterpret_cast<void*>(user->ptr()),
   12969           0 :            reinterpret_cast<void*>(prototype->ptr()));
   12970             :   }
   12971             :   return true;
   12972             : }
   12973             : 
   12974             : namespace {
   12975             : 
   12976             : // This function must be kept in sync with
   12977             : // AccessorAssembler::InvalidateValidityCellIfPrototype() which does pre-checks
   12978             : // before jumping here.
   12979    16296382 : void InvalidateOnePrototypeValidityCellInternal(Map map) {
   12980             :   DCHECK(map->is_prototype_map());
   12981    16296382 :   if (FLAG_trace_prototype_users) {
   12982             :     PrintF("Invalidating prototype map %p 's cell\n",
   12983           0 :            reinterpret_cast<void*>(map.ptr()));
   12984             :   }
   12985    16296382 :   Object maybe_cell = map->prototype_validity_cell();
   12986    16296401 :   if (maybe_cell->IsCell()) {
   12987             :     // Just set the value; the cell will be replaced lazily.
   12988    16231688 :     Cell cell = Cell::cast(maybe_cell);
   12989    16231688 :     cell->set_value(Smi::FromInt(Map::kPrototypeChainInvalid));
   12990             :   }
   12991    16296395 : }
   12992             : 
   12993    15415174 : void InvalidatePrototypeChainsInternal(Map map) {
   12994    15415174 :   InvalidateOnePrototypeValidityCellInternal(map);
   12995             : 
   12996    15415178 :   Object maybe_proto_info = map->prototype_info();
   12997    28315987 :   if (!maybe_proto_info->IsPrototypeInfo()) return;
   12998     4424185 :   PrototypeInfo proto_info = PrototypeInfo::cast(maybe_proto_info);
   12999     8848370 :   if (!proto_info->prototype_users()->IsWeakArrayList()) {
   13000             :     return;
   13001             :   }
   13002             :   WeakArrayList prototype_users =
   13003     5028722 :       WeakArrayList::cast(proto_info->prototype_users());
   13004             :   // For now, only maps register themselves as users.
   13005    14491264 :   for (int i = PrototypeUsers::kFirstIndex; i < prototype_users->length();
   13006             :        ++i) {
   13007     4731271 :     HeapObject heap_object;
   13008     7184863 :     if (prototype_users->Get(i)->GetHeapObjectIfWeak(&heap_object) &&
   13009             :         heap_object->IsMap()) {
   13010             :       // Walk the prototype chain (backwards, towards leaf objects) if
   13011             :       // necessary.
   13012     2453592 :       InvalidatePrototypeChainsInternal(Map::cast(heap_object));
   13013             :     }
   13014             :   }
   13015             : }
   13016             : 
   13017             : }  // namespace
   13018             : 
   13019             : // static
   13020     8663007 : Map JSObject::InvalidatePrototypeChains(Map map) {
   13021             :   DisallowHeapAllocation no_gc;
   13022    12961594 :   InvalidatePrototypeChainsInternal(map);
   13023     8663005 :   return map;
   13024             : }
   13025             : 
   13026             : // We also invalidate global objects validity cell when a new lexical
   13027             : // environment variable is added. This is necessary to ensure that
   13028             : // Load/StoreGlobalIC handlers that load/store from global object's prototype
   13029             : // get properly invalidated.
   13030             : // Note, that the normal Load/StoreICs that load/store through the global object
   13031             : // in the prototype chain are not affected by appearance of a new lexical
   13032             : // variable and therefore we don't propagate invalidation down.
   13033             : // static
   13034      881215 : void JSObject::InvalidatePrototypeValidityCell(JSGlobalObject global) {
   13035             :   DisallowHeapAllocation no_gc;
   13036      881215 :   InvalidateOnePrototypeValidityCellInternal(global->map());
   13037      881215 : }
   13038             : 
   13039             : // static
   13040      620044 : Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<JSObject> prototype,
   13041             :                                                     Isolate* isolate) {
   13042      620047 :   Object maybe_proto_info = prototype->map()->prototype_info();
   13043      620046 :   if (maybe_proto_info->IsPrototypeInfo()) {
   13044             :     return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
   13045             :   }
   13046      136148 :   Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
   13047      272296 :   prototype->map()->set_prototype_info(*proto_info);
   13048      136148 :   return proto_info;
   13049             : }
   13050             : 
   13051             : 
   13052             : // static
   13053     3891958 : Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> prototype_map,
   13054             :                                                     Isolate* isolate) {
   13055     3891960 :   Object maybe_proto_info = prototype_map->prototype_info();
   13056     3891969 :   if (maybe_proto_info->IsPrototypeInfo()) {
   13057             :     return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
   13058             :   }
   13059      545063 :   Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
   13060     1090131 :   prototype_map->set_prototype_info(*proto_info);
   13061      545068 :   return proto_info;
   13062             : }
   13063             : 
   13064             : // static
   13065      642573 : void Map::SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
   13066             :                                       Isolate* isolate) {
   13067      642573 :   if (value == false && !map->prototype_info()->IsPrototypeInfo()) {
   13068             :     // "False" is the implicit default value, so there's nothing to do.
   13069      642574 :     return;
   13070             :   }
   13071     1285147 :   GetOrCreatePrototypeInfo(map, isolate)->set_should_be_fast_map(value);
   13072             : }
   13073             : 
   13074             : // static
   13075     1609295 : Handle<Object> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
   13076             :                                                           Isolate* isolate) {
   13077             :   Handle<Object> maybe_prototype;
   13078     1609295 :   if (map->IsJSGlobalObjectMap()) {
   13079             :     DCHECK(map->is_prototype_map());
   13080             :     // Global object is prototype of a global proxy and therefore we can
   13081             :     // use its validity cell for guarding global object's prototype change.
   13082       43124 :     maybe_prototype = isolate->global_object();
   13083             :   } else {
   13084             :     maybe_prototype =
   13085     3132348 :         handle(map->GetPrototypeChainRootMap(isolate)->prototype(), isolate);
   13086             :   }
   13087     3218602 :   if (!maybe_prototype->IsJSObject()) {
   13088       66608 :     return handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
   13089             :   }
   13090     1542696 :   Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
   13091             :   // Ensure the prototype is registered with its own prototypes so its cell
   13092             :   // will be invalidated when necessary.
   13093             :   JSObject::LazyRegisterPrototypeUser(handle(prototype->map(), isolate),
   13094     1542697 :                                       isolate);
   13095             : 
   13096     1542702 :   Object maybe_cell = prototype->map()->prototype_validity_cell();
   13097             :   // Return existing cell if it's still valid.
   13098     1542706 :   if (maybe_cell->IsCell()) {
   13099             :     Handle<Cell> cell(Cell::cast(maybe_cell), isolate);
   13100     3085264 :     if (cell->value() == Smi::FromInt(Map::kPrototypeChainValid)) {
   13101     1126609 :       return cell;
   13102             :     }
   13103             :   }
   13104             :   // Otherwise create a new cell.
   13105             :   Handle<Cell> cell = isolate->factory()->NewCell(
   13106      416096 :       handle(Smi::FromInt(Map::kPrototypeChainValid), isolate));
   13107      832190 :   prototype->map()->set_prototype_validity_cell(*cell);
   13108      416097 :   return cell;
   13109             : }
   13110             : 
   13111             : // static
   13112           0 : bool Map::IsPrototypeChainInvalidated(Map map) {
   13113             :   DCHECK(map->is_prototype_map());
   13114           0 :   Object maybe_cell = map->prototype_validity_cell();
   13115           0 :   if (maybe_cell->IsCell()) {
   13116           0 :     Cell cell = Cell::cast(maybe_cell);
   13117           0 :     return cell->value() != Smi::FromInt(Map::kPrototypeChainValid);
   13118             :   }
   13119             :   return true;
   13120             : }
   13121             : 
   13122             : // static
   13123    31305081 : void Map::SetPrototype(Isolate* isolate, Handle<Map> map,
   13124             :                        Handle<Object> prototype,
   13125             :                        bool enable_prototype_setup_mode) {
   13126             :   RuntimeCallTimerScope stats_scope(isolate, *map,
   13127             :                                     RuntimeCallCounterId::kMap_SetPrototype);
   13128             : 
   13129             :   bool is_hidden = false;
   13130    62610274 :   if (prototype->IsJSObject()) {
   13131    26576543 :     Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype);
   13132    26576543 :     JSObject::OptimizeAsPrototype(prototype_jsobj, enable_prototype_setup_mode);
   13133             : 
   13134    26576589 :     Object maybe_constructor = prototype_jsobj->map()->GetConstructor();
   13135    26576595 :     if (maybe_constructor->IsJSFunction()) {
   13136    25581120 :       JSFunction constructor = JSFunction::cast(maybe_constructor);
   13137    51162241 :       Object data = constructor->shared()->function_data();
   13138      230423 :       is_hidden = (data->IsFunctionTemplateInfo() &&
   13139    77203945 :                    FunctionTemplateInfo::cast(data)->hidden_prototype()) ||
   13140    76512655 :                   prototype->IsJSGlobalObject();
   13141      995467 :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
   13142             :       is_hidden =
   13143          54 :           FunctionTemplateInfo::cast(maybe_constructor)->hidden_prototype() ||
   13144          36 :           prototype->IsJSGlobalObject();
   13145             :     }
   13146             :   }
   13147    62610330 :   map->set_has_hidden_prototype(is_hidden);
   13148             : 
   13149             :   WriteBarrierMode wb_mode =
   13150    62610250 :       prototype->IsNull(isolate) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
   13151    31305128 :   map->set_prototype(*prototype, wb_mode);
   13152    31305124 : }
   13153             : 
   13154         222 : Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
   13155             :                                        Handle<Map> initial_map) {
   13156             :   // Replace all of the cached initial array maps in the native context with
   13157             :   // the appropriate transitioned elements kind maps.
   13158         222 :   Handle<Map> current_map = initial_map;
   13159             :   ElementsKind kind = current_map->elements_kind();
   13160             :   DCHECK_EQ(GetInitialFastElementsKind(), kind);
   13161         444 :   native_context->set(Context::ArrayMapIndex(kind), *current_map);
   13162        1332 :   for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
   13163             :        i < kFastElementsKindCount; ++i) {
   13164             :     Handle<Map> new_map;
   13165        1110 :     ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
   13166        1110 :     Map maybe_elements_transition = current_map->ElementsTransitionMap();
   13167        1110 :     if (!maybe_elements_transition.is_null()) {
   13168             :       new_map = handle(maybe_elements_transition, native_context->GetIsolate());
   13169             :     } else {
   13170             :       new_map =
   13171             :           Map::CopyAsElementsKind(native_context->GetIsolate(), current_map,
   13172        2220 :                                   next_kind, INSERT_TRANSITION);
   13173             :     }
   13174             :     DCHECK_EQ(next_kind, new_map->elements_kind());
   13175        2220 :     native_context->set(Context::ArrayMapIndex(next_kind), *new_map);
   13176             :     current_map = new_map;
   13177             :   }
   13178         222 :   return initial_map;
   13179             : }
   13180             : 
   13181             : namespace {
   13182             : 
   13183      390144 : void SetInstancePrototype(Isolate* isolate, Handle<JSFunction> function,
   13184             :                           Handle<JSReceiver> value) {
   13185             :   // Now some logic for the maps of the objects that are created by using this
   13186             :   // function as a constructor.
   13187      274522 :   if (function->has_initial_map()) {
   13188             :     // If the function has allocated the initial map replace it with a
   13189             :     // copy containing the new prototype.  Also complete any in-object
   13190             :     // slack tracking that is in progress at this point because it is
   13191             :     // still tracking the old copy.
   13192      115622 :     function->CompleteInobjectSlackTrackingIfActive();
   13193             : 
   13194      231244 :     Handle<Map> initial_map(function->initial_map(), isolate);
   13195             : 
   13196      230467 :     if (!isolate->bootstrapper()->IsActive() &&
   13197             :         initial_map->instance_type() == JS_OBJECT_TYPE) {
   13198             :       // Put the value in the initial map field until an initial map is needed.
   13199             :       // At that point, a new initial map is created and the prototype is put
   13200             :       // into the initial map where it belongs.
   13201      229024 :       function->set_prototype_or_initial_map(*value);
   13202             :     } else {
   13203             :       Handle<Map> new_map =
   13204        1110 :           Map::Copy(isolate, initial_map, "SetInstancePrototype");
   13205        1110 :       JSFunction::SetInitialMap(function, new_map, value);
   13206             : 
   13207             :       // If the function is used as the global Array function, cache the
   13208             :       // updated initial maps (and transitioned versions) in the native context.
   13209        2220 :       Handle<Context> native_context(function->context()->native_context(),
   13210        2220 :                                      isolate);
   13211             :       Handle<Object> array_function(
   13212        2220 :           native_context->get(Context::ARRAY_FUNCTION_INDEX), isolate);
   13213        3219 :       if (array_function->IsJSFunction() &&
   13214             :           *function == JSFunction::cast(*array_function)) {
   13215         111 :         CacheInitialJSArrayMaps(native_context, new_map);
   13216             :       }
   13217             :     }
   13218             : 
   13219             :     // Deoptimize all code that embeds the previous initial map.
   13220      231244 :     initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
   13221      115622 :         isolate, DependentCode::kInitialMapChangedGroup);
   13222             :   } else {
   13223             :     // Put the value in the initial map field until an initial map is
   13224             :     // needed.  At that point, a new initial map is created and the
   13225             :     // prototype is put into the initial map where it belongs.
   13226      317800 :     function->set_prototype_or_initial_map(*value);
   13227      317800 :     if (value->IsJSObject()) {
   13228             :       // Optimize as prototype to detach it from its transition tree.
   13229      158837 :       JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
   13230             :     }
   13231             :   }
   13232      274522 : }
   13233             : 
   13234             : }  // anonymous namespace
   13235             : 
   13236      274522 : void JSFunction::SetPrototype(Handle<JSFunction> function,
   13237             :                               Handle<Object> value) {
   13238             :   DCHECK(function->IsConstructor() ||
   13239             :          IsGeneratorFunction(function->shared()->kind()));
   13240             :   Isolate* isolate = function->GetIsolate();
   13241             :   Handle<JSReceiver> construct_prototype;
   13242             : 
   13243             :   // If the value is not a JSReceiver, store the value in the map's
   13244             :   // constructor field so it can be accessed.  Also, set the prototype
   13245             :   // used for constructing objects to the original object prototype.
   13246             :   // See ECMA-262 13.2.2.
   13247      549044 :   if (!value->IsJSReceiver()) {
   13248             :     // Copy the map so this does not affect unrelated functions.
   13249             :     // Remove map transitions because they point to maps with a
   13250             :     // different prototype.
   13251             :     Handle<Map> new_map =
   13252       94213 :         Map::Copy(isolate, handle(function->map(), isolate), "SetPrototype");
   13253             : 
   13254       94213 :     JSObject::MigrateToMap(function, new_map);
   13255       94213 :     new_map->SetConstructor(*value);
   13256             :     new_map->set_has_non_instance_prototype(true);
   13257             : 
   13258      188426 :     FunctionKind kind = function->shared()->kind();
   13259      188426 :     Handle<Context> native_context(function->context()->native_context(),
   13260      188426 :                                    isolate);
   13261             : 
   13262             :     construct_prototype = Handle<JSReceiver>(
   13263             :         IsGeneratorFunction(kind)
   13264             :             ? IsAsyncFunction(kind)
   13265       94231 :                   ? native_context->initial_async_generator_prototype()
   13266       94285 :                   : native_context->initial_generator_prototype()
   13267      188345 :             : native_context->initial_object_prototype(),
   13268      376924 :         isolate);
   13269             :   } else {
   13270      180309 :     construct_prototype = Handle<JSReceiver>::cast(value);
   13271             :     function->map()->set_has_non_instance_prototype(false);
   13272             :   }
   13273             : 
   13274      274522 :   SetInstancePrototype(isolate, function, construct_prototype);
   13275      274522 : }
   13276             : 
   13277     4970763 : void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
   13278             :                                Handle<Object> prototype) {
   13279     4970766 :   if (map->prototype() != *prototype)
   13280     4970216 :     Map::SetPrototype(function->GetIsolate(), map, prototype);
   13281     9941537 :   function->set_prototype_or_initial_map(*map);
   13282     9941544 :   map->SetConstructor(*function);
   13283     4970768 :   if (FLAG_trace_maps) {
   13284        3639 :     LOG(function->GetIsolate(), MapEvent("InitialMap", Map(), *map, "",
   13285             :                                          function->shared()->DebugName()));
   13286             :   }
   13287     4970768 : }
   13288             : 
   13289             : 
   13290             : #ifdef DEBUG
   13291             : namespace {
   13292             : 
   13293             : bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
   13294             :   switch (instance_type) {
   13295             :     case JS_API_OBJECT_TYPE:
   13296             :     case JS_ARRAY_BUFFER_TYPE:
   13297             :     case JS_ARRAY_TYPE:
   13298             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
   13299             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
   13300             :     case JS_DATA_VIEW_TYPE:
   13301             :     case JS_DATE_TYPE:
   13302             :     case JS_FUNCTION_TYPE:
   13303             :     case JS_GENERATOR_OBJECT_TYPE:
   13304             : #ifdef V8_INTL_SUPPORT
   13305             :     case JS_INTL_COLLATOR_TYPE:
   13306             :     case JS_INTL_DATE_TIME_FORMAT_TYPE:
   13307             :     case JS_INTL_LIST_FORMAT_TYPE:
   13308             :     case JS_INTL_LOCALE_TYPE:
   13309             :     case JS_INTL_NUMBER_FORMAT_TYPE:
   13310             :     case JS_INTL_PLURAL_RULES_TYPE:
   13311             :     case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
   13312             :     case JS_INTL_SEGMENT_ITERATOR_TYPE:
   13313             :     case JS_INTL_SEGMENTER_TYPE:
   13314             :     case JS_INTL_V8_BREAK_ITERATOR_TYPE:
   13315             : #endif
   13316             :     case JS_ASYNC_FUNCTION_OBJECT_TYPE:
   13317             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
   13318             :     case JS_MAP_TYPE:
   13319             :     case JS_MESSAGE_OBJECT_TYPE:
   13320             :     case JS_OBJECT_TYPE:
   13321             :     case JS_ERROR_TYPE:
   13322             :     case JS_ARGUMENTS_TYPE:
   13323             :     case JS_PROMISE_TYPE:
   13324             :     case JS_REGEXP_TYPE:
   13325             :     case JS_SET_TYPE:
   13326             :     case JS_SPECIAL_API_OBJECT_TYPE:
   13327             :     case JS_TYPED_ARRAY_TYPE:
   13328             :     case JS_VALUE_TYPE:
   13329             :     case JS_WEAK_MAP_TYPE:
   13330             :     case JS_WEAK_SET_TYPE:
   13331             :     case WASM_GLOBAL_TYPE:
   13332             :     case WASM_INSTANCE_TYPE:
   13333             :     case WASM_MEMORY_TYPE:
   13334             :     case WASM_MODULE_TYPE:
   13335             :     case WASM_TABLE_TYPE:
   13336             :       return true;
   13337             : 
   13338             :     case BIGINT_TYPE:
   13339             :     case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
   13340             :     case BYTECODE_ARRAY_TYPE:
   13341             :     case BYTE_ARRAY_TYPE:
   13342             :     case CELL_TYPE:
   13343             :     case CODE_TYPE:
   13344             :     case FILLER_TYPE:
   13345             :     case FIXED_ARRAY_TYPE:
   13346             :     case SCRIPT_CONTEXT_TABLE_TYPE:
   13347             :     case FIXED_DOUBLE_ARRAY_TYPE:
   13348             :     case FEEDBACK_METADATA_TYPE:
   13349             :     case FOREIGN_TYPE:
   13350             :     case FREE_SPACE_TYPE:
   13351             :     case HASH_TABLE_TYPE:
   13352             :     case ORDERED_HASH_MAP_TYPE:
   13353             :     case ORDERED_HASH_SET_TYPE:
   13354             :     case ORDERED_NAME_DICTIONARY_TYPE:
   13355             :     case NAME_DICTIONARY_TYPE:
   13356             :     case GLOBAL_DICTIONARY_TYPE:
   13357             :     case NUMBER_DICTIONARY_TYPE:
   13358             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
   13359             :     case STRING_TABLE_TYPE:
   13360             :     case HEAP_NUMBER_TYPE:
   13361             :     case JS_BOUND_FUNCTION_TYPE:
   13362             :     case JS_GLOBAL_OBJECT_TYPE:
   13363             :     case JS_GLOBAL_PROXY_TYPE:
   13364             :     case JS_PROXY_TYPE:
   13365             :     case MAP_TYPE:
   13366             :     case MUTABLE_HEAP_NUMBER_TYPE:
   13367             :     case ODDBALL_TYPE:
   13368             :     case PROPERTY_CELL_TYPE:
   13369             :     case SHARED_FUNCTION_INFO_TYPE:
   13370             :     case SYMBOL_TYPE:
   13371             :     case ALLOCATION_SITE_TYPE:
   13372             : 
   13373             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
   13374             :   case FIXED_##TYPE##_ARRAY_TYPE:
   13375             : #undef TYPED_ARRAY_CASE
   13376             : 
   13377             : #define MAKE_STRUCT_CASE(TYPE, Name, name) case TYPE:
   13378             :       STRUCT_LIST(MAKE_STRUCT_CASE)
   13379             : #undef MAKE_STRUCT_CASE
   13380             :       // We must not end up here for these instance types at all.
   13381             :       UNREACHABLE();
   13382             :     // Fall through.
   13383             :     default:
   13384             :       return false;
   13385             :   }
   13386             : }
   13387             : 
   13388             : }  // namespace
   13389             : #endif
   13390             : 
   13391             : 
   13392    19744809 : void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
   13393             :   DCHECK(function->has_prototype_slot());
   13394             :   DCHECK(function->IsConstructor() ||
   13395             :          IsResumableFunction(function->shared()->kind()));
   13396    39179492 :   if (function->has_initial_map()) return;
   13397             :   Isolate* isolate = function->GetIsolate();
   13398             : 
   13399             :   // First create a new map with the size and number of in-object properties
   13400             :   // suggested by the function.
   13401             :   InstanceType instance_type;
   13402      620341 :   if (IsResumableFunction(function->shared()->kind())) {
   13403       17256 :     instance_type = IsAsyncGeneratorFunction(function->shared()->kind())
   13404             :                         ? JS_ASYNC_GENERATOR_OBJECT_TYPE
   13405        8628 :                         : JS_GENERATOR_OBJECT_TYPE;
   13406             :   } else {
   13407             :     instance_type = JS_OBJECT_TYPE;
   13408             :   }
   13409             : 
   13410             :   // The constructor should be compiled for the optimization hints to be
   13411             :   // available.
   13412             :   int expected_nof_properties = 0;
   13413      310170 :   IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
   13414      337206 :   if (is_compiled_scope.is_compiled() ||
   13415             :       Compiler::Compile(function, Compiler::CLEAR_EXCEPTION,
   13416       27037 :                         &is_compiled_scope)) {
   13417             :     DCHECK(function->shared()->is_compiled());
   13418      620319 :     expected_nof_properties = function->shared()->expected_nof_properties();
   13419             :   }
   13420             : 
   13421             :   int instance_size;
   13422             :   int inobject_properties;
   13423             :   CalculateInstanceSizeHelper(instance_type, false, 0, expected_nof_properties,
   13424      310168 :                               &instance_size, &inobject_properties);
   13425             : 
   13426             :   Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size,
   13427             :                                                TERMINAL_FAST_ELEMENTS_KIND,
   13428      310167 :                                                inobject_properties);
   13429             : 
   13430             :   // Fetch or allocate prototype.
   13431             :   Handle<Object> prototype;
   13432      310170 :   if (function->has_instance_prototype()) {
   13433      499494 :     prototype = handle(function->instance_prototype(), isolate);
   13434             :   } else {
   13435       60422 :     prototype = isolate->factory()->NewFunctionPrototype(function);
   13436             :   }
   13437             :   DCHECK(map->has_fast_object_elements());
   13438             : 
   13439             :   // Finally link initial map and constructor function.
   13440             :   DCHECK(prototype->IsJSReceiver());
   13441      310168 :   JSFunction::SetInitialMap(function, map, prototype);
   13442      310171 :   map->StartInobjectSlackTracking();
   13443             : }
   13444             : 
   13445             : namespace {
   13446      497258 : bool FastInitializeDerivedMap(Isolate* isolate, Handle<JSFunction> new_target,
   13447             :                               Handle<JSFunction> constructor,
   13448             :                               Handle<Map> constructor_initial_map) {
   13449             :   // Use the default intrinsic prototype instead.
   13450      497258 :   if (!new_target->has_prototype_slot()) return false;
   13451             :   // Check that |function|'s initial map still in sync with the |constructor|,
   13452             :   // otherwise we must create a new initial map for |function|.
   13453     1478733 :   if (new_target->has_initial_map() &&
   13454      981493 :       new_target->initial_map()->GetConstructor() == *constructor) {
   13455             :     DCHECK(new_target->instance_prototype()->IsJSReceiver());
   13456             :     return true;
   13457             :   }
   13458             :   InstanceType instance_type = constructor_initial_map->instance_type();
   13459             :   DCHECK(CanSubclassHaveInobjectProperties(instance_type));
   13460             :   // Create a new map with the size and number of in-object properties
   13461             :   // suggested by |function|.
   13462             : 
   13463             :   // Link initial map and constructor function if the new.target is actually a
   13464             :   // subclass constructor.
   13465      681488 :   if (!IsDerivedConstructor(new_target->shared()->kind())) return false;
   13466             : 
   13467             :   int instance_size;
   13468             :   int in_object_properties;
   13469             :   int embedder_fields =
   13470       11343 :       JSObject::GetEmbedderFieldCount(*constructor_initial_map);
   13471             :   bool success = JSFunction::CalculateInstanceSizeForDerivedClass(
   13472             :       new_target, instance_type, embedder_fields, &instance_size,
   13473       11343 :       &in_object_properties);
   13474             : 
   13475             :   Handle<Map> map;
   13476       11343 :   if (success) {
   13477       22686 :     int pre_allocated = constructor_initial_map->GetInObjectProperties() -
   13478       11343 :                         constructor_initial_map->UnusedPropertyFields();
   13479       22684 :     CHECK_LE(constructor_initial_map->UsedInstanceSize(), instance_size);
   13480       11343 :     int unused_property_fields = in_object_properties - pre_allocated;
   13481             :     map = Map::CopyInitialMap(isolate, constructor_initial_map, instance_size,
   13482       11343 :                               in_object_properties, unused_property_fields);
   13483             :   } else {
   13484           0 :     map = Map::CopyInitialMap(isolate, constructor_initial_map);
   13485             :   }
   13486       11343 :   map->set_new_target_is_base(false);
   13487       22686 :   Handle<Object> prototype(new_target->instance_prototype(), isolate);
   13488       11343 :   JSFunction::SetInitialMap(new_target, map, prototype);
   13489             :   DCHECK(new_target->instance_prototype()->IsJSReceiver());
   13490       22682 :   map->SetConstructor(*constructor);
   13491       11342 :   map->set_construction_counter(Map::kNoSlackTracking);
   13492       11343 :   map->StartInobjectSlackTracking();
   13493       11343 :   return true;
   13494             : }
   13495             : 
   13496             : }  // namespace
   13497             : 
   13498             : // static
   13499     3341697 : MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
   13500             :                                            Handle<JSFunction> constructor,
   13501             :                                            Handle<JSReceiver> new_target) {
   13502     3341697 :   EnsureHasInitialMap(constructor);
   13503             : 
   13504     6683442 :   Handle<Map> constructor_initial_map(constructor->initial_map(), isolate);
   13505     3341725 :   if (*new_target == *constructor) return constructor_initial_map;
   13506             : 
   13507             :   Handle<Map> result_map;
   13508             :   // Fast case, new.target is a subclass of constructor. The map is cacheable
   13509             :   // (and may already have been cached). new.target.prototype is guaranteed to
   13510             :   // be a JSReceiver.
   13511      997493 :   if (new_target->IsJSFunction()) {
   13512      497258 :     Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
   13513      497258 :     if (FastInitializeDerivedMap(isolate, function, constructor,
   13514             :                                  constructor_initial_map)) {
   13515      335695 :       return handle(function->initial_map(), isolate);
   13516             :     }
   13517             :   }
   13518             : 
   13519             :   // Slow path, new.target is either a proxy or can't cache the map.
   13520             :   // new.target.prototype is not guaranteed to be a JSReceiver, and may need to
   13521             :   // fall back to the intrinsicDefaultProto.
   13522             :   Handle<Object> prototype;
   13523      661791 :   if (new_target->IsJSFunction()) {
   13524      329411 :     Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
   13525      329406 :     if (function->has_prototype_slot()) {
   13526             :       // Make sure the new.target.prototype is cached.
   13527      329397 :       EnsureHasInitialMap(function);
   13528      658794 :       prototype = handle(function->prototype(), isolate);
   13529             :     } else {
   13530             :       // No prototype property, use the intrinsict default proto further down.
   13531             :       prototype = isolate->factory()->undefined_value();
   13532             :     }
   13533             :   } else {
   13534             :     Handle<String> prototype_string = isolate->factory()->prototype_string();
   13535        2970 :     ASSIGN_RETURN_ON_EXCEPTION(
   13536             :         isolate, prototype,
   13537             :         JSReceiver::GetProperty(isolate, new_target, prototype_string), Map);
   13538             :     // The above prototype lookup might change the constructor and its
   13539             :     // prototype, hence we have to reload the initial map.
   13540        1404 :     EnsureHasInitialMap(constructor);
   13541        2808 :     constructor_initial_map = handle(constructor->initial_map(), isolate);
   13542             :   }
   13543             : 
   13544             :   // If prototype is not a JSReceiver, fetch the intrinsicDefaultProto from the
   13545             :   // correct realm. Rather than directly fetching the .prototype, we fetch the
   13546             :   // constructor that points to the .prototype. This relies on
   13547             :   // constructor.prototype being FROZEN for those constructors.
   13548      661612 :   if (!prototype->IsJSReceiver()) {
   13549             :     Handle<Context> context;
   13550        2700 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, context,
   13551             :                                JSReceiver::GetFunctionRealm(new_target), Map);
   13552             :     DCHECK(context->IsNativeContext());
   13553             :     Handle<Object> maybe_index = JSReceiver::GetDataProperty(
   13554        1350 :         constructor, isolate->factory()->native_context_index_symbol());
   13555        2700 :     int index = maybe_index->IsSmi() ? Smi::ToInt(*maybe_index)
   13556        2601 :                                      : Context::OBJECT_FUNCTION_INDEX;
   13557             :     Handle<JSFunction> realm_constructor(JSFunction::cast(context->get(index)),
   13558        2700 :                                          isolate);
   13559        2700 :     prototype = handle(realm_constructor->prototype(), isolate);
   13560             :   }
   13561             : 
   13562      330818 :   Handle<Map> map = Map::CopyInitialMap(isolate, constructor_initial_map);
   13563      330809 :   map->set_new_target_is_base(false);
   13564      661624 :   CHECK(prototype->IsJSReceiver());
   13565      330814 :   if (map->prototype() != *prototype)
   13566      330059 :     Map::SetPrototype(isolate, map, prototype);
   13567      661616 :   map->SetConstructor(*constructor);
   13568      330814 :   return map;
   13569             : }
   13570             : 
   13571     3700530 : int JSFunction::ComputeInstanceSizeWithMinSlack(Isolate* isolate) {
   13572     3700530 :   CHECK(has_initial_map());
   13573     7401064 :   if (initial_map()->IsInobjectSlackTrackingInProgress()) {
   13574        6344 :     int slack = initial_map()->ComputeMinObjectSlack(isolate);
   13575       12688 :     return initial_map()->InstanceSizeFromSlack(slack);
   13576             :   }
   13577     7388375 :   return initial_map()->instance_size();
   13578             : }
   13579             : 
   13580           0 : void JSFunction::PrintName(FILE* out) {
   13581           0 :   std::unique_ptr<char[]> name = shared()->DebugName()->ToCString();
   13582           0 :   PrintF(out, "%s", name.get());
   13583           0 : }
   13584             : 
   13585             : 
   13586      507185 : Handle<String> JSFunction::GetName(Handle<JSFunction> function) {
   13587             :   Isolate* isolate = function->GetIsolate();
   13588             :   Handle<Object> name =
   13589      507185 :       JSReceiver::GetDataProperty(function, isolate->factory()->name_string());
   13590     1014370 :   if (name->IsString()) return Handle<String>::cast(name);
   13591     1013024 :   return handle(function->shared()->DebugName(), isolate);
   13592             : }
   13593             : 
   13594             : 
   13595      407372 : Handle<String> JSFunction::GetDebugName(Handle<JSFunction> function) {
   13596             :   Isolate* isolate = function->GetIsolate();
   13597             :   Handle<Object> name = JSReceiver::GetDataProperty(
   13598      407372 :       function, isolate->factory()->display_name_string());
   13599      814744 :   if (name->IsString()) return Handle<String>::cast(name);
   13600      407338 :   return JSFunction::GetName(function);
   13601             : }
   13602             : 
   13603        6925 : bool JSFunction::SetName(Handle<JSFunction> function, Handle<Name> name,
   13604             :                          Handle<String> prefix) {
   13605             :   Isolate* isolate = function->GetIsolate();
   13606             :   Handle<String> function_name;
   13607       13850 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, function_name,
   13608             :                                    Name::ToFunctionName(isolate, name), false);
   13609        6916 :   if (prefix->length() > 0) {
   13610        3183 :     IncrementalStringBuilder builder(isolate);
   13611        3183 :     builder.AppendString(prefix);
   13612             :     builder.AppendCharacter(' ');
   13613        3183 :     builder.AppendString(function_name);
   13614        6366 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, function_name, builder.Finish(),
   13615             :                                      false);
   13616             :   }
   13617       13796 :   RETURN_ON_EXCEPTION_VALUE(
   13618             :       isolate,
   13619             :       JSObject::DefinePropertyOrElementIgnoreAttributes(
   13620             :           function, isolate->factory()->name_string(), function_name,
   13621             :           static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)),
   13622             :       false);
   13623        6898 :   return true;
   13624             : }
   13625             : 
   13626             : namespace {
   13627             : 
   13628     1083056 : Handle<String> NativeCodeFunctionSourceString(
   13629             :     Handle<SharedFunctionInfo> shared_info) {
   13630             :   Isolate* const isolate = shared_info->GetIsolate();
   13631     1083056 :   IncrementalStringBuilder builder(isolate);
   13632             :   builder.AppendCString("function ");
   13633     2166112 :   builder.AppendString(handle(shared_info->Name(), isolate));
   13634             :   builder.AppendCString("() { [native code] }");
   13635     2166112 :   return builder.Finish().ToHandleChecked();
   13636             : }
   13637             : 
   13638             : }  // namespace
   13639             : 
   13640             : 
   13641             : // static
   13642          55 : Handle<String> JSBoundFunction::ToString(Handle<JSBoundFunction> function) {
   13643             :   Isolate* const isolate = function->GetIsolate();
   13644          55 :   return isolate->factory()->function_native_code_string();
   13645             : }
   13646             : 
   13647             : 
   13648             : // static
   13649     1873132 : Handle<String> JSFunction::ToString(Handle<JSFunction> function) {
   13650             :   Isolate* const isolate = function->GetIsolate();
   13651     3746264 :   Handle<SharedFunctionInfo> shared_info(function->shared(), isolate);
   13652             : 
   13653             :   // Check if {function} should hide its source code.
   13654     1873132 :   if (!shared_info->IsUserJavaScript()) {
   13655     1082984 :     return NativeCodeFunctionSourceString(shared_info);
   13656             :   }
   13657             : 
   13658             :   // Check if we should print {function} as a class.
   13659             :   Handle<Object> maybe_class_positions = JSReceiver::GetDataProperty(
   13660      790148 :       function, isolate->factory()->class_positions_symbol());
   13661     1580296 :   if (maybe_class_positions->IsTuple2()) {
   13662       21722 :     Tuple2 class_positions = Tuple2::cast(*maybe_class_positions);
   13663       21722 :     int start_position = Smi::ToInt(class_positions->value1());
   13664       21722 :     int end_position = Smi::ToInt(class_positions->value2());
   13665             :     Handle<String> script_source(
   13666       65166 :         String::cast(Script::cast(shared_info->script())->source()), isolate);
   13667             :     return isolate->factory()->NewSubString(script_source, start_position,
   13668       21722 :                                             end_position);
   13669             :   }
   13670             : 
   13671             :   // Check if we have source code for the {function}.
   13672      768426 :   if (!shared_info->HasSourceCode()) {
   13673           0 :     return NativeCodeFunctionSourceString(shared_info);
   13674             :   }
   13675             : 
   13676      768426 :   if (shared_info->function_token_position() == kNoSourcePosition) {
   13677             :     // If the function token position isn't valid, return [native code] to
   13678             :     // ensure calling eval on the returned source code throws rather than
   13679             :     // giving inconsistent call behaviour.
   13680             :     isolate->CountUsage(
   13681          72 :         v8::Isolate::UseCounterFeature::kFunctionTokenOffsetTooLongForToString);
   13682          72 :     return NativeCodeFunctionSourceString(shared_info);
   13683             :   }
   13684             :   return Handle<String>::cast(
   13685      768354 :       SharedFunctionInfo::GetSourceCodeHarmony(shared_info));
   13686             : }
   13687             : 
   13688             : STATIC_ASSERT(Oddball::kToNumberRawOffset == HeapNumber::kValueOffset);
   13689             : 
   13690         672 : void Oddball::Initialize(Isolate* isolate, Handle<Oddball> oddball,
   13691             :                          const char* to_string, Handle<Object> to_number,
   13692             :                          const char* type_of, byte kind) {
   13693             :   Handle<String> internalized_to_string =
   13694         672 :       isolate->factory()->InternalizeUtf8String(to_string);
   13695             :   Handle<String> internalized_type_of =
   13696         672 :       isolate->factory()->InternalizeUtf8String(type_of);
   13697        1344 :   if (to_number->IsHeapNumber()) {
   13698             :     oddball->set_to_number_raw_as_bits(
   13699         224 :         Handle<HeapNumber>::cast(to_number)->value_as_bits());
   13700             :   } else {
   13701        1120 :     oddball->set_to_number_raw(to_number->Number());
   13702             :   }
   13703         672 :   oddball->set_to_number(*to_number);
   13704         672 :   oddball->set_to_string(*internalized_to_string);
   13705         672 :   oddball->set_type_of(*internalized_type_of);
   13706             :   oddball->set_kind(kind);
   13707         672 : }
   13708             : 
   13709        2099 : int Script::GetEvalPosition() {
   13710             :   DisallowHeapAllocation no_gc;
   13711             :   DCHECK(compilation_type() == Script::COMPILATION_TYPE_EVAL);
   13712             :   int position = eval_from_position();
   13713        2099 :   if (position < 0) {
   13714             :     // Due to laziness, the position may not have been translated from code
   13715             :     // offset yet, which would be encoded as negative integer. In that case,
   13716             :     // translate and set the position.
   13717         772 :     if (!has_eval_from_shared()) {
   13718             :       position = 0;
   13719             :     } else {
   13720         772 :       SharedFunctionInfo shared = eval_from_shared();
   13721         772 :       position = shared->abstract_code()->SourcePosition(-position);
   13722             :     }
   13723             :     DCHECK_GE(position, 0);
   13724             :     set_eval_from_position(position);
   13725             :   }
   13726        2099 :   return position;
   13727             : }
   13728             : 
   13729     2566722 : void Script::InitLineEnds(Handle<Script> script) {
   13730             :   Isolate* isolate = script->GetIsolate();
   13731     7649893 :   if (!script->line_ends()->IsUndefined(isolate)) return;
   13732             :   DCHECK(script->type() != Script::TYPE_WASM ||
   13733             :          script->source_mapping_url()->IsString());
   13734             : 
   13735       50273 :   Object src_obj = script->source();
   13736       50273 :   if (!src_obj->IsString()) {
   13737             :     DCHECK(src_obj->IsUndefined(isolate));
   13738          10 :     script->set_line_ends(ReadOnlyRoots(isolate).empty_fixed_array());
   13739             :   } else {
   13740             :     DCHECK(src_obj->IsString());
   13741             :     Handle<String> src(String::cast(src_obj), isolate);
   13742       50268 :     Handle<FixedArray> array = String::CalculateLineEnds(isolate, src, true);
   13743      100536 :     script->set_line_ends(*array);
   13744             :   }
   13745             : 
   13746             :   DCHECK(script->line_ends()->IsFixedArray());
   13747             : }
   13748             : 
   13749     2341477 : bool Script::GetPositionInfo(Handle<Script> script, int position,
   13750             :                              PositionInfo* info, OffsetFlag offset_flag) {
   13751             :   // For wasm, we do not create an artificial line_ends array, but do the
   13752             :   // translation directly.
   13753     2341477 :   if (script->type() != Script::TYPE_WASM) InitLineEnds(script);
   13754     2341477 :   return script->GetPositionInfo(position, info, offset_flag);
   13755             : }
   13756             : 
   13757    19255512 : bool Script::IsUserJavaScript() { return type() == Script::TYPE_NORMAL; }
   13758             : 
   13759         388 : bool Script::ContainsAsmModule() {
   13760             :   DisallowHeapAllocation no_gc;
   13761         388 :   SharedFunctionInfo::ScriptIterator iter(this->GetIsolate(), *this);
   13762       14898 :   for (SharedFunctionInfo info = iter.Next(); !info.is_null();
   13763             :        info = iter.Next()) {
   13764        7070 :     if (info->HasAsmWasmData()) return true;
   13765             :   }
   13766         379 :   return false;
   13767             : }
   13768             : 
   13769             : namespace {
   13770      269534 : bool GetPositionInfoSlow(const Script script, int position,
   13771             :                          Script::PositionInfo* info) {
   13772      539068 :   if (!script->source()->IsString()) return false;
   13773      269534 :   if (position < 0) position = 0;
   13774             : 
   13775      539068 :   String source_string = String::cast(script->source());
   13776             :   int line = 0;
   13777             :   int line_start = 0;
   13778             :   int len = source_string->length();
   13779  5647902045 :   for (int pos = 0; pos <= len; ++pos) {
   13780 11295803042 :     if (pos == len || source_string->Get(pos) == '\n') {
   13781   180492594 :       if (position <= pos) {
   13782      269524 :         info->line = line;
   13783      269524 :         info->column = position - line_start;
   13784      269524 :         info->line_start = line_start;
   13785      269524 :         info->line_end = pos;
   13786      269524 :         return true;
   13787             :       }
   13788   180223070 :       line++;
   13789   180223070 :       line_start = pos + 1;
   13790             :     }
   13791             :   }
   13792             :   return false;
   13793             : }
   13794             : }  // namespace
   13795             : 
   13796             : #define SMI_VALUE(x) (Smi::ToInt(x))
   13797     5324883 : bool Script::GetPositionInfo(int position, PositionInfo* info,
   13798             :                              OffsetFlag offset_flag) const {
   13799             :   DisallowHeapAllocation no_allocation;
   13800             : 
   13801             :   // For wasm, we do not rely on the line_ends array, but do the translation
   13802             :   // directly.
   13803     5324883 :   if (type() == Script::TYPE_WASM) {
   13804             :     DCHECK_LE(0, position);
   13805         929 :     return WasmModuleObject::cast(wasm_module_object())
   13806        1858 :         ->GetPositionInfo(static_cast<uint32_t>(position), info);
   13807             :   }
   13808             : 
   13809    10647908 :   if (line_ends()->IsUndefined()) {
   13810             :     // Slow mode: we do not have line_ends. We have to iterate through source.
   13811      269534 :     if (!GetPositionInfoSlow(*this, position, info)) return false;
   13812             :   } else {
   13813             :     DCHECK(line_ends()->IsFixedArray());
   13814     5054420 :     FixedArray ends = FixedArray::cast(line_ends());
   13815             : 
   13816             :     const int ends_len = ends->length();
   13817     5054420 :     if (ends_len == 0) return false;
   13818             : 
   13819             :     // Return early on invalid positions. Negative positions behave as if 0 was
   13820             :     // passed, and positions beyond the end of the script return as failure.
   13821     5054405 :     if (position < 0) {
   13822             :       position = 0;
   13823    10108780 :     } else if (position > SMI_VALUE(ends->get(ends_len - 1))) {
   13824             :       return false;
   13825             :     }
   13826             : 
   13827             :     // Determine line number by doing a binary search on the line ends array.
   13828     5049064 :     if (SMI_VALUE(ends->get(0)) >= position) {
   13829      260303 :       info->line = 0;
   13830      260303 :       info->line_start = 0;
   13831      260303 :       info->column = position;
   13832             :     } else {
   13833             :       int left = 0;
   13834     4788761 :       int right = ends_len - 1;
   13835             : 
   13836    49007310 :       while (right > 0) {
   13837             :         DCHECK_LE(left, right);
   13838    44218549 :         const int mid = (left + right) / 2;
   13839    44218549 :         if (position > SMI_VALUE(ends->get(mid))) {
   13840    20571308 :           left = mid + 1;
   13841    47294482 :         } else if (position <= SMI_VALUE(ends->get(mid - 1))) {
   13842             :           right = mid - 1;
   13843             :         } else {
   13844     4788761 :           info->line = mid;
   13845     4788761 :           break;
   13846             :         }
   13847             :       }
   13848             :       DCHECK(SMI_VALUE(ends->get(info->line)) >= position &&
   13849             :              SMI_VALUE(ends->get(info->line - 1)) < position);
   13850     9577522 :       info->line_start = SMI_VALUE(ends->get(info->line - 1)) + 1;
   13851     4788761 :       info->column = position - info->line_start;
   13852             :     }
   13853             : 
   13854             :     // Line end is position of the linebreak character.
   13855    10098128 :     info->line_end = SMI_VALUE(ends->get(info->line));
   13856     5049064 :     if (info->line_end > 0) {
   13857             :       DCHECK(source()->IsString());
   13858    10096292 :       String src = String::cast(source());
   13859    10096292 :       if (src->length() >= info->line_end &&
   13860     5048146 :           src->Get(info->line_end - 1) == '\r') {
   13861           0 :         info->line_end--;
   13862             :       }
   13863             :     }
   13864             :   }
   13865             : 
   13866             :   // Add offsets if requested.
   13867     5318588 :   if (offset_flag == WITH_OFFSET) {
   13868     5185580 :     if (info->line == 0) {
   13869      440845 :       info->column += column_offset();
   13870             :     }
   13871     5185580 :     info->line += line_offset();
   13872             :   }
   13873             : 
   13874             :   return true;
   13875             : }
   13876             : #undef SMI_VALUE
   13877             : 
   13878      838415 : int Script::GetColumnNumber(Handle<Script> script, int code_pos) {
   13879             :   PositionInfo info;
   13880      838415 :   GetPositionInfo(script, code_pos, &info, WITH_OFFSET);
   13881      838415 :   return info.column;
   13882             : }
   13883             : 
   13884      134738 : int Script::GetColumnNumber(int code_pos) const {
   13885             :   PositionInfo info;
   13886      134738 :   GetPositionInfo(code_pos, &info, WITH_OFFSET);
   13887      134738 :   return info.column;
   13888             : }
   13889             : 
   13890      843561 : int Script::GetLineNumber(Handle<Script> script, int code_pos) {
   13891             :   PositionInfo info;
   13892      843561 :   GetPositionInfo(script, code_pos, &info, WITH_OFFSET);
   13893      843561 :   return info.line;
   13894             : }
   13895             : 
   13896     2848262 : int Script::GetLineNumber(int code_pos) const {
   13897             :   PositionInfo info;
   13898     2848262 :   GetPositionInfo(code_pos, &info, WITH_OFFSET);
   13899     2848262 :   return info.line;
   13900             : }
   13901             : 
   13902       25773 : Object Script::GetNameOrSourceURL() {
   13903             :   // Keep in sync with ScriptNameOrSourceURL in messages.js.
   13904       51546 :   if (!source_url()->IsUndefined()) return source_url();
   13905       24025 :   return name();
   13906             : }
   13907             : 
   13908     4078272 : MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
   13909     8156558 :     Isolate* isolate, const FunctionLiteral* fun) {
   13910     4078272 :   CHECK_NE(fun->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
   13911             :   // If this check fails, the problem is most probably the function id
   13912             :   // renumbering done by AstFunctionLiteralIdReindexer; in particular, that
   13913             :   // AstTraversalVisitor doesn't recurse properly in the construct which
   13914             :   // triggers the mismatch.
   13915     8156558 :   CHECK_LT(fun->function_literal_id(), shared_function_infos()->length());
   13916     4078286 :   MaybeObject shared = shared_function_infos()->Get(fun->function_literal_id());
   13917     4078294 :   HeapObject heap_object;
   13918     8156583 :   if (!shared->GetHeapObject(&heap_object) ||
   13919             :       heap_object->IsUndefined(isolate)) {
   13920     2557486 :     return MaybeHandle<SharedFunctionInfo>();
   13921             :   }
   13922     1520809 :   return handle(SharedFunctionInfo::cast(heap_object), isolate);
   13923             : }
   13924             : 
   13925      135670 : Script::Iterator::Iterator(Isolate* isolate)
   13926      271345 :     : iterator_(isolate->heap()->script_list()) {}
   13927             : 
   13928     5197484 : Script Script::Iterator::Next() {
   13929     5197484 :   Object o = iterator_.Next();
   13930     5197484 :   if (o != Object()) {
   13931             :     return Script::cast(o);
   13932             :   }
   13933        4253 :   return Script();
   13934             : }
   13935             : 
   13936    17681598 : Code SharedFunctionInfo::GetCode() const {
   13937             :   // ======
   13938             :   // NOTE: This chain of checks MUST be kept in sync with the equivalent CSA
   13939             :   // GetSharedFunctionInfoCode method in code-stub-assembler.cc.
   13940             :   // ======
   13941             : 
   13942             :   Isolate* isolate = GetIsolate();
   13943    17681615 :   Object data = function_data();
   13944    17681607 :   if (data->IsSmi()) {
   13945             :     // Holding a Smi means we are a builtin.
   13946             :     DCHECK(HasBuiltinId());
   13947     3320394 :     return isolate->builtins()->builtin(builtin_id());
   13948    14361230 :   } else if (data->IsBytecodeArray()) {
   13949             :     // Having a bytecode array means we are a compiled, interpreted function.
   13950             :     DCHECK(HasBytecodeArray());
   13951     6961104 :     return isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
   13952     7400127 :   } else if (data->IsAsmWasmData()) {
   13953             :     // Having AsmWasmData means we are an asm.js/wasm function.
   13954             :     DCHECK(HasAsmWasmData());
   13955        5048 :     return isolate->builtins()->builtin(Builtins::kInstantiateAsmJs);
   13956     7395073 :   } else if (data->IsUncompiledData()) {
   13957             :     // Having uncompiled data (with or without scope) means we need to compile.
   13958             :     DCHECK(HasUncompiledData());
   13959     3242113 :     return isolate->builtins()->builtin(Builtins::kCompileLazy);
   13960     4152962 :   } else if (data->IsFunctionTemplateInfo()) {
   13961             :     // Having a function template info means we are an API function.
   13962             :     DCHECK(IsApiFunction());
   13963     3887237 :     return isolate->builtins()->builtin(Builtins::kHandleApiCall);
   13964      265726 :   } else if (data->IsWasmExportedFunctionData()) {
   13965             :     // Having a WasmExportedFunctionData means the code is in there.
   13966             :     DCHECK(HasWasmExportedFunctionData());
   13967      265686 :     return wasm_exported_function_data()->wrapper_code();
   13968          40 :   } else if (data->IsInterpreterData()) {
   13969             :     Code code = InterpreterTrampoline();
   13970             :     DCHECK(code->IsCode());
   13971             :     DCHECK(code->is_interpreter_trampoline_builtin());
   13972          40 :     return code;
   13973             :   }
   13974           0 :   UNREACHABLE();
   13975             : }
   13976             : 
   13977      887863 : WasmExportedFunctionData SharedFunctionInfo::wasm_exported_function_data()
   13978             :     const {
   13979             :   DCHECK(HasWasmExportedFunctionData());
   13980      887866 :   return WasmExportedFunctionData::cast(function_data());
   13981             : }
   13982             : 
   13983      132196 : SharedFunctionInfo::ScriptIterator::ScriptIterator(Isolate* isolate,
   13984             :                                                    Script script)
   13985             :     : ScriptIterator(isolate,
   13986      264392 :                      handle(script->shared_function_infos(), isolate)) {}
   13987             : 
   13988           0 : SharedFunctionInfo::ScriptIterator::ScriptIterator(
   13989             :     Isolate* isolate, Handle<WeakFixedArray> shared_function_infos)
   13990             :     : isolate_(isolate),
   13991             :       shared_function_infos_(shared_function_infos),
   13992      240410 :       index_(0) {}
   13993             : 
   13994     2006359 : SharedFunctionInfo SharedFunctionInfo::ScriptIterator::Next() {
   13995     7819215 :   while (index_ < shared_function_infos_->length()) {
   13996     5548590 :     MaybeObject raw = shared_function_infos_->Get(index_++);
   13997     2774295 :     HeapObject heap_object;
   13998     5197836 :     if (!raw->GetHeapObject(&heap_object) ||
   13999     2423541 :         heap_object->IsUndefined(isolate_)) {
   14000      900069 :       continue;
   14001             :     }
   14002     1874226 :     return SharedFunctionInfo::cast(heap_object);
   14003             :   }
   14004      132133 :   return SharedFunctionInfo();
   14005             : }
   14006             : 
   14007          10 : void SharedFunctionInfo::ScriptIterator::Reset(Script script) {
   14008          20 :   shared_function_infos_ = handle(script->shared_function_infos(), isolate_);
   14009          10 :   index_ = 0;
   14010          10 : }
   14011             : 
   14012           5 : SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate)
   14013             :     : script_iterator_(isolate),
   14014             :       noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()),
   14015          10 :       sfi_iterator_(isolate, script_iterator_.Next()) {}
   14016             : 
   14017        3470 : SharedFunctionInfo SharedFunctionInfo::GlobalIterator::Next() {
   14018        3470 :   HeapObject next = noscript_sfi_iterator_.Next();
   14019        3470 :   if (!next.is_null()) return SharedFunctionInfo::cast(next);
   14020             :   for (;;) {
   14021          65 :     next = sfi_iterator_.Next();
   14022         120 :     if (!next.is_null()) return SharedFunctionInfo::cast(next);
   14023          15 :     Script next_script = script_iterator_.Next();
   14024          15 :     if (next_script.is_null()) return SharedFunctionInfo();
   14025          10 :     sfi_iterator_.Reset(next_script);
   14026          10 :   }
   14027             : }
   14028             : 
   14029     3564466 : void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
   14030             :                                    Handle<Object> script_object,
   14031             :                                    int function_literal_id,
   14032             :                                    bool reset_preparsed_scope_data) {
   14033    10693423 :   if (shared->script() == *script_object) return;
   14034             :   Isolate* isolate = shared->GetIsolate();
   14035             : 
   14036    10693434 :   if (reset_preparsed_scope_data &&
   14037     3564738 :       shared->HasUncompiledDataWithPreparseData()) {
   14038           0 :     shared->ClearPreparseData();
   14039             :   }
   14040             : 
   14041             :   // Add shared function info to new script's list. If a collection occurs,
   14042             :   // the shared function info may be temporarily in two lists.
   14043             :   // This is okay because the gc-time processing of these lists can tolerate
   14044             :   // duplicates.
   14045     7128947 :   if (script_object->IsScript()) {
   14046             :     DCHECK(!shared->script()->IsScript());
   14047     3564469 :     Handle<Script> script = Handle<Script>::cast(script_object);
   14048             :     Handle<WeakFixedArray> list =
   14049     7128943 :         handle(script->shared_function_infos(), isolate);
   14050             : #ifdef DEBUG
   14051             :     DCHECK_LT(function_literal_id, list->length());
   14052             :     MaybeObject maybe_object = list->Get(function_literal_id);
   14053             :     HeapObject heap_object;
   14054             :     if (maybe_object->GetHeapObjectIfWeak(&heap_object)) {
   14055             :       DCHECK_EQ(heap_object, *shared);
   14056             :     }
   14057             : #endif
   14058     7128949 :     list->Set(function_literal_id, HeapObjectReference::Weak(*shared));
   14059             : 
   14060             :     // Remove shared function info from root array.
   14061             :     WeakArrayList noscript_list =
   14062     3564475 :         isolate->heap()->noscript_shared_function_infos();
   14063     3564469 :     CHECK(noscript_list->RemoveOne(MaybeObjectHandle::Weak(shared)));
   14064             :   } else {
   14065             :     DCHECK(shared->script()->IsScript());
   14066             :     Handle<WeakArrayList> list =
   14067             :         isolate->factory()->noscript_shared_function_infos();
   14068             : 
   14069             : #ifdef DEBUG
   14070             :     if (FLAG_enable_slow_asserts) {
   14071             :       WeakArrayList::Iterator iterator(*list);
   14072             :       for (HeapObject next = iterator.Next(); !next.is_null();
   14073             :            next = iterator.Next()) {
   14074             :         DCHECK_NE(next, *shared);
   14075             :       }
   14076             :     }
   14077             : #endif  // DEBUG
   14078             : 
   14079             :     list =
   14080           0 :         WeakArrayList::AddToEnd(isolate, list, MaybeObjectHandle::Weak(shared));
   14081             : 
   14082           0 :     isolate->heap()->SetRootNoScriptSharedFunctionInfos(*list);
   14083             : 
   14084             :     // Remove shared function info from old script's list.
   14085           0 :     Script old_script = Script::cast(shared->script());
   14086             : 
   14087             :     // Due to liveedit, it might happen that the old_script doesn't know
   14088             :     // about the SharedFunctionInfo, so we have to guard against that.
   14089           0 :     Handle<WeakFixedArray> infos(old_script->shared_function_infos(), isolate);
   14090           0 :     if (function_literal_id < infos->length()) {
   14091             :       MaybeObject raw =
   14092           0 :           old_script->shared_function_infos()->Get(function_literal_id);
   14093           0 :       HeapObject heap_object;
   14094           0 :       if (raw->GetHeapObjectIfWeak(&heap_object) && heap_object == *shared) {
   14095             :         old_script->shared_function_infos()->Set(
   14096             :             function_literal_id, HeapObjectReference::Strong(
   14097           0 :                                      ReadOnlyRoots(isolate).undefined_value()));
   14098             :       }
   14099             :     }
   14100             :   }
   14101             : 
   14102             :   // Finally set new script.
   14103     3564469 :   shared->set_script(*script_object);
   14104             : }
   14105             : 
   14106     8668073 : bool SharedFunctionInfo::HasBreakInfo() const {
   14107     8668073 :   if (!HasDebugInfo()) return false;
   14108      477718 :   DebugInfo info = GetDebugInfo();
   14109      477718 :   bool has_break_info = info->HasBreakInfo();
   14110      477718 :   return has_break_info;
   14111             : }
   14112             : 
   14113       16237 : bool SharedFunctionInfo::BreakAtEntry() const {
   14114       16237 :   if (!HasDebugInfo()) return false;
   14115         470 :   DebugInfo info = GetDebugInfo();
   14116         470 :   bool break_at_entry = info->BreakAtEntry();
   14117         470 :   return break_at_entry;
   14118             : }
   14119             : 
   14120      255459 : bool SharedFunctionInfo::HasCoverageInfo() const {
   14121      255459 :   if (!HasDebugInfo()) return false;
   14122      239280 :   DebugInfo info = GetDebugInfo();
   14123      239280 :   bool has_coverage_info = info->HasCoverageInfo();
   14124      239280 :   return has_coverage_info;
   14125             : }
   14126             : 
   14127      224265 : CoverageInfo SharedFunctionInfo::GetCoverageInfo() const {
   14128             :   DCHECK(HasCoverageInfo());
   14129      448530 :   return CoverageInfo::cast(GetDebugInfo()->coverage_info());
   14130             : }
   14131             : 
   14132     7217412 : String SharedFunctionInfo::DebugName() {
   14133             :   DisallowHeapAllocation no_gc;
   14134     7217412 :   String function_name = Name();
   14135     7217439 :   if (function_name->length() > 0) return function_name;
   14136     1951627 :   return inferred_name();
   14137             : }
   14138             : 
   14139      926643 : bool SharedFunctionInfo::PassesFilter(const char* raw_filter) {
   14140      926643 :   Vector<const char> filter = CStrVector(raw_filter);
   14141     1853290 :   std::unique_ptr<char[]> cstrname(DebugName()->ToCString());
   14142     1853307 :   return v8::internal::PassesFilter(CStrVector(cstrname.get()), filter);
   14143             : }
   14144             : 
   14145     6808968 : bool SharedFunctionInfo::HasSourceCode() const {
   14146             :   Isolate* isolate = GetIsolate();
   14147    27235872 :   return !script()->IsUndefined(isolate) &&
   14148    27235872 :          !Script::cast(script())->source()->IsUndefined(isolate);
   14149             : }
   14150             : 
   14151         364 : void SharedFunctionInfo::DiscardCompiledMetadata(
   14152             :     Isolate* isolate,
   14153             :     std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
   14154             :         gc_notify_updated_slot) {
   14155             :   DisallowHeapAllocation no_gc;
   14156         364 :   if (is_compiled()) {
   14157             :     HeapObject outer_scope_info;
   14158         357 :     if (scope_info()->HasOuterScopeInfo()) {
   14159         171 :       outer_scope_info = scope_info()->OuterScopeInfo();
   14160             :     } else {
   14161         186 :       outer_scope_info = ReadOnlyRoots(isolate).the_hole_value();
   14162             :     }
   14163             : 
   14164             :     // Raw setter to avoid validity checks, since we're performing the unusual
   14165             :     // task of decompiling.
   14166         357 :     set_raw_outer_scope_info_or_feedback_metadata(outer_scope_info);
   14167             :     gc_notify_updated_slot(
   14168             :         *this,
   14169             :         RawField(SharedFunctionInfo::kOuterScopeInfoOrFeedbackMetadataOffset),
   14170         357 :         outer_scope_info);
   14171             :   } else {
   14172             :     DCHECK(outer_scope_info()->IsScopeInfo() ||
   14173             :            outer_scope_info()->IsTheHole());
   14174             :   }
   14175             : 
   14176             :   // TODO(rmcilroy): Possibly discard ScopeInfo here as well.
   14177         364 : }
   14178             : 
   14179             : // static
   14180         253 : void SharedFunctionInfo::DiscardCompiled(
   14181             :     Isolate* isolate, Handle<SharedFunctionInfo> shared_info) {
   14182             :   DCHECK(shared_info->CanDiscardCompiled());
   14183             : 
   14184             :   Handle<String> inferred_name_val =
   14185         506 :       handle(shared_info->inferred_name(), isolate);
   14186         253 :   int start_position = shared_info->StartPosition();
   14187         253 :   int end_position = shared_info->EndPosition();
   14188         253 :   int function_literal_id = shared_info->FunctionLiteralId(isolate);
   14189             : 
   14190         506 :   shared_info->DiscardCompiledMetadata(isolate);
   14191             : 
   14192             :   // Replace compiled data with a new UncompiledData object.
   14193         253 :   if (shared_info->HasUncompiledDataWithPreparseData()) {
   14194             :     // If this is uncompiled data with a pre-parsed scope data, we can just
   14195             :     // clear out the scope data and keep the uncompiled data.
   14196           7 :     shared_info->ClearPreparseData();
   14197             :   } else {
   14198             :     // Create a new UncompiledData, without pre-parsed scope, and update the
   14199             :     // function data to point to it. Use the raw function data setter to avoid
   14200             :     // validity checks, since we're performing the unusual task of decompiling.
   14201             :     Handle<UncompiledData> data =
   14202             :         isolate->factory()->NewUncompiledDataWithoutPreparseData(
   14203             :             inferred_name_val, start_position, end_position,
   14204         246 :             function_literal_id);
   14205         492 :     shared_info->set_function_data(*data);
   14206             :   }
   14207         253 : }
   14208             : 
   14209             : // static
   14210         567 : Handle<Object> SharedFunctionInfo::GetSourceCode(
   14211             :     Handle<SharedFunctionInfo> shared) {
   14212             :   Isolate* isolate = shared->GetIsolate();
   14213         567 :   if (!shared->HasSourceCode()) return isolate->factory()->undefined_value();
   14214        1134 :   Handle<String> source(String::cast(Script::cast(shared->script())->source()),
   14215        1134 :                         isolate);
   14216             :   return isolate->factory()->NewSubString(source, shared->StartPosition(),
   14217        1134 :                                           shared->EndPosition());
   14218             : }
   14219             : 
   14220             : // static
   14221      768354 : Handle<Object> SharedFunctionInfo::GetSourceCodeHarmony(
   14222             :     Handle<SharedFunctionInfo> shared) {
   14223             :   Isolate* isolate = shared->GetIsolate();
   14224      768354 :   if (!shared->HasSourceCode()) return isolate->factory()->undefined_value();
   14225             :   Handle<String> script_source(
   14226     2305062 :       String::cast(Script::cast(shared->script())->source()), isolate);
   14227      768354 :   int start_pos = shared->function_token_position();
   14228             :   DCHECK_NE(start_pos, kNoSourcePosition);
   14229             :   Handle<String> source = isolate->factory()->NewSubString(
   14230      768354 :       script_source, start_pos, shared->EndPosition());
   14231      768354 :   if (!shared->is_wrapped()) return source;
   14232             : 
   14233             :   DCHECK(!shared->name_should_print_as_anonymous());
   14234          15 :   IncrementalStringBuilder builder(isolate);
   14235             :   builder.AppendCString("function ");
   14236          30 :   builder.AppendString(Handle<String>(shared->Name(), isolate));
   14237             :   builder.AppendCString("(");
   14238          30 :   Handle<FixedArray> args(Script::cast(shared->script())->wrapped_arguments(),
   14239          30 :                           isolate);
   14240             :   int argc = args->length();
   14241          20 :   for (int i = 0; i < argc; i++) {
   14242           5 :     if (i > 0) builder.AppendCString(", ");
   14243           5 :     builder.AppendString(Handle<String>(String::cast(args->get(i)), isolate));
   14244             :   }
   14245             :   builder.AppendCString(") {\n");
   14246          15 :   builder.AppendString(source);
   14247             :   builder.AppendCString("\n}");
   14248          30 :   return builder.Finish().ToHandleChecked();
   14249             : }
   14250             : 
   14251      284631 : bool SharedFunctionInfo::IsInlineable() {
   14252             :   // Check that the function has a script associated with it.
   14253      569266 :   if (!script()->IsScript()) return false;
   14254             : 
   14255      247295 :   if (GetIsolate()->is_precise_binary_code_coverage() &&
   14256          10 :       !has_reported_binary_coverage()) {
   14257             :     // We may miss invocations if this function is inlined.
   14258             :     return false;
   14259             :   }
   14260             : 
   14261      247287 :   if (optimization_disabled()) return false;
   14262             : 
   14263             :   // Built-in functions are handled by the JSCallReducer.
   14264      246203 :   if (HasBuiltinFunctionId()) return false;
   14265             : 
   14266             :   // Only choose user code for inlining.
   14267      246202 :   if (!IsUserJavaScript()) return false;
   14268             : 
   14269             :   // If there is no bytecode array, it is either not compiled or it is compiled
   14270             :   // with WebAssembly for the asm.js pipeline. In either case we don't want to
   14271             :   // inline.
   14272      245849 :   if (!HasBytecodeArray()) return false;
   14273             : 
   14274             :   // Quick check on the size of the bytecode to avoid inlining large functions.
   14275      466789 :   if (GetBytecodeArray()->length() > FLAG_max_inlined_bytecode_size) {
   14276             :     return false;
   14277             :   }
   14278             : 
   14279      233145 :   return true;
   14280             : }
   14281             : 
   14282           0 : int SharedFunctionInfo::SourceSize() { return EndPosition() - StartPosition(); }
   14283             : 
   14284      108214 : int SharedFunctionInfo::FindIndexInScript(Isolate* isolate) const {
   14285             :   DisallowHeapAllocation no_gc;
   14286             : 
   14287      108214 :   Object script_obj = script();
   14288      108214 :   if (!script_obj->IsScript()) return FunctionLiteral::kIdTypeInvalid;
   14289             : 
   14290             :   WeakFixedArray shared_info_list =
   14291      108214 :       Script::cast(script_obj)->shared_function_infos();
   14292             :   SharedFunctionInfo::ScriptIterator iterator(
   14293             :       isolate,
   14294             :       Handle<WeakFixedArray>(reinterpret_cast<Address*>(&shared_info_list)));
   14295             : 
   14296      686304 :   for (SharedFunctionInfo shared = iterator.Next(); !shared.is_null();
   14297             :        shared = iterator.Next()) {
   14298      686304 :     if (shared == *this) {
   14299      108214 :       return iterator.CurrentIndex();
   14300             :     }
   14301             :   }
   14302             : 
   14303             :   return FunctionLiteral::kIdTypeInvalid;
   14304             : }
   14305             : 
   14306      321510 : void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type,
   14307             :                                              bool has_prototype_slot,
   14308             :                                              int requested_embedder_fields,
   14309             :                                              int requested_in_object_properties,
   14310             :                                              int* instance_size,
   14311             :                                              int* in_object_properties) {
   14312             :   DCHECK_LE(static_cast<unsigned>(requested_embedder_fields),
   14313             :             JSObject::kMaxEmbedderFields);
   14314      321510 :   int header_size = JSObject::GetHeaderSize(instance_type, has_prototype_slot);
   14315      321510 :   if (requested_embedder_fields) {
   14316             :     // If there are embedder fields, then the embedder fields start offset must
   14317             :     // be properly aligned (embedder fields are located between object header
   14318             :     // and inobject fields).
   14319             :     header_size = RoundUp<kSystemPointerSize>(header_size);
   14320             :     requested_embedder_fields *= kEmbedderDataSlotSizeInTaggedSlots;
   14321             :   }
   14322             :   int max_nof_fields =
   14323      321510 :       (JSObject::kMaxInstanceSize - header_size) >> kTaggedSizeLog2;
   14324      321510 :   CHECK_LE(max_nof_fields, JSObject::kMaxInObjectProperties);
   14325      321510 :   CHECK_LE(static_cast<unsigned>(requested_embedder_fields),
   14326             :            static_cast<unsigned>(max_nof_fields));
   14327             :   *in_object_properties = Min(requested_in_object_properties,
   14328      643020 :                               max_nof_fields - requested_embedder_fields);
   14329             :   *instance_size =
   14330      321510 :       header_size +
   14331      643020 :       ((requested_embedder_fields + *in_object_properties) << kTaggedSizeLog2);
   14332      321510 :   CHECK_EQ(*in_object_properties,
   14333             :            ((*instance_size - header_size) >> kTaggedSizeLog2) -
   14334             :                requested_embedder_fields);
   14335      321510 :   CHECK_LE(static_cast<unsigned>(*instance_size),
   14336             :            static_cast<unsigned>(JSObject::kMaxInstanceSize));
   14337      321510 : }
   14338             : 
   14339             : // static
   14340       11343 : bool JSFunction::CalculateInstanceSizeForDerivedClass(
   14341             :     Handle<JSFunction> function, InstanceType instance_type,
   14342             :     int requested_embedder_fields, int* instance_size,
   14343             :     int* in_object_properties) {
   14344             :   Isolate* isolate = function->GetIsolate();
   14345             :   int expected_nof_properties = 0;
   14346       44947 :   for (PrototypeIterator iter(isolate, function, kStartAtReceiver);
   14347       22261 :        !iter.IsAtEnd(); iter.Advance()) {
   14348             :     Handle<JSReceiver> current =
   14349             :         PrototypeIterator::GetCurrent<JSReceiver>(iter);
   14350       67209 :     if (!current->IsJSFunction()) break;
   14351       33497 :     Handle<JSFunction> func(Handle<JSFunction>::cast(current));
   14352             :     // The super constructor should be compiled for the number of expected
   14353             :     // properties to be available.
   14354       66992 :     Handle<SharedFunctionInfo> shared(func->shared(), isolate);
   14355       33496 :     IsCompiledScope is_compiled_scope(shared->is_compiled_scope());
   14356       33505 :     if (is_compiled_scope.is_compiled() ||
   14357             :         Compiler::Compile(func, Compiler::CLEAR_EXCEPTION,
   14358          10 :                           &is_compiled_scope)) {
   14359             :       DCHECK(shared->is_compiled());
   14360       33496 :       int count = shared->expected_nof_properties();
   14361             :       // Check that the estimate is sane.
   14362       33496 :       if (expected_nof_properties <= JSObject::kMaxInObjectProperties - count) {
   14363       28652 :         expected_nof_properties += count;
   14364             :       } else {
   14365             :         expected_nof_properties = JSObject::kMaxInObjectProperties;
   14366             :       }
   14367             :     } else {
   14368             :       // In case there was a compilation error for the constructor we will
   14369             :       // throw an error during instantiation. Hence we directly return 0;
   14370           0 :       return false;
   14371             :     }
   14372       33496 :     if (!IsDerivedConstructor(shared->kind())) break;
   14373             :   }
   14374             :   CalculateInstanceSizeHelper(instance_type, true, requested_embedder_fields,
   14375             :                               expected_nof_properties, instance_size,
   14376       11343 :                               in_object_properties);
   14377       11343 :   return true;
   14378             : }
   14379             : 
   14380             : 
   14381             : // Output the source code without any allocation in the heap.
   14382          27 : std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) {
   14383          27 :   const SharedFunctionInfo s = v.value;
   14384             :   // For some native functions there is no source.
   14385          27 :   if (!s->HasSourceCode()) return os << "<No Source>";
   14386             : 
   14387             :   // Get the source for the script which this function came from.
   14388             :   // Don't use String::cast because we don't want more assertion errors while
   14389             :   // we are already creating a stack dump.
   14390             :   String script_source =
   14391          54 :       String::unchecked_cast(Script::cast(s->script())->source());
   14392             : 
   14393          27 :   if (!script_source->LooksValid()) return os << "<Invalid Source>";
   14394             : 
   14395          27 :   if (!s->is_toplevel()) {
   14396          18 :     os << "function ";
   14397          18 :     String name = s->Name();
   14398          18 :     if (name->length() > 0) {
   14399          18 :       name->PrintUC16(os);
   14400             :     }
   14401             :   }
   14402             : 
   14403          27 :   int len = s->EndPosition() - s->StartPosition();
   14404          27 :   if (len <= v.max_length || v.max_length < 0) {
   14405           9 :     script_source->PrintUC16(os, s->StartPosition(), s->EndPosition());
   14406           9 :     return os;
   14407             :   } else {
   14408             :     script_source->PrintUC16(os, s->StartPosition(),
   14409          18 :                              s->StartPosition() + v.max_length);
   14410          18 :     return os << "...\n";
   14411             :   }
   14412             : }
   14413             : 
   14414             : 
   14415       20123 : void SharedFunctionInfo::DisableOptimization(BailoutReason reason) {
   14416             :   DCHECK_NE(reason, BailoutReason::kNoReason);
   14417             : 
   14418             :   set_flags(DisabledOptimizationReasonBits::update(flags(), reason));
   14419             :   // Code should be the lazy compilation stub or else interpreted.
   14420             :   DCHECK(abstract_code()->kind() == AbstractCode::INTERPRETED_FUNCTION ||
   14421             :          abstract_code()->kind() == AbstractCode::BUILTIN);
   14422       40246 :   PROFILE(GetIsolate(), CodeDisableOptEvent(abstract_code(), *this));
   14423       20123 :   if (FLAG_trace_opt) {
   14424           0 :     PrintF("[disabled optimization for ");
   14425           0 :     ShortPrint();
   14426           0 :     PrintF(", reason: %s]\n", GetBailoutReason(reason));
   14427             :   }
   14428       20123 : }
   14429             : 
   14430     3564344 : void SharedFunctionInfo::InitFromFunctionLiteral(
   14431    23943554 :     Handle<SharedFunctionInfo> shared_info, FunctionLiteral* lit,
   14432             :     bool is_toplevel) {
   14433             :   Isolate* isolate = shared_info->GetIsolate();
   14434             :   bool needs_position_info = true;
   14435             : 
   14436             :   // When adding fields here, make sure DeclarationScope::AnalyzePartially is
   14437             :   // updated accordingly.
   14438             :   shared_info->set_internal_formal_parameter_count(lit->parameter_count());
   14439             :   shared_info->SetFunctionTokenPosition(lit->function_token_position(),
   14440    10693047 :                                         lit->start_position());
   14441     3564348 :   if (shared_info->scope_info()->HasPositionInfo()) {
   14442           0 :     shared_info->scope_info()->SetPositionInfo(lit->start_position(),
   14443           0 :                                                lit->end_position());
   14444             :     needs_position_info = false;
   14445             :   }
   14446     7128692 :   shared_info->set_is_declaration(lit->is_declaration());
   14447     7128691 :   shared_info->set_is_named_expression(lit->is_named_expression());
   14448     7128689 :   shared_info->set_is_anonymous_expression(lit->is_anonymous_expression());
   14449     7128691 :   shared_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
   14450     7128695 :   shared_info->set_language_mode(lit->language_mode());
   14451     7128698 :   shared_info->set_is_wrapped(lit->is_wrapped());
   14452             :   //  shared_info->set_kind(lit->kind());
   14453             :   // FunctionKind must have already been set.
   14454             :   DCHECK(lit->kind() == shared_info->kind());
   14455     7128684 :   shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject());
   14456             :   DCHECK_IMPLIES(lit->requires_instance_members_initializer(),
   14457             :                  IsClassConstructor(lit->kind()));
   14458             :   shared_info->set_requires_instance_members_initializer(
   14459     7128694 :       lit->requires_instance_members_initializer());
   14460             : 
   14461     7128689 :   shared_info->set_is_toplevel(is_toplevel);
   14462             :   DCHECK(shared_info->outer_scope_info()->IsTheHole());
   14463     3564345 :   if (!is_toplevel) {
   14464     2557486 :     Scope* outer_scope = lit->scope()->GetOuterScopeWithContext();
   14465     2557482 :     if (outer_scope) {
   14466     4322427 :       shared_info->set_outer_scope_info(*outer_scope->scope_info());
   14467             :     }
   14468             :   }
   14469             : 
   14470             :   // For lazy parsed functions, the following flags will be inaccurate since we
   14471             :   // don't have the information yet. They're set later in
   14472             :   // SetSharedFunctionFlagsFromLiteral (compiler.cc), when the function is
   14473             :   // really parsed and compiled.
   14474     3564342 :   if (lit->ShouldEagerCompile()) {
   14475             :     shared_info->set_length(lit->function_length());
   14476     3041549 :     shared_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
   14477     3041558 :     shared_info->SetExpectedNofPropertiesFromEstimate(lit);
   14478             :     DCHECK_NULL(lit->produced_preparse_data());
   14479             :     // If we're about to eager compile, we'll have the function literal
   14480             :     // available, so there's no need to wastefully allocate an uncompiled data.
   14481             :     // TODO(leszeks): This should be explicitly passed as a parameter, rather
   14482             :     // than relying on a property of the literal.
   14483             :     needs_position_info = false;
   14484             :   } else {
   14485             :     // Set an invalid length for lazy functions. This way we can set the correct
   14486             :     // value after compiling, but avoid overwriting values set manually by the
   14487             :     // bootstrapper.
   14488             :     shared_info->set_length(SharedFunctionInfo::kInvalidLength);
   14489             :     ProducedPreparseData* scope_data = lit->produced_preparse_data();
   14490     2043566 :     if (scope_data != nullptr) {
   14491             :       Handle<PreparseData> preparse_data =
   14492      118694 :           scope_data->Serialize(shared_info->GetIsolate());
   14493             :       Handle<UncompiledData> data =
   14494             :           isolate->factory()->NewUncompiledDataWithPreparseData(
   14495             :               lit->inferred_name(), lit->start_position(), lit->end_position(),
   14496       59347 :               lit->function_literal_id(), preparse_data);
   14497      118694 :       shared_info->set_uncompiled_data(*data);
   14498             :       needs_position_info = false;
   14499             :     }
   14500             :   }
   14501     3564345 :   if (needs_position_info) {
   14502             :     Handle<UncompiledData> data =
   14503             :         isolate->factory()->NewUncompiledDataWithoutPreparseData(
   14504             :             lit->inferred_name(), lit->start_position(), lit->end_position(),
   14505     1984220 :             lit->function_literal_id());
   14506     3968441 :     shared_info->set_uncompiled_data(*data);
   14507             :   }
   14508     3564346 : }
   14509             : 
   14510     2089347 : void SharedFunctionInfo::SetExpectedNofPropertiesFromEstimate(
   14511     3610126 :     FunctionLiteral* literal) {
   14512     3610126 :   int estimate = literal->expected_property_count();
   14513             : 
   14514             :   // If no properties are added in the constructor, they are more likely
   14515             :   // to be added later.
   14516     3610126 :   if (estimate == 0) estimate = 2;
   14517             : 
   14518             :   // Inobject slack tracking will reclaim redundant inobject space later,
   14519             :   // so we can afford to adjust the estimate generously.
   14520     3610126 :   estimate += 8;
   14521             : 
   14522             :   // Limit actual estimate to fit in a 8 bit field, we will never allocate
   14523             :   // more than this in any case.
   14524             :   STATIC_ASSERT(JSObject::kMaxInObjectProperties <= kMaxUInt8);
   14525     3610126 :   estimate = std::min(estimate, kMaxUInt8);
   14526             : 
   14527             :   set_expected_nof_properties(estimate);
   14528     2089347 : }
   14529             : 
   14530        1137 : void SharedFunctionInfo::SetFunctionTokenPosition(int function_token_position,
   14531             :                                                   int start_position) {
   14532             :   int offset;
   14533     3565486 :   if (function_token_position == kNoSourcePosition) {
   14534             :     offset = 0;
   14535             :   } else {
   14536     2533122 :     offset = start_position - function_token_position;
   14537             :   }
   14538             : 
   14539     3565486 :   if (offset > kMaximumFunctionTokenOffset) {
   14540             :     offset = kFunctionTokenOutOfRange;
   14541             :   }
   14542             :   set_raw_function_token_offset(offset);
   14543        1137 : }
   14544             : 
   14545    10138624 : int SharedFunctionInfo::StartPosition() const {
   14546    10138624 :   Object maybe_scope_info = name_or_scope_info();
   14547    10138634 :   if (maybe_scope_info->IsScopeInfo()) {
   14548     6268550 :     ScopeInfo info = ScopeInfo::cast(maybe_scope_info);
   14549     6268550 :     if (info->HasPositionInfo()) {
   14550     6268550 :       return info->StartPosition();
   14551             :     }
   14552     3870083 :   } else if (HasUncompiledData()) {
   14553             :     // Works with or without scope.
   14554     5679533 :     return uncompiled_data()->start_position();
   14555     1030314 :   } else if (IsApiFunction() || HasBuiltinId()) {
   14556             :     DCHECK_IMPLIES(HasBuiltinId(), builtin_id() != Builtins::kCompileLazy);
   14557             :     return 0;
   14558             :   }
   14559             :   return kNoSourcePosition;
   14560             : }
   14561             : 
   14562     2281159 : int SharedFunctionInfo::EndPosition() const {
   14563     2281159 :   Object maybe_scope_info = name_or_scope_info();
   14564     2281166 :   if (maybe_scope_info->IsScopeInfo()) {
   14565      464959 :     ScopeInfo info = ScopeInfo::cast(maybe_scope_info);
   14566      464959 :     if (info->HasPositionInfo()) {
   14567      464959 :       return info->EndPosition();
   14568             :     }
   14569     1816207 :   } else if (HasUncompiledData()) {
   14570             :     // Works with or without scope.
   14571     3632407 :     return uncompiled_data()->end_position();
   14572           0 :   } else if (IsApiFunction() || HasBuiltinId()) {
   14573             :     DCHECK_IMPLIES(HasBuiltinId(), builtin_id() != Builtins::kCompileLazy);
   14574             :     return 0;
   14575             :   }
   14576             :   return kNoSourcePosition;
   14577             : }
   14578             : 
   14579      719686 : int SharedFunctionInfo::FunctionLiteralId(Isolate* isolate) const {
   14580             :   // Fast path for the common case when the SFI is uncompiled and so the
   14581             :   // function literal id is already in the uncompiled data.
   14582      719686 :   if (HasUncompiledData()) {
   14583     1222973 :     int id = uncompiled_data()->function_literal_id();
   14584             :     // Make sure the id is what we should have found with the slow path.
   14585             :     DCHECK_EQ(id, FindIndexInScript(isolate));
   14586      611488 :     return id;
   14587             :   }
   14588             : 
   14589             :   // Otherwise, search for the function in the SFI's script's function list,
   14590             :   // and return its index in that list.e
   14591      108214 :   return FindIndexInScript(isolate);
   14592             : }
   14593             : 
   14594        1137 : void SharedFunctionInfo::SetPosition(int start_position, int end_position) {
   14595        1137 :   Object maybe_scope_info = name_or_scope_info();
   14596        1137 :   if (maybe_scope_info->IsScopeInfo()) {
   14597        1067 :     ScopeInfo info = ScopeInfo::cast(maybe_scope_info);
   14598        1067 :     if (info->HasPositionInfo()) {
   14599        1067 :       info->SetPositionInfo(start_position, end_position);
   14600             :     }
   14601          70 :   } else if (HasUncompiledData()) {
   14602          70 :     if (HasUncompiledDataWithPreparseData()) {
   14603             :       // Clear out preparsed scope data, since the position setter invalidates
   14604             :       // any scope data.
   14605          14 :       ClearPreparseData();
   14606             :     }
   14607         140 :     uncompiled_data()->set_start_position(start_position);
   14608         140 :     uncompiled_data()->set_end_position(end_position);
   14609             :   } else {
   14610           0 :     UNREACHABLE();
   14611             :   }
   14612        1137 : }
   14613             : 
   14614      321510 : void Map::StartInobjectSlackTracking() {
   14615             :   DCHECK(!IsInobjectSlackTrackingInProgress());
   14616      643023 :   if (UnusedPropertyFields() == 0) return;
   14617      227350 :   set_construction_counter(Map::kSlackTrackingCounterStart);
   14618             : }
   14619             : 
   14620   390204089 : void ObjectVisitor::VisitRelocInfo(RelocIterator* it) {
   14621   526686788 :   for (; !it->done(); it->next()) {
   14622   136713055 :     it->rinfo()->Visit(this);
   14623             :   }
   14624   126562681 : }
   14625             : 
   14626         282 : void Code::ClearEmbeddedObjects(Heap* heap) {
   14627             :   HeapObject undefined = ReadOnlyRoots(heap).undefined_value();
   14628             :   int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
   14629        4858 :   for (RelocIterator it(*this, mode_mask); !it.done(); it.next()) {
   14630        4576 :     RelocInfo::Mode mode = it.rinfo()->rmode();
   14631        4576 :     if (mode == RelocInfo::EMBEDDED_OBJECT) {
   14632             :       it.rinfo()->set_target_object(heap, undefined, SKIP_WRITE_BARRIER);
   14633             :     }
   14634             :   }
   14635         282 :   set_embedded_objects_cleared(true);
   14636         282 : }
   14637             : 
   14638             : 
   14639        1678 : void Code::Relocate(intptr_t delta) {
   14640       28999 :   for (RelocIterator it(*this, RelocInfo::kApplyMask); !it.done(); it.next()) {
   14641       27321 :     it.rinfo()->apply(delta);
   14642             :   }
   14643             :   FlushICache();
   14644        1679 : }
   14645             : 
   14646     2200272 : void Code::FlushICache() const {
   14647     2201951 :   Assembler::FlushICache(raw_instruction_start(), raw_instruction_size());
   14648     2200275 : }
   14649             : 
   14650     4400544 : void Code::CopyFromNoFlush(Heap* heap, const CodeDesc& desc) {
   14651             :   // Copy code.
   14652             :   CopyBytes(reinterpret_cast<byte*>(raw_instruction_start()), desc.buffer,
   14653     4400546 :             static_cast<size_t>(desc.instr_size));
   14654             : 
   14655             :   // Copy unwinding info, if any.
   14656     2200271 :   if (desc.unwinding_info) {
   14657             :     DCHECK_GT(desc.unwinding_info_size, 0);
   14658          28 :     set_unwinding_info_size(desc.unwinding_info_size);
   14659             :     CopyBytes(reinterpret_cast<byte*>(unwinding_info_start()),
   14660             :               desc.unwinding_info,
   14661          56 :               static_cast<size_t>(desc.unwinding_info_size));
   14662             :   }
   14663             : 
   14664             :   // Copy reloc info.
   14665             :   CopyRelocInfoToByteArray(unchecked_relocation_info(), desc);
   14666             : 
   14667             :   // Unbox handles and relocate.
   14668     2200274 :   Assembler* origin = desc.origin;
   14669             :   AllowDeferredHandleDereference embedding_raw_address;
   14670             :   const int mode_mask = RelocInfo::PostCodegenRelocationMask();
   14671    11818788 :   for (RelocIterator it(*this, mode_mask); !it.done(); it.next()) {
   14672     9618504 :     RelocInfo::Mode mode = it.rinfo()->rmode();
   14673     9618504 :     if (mode == RelocInfo::EMBEDDED_OBJECT) {
   14674     5953665 :       Handle<HeapObject> p = it.rinfo()->target_object_handle(origin);
   14675             :       it.rinfo()->set_target_object(heap, *p, UPDATE_WRITE_BARRIER,
   14676             :                                     SKIP_ICACHE_FLUSH);
   14677     3664839 :     } else if (RelocInfo::IsCodeTargetMode(mode)) {
   14678             :       // Rewrite code handles to direct pointers to the first instruction in the
   14679             :       // code object.
   14680      954278 :       Handle<Object> p = it.rinfo()->target_object_handle(origin);
   14681             :       Code code = Code::cast(*p);
   14682             :       it.rinfo()->set_target_address(code->raw_instruction_start(),
   14683      954287 :                                      UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
   14684     2710561 :     } else if (RelocInfo::IsRuntimeEntry(mode)) {
   14685     2702431 :       Address p = it.rinfo()->target_runtime_entry(origin);
   14686             :       it.rinfo()->set_target_runtime_entry(p, UPDATE_WRITE_BARRIER,
   14687             :                                            SKIP_ICACHE_FLUSH);
   14688             :     } else {
   14689             :       intptr_t delta =
   14690        8130 :           raw_instruction_start() - reinterpret_cast<Address>(desc.buffer);
   14691        8130 :       it.rinfo()->apply(delta);
   14692             :     }
   14693             :   }
   14694     2200280 : }
   14695             : 
   14696             : 
   14697     3017306 : SafepointEntry Code::GetSafepointEntry(Address pc) {
   14698     3017306 :   SafepointTable table(*this);
   14699     3017306 :   return table.FindEntry(pc);
   14700             : }
   14701             : 
   14702    38309338 : int Code::OffHeapInstructionSize() const {
   14703             :   DCHECK(is_off_heap_trampoline());
   14704    38309338 :   if (Isolate::CurrentEmbeddedBlob() == nullptr) return raw_instruction_size();
   14705    38309339 :   EmbeddedData d = EmbeddedData::FromBlob();
   14706    38309339 :   return d.InstructionSizeOfBuiltin(builtin_index());
   14707             : }
   14708             : 
   14709   235608579 : Address Code::OffHeapInstructionStart() const {
   14710             :   DCHECK(is_off_heap_trampoline());
   14711   235608579 :   if (Isolate::CurrentEmbeddedBlob() == nullptr) return raw_instruction_start();
   14712   235609642 :   EmbeddedData d = EmbeddedData::FromBlob();
   14713   235609642 :   return d.InstructionStartOfBuiltin(builtin_index());
   14714             : }
   14715             : 
   14716       96694 : Address Code::OffHeapInstructionEnd() const {
   14717             :   DCHECK(is_off_heap_trampoline());
   14718       96694 :   if (Isolate::CurrentEmbeddedBlob() == nullptr) return raw_instruction_end();
   14719       96694 :   EmbeddedData d = EmbeddedData::FromBlob();
   14720      193388 :   return d.InstructionStartOfBuiltin(builtin_index()) +
   14721      193388 :          d.InstructionSizeOfBuiltin(builtin_index());
   14722             : }
   14723             : 
   14724             : namespace {
   14725             : template <typename Code>
   14726       10534 : void SetStackFrameCacheCommon(Isolate* isolate, Handle<Code> code,
   14727             :                               Handle<SimpleNumberDictionary> cache) {
   14728       21068 :   Handle<Object> maybe_table(code->source_position_table(), isolate);
   14729       21068 :   if (maybe_table->IsSourcePositionTableWithFrameCache()) {
   14730        2410 :     Handle<SourcePositionTableWithFrameCache>::cast(maybe_table)
   14731        7230 :         ->set_stack_frame_cache(*cache);
   14732       12944 :     return;
   14733             :   }
   14734             :   DCHECK(maybe_table->IsByteArray());
   14735        8124 :   Handle<ByteArray> table(Handle<ByteArray>::cast(maybe_table));
   14736             :   Handle<SourcePositionTableWithFrameCache> table_with_cache =
   14737        8124 :       isolate->factory()->NewSourcePositionTableWithFrameCache(table, cache);
   14738       16248 :   code->set_source_position_table(*table_with_cache);
   14739             : }
   14740             : }  // namespace
   14741             : 
   14742             : // static
   14743       10534 : void AbstractCode::SetStackFrameCache(Handle<AbstractCode> abstract_code,
   14744             :                                       Handle<SimpleNumberDictionary> cache) {
   14745       21068 :   if (abstract_code->IsCode()) {
   14746             :     SetStackFrameCacheCommon(
   14747             :         abstract_code->GetIsolate(),
   14748           0 :         handle(abstract_code->GetCode(), abstract_code->GetIsolate()), cache);
   14749             :   } else {
   14750             :     SetStackFrameCacheCommon(
   14751             :         abstract_code->GetIsolate(),
   14752             :         handle(abstract_code->GetBytecodeArray(), abstract_code->GetIsolate()),
   14753       21068 :         cache);
   14754             :   }
   14755       10534 : }
   14756             : 
   14757             : namespace {
   14758             : template <typename Code>
   14759      892156 : void DropStackFrameCacheCommon(Code code) {
   14760      892156 :   i::Object maybe_table = code->source_position_table();
   14761     1784292 :   if (maybe_table->IsByteArray()) return;
   14762             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
   14763          20 :   code->set_source_position_table(
   14764             :       i::SourcePositionTableWithFrameCache::cast(maybe_table)
   14765          40 :           ->source_position_table());
   14766             : }
   14767             : }  // namespace
   14768             : 
   14769      892156 : void AbstractCode::DropStackFrameCache() {
   14770     1784312 :   if (IsCode()) {
   14771      891701 :     DropStackFrameCacheCommon(GetCode());
   14772             :   } else {
   14773         455 :     DropStackFrameCacheCommon(GetBytecodeArray());
   14774             :   }
   14775      892156 : }
   14776             : 
   14777     1414195 : int AbstractCode::SourcePosition(int offset) {
   14778             :   int position = 0;
   14779             :   // Subtract one because the current PC is one instruction after the call site.
   14780     2828390 :   if (IsCode()) offset--;
   14781    38017080 :   for (SourcePositionTableIterator iterator(source_position_table());
   14782    36602885 :        !iterator.done() && iterator.code_offset() <= offset;
   14783    35188690 :        iterator.Advance()) {
   14784    35188690 :     position = iterator.source_position().ScriptOffset();
   14785             :   }
   14786     1414195 :   return position;
   14787             : }
   14788             : 
   14789      107756 : int AbstractCode::SourceStatementPosition(int offset) {
   14790             :   // First find the closest position.
   14791      107756 :   int position = SourcePosition(offset);
   14792             :   // Now find the closest statement position before the position.
   14793             :   int statement_position = 0;
   14794    11291536 :   for (SourcePositionTableIterator it(source_position_table()); !it.done();
   14795    11076024 :        it.Advance()) {
   14796    11076024 :     if (it.is_statement()) {
   14797     7018666 :       int p = it.source_position().ScriptOffset();
   14798     7018666 :       if (statement_position < p && p <= position) {
   14799             :         statement_position = p;
   14800             :       }
   14801             :     }
   14802             :   }
   14803      107756 :   return statement_position;
   14804             : }
   14805             : 
   14806       52310 : void JSFunction::ClearTypeFeedbackInfo() {
   14807       52310 :   ResetIfBytecodeFlushed();
   14808       52310 :   if (has_feedback_vector()) {
   14809       52288 :     FeedbackVector vector = feedback_vector();
   14810             :     Isolate* isolate = GetIsolate();
   14811       52288 :     if (vector->ClearSlots(isolate)) {
   14812             :       IC::OnFeedbackChanged(isolate, vector, FeedbackSlot::Invalid(), *this,
   14813       27472 :                             "ClearTypeFeedbackInfo");
   14814             :     }
   14815             :   }
   14816       52310 : }
   14817             : 
   14818         300 : void Code::PrintDeoptLocation(FILE* out, const char* str, Address pc) {
   14819         300 :   Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(*this, pc);
   14820         300 :   class SourcePosition pos = info.position;
   14821         300 :   if (info.deopt_reason != DeoptimizeReason::kUnknown || pos.IsKnown()) {
   14822         300 :     PrintF(out, "%s", str);
   14823         300 :     OFStream outstr(out);
   14824         300 :     pos.Print(outstr, *this);
   14825         300 :     PrintF(out, ", %s\n", DeoptimizeReasonToString(info.deopt_reason));
   14826             :   }
   14827         300 : }
   14828             : 
   14829             : 
   14830        9895 : bool Code::CanDeoptAt(Address pc) {
   14831             :   DeoptimizationData deopt_data =
   14832       19790 :       DeoptimizationData::cast(deoptimization_data());
   14833        9895 :   Address code_start_address = InstructionStart();
   14834       92656 :   for (int i = 0; i < deopt_data->DeoptCount(); i++) {
   14835      182314 :     if (deopt_data->Pc(i)->value() == -1) continue;
   14836      119380 :     Address address = code_start_address + deopt_data->Pc(i)->value();
   14837       68086 :     if (address == pc && deopt_data->BytecodeOffset(i) != BailoutId::None()) {
   14838             :       return true;
   14839             :     }
   14840             :   }
   14841             :   return false;
   14842             : }
   14843             : 
   14844             : 
   14845             : // Identify kind of code.
   14846       20120 : const char* Code::Kind2String(Kind kind) {
   14847       20120 :   switch (kind) {
   14848             : #define CASE(name) case name: return #name;
   14849           0 :     CODE_KIND_LIST(CASE)
   14850             : #undef CASE
   14851             :     case NUMBER_OF_KINDS: break;
   14852             :   }
   14853           0 :   UNREACHABLE();
   14854             : }
   14855             : 
   14856             : // Identify kind of code.
   14857           0 : const char* AbstractCode::Kind2String(Kind kind) {
   14858           0 :   if (kind < AbstractCode::INTERPRETED_FUNCTION)
   14859           0 :     return Code::Kind2String(static_cast<Code::Kind>(kind));
   14860           0 :   if (kind == AbstractCode::INTERPRETED_FUNCTION) return "INTERPRETED_FUNCTION";
   14861           0 :   UNREACHABLE();
   14862             : }
   14863             : 
   14864       84616 : bool Code::IsIsolateIndependent(Isolate* isolate) {
   14865             :   constexpr int all_real_modes_mask =
   14866             :       (1 << (RelocInfo::LAST_REAL_RELOC_MODE + 1)) - 1;
   14867             :   constexpr int mode_mask = all_real_modes_mask &
   14868             :                             ~RelocInfo::ModeMask(RelocInfo::CONST_POOL) &
   14869             :                             ~RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) &
   14870             :                             ~RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
   14871             :   STATIC_ASSERT(RelocInfo::LAST_REAL_RELOC_MODE == RelocInfo::VENEER_POOL);
   14872             :   STATIC_ASSERT(mode_mask ==
   14873             :                 (RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
   14874             :                  RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET) |
   14875             :                  RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
   14876             :                  RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
   14877             :                  RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
   14878             :                  RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
   14879             :                  RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
   14880             :                  RelocInfo::ModeMask(RelocInfo::WASM_CALL) |
   14881             :                  RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL)));
   14882             : 
   14883             :   bool is_process_independent = true;
   14884      500024 :   for (RelocIterator it(*this, mode_mask); !it.done(); it.next()) {
   14885             : #if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_ARM64) || \
   14886             :     defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS) ||  \
   14887             :     defined(V8_TARGET_ARCH_S390) || defined(V8_TARGET_ARCH_IA32)
   14888             :     // On these platforms we emit relative builtin-to-builtin
   14889             :     // jumps for isolate independent builtins in the snapshot. They are later
   14890             :     // rewritten as pc-relative jumps to the off-heap instruction stream and are
   14891             :     // thus process-independent. See also: FinalizeEmbeddedCodeTargets.
   14892      415408 :     if (RelocInfo::IsCodeTargetMode(it.rinfo()->rmode())) {
   14893      415408 :       Address target_address = it.rinfo()->target_address();
   14894      830816 :       if (InstructionStream::PcIsOffHeap(isolate, target_address)) continue;
   14895             : 
   14896      415408 :       Code target = Code::GetCodeFromTargetAddress(target_address);
   14897      415408 :       CHECK(target->IsCode());
   14898      415408 :       if (Builtins::IsIsolateIndependentBuiltin(target)) continue;
   14899             :     }
   14900             : #endif
   14901             :     is_process_independent = false;
   14902             :   }
   14903             : 
   14904       84616 :   return is_process_independent;
   14905             : }
   14906             : 
   14907       16913 : bool Code::Inlines(SharedFunctionInfo sfi) {
   14908             :   // We can only check for inlining for optimized code.
   14909             :   DCHECK(is_optimized_code());
   14910             :   DisallowHeapAllocation no_gc;
   14911             :   DeoptimizationData const data =
   14912       33826 :       DeoptimizationData::cast(deoptimization_data());
   14913       16913 :   if (data->length() == 0) return false;
   14914       33826 :   if (data->SharedFunctionInfo() == sfi) return true;
   14915       16619 :   FixedArray const literals = data->LiteralArray();
   14916       33238 :   int const inlined_count = data->InlinedFunctionCount()->value();
   14917       16710 :   for (int i = 0; i < inlined_count; ++i) {
   14918         134 :     if (SharedFunctionInfo::cast(literals->get(i)) == sfi) return true;
   14919             :   }
   14920             :   return false;
   14921             : }
   14922             : 
   14923       12357 : Code::OptimizedCodeIterator::OptimizedCodeIterator(Isolate* isolate) {
   14924       12357 :   isolate_ = isolate;
   14925       12357 :   Object list = isolate->heap()->native_contexts_list();
   14926       24714 :   next_context_ = list->IsUndefined(isolate_) ? Context() : Context::cast(list);
   14927       12357 : }
   14928             : 
   14929       29270 : Code Code::OptimizedCodeIterator::Next() {
   14930       30020 :   do {
   14931       42377 :     Object next;
   14932       42377 :     if (!current_code_.is_null()) {
   14933             :       // Get next code in the linked list.
   14934       33826 :       next = current_code_->next_code_link();
   14935       25464 :     } else if (!next_context_.is_null()) {
   14936             :       // Linked list of code exhausted. Get list of next context.
   14937       13107 :       next = next_context_->OptimizedCodeListHead();
   14938       13107 :       Object next_context = next_context_->next_context_link();
   14939       13107 :       next_context_ = next_context->IsUndefined(isolate_)
   14940             :                           ? Context()
   14941       13857 :                           : Context::cast(next_context);
   14942             :     } else {
   14943             :       // Exhausted contexts.
   14944       12357 :       return Code();
   14945             :     }
   14946       76953 :     current_code_ = next->IsUndefined(isolate_) ? Code() : Code::cast(next);
   14947             :   } while (current_code_.is_null());
   14948             :   DCHECK_EQ(Code::OPTIMIZED_FUNCTION, current_code_->kind());
   14949       16913 :   return current_code_;
   14950             : }
   14951             : 
   14952             : #ifdef ENABLE_DISASSEMBLER
   14953             : 
   14954             : namespace {
   14955             : void print_pc(std::ostream& os, int pc) {
   14956             :   if (pc == -1) {
   14957             :     os << "NA";
   14958             :   } else {
   14959             :     os << std::hex << pc << std::dec;
   14960             :   }
   14961             : }
   14962             : }  // anonymous namespace
   14963             : 
   14964             : void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) {  // NOLINT
   14965             :   if (length() == 0) {
   14966             :     os << "Deoptimization Input Data invalidated by lazy deoptimization\n";
   14967             :     return;
   14968             :   }
   14969             : 
   14970             :   disasm::NameConverter converter;
   14971             :   int const inlined_function_count = InlinedFunctionCount()->value();
   14972             :   os << "Inlined functions (count = " << inlined_function_count << ")\n";
   14973             :   for (int id = 0; id < inlined_function_count; ++id) {
   14974             :     Object info = LiteralArray()->get(id);
   14975             :     os << " " << Brief(SharedFunctionInfo::cast(info)) << "\n";
   14976             :   }
   14977             :   os << "\n";
   14978             :   int deopt_count = DeoptCount();
   14979             :   os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
   14980             :   if (0 != deopt_count) {
   14981             :     os << " index  bytecode-offset    pc";
   14982             :     if (FLAG_print_code_verbose) os << "  commands";
   14983             :     os << "\n";
   14984             :   }
   14985             :   for (int i = 0; i < deopt_count; i++) {
   14986             :     os << std::setw(6) << i << "  " << std::setw(15)
   14987             :        << BytecodeOffset(i).ToInt() << "  " << std::setw(4);
   14988             :     print_pc(os, Pc(i)->value());
   14989             :     os << std::setw(2);
   14990             : 
   14991             :     if (!FLAG_print_code_verbose) {
   14992             :       os << "\n";
   14993             :       continue;
   14994             :     }
   14995             : 
   14996             :     // Print details of the frame translation.
   14997             :     int translation_index = TranslationIndex(i)->value();
   14998             :     TranslationIterator iterator(TranslationByteArray(), translation_index);
   14999             :     Translation::Opcode opcode =
   15000             :         static_cast<Translation::Opcode>(iterator.Next());
   15001             :     DCHECK(Translation::BEGIN == opcode);
   15002             :     int frame_count = iterator.Next();
   15003             :     int jsframe_count = iterator.Next();
   15004             :     int update_feedback_count = iterator.Next();
   15005             :     os << "  " << Translation::StringFor(opcode)
   15006             :        << " {frame count=" << frame_count
   15007             :        << ", js frame count=" << jsframe_count
   15008             :        << ", update_feedback_count=" << update_feedback_count << "}\n";
   15009             : 
   15010             :     while (iterator.HasNext() &&
   15011             :            Translation::BEGIN !=
   15012             :            (opcode = static_cast<Translation::Opcode>(iterator.Next()))) {
   15013             :       os << std::setw(31) << "    " << Translation::StringFor(opcode) << " ";
   15014             : 
   15015             :       switch (opcode) {
   15016             :         case Translation::BEGIN:
   15017             :           UNREACHABLE();
   15018             :           break;
   15019             : 
   15020             :         case Translation::INTERPRETED_FRAME: {
   15021             :           int bytecode_offset = iterator.Next();
   15022             :           int shared_info_id = iterator.Next();
   15023             :           unsigned height = iterator.Next();
   15024             :           int return_value_offset = iterator.Next();
   15025             :           int return_value_count = iterator.Next();
   15026             :           Object shared_info = LiteralArray()->get(shared_info_id);
   15027             :           os << "{bytecode_offset=" << bytecode_offset << ", function="
   15028             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   15029             :              << ", height=" << height << ", retval=@" << return_value_offset
   15030             :              << "(#" << return_value_count << ")}";
   15031             :           break;
   15032             :         }
   15033             : 
   15034             :         case Translation::CONSTRUCT_STUB_FRAME: {
   15035             :           int bailout_id = iterator.Next();
   15036             :           int shared_info_id = iterator.Next();
   15037             :           Object shared_info = LiteralArray()->get(shared_info_id);
   15038             :           unsigned height = iterator.Next();
   15039             :           os << "{bailout_id=" << bailout_id << ", function="
   15040             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   15041             :              << ", height=" << height << "}";
   15042             :           break;
   15043             :         }
   15044             : 
   15045             :         case Translation::BUILTIN_CONTINUATION_FRAME:
   15046             :         case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME:
   15047             :         case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME: {
   15048             :           int bailout_id = iterator.Next();
   15049             :           int shared_info_id = iterator.Next();
   15050             :           Object shared_info = LiteralArray()->get(shared_info_id);
   15051             :           unsigned height = iterator.Next();
   15052             :           os << "{bailout_id=" << bailout_id << ", function="
   15053             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   15054             :              << ", height=" << height << "}";
   15055             :           break;
   15056             :         }
   15057             : 
   15058             :         case Translation::ARGUMENTS_ADAPTOR_FRAME: {
   15059             :           int shared_info_id = iterator.Next();
   15060             :           Object shared_info = LiteralArray()->get(shared_info_id);
   15061             :           unsigned height = iterator.Next();
   15062             :           os << "{function="
   15063             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   15064             :              << ", height=" << height << "}";
   15065             :           break;
   15066             :         }
   15067             : 
   15068             :         case Translation::REGISTER: {
   15069             :           int reg_code = iterator.Next();
   15070             :           os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
   15071             :           break;
   15072             :         }
   15073             : 
   15074             :         case Translation::INT32_REGISTER: {
   15075             :           int reg_code = iterator.Next();
   15076             :           os << "{input=" << converter.NameOfCPURegister(reg_code)
   15077             :              << " (int32)}";
   15078             :           break;
   15079             :         }
   15080             : 
   15081             :         case Translation::INT64_REGISTER: {
   15082             :           int reg_code = iterator.Next();
   15083             :           os << "{input=" << converter.NameOfCPURegister(reg_code)
   15084             :              << " (int64)}";
   15085             :           break;
   15086             :         }
   15087             : 
   15088             :         case Translation::UINT32_REGISTER: {
   15089             :           int reg_code = iterator.Next();
   15090             :           os << "{input=" << converter.NameOfCPURegister(reg_code)
   15091             :              << " (uint32)}";
   15092             :           break;
   15093             :         }
   15094             : 
   15095             :         case Translation::BOOL_REGISTER: {
   15096             :           int reg_code = iterator.Next();
   15097             :           os << "{input=" << converter.NameOfCPURegister(reg_code)
   15098             :              << " (bool)}";
   15099             :           break;
   15100             :         }
   15101             : 
   15102             :         case Translation::FLOAT_REGISTER: {
   15103             :           int reg_code = iterator.Next();
   15104             :           os << "{input=" << FloatRegister::from_code(reg_code) << "}";
   15105             :           break;
   15106             :         }
   15107             : 
   15108             :         case Translation::DOUBLE_REGISTER: {
   15109             :           int reg_code = iterator.Next();
   15110             :           os << "{input=" << DoubleRegister::from_code(reg_code) << "}";
   15111             :           break;
   15112             :         }
   15113             : 
   15114             :         case Translation::STACK_SLOT: {
   15115             :           int input_slot_index = iterator.Next();
   15116             :           os << "{input=" << input_slot_index << "}";
   15117             :           break;
   15118             :         }
   15119             : 
   15120             :         case Translation::INT32_STACK_SLOT: {
   15121             :           int input_slot_index = iterator.Next();
   15122             :           os << "{input=" << input_slot_index << " (int32)}";
   15123             :           break;
   15124             :         }
   15125             : 
   15126             :         case Translation::INT64_STACK_SLOT: {
   15127             :           int input_slot_index = iterator.Next();
   15128             :           os << "{input=" << input_slot_index << " (int64)}";
   15129             :           break;
   15130             :         }
   15131             : 
   15132             :         case Translation::UINT32_STACK_SLOT: {
   15133             :           int input_slot_index = iterator.Next();
   15134             :           os << "{input=" << input_slot_index << " (uint32)}";
   15135             :           break;
   15136             :         }
   15137             : 
   15138             :         case Translation::BOOL_STACK_SLOT: {
   15139             :           int input_slot_index = iterator.Next();
   15140             :           os << "{input=" << input_slot_index << " (bool)}";
   15141             :           break;
   15142             :         }
   15143             : 
   15144             :         case Translation::FLOAT_STACK_SLOT:
   15145             :         case Translation::DOUBLE_STACK_SLOT: {
   15146             :           int input_slot_index = iterator.Next();
   15147             :           os << "{input=" << input_slot_index << "}";
   15148             :           break;
   15149             :         }
   15150             : 
   15151             :         case Translation::LITERAL: {
   15152             :           int literal_index = iterator.Next();
   15153             :           Object literal_value = LiteralArray()->get(literal_index);
   15154             :           os << "{literal_id=" << literal_index << " (" << Brief(literal_value)
   15155             :              << ")}";
   15156             :           break;
   15157             :         }
   15158             : 
   15159             :         case Translation::DUPLICATED_OBJECT: {
   15160             :           int object_index = iterator.Next();
   15161             :           os << "{object_index=" << object_index << "}";
   15162             :           break;
   15163             :         }
   15164             : 
   15165             :         case Translation::ARGUMENTS_ELEMENTS:
   15166             :         case Translation::ARGUMENTS_LENGTH: {
   15167             :           CreateArgumentsType arguments_type =
   15168             :               static_cast<CreateArgumentsType>(iterator.Next());
   15169             :           os << "{arguments_type=" << arguments_type << "}";
   15170             :           break;
   15171             :         }
   15172             : 
   15173             :         case Translation::CAPTURED_OBJECT: {
   15174             :           int args_length = iterator.Next();
   15175             :           os << "{length=" << args_length << "}";
   15176             :           break;
   15177             :         }
   15178             : 
   15179             :         case Translation::UPDATE_FEEDBACK: {
   15180             :           int literal_index = iterator.Next();
   15181             :           FeedbackSlot slot(iterator.Next());
   15182             :           os << "{feedback={vector_index=" << literal_index << ", slot=" << slot
   15183             :              << "}}";
   15184             :           break;
   15185             :         }
   15186             :       }
   15187             :       os << "\n";
   15188             :     }
   15189             :   }
   15190             : }
   15191             : 
   15192             : const char* Code::GetName(Isolate* isolate) const {
   15193             :   if (kind() == BYTECODE_HANDLER) {
   15194             :     return isolate->interpreter()->LookupNameOfBytecodeHandler(*this);
   15195             :   } else {
   15196             :     // There are some handlers and ICs that we can also find names for with
   15197             :     // Builtins::Lookup.
   15198             :     return isolate->builtins()->Lookup(raw_instruction_start());
   15199             :   }
   15200             : }
   15201             : 
   15202             : namespace {
   15203             : 
   15204             : inline void DisassembleCodeRange(Isolate* isolate, std::ostream& os, Code code,
   15205             :                                  Address begin, size_t size,
   15206             :                                  Address current_pc) {
   15207             :   Address end = begin + size;
   15208             :   // TODO(mstarzinger): Refactor CodeReference to avoid the
   15209             :   // unhandlified->handlified transition.
   15210             :   AllowHandleAllocation allow_handles;
   15211             :   DisallowHeapAllocation no_gc;
   15212             :   HandleScope handle_scope(isolate);
   15213             :   Disassembler::Decode(isolate, &os, reinterpret_cast<byte*>(begin),
   15214             :                        reinterpret_cast<byte*>(end),
   15215             :                        CodeReference(handle(code, isolate)), current_pc);
   15216             : }
   15217             : 
   15218             : }  // namespace
   15219             : 
   15220             : void Code::Disassemble(const char* name, std::ostream& os, Address current_pc) {
   15221             :   Isolate* isolate = GetIsolate();
   15222             :   os << "kind = " << Kind2String(kind()) << "\n";
   15223             :   if (name == nullptr) {
   15224             :     name = GetName(isolate);
   15225             :   }
   15226             :   if ((name != nullptr) && (name[0] != '\0')) {
   15227             :     os << "name = " << name << "\n";
   15228             :   }
   15229             :   if (kind() == OPTIMIZED_FUNCTION) {
   15230             :     os << "stack_slots = " << stack_slots() << "\n";
   15231             :   }
   15232             :   os << "compiler = " << (is_turbofanned() ? "turbofan" : "unknown") << "\n";
   15233             :   os << "address = " << static_cast<const void*>(this) << "\n\n";
   15234             : 
   15235             :   if (is_off_heap_trampoline()) {
   15236             :     int trampoline_size = raw_instruction_size();
   15237             :     os << "Trampoline (size = " << trampoline_size << ")\n";
   15238             :     DisassembleCodeRange(isolate, os, *this, raw_instruction_start(),
   15239             :                          trampoline_size, current_pc);
   15240             :     os << "\n";
   15241             :   }
   15242             : 
   15243             :   {
   15244             :     int size = InstructionSize();
   15245             :     int safepoint_offset =
   15246             :         has_safepoint_info() ? safepoint_table_offset() : size;
   15247             :     int const_pool_offset = constant_pool_offset();
   15248             :     int handler_offset = handler_table_offset() ? handler_table_offset() : size;
   15249             :     int comments_offset = code_comments_offset();
   15250             : 
   15251             :     // Stop before reaching any embedded tables
   15252             :     int code_size = std::min(
   15253             :         {handler_offset, safepoint_offset, const_pool_offset, comments_offset});
   15254             :     os << "Instructions (size = " << code_size << ")\n";
   15255             :     DisassembleCodeRange(isolate, os, *this, InstructionStart(), code_size,
   15256             :                          current_pc);
   15257             : 
   15258             :     if (int pool_size = constant_pool_size()) {
   15259             :       DCHECK_EQ(pool_size & kPointerAlignmentMask, 0);
   15260             :       os << "\nConstant Pool (size = " << pool_size << ")\n";
   15261             :       Vector<char> buf = Vector<char>::New(50);
   15262             :       intptr_t* ptr =
   15263             :           reinterpret_cast<intptr_t*>(InstructionStart() + const_pool_offset);
   15264             :       for (int i = 0; i < pool_size; i += kSystemPointerSize, ptr++) {
   15265             :         SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr);
   15266             :         os << static_cast<const void*>(ptr) << "  " << buf.start() << "\n";
   15267             :       }
   15268             :     }
   15269             :   }
   15270             :   os << "\n";
   15271             : 
   15272             :   SourcePositionTableIterator it(SourcePositionTable());
   15273             :   if (!it.done()) {
   15274             :     os << "Source positions:\n pc offset  position\n";
   15275             :     for (; !it.done(); it.Advance()) {
   15276             :       os << std::setw(10) << std::hex << it.code_offset() << std::dec
   15277             :          << std::setw(10) << it.source_position().ScriptOffset()
   15278             :          << (it.is_statement() ? "  statement" : "") << "\n";
   15279             :     }
   15280             :     os << "\n";
   15281             :   }
   15282             : 
   15283             :   if (kind() == OPTIMIZED_FUNCTION) {
   15284             :     DeoptimizationData data =
   15285             :         DeoptimizationData::cast(this->deoptimization_data());
   15286             :     data->DeoptimizationDataPrint(os);
   15287             :   }
   15288             :   os << "\n";
   15289             : 
   15290             :   if (has_safepoint_info()) {
   15291             :     SafepointTable table(*this);
   15292             :     os << "Safepoints (size = " << table.size() << ")\n";
   15293             :     for (unsigned i = 0; i < table.length(); i++) {
   15294             :       unsigned pc_offset = table.GetPcOffset(i);
   15295             :       os << reinterpret_cast<const void*>(InstructionStart() + pc_offset)
   15296             :          << "  ";
   15297             :       os << std::setw(6) << std::hex << pc_offset << "  " << std::setw(4);
   15298             :       int trampoline_pc = table.GetTrampolinePcOffset(i);
   15299             :       print_pc(os, trampoline_pc);
   15300             :       os << std::dec << "  ";
   15301             :       table.PrintEntry(i, os);
   15302             :       os << " (sp -> fp)  ";
   15303             :       SafepointEntry entry = table.GetEntry(i);
   15304             :       if (entry.has_deoptimization_index()) {
   15305             :         os << std::setw(6) << entry.deoptimization_index();
   15306             :       } else {
   15307             :         os << "<none>";
   15308             :       }
   15309             :       if (entry.has_argument_count()) {
   15310             :         os << " argc: " << entry.argument_count();
   15311             :       }
   15312             :       os << "\n";
   15313             :     }
   15314             :     os << "\n";
   15315             :   }
   15316             : 
   15317             :   if (handler_table_offset() > 0) {
   15318             :     HandlerTable table(*this);
   15319             :     os << "Handler Table (size = " << table.NumberOfReturnEntries() << ")\n";
   15320             :     if (kind() == OPTIMIZED_FUNCTION) {
   15321             :       table.HandlerTableReturnPrint(os);
   15322             :     }
   15323             :     os << "\n";
   15324             :   }
   15325             : 
   15326             :   os << "RelocInfo (size = " << relocation_size() << ")\n";
   15327             :   for (RelocIterator it(*this); !it.done(); it.next()) {
   15328             :     it.rinfo()->Print(isolate, os);
   15329             :   }
   15330             :   os << "\n";
   15331             : 
   15332             :   if (has_unwinding_info()) {
   15333             :     os << "UnwindingInfo (size = " << unwinding_info_size() << ")\n";
   15334             :     EhFrameDisassembler eh_frame_disassembler(
   15335             :         reinterpret_cast<byte*>(unwinding_info_start()),
   15336             :         reinterpret_cast<byte*>(unwinding_info_end()));
   15337             :     eh_frame_disassembler.DisassembleToStream(os);
   15338             :     os << "\n";
   15339             :   }
   15340             : 
   15341             :   if (code_comments_offset() < InstructionSize()) {
   15342             :     PrintCodeCommentsSection(os, code_comments());
   15343             :   }
   15344             : }
   15345             : #endif  // ENABLE_DISASSEMBLER
   15346             : 
   15347           0 : void BytecodeArray::Disassemble(std::ostream& os) {
   15348             :   DisallowHeapAllocation no_gc;
   15349             : 
   15350           0 :   os << "Parameter count " << parameter_count() << "\n";
   15351           0 :   os << "Frame size " << frame_size() << "\n";
   15352             : 
   15353             :   Address base_address = GetFirstBytecodeAddress();
   15354           0 :   SourcePositionTableIterator source_positions(SourcePositionTable());
   15355             : 
   15356             :   // Storage for backing the handle passed to the iterator. This handle won't be
   15357             :   // updated by the gc, but that's ok because we've disallowed GCs anyway.
   15358           0 :   BytecodeArray handle_storage = *this;
   15359             :   Handle<BytecodeArray> handle(reinterpret_cast<Address*>(&handle_storage));
   15360           0 :   interpreter::BytecodeArrayIterator iterator(handle);
   15361           0 :   while (!iterator.done()) {
   15362           0 :     if (!source_positions.done() &&
   15363           0 :         iterator.current_offset() == source_positions.code_offset()) {
   15364           0 :       os << std::setw(5) << source_positions.source_position().ScriptOffset();
   15365           0 :       os << (source_positions.is_statement() ? " S> " : " E> ");
   15366           0 :       source_positions.Advance();
   15367             :     } else {
   15368           0 :       os << "         ";
   15369             :     }
   15370           0 :     Address current_address = base_address + iterator.current_offset();
   15371           0 :     os << reinterpret_cast<const void*>(current_address) << " @ "
   15372           0 :        << std::setw(4) << iterator.current_offset() << " : ";
   15373             :     interpreter::BytecodeDecoder::Decode(
   15374           0 :         os, reinterpret_cast<byte*>(current_address), parameter_count());
   15375           0 :     if (interpreter::Bytecodes::IsJump(iterator.current_bytecode())) {
   15376           0 :       Address jump_target = base_address + iterator.GetJumpTargetOffset();
   15377           0 :       os << " (" << reinterpret_cast<void*>(jump_target) << " @ "
   15378           0 :          << iterator.GetJumpTargetOffset() << ")";
   15379             :     }
   15380           0 :     if (interpreter::Bytecodes::IsSwitch(iterator.current_bytecode())) {
   15381           0 :       os << " {";
   15382             :       bool first_entry = true;
   15383           0 :       for (const auto& entry : iterator.GetJumpTableTargetOffsets()) {
   15384           0 :         if (first_entry) {
   15385             :           first_entry = false;
   15386             :         } else {
   15387           0 :           os << ",";
   15388             :         }
   15389           0 :         os << " " << entry.case_value << ": @" << entry.target_offset;
   15390             :       }
   15391           0 :       os << " }";
   15392             :     }
   15393             :     os << std::endl;
   15394           0 :     iterator.Advance();
   15395             :   }
   15396             : 
   15397           0 :   os << "Constant pool (size = " << constant_pool()->length() << ")\n";
   15398             : #ifdef OBJECT_PRINT
   15399             :   if (constant_pool()->length() > 0) {
   15400             :     constant_pool()->Print();
   15401             :   }
   15402             : #endif
   15403             : 
   15404           0 :   os << "Handler Table (size = " << handler_table()->length() << ")\n";
   15405             : #ifdef ENABLE_DISASSEMBLER
   15406             :   if (handler_table()->length() > 0) {
   15407             :     HandlerTable table(*this);
   15408             :     table.HandlerTableRangePrint(os);
   15409             :   }
   15410             : #endif
   15411           0 : }
   15412             : 
   15413       10538 : void BytecodeArray::CopyBytecodesTo(BytecodeArray to) {
   15414       10538 :   BytecodeArray from = *this;
   15415             :   DCHECK_EQ(from->length(), to->length());
   15416             :   CopyBytes(reinterpret_cast<byte*>(to->GetFirstBytecodeAddress()),
   15417             :             reinterpret_cast<byte*>(from->GetFirstBytecodeAddress()),
   15418       31614 :             from->length());
   15419       10538 : }
   15420             : 
   15421     5049369 : void BytecodeArray::MakeOlder() {
   15422             :   // BytecodeArray is aged in concurrent marker.
   15423             :   // The word must be completely within the byte code array.
   15424     5049369 :   Address age_addr = address() + kBytecodeAgeOffset;
   15425             :   DCHECK_LE(RoundDown(age_addr, kSystemPointerSize) + kSystemPointerSize,
   15426             :             address() + Size());
   15427             :   Age age = bytecode_age();
   15428     5049369 :   if (age < kLastBytecodeAge) {
   15429             :     base::AsAtomic8::Release_CompareAndSwap(reinterpret_cast<byte*>(age_addr),
   15430     1365231 :                                             age, age + 1);
   15431             :   }
   15432             : 
   15433             :   DCHECK_GE(bytecode_age(), kFirstBytecodeAge);
   15434             :   DCHECK_LE(bytecode_age(), kLastBytecodeAge);
   15435     5049369 : }
   15436             : 
   15437         119 : bool BytecodeArray::IsOld() const {
   15438         119 :   return bytecode_age() >= kIsOldBytecodeAge;
   15439             : }
   15440             : 
   15441             : // static
   15442      156414 : void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) {
   15443             :   DCHECK_GE(capacity, 0);
   15444             :   array->GetIsolate()->factory()->NewJSArrayStorage(
   15445      156432 :       array, length, capacity, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
   15446      156439 : }
   15447             : 
   15448      924647 : void JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) {
   15449             :   // We should never end in here with a pixel or external array.
   15450             :   DCHECK(array->AllowsSetLength());
   15451      924647 :   if (array->SetLengthWouldNormalize(new_length)) {
   15452         437 :     JSObject::NormalizeElements(array);
   15453             :   }
   15454     1849294 :   array->GetElementsAccessor()->SetLength(array, new_length);
   15455      924647 : }
   15456             : 
   15457      867737 : DependentCode DependentCode::GetDependentCode(Handle<HeapObject> object) {
   15458     1735474 :   if (object->IsMap()) {
   15459      474828 :     return Handle<Map>::cast(object)->dependent_code();
   15460     1260646 :   } else if (object->IsPropertyCell()) {
   15461     1239496 :     return Handle<PropertyCell>::cast(object)->dependent_code();
   15462       21150 :   } else if (object->IsAllocationSite()) {
   15463       21150 :     return Handle<AllocationSite>::cast(object)->dependent_code();
   15464             :   }
   15465           0 :   UNREACHABLE();
   15466             : }
   15467             : 
   15468      315953 : void DependentCode::SetDependentCode(Handle<HeapObject> object,
   15469             :                                      Handle<DependentCode> dep) {
   15470      631905 :   if (object->IsMap()) {
   15471      211208 :     Handle<Map>::cast(object)->set_dependent_code(*dep);
   15472      420696 :   } else if (object->IsPropertyCell()) {
   15473      400992 :     Handle<PropertyCell>::cast(object)->set_dependent_code(*dep);
   15474       19704 :   } else if (object->IsAllocationSite()) {
   15475       19704 :     Handle<AllocationSite>::cast(object)->set_dependent_code(*dep);
   15476             :   } else {
   15477           0 :     UNREACHABLE();
   15478             :   }
   15479      315953 : }
   15480             : 
   15481      867737 : void DependentCode::InstallDependency(Isolate* isolate,
   15482             :                                       const MaybeObjectHandle& code,
   15483             :                                       Handle<HeapObject> object,
   15484             :                                       DependencyGroup group) {
   15485             :   Handle<DependentCode> old_deps(DependentCode::GetDependentCode(object),
   15486      867737 :                                  isolate);
   15487             :   Handle<DependentCode> new_deps =
   15488      867737 :       InsertWeakCode(isolate, old_deps, group, code);
   15489             :   // Update the list head if necessary.
   15490      867736 :   if (!new_deps.is_identical_to(old_deps))
   15491      315953 :     DependentCode::SetDependentCode(object, new_deps);
   15492      867736 : }
   15493             : 
   15494      868246 : Handle<DependentCode> DependentCode::InsertWeakCode(
   15495             :     Isolate* isolate, Handle<DependentCode> entries, DependencyGroup group,
   15496             :     const MaybeObjectHandle& code) {
   15497     2171334 :   if (entries->length() == 0 || entries->group() > group) {
   15498             :     // There is no such group.
   15499      219402 :     return DependentCode::New(isolate, group, code, entries);
   15500             :   }
   15501     1297688 :   if (entries->group() < group) {
   15502             :     // The group comes later in the list.
   15503        1018 :     Handle<DependentCode> old_next(entries->next_link(), isolate);
   15504             :     Handle<DependentCode> new_next =
   15505         509 :         InsertWeakCode(isolate, old_next, group, code);
   15506         509 :     if (!old_next.is_identical_to(new_next)) {
   15507         604 :       entries->set_next_link(*new_next);
   15508             :     }
   15509         509 :     return entries;
   15510             :   }
   15511             :   DCHECK_EQ(group, entries->group());
   15512     1296670 :   int count = entries->count();
   15513             :   // Check for existing entry to avoid duplicates.
   15514    83580721 :   for (int i = 0; i < count; i++) {
   15515   249839481 :     if (entries->object_at(i) == *code) return entries;
   15516             :   }
   15517      601788 :   if (entries->length() < kCodesStartIndex + count + 1) {
   15518      100400 :     entries = EnsureSpace(isolate, entries);
   15519             :     // Count could have changed, reload it.
   15520      200800 :     count = entries->count();
   15521             :   }
   15522      902681 :   entries->set_object_at(count, *code);
   15523      601787 :   entries->set_count(count + 1);
   15524      300894 :   return entries;
   15525             : }
   15526             : 
   15527      219402 : Handle<DependentCode> DependentCode::New(Isolate* isolate,
   15528             :                                          DependencyGroup group,
   15529             :                                          const MaybeObjectHandle& object,
   15530             :                                          Handle<DependentCode> next) {
   15531             :   Handle<DependentCode> result = Handle<DependentCode>::cast(
   15532      219402 :       isolate->factory()->NewWeakFixedArray(kCodesStartIndex + 1, TENURED));
   15533      438804 :   result->set_next_link(*next);
   15534      658206 :   result->set_flags(GroupField::encode(group) | CountField::encode(1));
   15535      658206 :   result->set_object_at(0, *object);
   15536      219402 :   return result;
   15537             : }
   15538             : 
   15539      100399 : Handle<DependentCode> DependentCode::EnsureSpace(
   15540             :     Isolate* isolate, Handle<DependentCode> entries) {
   15541      100400 :   if (entries->Compact()) return entries;
   15542      193704 :   int capacity = kCodesStartIndex + DependentCode::Grow(entries->count());
   15543       96853 :   int grow_by = capacity - entries->length();
   15544             :   return Handle<DependentCode>::cast(
   15545       96853 :       isolate->factory()->CopyWeakFixedArrayAndGrow(entries, grow_by, TENURED));
   15546             : }
   15547             : 
   15548             : 
   15549      100400 : bool DependentCode::Compact() {
   15550             :   int old_count = count();
   15551             :   int new_count = 0;
   15552     1172923 :   for (int i = 0; i < old_count; i++) {
   15553             :     MaybeObject obj = object_at(i);
   15554     1072523 :     if (!obj->IsCleared()) {
   15555     1022491 :       if (i != new_count) {
   15556       12396 :         copy(i, new_count);
   15557             :       }
   15558     1022491 :       new_count++;
   15559             :     }
   15560             :   }
   15561      100400 :   set_count(new_count);
   15562      150431 :   for (int i = new_count; i < old_count; i++) {
   15563       50032 :     clear_at(i);
   15564             :   }
   15565      100399 :   return new_count < old_count;
   15566             : }
   15567             : 
   15568    20025014 : bool DependentCode::MarkCodeForDeoptimization(
   15569             :     Isolate* isolate,
   15570             :     DependentCode::DependencyGroup group) {
   15571    20029882 :   if (this->length() == 0 || this->group() > group) {
   15572             :     // There is no such group.
   15573             :     return false;
   15574             :   }
   15575        4588 :   if (this->group() < group) {
   15576             :     // The group comes later in the list.
   15577         170 :     return next_link()->MarkCodeForDeoptimization(isolate, group);
   15578             :   }
   15579             :   DCHECK_EQ(group, this->group());
   15580             :   DisallowHeapAllocation no_allocation_scope;
   15581             :   // Mark all the code that needs to be deoptimized.
   15582             :   bool marked = false;
   15583             :   int count = this->count();
   15584       12489 :   for (int i = 0; i < count; i++) {
   15585        8071 :     MaybeObject obj = object_at(i);
   15586        8095 :     if (obj->IsCleared()) continue;
   15587        8047 :     Code code = Code::cast(obj->GetHeapObjectAssumeWeak());
   15588        8047 :     if (!code->marked_for_deoptimization()) {
   15589        4998 :       code->SetMarkedForDeoptimization(DependencyGroupName(group));
   15590             :       marked = true;
   15591             :     }
   15592             :   }
   15593        8071 :   for (int i = 0; i < count; i++) {
   15594        8071 :     clear_at(i);
   15595             :   }
   15596        4418 :   set_count(0);
   15597        4418 :   return marked;
   15598             : }
   15599             : 
   15600             : 
   15601    20024788 : void DependentCode::DeoptimizeDependentCodeGroup(
   15602             :     Isolate* isolate,
   15603             :     DependentCode::DependencyGroup group) {
   15604             :   DisallowHeapAllocation no_allocation_scope;
   15605    20024788 :   bool marked = MarkCodeForDeoptimization(isolate, group);
   15606    20024789 :   if (marked) {
   15607             :     DCHECK(AllowCodeDependencyChange::IsAllowed());
   15608        2387 :     Deoptimizer::DeoptimizeMarkedCode(isolate);
   15609             :   }
   15610    20024789 : }
   15611             : 
   15612        5062 : void Code::SetMarkedForDeoptimization(const char* reason) {
   15613        5062 :   set_marked_for_deoptimization(true);
   15614       15186 :   if (FLAG_trace_deopt &&
   15615        5068 :       (deoptimization_data() != GetReadOnlyRoots().empty_fixed_array())) {
   15616             :     DeoptimizationData deopt_data =
   15617           4 :         DeoptimizationData::cast(deoptimization_data());
   15618           2 :     CodeTracer::Scope scope(GetHeap()->isolate()->GetCodeTracer());
   15619             :     PrintF(scope.file(),
   15620             :            "[marking dependent code " V8PRIxPTR_FMT
   15621             :            " (opt #%d) for deoptimization, reason: %s]\n",
   15622           4 :            ptr(), deopt_data->OptimizationId()->value(), reason);
   15623             :   }
   15624        5062 : }
   15625             : 
   15626             : 
   15627        4998 : const char* DependentCode::DependencyGroupName(DependencyGroup group) {
   15628        4998 :   switch (group) {
   15629             :     case kTransitionGroup:
   15630             :       return "transition";
   15631             :     case kPrototypeCheckGroup:
   15632        1081 :       return "prototype-check";
   15633             :     case kPropertyCellChangedGroup:
   15634        3701 :       return "property-cell-changed";
   15635             :     case kFieldOwnerGroup:
   15636          83 :       return "field-owner";
   15637             :     case kInitialMapChangedGroup:
   15638         104 :       return "initial-map-changed";
   15639             :     case kAllocationSiteTenuringChangedGroup:
   15640           6 :       return "allocation-site-tenuring-changed";
   15641             :     case kAllocationSiteTransitionChangedGroup:
   15642           4 :       return "allocation-site-transition-changed";
   15643             :   }
   15644           0 :   UNREACHABLE();
   15645             : }
   15646             : 
   15647      185839 : Handle<Map> Map::TransitionToPrototype(Isolate* isolate, Handle<Map> map,
   15648             :                                        Handle<Object> prototype) {
   15649             :   Handle<Map> new_map =
   15650      185839 :       TransitionsAccessor(isolate, map).GetPrototypeTransition(prototype);
   15651      185839 :   if (new_map.is_null()) {
   15652      169535 :     new_map = Copy(isolate, map, "TransitionToPrototype");
   15653             :     TransitionsAccessor(isolate, map)
   15654      169535 :         .PutPrototypeTransition(prototype, new_map);
   15655      169535 :     Map::SetPrototype(isolate, new_map, prototype);
   15656             :   }
   15657      185839 :   return new_map;
   15658             : }
   15659             : 
   15660             : 
   15661      280478 : Maybe<bool> JSReceiver::SetPrototype(Handle<JSReceiver> object,
   15662             :                                      Handle<Object> value, bool from_javascript,
   15663             :                                      ShouldThrow should_throw) {
   15664      560956 :   if (object->IsJSProxy()) {
   15665             :     return JSProxy::SetPrototype(Handle<JSProxy>::cast(object), value,
   15666       71931 :                                  from_javascript, should_throw);
   15667             :   }
   15668             :   return JSObject::SetPrototype(Handle<JSObject>::cast(object), value,
   15669      208547 :                                 from_javascript, should_throw);
   15670             : }
   15671             : 
   15672             : 
   15673             : // ES6: 9.5.2 [[SetPrototypeOf]] (V)
   15674             : // static
   15675       71931 : Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value,
   15676             :                                   bool from_javascript,
   15677             :                                   ShouldThrow should_throw) {
   15678             :   Isolate* isolate = proxy->GetIsolate();
   15679       71931 :   STACK_CHECK(isolate, Nothing<bool>());
   15680             :   Handle<Name> trap_name = isolate->factory()->setPrototypeOf_string();
   15681             :   // 1. Assert: Either Type(V) is Object or Type(V) is Null.
   15682             :   DCHECK(value->IsJSReceiver() || value->IsNull(isolate));
   15683             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
   15684      143842 :   Handle<Object> handler(proxy->handler(), isolate);
   15685             :   // 3. If handler is null, throw a TypeError exception.
   15686             :   // 4. Assert: Type(handler) is Object.
   15687      143842 :   if (proxy->IsRevoked()) {
   15688             :     isolate->Throw(*isolate->factory()->NewTypeError(
   15689          18 :         MessageTemplate::kProxyRevoked, trap_name));
   15690             :     return Nothing<bool>();
   15691             :   }
   15692             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot.
   15693      143824 :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
   15694             :   // 6. Let trap be ? GetMethod(handler, "getPrototypeOf").
   15695             :   Handle<Object> trap;
   15696      143824 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   15697             :       isolate, trap,
   15698             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
   15699             :       Nothing<bool>());
   15700             :   // 7. If trap is undefined, then return target.[[SetPrototypeOf]]().
   15701      143824 :   if (trap->IsUndefined(isolate)) {
   15702             :     return JSReceiver::SetPrototype(target, value, from_javascript,
   15703       63182 :                                     should_throw);
   15704             :   }
   15705             :   // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, V»)).
   15706        8730 :   Handle<Object> argv[] = {target, value};
   15707             :   Handle<Object> trap_result;
   15708       17460 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   15709             :       isolate, trap_result,
   15710             :       Execution::Call(isolate, trap, handler, arraysize(argv), argv),
   15711             :       Nothing<bool>());
   15712          90 :   bool bool_trap_result = trap_result->BooleanValue(isolate);
   15713             :   // 9. If booleanTrapResult is false, return false.
   15714          90 :   if (!bool_trap_result) {
   15715          90 :     RETURN_FAILURE(
   15716             :         isolate, should_throw,
   15717             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
   15718             :   }
   15719             :   // 10. Let extensibleTarget be ? IsExtensible(target).
   15720          54 :   Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
   15721          54 :   if (is_extensible.IsNothing()) return Nothing<bool>();
   15722             :   // 11. If extensibleTarget is true, return true.
   15723          54 :   if (is_extensible.FromJust()) {
   15724          27 :     if (bool_trap_result) return Just(true);
   15725           0 :     RETURN_FAILURE(
   15726             :         isolate, should_throw,
   15727             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
   15728             :   }
   15729             :   // 12. Let targetProto be ? target.[[GetPrototypeOf]]().
   15730             :   Handle<Object> target_proto;
   15731          54 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_proto,
   15732             :                                    JSReceiver::GetPrototype(isolate, target),
   15733             :                                    Nothing<bool>());
   15734             :   // 13. If SameValue(V, targetProto) is false, throw a TypeError exception.
   15735          36 :   if (bool_trap_result && !value->SameValue(*target_proto)) {
   15736             :     isolate->Throw(*isolate->factory()->NewTypeError(
   15737          18 :         MessageTemplate::kProxySetPrototypeOfNonExtensible));
   15738             :     return Nothing<bool>();
   15739             :   }
   15740             :   // 14. Return true.
   15741             :   return Just(true);
   15742             : }
   15743             : 
   15744             : 
   15745      210989 : Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
   15746             :                                    Handle<Object> value, bool from_javascript,
   15747             :                                    ShouldThrow should_throw) {
   15748             :   Isolate* isolate = object->GetIsolate();
   15749             : 
   15750             : #ifdef DEBUG
   15751             :   int size = object->Size();
   15752             : #endif
   15753             : 
   15754      210989 :   if (from_javascript) {
   15755      382223 :     if (object->IsAccessCheckNeeded() &&
   15756          35 :         !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
   15757           0 :       isolate->ReportFailedAccessCheck(object);
   15758           0 :       RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
   15759           0 :       RETURN_FAILURE(isolate, should_throw,
   15760             :                      NewTypeError(MessageTemplate::kNoAccess));
   15761             :     }
   15762             :   } else {
   15763             :     DCHECK(!object->IsAccessCheckNeeded());
   15764             :   }
   15765             : 
   15766             :   // Silently ignore the change if value is not a JSObject or null.
   15767             :   // SpiderMonkey behaves this way.
   15768      445382 :   if (!value->IsJSReceiver() && !value->IsNull(isolate)) return Just(true);
   15769             : 
   15770             :   bool all_extensible = object->map()->is_extensible();
   15771             :   Handle<JSObject> real_receiver = object;
   15772      210974 :   if (from_javascript) {
   15773             :     // Find the first object in the chain whose prototype object is not
   15774             :     // hidden.
   15775             :     PrototypeIterator iter(isolate, real_receiver, kStartAtPrototype,
   15776      191094 :                            PrototypeIterator::END_AT_NON_HIDDEN);
   15777      385368 :     while (!iter.IsAtEnd()) {
   15778             :       // Casting to JSObject is fine because hidden prototypes are never
   15779             :       // JSProxies.
   15780             :       real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
   15781        3180 :       iter.Advance();
   15782        6360 :       all_extensible = all_extensible && real_receiver->map()->is_extensible();
   15783             :     }
   15784             :   }
   15785             :   Handle<Map> map(real_receiver->map(), isolate);
   15786             : 
   15787             :   // Nothing to do if prototype is already set.
   15788      210974 :   if (map->prototype() == *value) return Just(true);
   15789             : 
   15790      185292 :   bool immutable_proto = map->is_immutable_proto();
   15791      185292 :   if (immutable_proto) {
   15792         171 :     RETURN_FAILURE(
   15793             :         isolate, should_throw,
   15794             :         NewTypeError(MessageTemplate::kImmutablePrototypeSet, object));
   15795             :   }
   15796             : 
   15797             :   // From 8.6.2 Object Internal Methods
   15798             :   // ...
   15799             :   // In addition, if [[Extensible]] is false the value of the [[Class]] and
   15800             :   // [[Prototype]] internal properties of the object may not be modified.
   15801             :   // ...
   15802             :   // Implementation specific extensions that modify [[Class]], [[Prototype]]
   15803             :   // or [[Extensible]] must not violate the invariants defined in the preceding
   15804             :   // paragraph.
   15805      185229 :   if (!all_extensible) {
   15806         495 :     RETURN_FAILURE(isolate, should_throw,
   15807             :                    NewTypeError(MessageTemplate::kNonExtensibleProto, object));
   15808             :   }
   15809             : 
   15810             :   // Before we can set the prototype we need to be sure prototype cycles are
   15811             :   // prevented.  It is sufficient to validate that the receiver is not in the
   15812             :   // new prototype chain.
   15813      369972 :   if (value->IsJSReceiver()) {
   15814      551711 :     for (PrototypeIterator iter(isolate, JSReceiver::cast(*value),
   15815             :                                 kStartAtReceiver);
   15816      378391 :          !iter.IsAtEnd(); iter.Advance()) {
   15817      756938 :       if (iter.GetCurrent<JSReceiver>() == *object) {
   15818             :         // Cycle detected.
   15819         198 :         RETURN_FAILURE(isolate, should_throw,
   15820             :                        NewTypeError(MessageTemplate::kCyclicProto));
   15821             :       }
   15822             :     }
   15823             :   }
   15824             : 
   15825             :   // Set the new prototype of the object.
   15826             : 
   15827             :   isolate->UpdateNoElementsProtectorOnSetPrototype(real_receiver);
   15828             : 
   15829      184908 :   Handle<Map> new_map = Map::TransitionToPrototype(isolate, map, value);
   15830             :   DCHECK(new_map->prototype() == *value);
   15831      184908 :   JSObject::MigrateToMap(real_receiver, new_map);
   15832             : 
   15833             :   DCHECK(size == object->Size());
   15834             :   return Just(true);
   15835             : }
   15836             : 
   15837             : // static
   15838          24 : void JSObject::SetImmutableProto(Handle<JSObject> object) {
   15839             :   DCHECK(!object->IsAccessCheckNeeded());  // Never called from JS
   15840             :   Handle<Map> map(object->map(), object->GetIsolate());
   15841             : 
   15842             :   // Nothing to do if prototype is already set.
   15843          42 :   if (map->is_immutable_proto()) return;
   15844             : 
   15845             :   Handle<Map> new_map =
   15846           6 :       Map::TransitionToImmutableProto(object->GetIsolate(), map);
   15847           6 :   object->synchronized_set_map(*new_map);
   15848             : }
   15849             : 
   15850      455411 : void JSObject::EnsureCanContainElements(Handle<JSObject> object,
   15851             :                                         Arguments* args,
   15852             :                                         uint32_t first_arg,
   15853             :                                         uint32_t arg_count,
   15854             :                                         EnsureElementsMode mode) {
   15855             :   // Elements in |Arguments| are ordered backwards (because they're on the
   15856             :   // stack), but the method that's called here iterates over them in forward
   15857             :   // direction.
   15858             :   return EnsureCanContainElements(
   15859      910822 :       object, args->slot_at(first_arg + arg_count - 1), arg_count, mode);
   15860             : }
   15861             : 
   15862             : 
   15863   258321486 : ElementsAccessor* JSObject::GetElementsAccessor() {
   15864   517864505 :   return ElementsAccessor::ForKind(GetElementsKind());
   15865             : }
   15866             : 
   15867     3729166 : void JSObject::ValidateElements(JSObject object) {
   15868             : #ifdef ENABLE_SLOW_DCHECKS
   15869             :   if (FLAG_enable_slow_asserts) {
   15870             :     object->GetElementsAccessor()->Validate(object);
   15871             :   }
   15872             : #endif
   15873     3729166 : }
   15874             : 
   15875     5315114 : static bool ShouldConvertToSlowElements(JSObject object, uint32_t capacity,
   15876             :                                         uint32_t index,
   15877             :                                         uint32_t* new_capacity) {
   15878             :   STATIC_ASSERT(JSObject::kMaxUncheckedOldFastElementsLength <=
   15879             :                 JSObject::kMaxUncheckedFastElementsLength);
   15880     5315114 :   if (index < capacity) {
   15881     4751280 :     *new_capacity = capacity;
   15882     4751280 :     return false;
   15883             :   }
   15884      563834 :   if (index - capacity >= JSObject::kMaxGap) return true;
   15885      624132 :   *new_capacity = JSObject::NewElementsCapacity(index + 1);
   15886             :   DCHECK_LT(index, *new_capacity);
   15887      624132 :   if (*new_capacity <= JSObject::kMaxUncheckedOldFastElementsLength ||
   15888       44317 :       (*new_capacity <= JSObject::kMaxUncheckedFastElementsLength &&
   15889             :        Heap::InNewSpace(object))) {
   15890             :     return false;
   15891             :   }
   15892             :   // If the fast-case backing storage takes up much more memory than a
   15893             :   // dictionary backing storage would, the object should have slow elements.
   15894        1554 :   int used_elements = object->GetFastElementsUsage();
   15895             :   uint32_t size_threshold = NumberDictionary::kPreferFastElementsSizeFactor *
   15896        1554 :                             NumberDictionary::ComputeCapacity(used_elements) *
   15897        1554 :                             NumberDictionary::kEntrySize;
   15898        1554 :   return size_threshold <= *new_capacity;
   15899             : }
   15900             : 
   15901      102992 : bool JSObject::WouldConvertToSlowElements(uint32_t index) {
   15902      102992 :   if (!HasFastElements()) return false;
   15903       25242 :   uint32_t capacity = static_cast<uint32_t>(elements()->length());
   15904             :   uint32_t new_capacity;
   15905       12621 :   return ShouldConvertToSlowElements(*this, capacity, index, &new_capacity);
   15906             : }
   15907             : 
   15908         488 : static ElementsKind BestFittingFastElementsKind(JSObject object) {
   15909         488 :   if (!object->map()->CanHaveFastTransitionableElementsKind()) {
   15910             :     return HOLEY_ELEMENTS;
   15911             :   }
   15912         213 :   if (object->HasSloppyArgumentsElements()) {
   15913             :     return FAST_SLOPPY_ARGUMENTS_ELEMENTS;
   15914             :   }
   15915         213 :   if (object->HasStringWrapperElements()) {
   15916             :     return FAST_STRING_WRAPPER_ELEMENTS;
   15917             :   }
   15918             :   DCHECK(object->HasDictionaryElements());
   15919         204 :   NumberDictionary dictionary = object->element_dictionary();
   15920             :   ElementsKind kind = HOLEY_SMI_ELEMENTS;
   15921      217904 :   for (int i = 0; i < dictionary->Capacity(); i++) {
   15922      217745 :     Object key = dictionary->KeyAt(i);
   15923      217745 :     if (key->IsNumber()) {
   15924       72427 :       Object value = dictionary->ValueAt(i);
   15925       72472 :       if (!value->IsNumber()) return HOLEY_ELEMENTS;
   15926       72382 :       if (!value->IsSmi()) {
   15927        6838 :         if (!FLAG_unbox_double_arrays) return HOLEY_ELEMENTS;
   15928             :         kind = HOLEY_DOUBLE_ELEMENTS;
   15929             :       }
   15930             :     }
   15931             :   }
   15932             :   return kind;
   15933             : }
   15934             : 
   15935      878518 : static bool ShouldConvertToFastElements(JSObject object,
   15936             :                                         NumberDictionary dictionary,
   15937             :                                         uint32_t index,
   15938             :                                         uint32_t* new_capacity) {
   15939             :   // If properties with non-standard attributes or accessors were added, we
   15940             :   // cannot go back to fast elements.
   15941      878518 :   if (dictionary->requires_slow_elements()) return false;
   15942             : 
   15943             :   // Adding a property with this index will require slow elements.
   15944      855138 :   if (index >= static_cast<uint32_t>(Smi::kMaxValue)) return false;
   15945             : 
   15946      855015 :   if (object->IsJSArray()) {
   15947      569739 :     Object length = JSArray::cast(object)->length();
   15948      569739 :     if (!length->IsSmi()) return false;
   15949      569721 :     *new_capacity = static_cast<uint32_t>(Smi::ToInt(length));
   15950      285276 :   } else if (object->IsJSSloppyArgumentsObject()) {
   15951             :     return false;
   15952             :   } else {
   15953      186150 :     *new_capacity = dictionary->max_number_key() + 1;
   15954             :   }
   15955     1511742 :   *new_capacity = Max(index + 1, *new_capacity);
   15956             : 
   15957      755871 :   uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
   15958      755871 :                              NumberDictionary::kEntrySize;
   15959             : 
   15960             :   // Turn fast if the dictionary only saves 50% space.
   15961      755871 :   return 2 * dictionary_size >= *new_capacity;
   15962             : }
   15963             : 
   15964             : // static
   15965     6199809 : void JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
   15966             :                               Handle<Object> value,
   15967             :                               PropertyAttributes attributes) {
   15968             :   DCHECK(object->map()->is_extensible());
   15969             : 
   15970             :   Isolate* isolate = object->GetIsolate();
   15971             : 
   15972     6199812 :   uint32_t old_length = 0;
   15973     6199812 :   uint32_t new_capacity = 0;
   15974             : 
   15975    12399622 :   if (object->IsJSArray()) {
   15976     5705215 :     CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length));
   15977             :   }
   15978             : 
   15979     6199813 :   ElementsKind kind = object->GetElementsKind();
   15980     6199813 :   FixedArrayBase elements = object->elements();
   15981             :   ElementsKind dictionary_kind = DICTIONARY_ELEMENTS;
   15982     6199813 :   if (IsSloppyArgumentsElementsKind(kind)) {
   15983      119568 :     elements = SloppyArgumentsElements::cast(elements)->arguments();
   15984             :     dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
   15985     6080245 :   } else if (IsStringWrapperElementsKind(kind)) {
   15986             :     dictionary_kind = SLOW_STRING_WRAPPER_ELEMENTS;
   15987             :   }
   15988             : 
   15989     6199813 :   if (attributes != NONE) {
   15990             :     kind = dictionary_kind;
   15991     6180576 :   } else if (elements->IsNumberDictionary()) {
   15992             :     kind = ShouldConvertToFastElements(
   15993      878518 :                *object, NumberDictionary::cast(elements), index, &new_capacity)
   15994             :                ? BestFittingFastElementsKind(*object)
   15995      879006 :                : dictionary_kind;
   15996     5302057 :   } else if (ShouldConvertToSlowElements(
   15997             :                  *object, static_cast<uint32_t>(elements->length()), index,
   15998     5302057 :                  &new_capacity)) {
   15999             :     kind = dictionary_kind;
   16000             :   }
   16001             : 
   16002     6199812 :   ElementsKind to = value->OptimalElementsKind();
   16003     8987843 :   if (IsHoleyElementsKind(kind) || !object->IsJSArray() || index > old_length) {
   16004             :     to = GetHoleyElementsKind(to);
   16005             :     kind = GetHoleyElementsKind(kind);
   16006             :   }
   16007             :   to = GetMoreGeneralElementsKind(kind, to);
   16008             :   ElementsAccessor* accessor = ElementsAccessor::ForKind(to);
   16009     6199810 :   accessor->Add(object, index, value, attributes, new_capacity);
   16010             : 
   16011    12399624 :   if (object->IsJSArray() && index >= old_length) {
   16012             :     Handle<Object> new_length =
   16013     1548930 :         isolate->factory()->NewNumberFromUint(index + 1);
   16014     1548929 :     JSArray::cast(*object)->set_length(*new_length);
   16015             :   }
   16016     6199812 : }
   16017             : 
   16018             : 
   16019      924647 : bool JSArray::SetLengthWouldNormalize(uint32_t new_length) {
   16020     1849294 :   if (!HasFastElements()) return false;
   16021     1833806 :   uint32_t capacity = static_cast<uint32_t>(elements()->length());
   16022             :   uint32_t new_capacity;
   16023      917340 :   return JSArray::SetLengthWouldNormalize(GetHeap(), new_length) &&
   16024             :          ShouldConvertToSlowElements(*this, capacity, new_length - 1,
   16025      917340 :                                      &new_capacity);
   16026             : }
   16027             : 
   16028             : 
   16029             : const double AllocationSite::kPretenureRatio = 0.85;
   16030             : 
   16031             : 
   16032           0 : void AllocationSite::ResetPretenureDecision() {
   16033             :   set_pretenure_decision(kUndecided);
   16034             :   set_memento_found_count(0);
   16035             :   set_memento_create_count(0);
   16036           0 : }
   16037             : 
   16038       25047 : PretenureFlag AllocationSite::GetPretenureMode() const {
   16039             :   PretenureDecision mode = pretenure_decision();
   16040             :   // Zombie objects "decide" to be untenured.
   16041       25047 :   return mode == kTenure ? TENURED : NOT_TENURED;
   16042             : }
   16043             : 
   16044           0 : bool AllocationSite::IsNested() {
   16045             :   DCHECK(FLAG_trace_track_allocation_sites);
   16046           0 :   Object current = boilerplate()->GetHeap()->allocation_sites_list();
   16047           0 :   while (current->IsAllocationSite()) {
   16048           0 :     AllocationSite current_site = AllocationSite::cast(current);
   16049           0 :     if (current_site->nested_site() == *this) {
   16050           0 :       return true;
   16051             :     }
   16052           0 :     current = current_site->weak_next();
   16053             :   }
   16054             :   return false;
   16055             : }
   16056             : 
   16057             : template <AllocationSiteUpdateMode update_or_check>
   16058      366979 : bool AllocationSite::DigestTransitionFeedback(Handle<AllocationSite> site,
   16059             :                                               ElementsKind to_kind) {
   16060             :   Isolate* isolate = site->GetIsolate();
   16061             :   bool result = false;
   16062             : 
   16063      387442 :   if (site->PointsToLiteral() && site->boilerplate()->IsJSArray()) {
   16064       20462 :     Handle<JSArray> boilerplate(JSArray::cast(site->boilerplate()), isolate);
   16065       10231 :     ElementsKind kind = boilerplate->GetElementsKind();
   16066             :     // if kind is holey ensure that to_kind is as well.
   16067       10231 :     if (IsHoleyElementsKind(kind)) {
   16068             :       to_kind = GetHoleyElementsKind(to_kind);
   16069             :     }
   16070       10231 :     if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
   16071             :       // If the array is huge, it's not likely to be defined in a local
   16072             :       // function, so we shouldn't make new instances of it very often.
   16073        7782 :       uint32_t length = 0;
   16074       15564 :       CHECK(boilerplate->length()->ToArrayLength(&length));
   16075        7782 :       if (length <= kMaximumArrayBytesToPretransition) {
   16076             :         if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) {
   16077           0 :           return true;
   16078             :         }
   16079        7782 :         if (FLAG_trace_track_allocation_sites) {
   16080           0 :           bool is_nested = site->IsNested();
   16081           0 :           PrintF("AllocationSite: JSArray %p boilerplate %supdated %s->%s\n",
   16082             :                  reinterpret_cast<void*>(site->ptr()),
   16083             :                  is_nested ? "(nested)" : " ", ElementsKindToString(kind),
   16084           0 :                  ElementsKindToString(to_kind));
   16085             :         }
   16086        7782 :         JSObject::TransitionElementsKind(boilerplate, to_kind);
   16087       23346 :         site->dependent_code()->DeoptimizeDependentCodeGroup(
   16088       15564 :             isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
   16089             :         result = true;
   16090             :       }
   16091             :     }
   16092             :   } else {
   16093             :     // The AllocationSite is for a constructed Array.
   16094      713495 :     ElementsKind kind = site->GetElementsKind();
   16095             :     // if kind is holey ensure that to_kind is as well.
   16096      356749 :     if (IsHoleyElementsKind(kind)) {
   16097             :       to_kind = GetHoleyElementsKind(to_kind);
   16098             :     }
   16099      356749 :     if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
   16100             :       if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) return true;
   16101       14892 :       if (FLAG_trace_track_allocation_sites) {
   16102           0 :         PrintF("AllocationSite: JSArray %p site updated %s->%s\n",
   16103             :                reinterpret_cast<void*>(site->ptr()), ElementsKindToString(kind),
   16104           0 :                ElementsKindToString(to_kind));
   16105             :       }
   16106       14892 :       site->SetElementsKind(to_kind);
   16107       44681 :       site->dependent_code()->DeoptimizeDependentCodeGroup(
   16108       29787 :           isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
   16109             :       result = true;
   16110             :     }
   16111             :   }
   16112             :   return result;
   16113             : }
   16114             : 
   16115        4984 : bool AllocationSite::ShouldTrack(ElementsKind from, ElementsKind to) {
   16116        7840 :   return IsSmiElementsKind(from) &&
   16117        7840 :          IsMoreGeneralElementsKindTransition(from, to);
   16118             : }
   16119             : 
   16120           0 : const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) {
   16121           0 :   switch (decision) {
   16122             :     case kUndecided: return "undecided";
   16123           0 :     case kDontTenure: return "don't tenure";
   16124           0 :     case kMaybeTenure: return "maybe tenure";
   16125           0 :     case kTenure: return "tenure";
   16126           0 :     case kZombie: return "zombie";
   16127           0 :     default: UNREACHABLE();
   16128             :   }
   16129             :   return nullptr;
   16130             : }
   16131             : 
   16132             : template <AllocationSiteUpdateMode update_or_check>
   16133      885547 : bool JSObject::UpdateAllocationSite(Handle<JSObject> object,
   16134             :                                     ElementsKind to_kind) {
   16135     1771095 :   if (!object->IsJSArray()) return false;
   16136             : 
   16137      631049 :   if (!Heap::InNewSpace(*object)) return false;
   16138             : 
   16139             :   Handle<AllocationSite> site;
   16140             :   {
   16141             :     DisallowHeapAllocation no_allocation;
   16142             : 
   16143             :     Heap* heap = object->GetHeap();
   16144             :     AllocationMemento memento =
   16145     1238072 :         heap->FindAllocationMemento<Heap::kForRuntime>(object->map(), *object);
   16146      619035 :     if (memento.is_null()) return false;
   16147             : 
   16148             :     // Walk through to the Allocation Site
   16149      733960 :     site = handle(memento->GetAllocationSite(), heap->isolate());
   16150             :   }
   16151             :   return AllocationSite::DigestTransitionFeedback<update_or_check>(site,
   16152      366979 :                                                                    to_kind);
   16153             : }
   16154             : 
   16155             : template bool
   16156             : JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kCheckOnly>(
   16157             :     Handle<JSObject> object, ElementsKind to_kind);
   16158             : 
   16159             : template bool JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kUpdate>(
   16160             :     Handle<JSObject> object, ElementsKind to_kind);
   16161             : 
   16162      142072 : void JSObject::TransitionElementsKind(Handle<JSObject> object,
   16163             :                                       ElementsKind to_kind) {
   16164      142072 :   ElementsKind from_kind = object->GetElementsKind();
   16165             : 
   16166      142073 :   if (IsHoleyElementsKind(from_kind)) {
   16167             :     to_kind = GetHoleyElementsKind(to_kind);
   16168             :   }
   16169             : 
   16170      284145 :   if (from_kind == to_kind) return;
   16171             : 
   16172             :   // This method should never be called for any other case.
   16173             :   DCHECK(IsFastElementsKind(from_kind));
   16174             :   DCHECK(IsFastElementsKind(to_kind));
   16175             :   DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
   16176             : 
   16177      141931 :   UpdateAllocationSite(object, to_kind);
   16178      565374 :   if (object->elements() == object->GetReadOnlyRoots().empty_fixed_array() ||
   16179             :       IsDoubleElementsKind(from_kind) == IsDoubleElementsKind(to_kind)) {
   16180             :     // No change is needed to the elements() buffer, the transition
   16181             :     // only requires a map change.
   16182      136900 :     Handle<Map> new_map = GetElementsTransitionMap(object, to_kind);
   16183      136901 :     MigrateToMap(object, new_map);
   16184             :     if (FLAG_trace_elements_transitions) {
   16185             :       Handle<FixedArrayBase> elms(object->elements(), object->GetIsolate());
   16186             :       PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms);
   16187             :     }
   16188             :   } else {
   16189             :     DCHECK((IsSmiElementsKind(from_kind) && IsDoubleElementsKind(to_kind)) ||
   16190             :            (IsDoubleElementsKind(from_kind) && IsObjectElementsKind(to_kind)));
   16191       10060 :     uint32_t c = static_cast<uint32_t>(object->elements()->length());
   16192        5030 :     ElementsAccessor::ForKind(to_kind)->GrowCapacityAndConvert(object, c);
   16193             :   }
   16194             : }
   16195             : 
   16196             : 
   16197    12985851 : bool JSArray::HasReadOnlyLength(Handle<JSArray> array) {
   16198    12985877 :   Map map = array->map();
   16199             :   // Fast path: "length" is the first fast property of arrays. Since it's not
   16200             :   // configurable, it's guaranteed to be the first in the descriptor array.
   16201    12985877 :   if (!map->is_dictionary_map()) {
   16202             :     DCHECK(map->instance_descriptors()->GetKey(0) ==
   16203             :            array->GetReadOnlyRoots().length_string());
   16204    25970683 :     return map->instance_descriptors()->GetDetails(0).IsReadOnly();
   16205             :   }
   16206             : 
   16207             :   Isolate* isolate = array->GetIsolate();
   16208             :   LookupIterator it(array, isolate->factory()->length_string(), array,
   16209         565 :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
   16210         565 :   CHECK_EQ(LookupIterator::ACCESSOR, it.state());
   16211         565 :   return it.IsReadOnly();
   16212             : }
   16213             : 
   16214             : 
   16215     2841876 : bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
   16216             :                                         uint32_t index) {
   16217     2841876 :   uint32_t length = 0;
   16218     5683751 :   CHECK(array->length()->ToArrayLength(&length));
   16219     2841875 :   if (length <= index) return HasReadOnlyLength(array);
   16220             :   return false;
   16221             : }
   16222             : 
   16223             : template <typename BackingStore>
   16224      283342 : static int HoleyElementsUsage(JSObject object, BackingStore store) {
   16225             :   Isolate* isolate = object->GetIsolate();
   16226      289180 :   int limit = object->IsJSArray() ? Smi::ToInt(JSArray::cast(object)->length())
   16227      566684 :                                   : store->length();
   16228             :   int used = 0;
   16229   290533753 :   for (int i = 0; i < limit; ++i) {
   16230   290533559 :     if (!store->is_the_hole(isolate, i)) ++used;
   16231             :   }
   16232      283342 :   return used;
   16233             : }
   16234             : 
   16235      295208 : int JSObject::GetFastElementsUsage() {
   16236      295208 :   FixedArrayBase store = elements();
   16237      295208 :   switch (GetElementsKind()) {
   16238             :     case PACKED_SMI_ELEMENTS:
   16239             :     case PACKED_DOUBLE_ELEMENTS:
   16240             :     case PACKED_ELEMENTS:
   16241       47162 :       return IsJSArray() ? Smi::ToInt(JSArray::cast(*this)->length())
   16242       35420 :                          : store->length();
   16243             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
   16244         741 :       store = SloppyArgumentsElements::cast(store)->arguments();
   16245             :       V8_FALLTHROUGH;
   16246             :     case HOLEY_SMI_ELEMENTS:
   16247             :     case HOLEY_ELEMENTS:
   16248             :     case FAST_STRING_WRAPPER_ELEMENTS:
   16249      283148 :       return HoleyElementsUsage(*this, FixedArray::cast(store));
   16250             :     case HOLEY_DOUBLE_ELEMENTS:
   16251         442 :       if (elements()->length() == 0) return 0;
   16252         194 :       return HoleyElementsUsage(*this, FixedDoubleArray::cast(store));
   16253             : 
   16254             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
   16255             :     case SLOW_STRING_WRAPPER_ELEMENTS:
   16256             :     case DICTIONARY_ELEMENTS:
   16257             :     case NO_ELEMENTS:
   16258             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
   16259             : 
   16260             :       TYPED_ARRAYS(TYPED_ARRAY_CASE)
   16261             : #undef TYPED_ARRAY_CASE
   16262           0 :     UNREACHABLE();
   16263             :   }
   16264             :   return 0;
   16265             : }
   16266             : 
   16267             : 
   16268             : // Certain compilers request function template instantiation when they
   16269             : // see the definition of the other template functions in the
   16270             : // class. This requires us to have the template functions put
   16271             : // together, so even though this function belongs in objects-debug.cc,
   16272             : // we keep it here instead to satisfy certain compilers.
   16273             : #ifdef OBJECT_PRINT
   16274             : template <typename Derived, typename Shape>
   16275             : void Dictionary<Derived, Shape>::Print(std::ostream& os) {
   16276             :   DisallowHeapAllocation no_gc;
   16277             :   ReadOnlyRoots roots = this->GetReadOnlyRoots();
   16278             :   Derived dictionary = Derived::cast(*this);
   16279             :   int capacity = dictionary->Capacity();
   16280             :   for (int i = 0; i < capacity; i++) {
   16281             :     Object k = dictionary->KeyAt(i);
   16282             :     if (!dictionary->ToKey(roots, i, &k)) continue;
   16283             :     os << "\n   ";
   16284             :     if (k->IsString()) {
   16285             :       String::cast(k)->StringPrint(os);
   16286             :     } else {
   16287             :       os << Brief(k);
   16288             :     }
   16289             :     os << ": " << Brief(dictionary->ValueAt(i)) << " ";
   16290             :     dictionary->DetailsAt(i).PrintAsSlowTo(os);
   16291             :   }
   16292             : }
   16293             : template <typename Derived, typename Shape>
   16294             : void Dictionary<Derived, Shape>::Print() {
   16295             :   StdoutStream os;
   16296             :   Print(os);
   16297             :   os << std::endl;
   16298             : }
   16299             : #endif
   16300             : 
   16301             : 
   16302      114113 : MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
   16303             :                                                          bool* done) {
   16304             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
   16305      114113 :   return GetPropertyWithInterceptorInternal(it, it->GetInterceptor(), done);
   16306             : }
   16307             : 
   16308       12042 : Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object,
   16309             :                                            Handle<Name> name) {
   16310             :   LookupIterator it = LookupIterator::PropertyOrElement(
   16311       12042 :       object->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   16312       12042 :   return HasProperty(&it);
   16313             : }
   16314             : 
   16315             : 
   16316          17 : Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object,
   16317             :                                              uint32_t index) {
   16318             :   Isolate* isolate = object->GetIsolate();
   16319             :   LookupIterator it(isolate, object, index, object,
   16320             :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
   16321          17 :   return HasProperty(&it);
   16322             : }
   16323             : 
   16324             : 
   16325           5 : Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
   16326             :                                                    Handle<Name> name) {
   16327             :   LookupIterator it = LookupIterator::PropertyOrElement(
   16328           5 :       object->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   16329           5 :   Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
   16330           5 :   return maybe_result.IsJust() ? Just(it.state() == LookupIterator::ACCESSOR)
   16331          10 :                                : Nothing<bool>();
   16332             : }
   16333             : 
   16334        5380 : int FixedArrayBase::GetMaxLengthForNewSpaceAllocation(ElementsKind kind) {
   16335             :   return ((kMaxRegularHeapObjectSize - FixedArrayBase::kHeaderSize) >>
   16336        5380 :           ElementsKindToShiftSize(kind));
   16337             : }
   16338             : 
   16339      477345 : bool FixedArrayBase::IsCowArray() const {
   16340      954692 :   return map() == GetReadOnlyRoots().fixed_cow_array_map();
   16341             : }
   16342             : 
   16343           0 : bool JSObject::IsApiWrapper() {
   16344             :   // These object types can carry information relevant for embedders. The
   16345             :   // *_API_* types are generated through templates which can have embedder
   16346             :   // fields. The other types have their embedder fields added at compile time.
   16347             :   auto instance_type = map()->instance_type();
   16348           0 :   return instance_type == JS_API_OBJECT_TYPE ||
   16349           0 :          instance_type == JS_ARRAY_BUFFER_TYPE ||
   16350           0 :          instance_type == JS_DATA_VIEW_TYPE ||
   16351           0 :          instance_type == JS_SPECIAL_API_OBJECT_TYPE ||
   16352           0 :          instance_type == JS_TYPED_ARRAY_TYPE;
   16353             : }
   16354             : 
   16355       26797 : bool JSObject::IsDroppableApiWrapper() {
   16356             :   auto instance_type = map()->instance_type();
   16357       26797 :   return instance_type == JS_API_OBJECT_TYPE ||
   16358       26797 :          instance_type == JS_SPECIAL_API_OBJECT_TYPE;
   16359             : }
   16360             : 
   16361        1834 : const char* Symbol::PrivateSymbolToName() const {
   16362        1834 :   ReadOnlyRoots roots = GetReadOnlyRoots();
   16363             : #define SYMBOL_CHECK_AND_PRINT(_, name) \
   16364             :   if (*this == roots.name()) return #name;
   16365       27879 :   PRIVATE_SYMBOL_LIST_GENERATOR(SYMBOL_CHECK_AND_PRINT, /* not used */)
   16366             : #undef SYMBOL_CHECK_AND_PRINT
   16367         150 :   return "UNKNOWN";
   16368             : }
   16369             : 
   16370             : 
   16371        4303 : void Symbol::SymbolShortPrint(std::ostream& os) {
   16372        4303 :   os << "<Symbol:";
   16373        8606 :   if (!name()->IsUndefined()) {
   16374        2469 :     os << " ";
   16375             :     HeapStringAllocator allocator;
   16376             :     StringStream accumulator(&allocator);
   16377        4938 :     String::cast(name())->StringShortPrint(&accumulator, false);
   16378        7407 :     os << accumulator.ToCString().get();
   16379             :   } else {
   16380        1834 :     os << " (" << PrivateSymbolToName() << ")";
   16381             :   }
   16382        4303 :   os << ">";
   16383        4303 : }
   16384             : 
   16385             : 
   16386             : // StringSharedKeys are used as keys in the eval cache.
   16387     3521393 : class StringSharedKey : public HashTableKey {
   16388             :  public:
   16389             :   // This tuple unambiguously identifies calls to eval() or
   16390             :   // CreateDynamicFunction() (such as through the Function() constructor).
   16391             :   // * source is the string passed into eval(). For dynamic functions, this is
   16392             :   //   the effective source for the function, some of which is implicitly
   16393             :   //   generated.
   16394             :   // * shared is the shared function info for the function containing the call
   16395             :   //   to eval(). for dynamic functions, shared is the native context closure.
   16396             :   // * When positive, position is the position in the source where eval is
   16397             :   //   called. When negative, position is the negation of the position in the
   16398             :   //   dynamic function's effective source where the ')' ends the parameters.
   16399     5120613 :   StringSharedKey(Handle<String> source, Handle<SharedFunctionInfo> shared,
   16400             :                   LanguageMode language_mode, int position)
   16401             :       : HashTableKey(CompilationCacheShape::StringSharedHash(
   16402             :             *source, *shared, language_mode, position)),
   16403             :         source_(source),
   16404             :         shared_(shared),
   16405             :         language_mode_(language_mode),
   16406    10241226 :         position_(position) {}
   16407             : 
   16408     6286751 :   bool IsMatch(Object other) override {
   16409             :     DisallowHeapAllocation no_allocation;
   16410     6286751 :     if (!other->IsFixedArray()) {
   16411             :       DCHECK(other->IsNumber());
   16412     1963807 :       uint32_t other_hash = static_cast<uint32_t>(other->Number());
   16413     1963807 :       return Hash() == other_hash;
   16414             :     }
   16415             :     FixedArray other_array = FixedArray::cast(other);
   16416             :     SharedFunctionInfo shared = SharedFunctionInfo::cast(other_array->get(0));
   16417     4322944 :     if (shared != *shared_) return false;
   16418     4158066 :     int language_unchecked = Smi::ToInt(other_array->get(2));
   16419             :     DCHECK(is_valid_language_mode(language_unchecked));
   16420     4158066 :     LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
   16421     4158066 :     if (language_mode != language_mode_) return false;
   16422     4145141 :     int position = Smi::ToInt(other_array->get(3));
   16423     4145141 :     if (position != position_) return false;
   16424     4144968 :     String source = String::cast(other_array->get(1));
   16425     4144968 :     return source->Equals(*source_);
   16426             :   }
   16427             : 
   16428     1327432 :   Handle<Object> AsHandle(Isolate* isolate) {
   16429     1327432 :     Handle<FixedArray> array = isolate->factory()->NewFixedArray(4);
   16430     2654864 :     array->set(0, *shared_);
   16431     2654864 :     array->set(1, *source_);
   16432     1327432 :     array->set(2, Smi::FromEnum(language_mode_));
   16433     1327432 :     array->set(3, Smi::FromInt(position_));
   16434     1327432 :     array->set_map(ReadOnlyRoots(isolate).fixed_cow_array_map());
   16435     1327432 :     return array;
   16436             :   }
   16437             : 
   16438             :  private:
   16439             :   Handle<String> source_;
   16440             :   Handle<SharedFunctionInfo> shared_;
   16441             :   LanguageMode language_mode_;
   16442             :   int position_;
   16443             : };
   16444             : 
   16445      194863 : v8::Promise::PromiseState JSPromise::status() const {
   16446      194863 :   int value = flags() & kStatusMask;
   16447             :   DCHECK(value == 0 || value == 1 || value == 2);
   16448      194863 :   return static_cast<v8::Promise::PromiseState>(value);
   16449             : }
   16450             : 
   16451       40825 : void JSPromise::set_status(Promise::PromiseState status) {
   16452       40825 :   int value = flags() & ~kStatusMask;
   16453       40825 :   set_flags(value | status);
   16454       40825 : }
   16455             : 
   16456             : // static
   16457          40 : const char* JSPromise::Status(v8::Promise::PromiseState status) {
   16458          40 :   switch (status) {
   16459             :     case v8::Promise::kFulfilled:
   16460             :       return "resolved";
   16461             :     case v8::Promise::kPending:
   16462          15 :       return "pending";
   16463             :     case v8::Promise::kRejected:
   16464           5 :       return "rejected";
   16465             :   }
   16466           0 :   UNREACHABLE();
   16467             : }
   16468             : 
   16469       21898 : int JSPromise::async_task_id() const {
   16470       43796 :   return AsyncTaskIdField::decode(flags());
   16471             : }
   16472             : 
   16473        6608 : void JSPromise::set_async_task_id(int id) {
   16474       13216 :   set_flags(AsyncTaskIdField::update(flags(), id));
   16475        6608 : }
   16476             : 
   16477             : // static
   16478       29378 : Handle<Object> JSPromise::Fulfill(Handle<JSPromise> promise,
   16479             :                                   Handle<Object> value) {
   16480             :   Isolate* const isolate = promise->GetIsolate();
   16481             : 
   16482             :   // 1. Assert: The value of promise.[[PromiseState]] is "pending".
   16483             :   DCHECK_EQ(Promise::kPending, promise->status());
   16484             : 
   16485             :   // 2. Let reactions be promise.[[PromiseFulfillReactions]].
   16486       58756 :   Handle<Object> reactions(promise->reactions(), isolate);
   16487             : 
   16488             :   // 3. Set promise.[[PromiseResult]] to value.
   16489             :   // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
   16490             :   // 5. Set promise.[[PromiseRejectReactions]] to undefined.
   16491       29378 :   promise->set_reactions_or_result(*value);
   16492             : 
   16493             :   // 6. Set promise.[[PromiseState]] to "fulfilled".
   16494       29378 :   promise->set_status(Promise::kFulfilled);
   16495             : 
   16496             :   // 7. Return TriggerPromiseReactions(reactions, value).
   16497             :   return TriggerPromiseReactions(isolate, reactions, value,
   16498       29378 :                                  PromiseReaction::kFulfill);
   16499             : }
   16500             : 
   16501             : // static
   16502       11447 : Handle<Object> JSPromise::Reject(Handle<JSPromise> promise,
   16503             :                                  Handle<Object> reason, bool debug_event) {
   16504        8039 :   Isolate* const isolate = promise->GetIsolate();
   16505             : 
   16506       19486 :   if (debug_event) isolate->debug()->OnPromiseReject(promise, reason);
   16507             :   isolate->RunPromiseHook(PromiseHookType::kResolve, promise,
   16508       11447 :                           isolate->factory()->undefined_value());
   16509             : 
   16510             :   // 1. Assert: The value of promise.[[PromiseState]] is "pending".
   16511             :   DCHECK_EQ(Promise::kPending, promise->status());
   16512             : 
   16513             :   // 2. Let reactions be promise.[[PromiseRejectReactions]].
   16514       22894 :   Handle<Object> reactions(promise->reactions(), isolate);
   16515             : 
   16516             :   // 3. Set promise.[[PromiseResult]] to reason.
   16517             :   // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
   16518             :   // 5. Set promise.[[PromiseRejectReactions]] to undefined.
   16519       11447 :   promise->set_reactions_or_result(*reason);
   16520             : 
   16521             :   // 6. Set promise.[[PromiseState]] to "rejected".
   16522       11447 :   promise->set_status(Promise::kRejected);
   16523             : 
   16524             :   // 7. If promise.[[PromiseIsHandled]] is false, perform
   16525             :   //    HostPromiseRejectionTracker(promise, "reject").
   16526       11447 :   if (!promise->has_handler()) {
   16527        8970 :     isolate->ReportPromiseReject(promise, reason, kPromiseRejectWithNoHandler);
   16528             :   }
   16529             : 
   16530             :   // 8. Return TriggerPromiseReactions(reactions, reason).
   16531             :   return TriggerPromiseReactions(isolate, reactions, reason,
   16532       11447 :                                  PromiseReaction::kReject);
   16533             : }
   16534             : 
   16535             : // static
   16536       31037 : MaybeHandle<Object> JSPromise::Resolve(Handle<JSPromise> promise,
   16537             :                                        Handle<Object> resolution) {
   16538        1545 :   Isolate* const isolate = promise->GetIsolate();
   16539             : 
   16540             :   isolate->RunPromiseHook(PromiseHookType::kResolve, promise,
   16541       31037 :                           isolate->factory()->undefined_value());
   16542             : 
   16543             :   // 6. If SameValue(resolution, promise) is true, then
   16544       31037 :   if (promise.is_identical_to(resolution)) {
   16545             :     // a. Let selfResolutionError be a newly created TypeError object.
   16546             :     Handle<Object> self_resolution_error = isolate->factory()->NewTypeError(
   16547          50 :         MessageTemplate::kPromiseCyclic, resolution);
   16548             :     // b. Return RejectPromise(promise, selfResolutionError).
   16549          50 :     return Reject(promise, self_resolution_error);
   16550             :   }
   16551             : 
   16552             :   // 7. If Type(resolution) is not Object, then
   16553       61974 :   if (!resolution->IsJSReceiver()) {
   16554             :     // a. Return FulfillPromise(promise, resolution).
   16555       27228 :     return Fulfill(promise, resolution);
   16556             :   }
   16557             : 
   16558             :   // 8. Let then be Get(resolution, "then").
   16559             :   MaybeHandle<Object> then;
   16560        3759 :   if (isolate->IsPromiseThenLookupChainIntact(
   16561        3759 :           Handle<JSReceiver>::cast(resolution))) {
   16562             :     // We can skip the "then" lookup on {resolution} if its [[Prototype]]
   16563             :     // is the (initial) Promise.prototype and the Promise#then protector
   16564             :     // is intact, as that guards the lookup path for the "then" property
   16565             :     // on JSPromise instances which have the (initial) %PromisePrototype%.
   16566        1540 :     then = isolate->promise_then();
   16567             :   } else {
   16568             :     then =
   16569             :         JSReceiver::GetProperty(isolate, Handle<JSReceiver>::cast(resolution),
   16570        2219 :                                 isolate->factory()->then_string());
   16571             :   }
   16572             : 
   16573             :   // 9. If then is an abrupt completion, then
   16574             :   Handle<Object> then_action;
   16575        3759 :   if (!then.ToHandle(&then_action)) {
   16576             :     // a. Return RejectPromise(promise, then.[[Value]]).
   16577             :     Handle<Object> reason(isolate->pending_exception(), isolate);
   16578          64 :     isolate->clear_pending_exception();
   16579          64 :     return Reject(promise, reason, false);
   16580             :   }
   16581             : 
   16582             :   // 10. Let thenAction be then.[[Value]].
   16583             :   // 11. If IsCallable(thenAction) is false, then
   16584        7390 :   if (!then_action->IsCallable()) {
   16585             :     // a. Return FulfillPromise(promise, resolution).
   16586        2150 :     return Fulfill(promise, resolution);
   16587             :   }
   16588             : 
   16589             :   // 12. Perform EnqueueJob("PromiseJobs", PromiseResolveThenableJob,
   16590             :   //                        «promise, resolution, thenAction»).
   16591             :   Handle<PromiseResolveThenableJobTask> task =
   16592             :       isolate->factory()->NewPromiseResolveThenableJobTask(
   16593             :           promise, Handle<JSReceiver>::cast(then_action),
   16594        3090 :           Handle<JSReceiver>::cast(resolution), isolate->native_context());
   16595        4275 :   if (isolate->debug()->is_active() && resolution->IsJSPromise()) {
   16596             :     // Mark the dependency of the new {promise} on the {resolution}.
   16597             :     Object::SetProperty(isolate, resolution,
   16598             :                         isolate->factory()->promise_handled_by_symbol(),
   16599        1365 :                         promise, LanguageMode::kStrict)
   16600        2730 :         .Check();
   16601             :   }
   16602        3090 :   isolate->native_context()->microtask_queue()->EnqueueMicrotask(*task);
   16603             : 
   16604             :   // 13. Return undefined.
   16605        1545 :   return isolate->factory()->undefined_value();
   16606             : }
   16607             : 
   16608             : // static
   16609       40825 : Handle<Object> JSPromise::TriggerPromiseReactions(Isolate* isolate,
   16610             :                                                   Handle<Object> reactions,
   16611             :                                                   Handle<Object> argument,
   16612             :                                                   PromiseReaction::Type type) {
   16613             :   DCHECK(reactions->IsSmi() || reactions->IsPromiseReaction());
   16614             : 
   16615             :   // We need to reverse the {reactions} here, since we record them
   16616             :   // on the JSPromise in the reverse order.
   16617             :   {
   16618             :     DisallowHeapAllocation no_gc;
   16619       40825 :     Object current = *reactions;
   16620             :     Object reversed = Smi::kZero;
   16621       90638 :     while (!current->IsSmi()) {
   16622        8988 :       Object next = PromiseReaction::cast(current)->next();
   16623        8988 :       PromiseReaction::cast(current)->set_next(reversed);
   16624        8988 :       reversed = current;
   16625        8988 :       current = next;
   16626             :     }
   16627             :     reactions = handle(reversed, isolate);
   16628             :   }
   16629             : 
   16630             :   // Morph the {reactions} into PromiseReactionJobTasks
   16631             :   // and push them onto the microtask queue.
   16632      140451 :   while (!reactions->IsSmi()) {
   16633        8988 :     Handle<HeapObject> task = Handle<HeapObject>::cast(reactions);
   16634        8988 :     Handle<PromiseReaction> reaction = Handle<PromiseReaction>::cast(task);
   16635       17976 :     reactions = handle(reaction->next(), isolate);
   16636             : 
   16637             :     STATIC_ASSERT(static_cast<int>(PromiseReaction::kSize) ==
   16638             :                   static_cast<int>(PromiseReactionJobTask::kSize));
   16639        8988 :     if (type == PromiseReaction::kFulfill) {
   16640             :       task->synchronized_set_map(
   16641        6491 :           ReadOnlyRoots(isolate).promise_fulfill_reaction_job_task_map());
   16642       19473 :       Handle<PromiseFulfillReactionJobTask>::cast(task)->set_argument(
   16643        6491 :           *argument);
   16644       19473 :       Handle<PromiseFulfillReactionJobTask>::cast(task)->set_context(
   16645       25964 :           *isolate->native_context());
   16646             :       STATIC_ASSERT(
   16647             :           static_cast<int>(PromiseReaction::kFulfillHandlerOffset) ==
   16648             :           static_cast<int>(PromiseFulfillReactionJobTask::kHandlerOffset));
   16649             :       STATIC_ASSERT(
   16650             :           static_cast<int>(PromiseReaction::kPromiseOrCapabilityOffset) ==
   16651             :           static_cast<int>(
   16652             :               PromiseFulfillReactionJobTask::kPromiseOrCapabilityOffset));
   16653             :     } else {
   16654             :       DisallowHeapAllocation no_gc;
   16655        2497 :       HeapObject handler = reaction->reject_handler();
   16656             :       task->synchronized_set_map(
   16657        2497 :           ReadOnlyRoots(isolate).promise_reject_reaction_job_task_map());
   16658        4994 :       Handle<PromiseRejectReactionJobTask>::cast(task)->set_argument(*argument);
   16659        7491 :       Handle<PromiseRejectReactionJobTask>::cast(task)->set_context(
   16660        9988 :           *isolate->native_context());
   16661        4994 :       Handle<PromiseRejectReactionJobTask>::cast(task)->set_handler(handler);
   16662             :       STATIC_ASSERT(
   16663             :           static_cast<int>(PromiseReaction::kPromiseOrCapabilityOffset) ==
   16664             :           static_cast<int>(
   16665             :               PromiseRejectReactionJobTask::kPromiseOrCapabilityOffset));
   16666             :     }
   16667             : 
   16668       17976 :     isolate->native_context()->microtask_queue()->EnqueueMicrotask(
   16669       35952 :         *Handle<PromiseReactionJobTask>::cast(task));
   16670             :   }
   16671             : 
   16672       40825 :   return isolate->factory()->undefined_value();
   16673             : }
   16674             : 
   16675             : namespace {
   16676             : 
   16677             : constexpr JSRegExp::Flag kCharFlagValues[] = {
   16678             :     JSRegExp::kGlobal,      // g
   16679             :     JSRegExp::kInvalid,     // h
   16680             :     JSRegExp::kIgnoreCase,  // i
   16681             :     JSRegExp::kInvalid,     // j
   16682             :     JSRegExp::kInvalid,     // k
   16683             :     JSRegExp::kInvalid,     // l
   16684             :     JSRegExp::kMultiline,   // m
   16685             :     JSRegExp::kInvalid,     // n
   16686             :     JSRegExp::kInvalid,     // o
   16687             :     JSRegExp::kInvalid,     // p
   16688             :     JSRegExp::kInvalid,     // q
   16689             :     JSRegExp::kInvalid,     // r
   16690             :     JSRegExp::kDotAll,      // s
   16691             :     JSRegExp::kInvalid,     // t
   16692             :     JSRegExp::kUnicode,     // u
   16693             :     JSRegExp::kInvalid,     // v
   16694             :     JSRegExp::kInvalid,     // w
   16695             :     JSRegExp::kInvalid,     // x
   16696             :     JSRegExp::kSticky,      // y
   16697             : };
   16698             : 
   16699             : constexpr JSRegExp::Flag CharToFlag(uc16 flag_char) {
   16700       76529 :   return (flag_char < 'g' || flag_char > 'y')
   16701             :              ? JSRegExp::kInvalid
   16702       76529 :              : kCharFlagValues[flag_char - 'g'];
   16703             : }
   16704             : 
   16705      379521 : JSRegExp::Flags RegExpFlagsFromString(Isolate* isolate, Handle<String> flags,
   16706             :                                       bool* success) {
   16707             :   STATIC_ASSERT(CharToFlag('g') == JSRegExp::kGlobal);
   16708             :   STATIC_ASSERT(CharToFlag('i') == JSRegExp::kIgnoreCase);
   16709             :   STATIC_ASSERT(CharToFlag('m') == JSRegExp::kMultiline);
   16710             :   STATIC_ASSERT(CharToFlag('s') == JSRegExp::kDotAll);
   16711             :   STATIC_ASSERT(CharToFlag('u') == JSRegExp::kUnicode);
   16712             :   STATIC_ASSERT(CharToFlag('y') == JSRegExp::kSticky);
   16713             : 
   16714             :   int length = flags->length();
   16715      379521 :   if (length == 0) {
   16716      304199 :     *success = true;
   16717      304199 :     return JSRegExp::kNone;
   16718             :   }
   16719             :   // A longer flags string cannot be valid.
   16720       75322 :   if (length > JSRegExp::FlagCount()) return JSRegExp::Flags(0);
   16721             :   // Initialize {value} to {kInvalid} to allow 2-in-1 duplicate/invalid check.
   16722             :   JSRegExp::Flags value = JSRegExp::kInvalid;
   16723      150644 :   if (flags->IsSeqOneByteString()) {
   16724             :     DisallowHeapAllocation no_gc;
   16725             :     SeqOneByteString seq_flags = SeqOneByteString::cast(*flags);
   16726      151707 :     for (int i = 0; i < length; i++) {
   16727             :       JSRegExp::Flag flag = CharToFlag(seq_flags.SeqOneByteStringGet(i));
   16728             :       // Duplicate or invalid flag.
   16729       76529 :       if (value & flag) return JSRegExp::Flags(0);
   16730             :       value |= flag;
   16731             :     }
   16732             :   } else {
   16733           0 :     flags = String::Flatten(isolate, flags);
   16734             :     DisallowHeapAllocation no_gc;
   16735           0 :     String::FlatContent flags_content = flags->GetFlatContent(no_gc);
   16736           0 :     for (int i = 0; i < length; i++) {
   16737           0 :       JSRegExp::Flag flag = CharToFlag(flags_content.Get(i));
   16738             :       // Duplicate or invalid flag.
   16739           0 :       if (value & flag) return JSRegExp::Flags(0);
   16740             :       value |= flag;
   16741             :     }
   16742             :   }
   16743       75178 :   *success = true;
   16744             :   // Drop the initially set {kInvalid} bit.
   16745             :   value ^= JSRegExp::kInvalid;
   16746       75178 :   return value;
   16747             : }
   16748             : 
   16749             : }  // namespace
   16750             : 
   16751             : 
   16752             : // static
   16753       82106 : MaybeHandle<JSRegExp> JSRegExp::New(Isolate* isolate, Handle<String> pattern,
   16754             :                                     Flags flags) {
   16755       82106 :   Handle<JSFunction> constructor = isolate->regexp_function();
   16756             :   Handle<JSRegExp> regexp =
   16757       82106 :       Handle<JSRegExp>::cast(isolate->factory()->NewJSObject(constructor));
   16758             : 
   16759       82106 :   return JSRegExp::Initialize(regexp, pattern, flags);
   16760             : }
   16761             : 
   16762             : 
   16763             : // static
   16764       18621 : Handle<JSRegExp> JSRegExp::Copy(Handle<JSRegExp> regexp) {
   16765             :   Isolate* const isolate = regexp->GetIsolate();
   16766       18621 :   return Handle<JSRegExp>::cast(isolate->factory()->CopyJSObject(regexp));
   16767             : }
   16768             : 
   16769             : namespace {
   16770             : 
   16771             : template <typename Char>
   16772      461483 : int CountRequiredEscapes(Handle<String> source) {
   16773             :   DisallowHeapAllocation no_gc;
   16774             :   int escapes = 0;
   16775      922966 :   Vector<const Char> src = source->GetCharVector<Char>(no_gc);
   16776 19348059582 :   for (int i = 0; i < src.length(); i++) {
   16777 19347136616 :     const Char c = src[i];
   16778  9673568308 :     if (c == '\\') {
   16779             :       // Escape. Skip next character;
   16780      131472 :       i++;
   16781  9673436836 :     } else if (c == '/') {
   16782             :       // Not escaped forward-slash needs escape.
   16783        1521 :       escapes++;
   16784  9673435315 :     } else if (c == '\n') {
   16785        1141 :       escapes++;
   16786  9673434174 :     } else if (c == '\r') {
   16787          36 :       escapes++;
   16788      446006 :     } else if (static_cast<int>(c) == 0x2028) {
   16789          20 :       escapes += std::strlen("\\u2028") - 1;
   16790      445986 :     } else if (static_cast<int>(c) == 0x2029) {
   16791          20 :       escapes += std::strlen("\\u2029") - 1;
   16792             :     } else {
   16793             :       DCHECK(!unibrow::IsLineTerminator(static_cast<unibrow::uchar>(c)));
   16794             :     }
   16795             :   }
   16796      461483 :   return escapes;
   16797             : }
   16798             : 
   16799             : template <typename Char>
   16800             : void WriteStringToCharVector(Vector<Char> v, int* d, const char* string) {
   16801             :   int s = 0;
   16802        5188 :   while (string[s] != '\0') v[(*d)++] = string[s++];
   16803             : }
   16804             : 
   16805             : template <typename Char, typename StringType>
   16806        1774 : Handle<StringType> WriteEscapedRegExpSource(Handle<String> source,
   16807             :                                             Handle<StringType> result) {
   16808             :   DisallowHeapAllocation no_gc;
   16809        3548 :   Vector<const Char> src = source->GetCharVector<Char>(no_gc);
   16810             :   Vector<Char> dst(result->GetChars(no_gc), result->length());
   16811             :   int s = 0;
   16812             :   int d = 0;
   16813             :   // TODO(v8:1982): Fully implement
   16814             :   // https://tc39.github.io/ecma262/#sec-escaperegexppattern
   16815       38171 :   while (s < src.length()) {
   16816       69246 :     if (src[s] == '\\') {
   16817             :       // Escape. Copy this and next character.
   16818        3990 :       dst[d++] = src[s++];
   16819        1995 :       if (s == src.length()) break;
   16820       32628 :     } else if (src[s] == '/') {
   16821             :       // Not escaped forward-slash needs escape.
   16822        3042 :       dst[d++] = '\\';
   16823       31107 :     } else if (src[s] == '\n') {
   16824             :       WriteStringToCharVector(dst, &d, "\\n");
   16825        1141 :       s++;
   16826        1141 :       continue;
   16827       29966 :     } else if (src[s] == '\r') {
   16828             :       WriteStringToCharVector(dst, &d, "\\r");
   16829          36 :       s++;
   16830          36 :       continue;
   16831          51 :     } else if (static_cast<int>(src[s]) == 0x2028) {
   16832             :       WriteStringToCharVector(dst, &d, "\\u2028");
   16833          20 :       s++;
   16834          20 :       continue;
   16835          31 :     } else if (static_cast<int>(src[s]) == 0x2029) {
   16836             :       WriteStringToCharVector(dst, &d, "\\u2029");
   16837          20 :       s++;
   16838          20 :       continue;
   16839             :     }
   16840      100218 :     dst[d++] = src[s++];
   16841             :   }
   16842             :   DCHECK_EQ(result->length(), d);
   16843        1774 :   return result;
   16844             : }
   16845             : 
   16846      461483 : MaybeHandle<String> EscapeRegExpSource(Isolate* isolate,
   16847             :                                        Handle<String> source) {
   16848             :   DCHECK(source->IsFlat());
   16849      461483 :   if (source->length() == 0) return isolate->factory()->query_colon_string();
   16850      461483 :   bool one_byte = String::IsOneByteRepresentationUnderneath(*source);
   16851             :   int escapes = one_byte ? CountRequiredEscapes<uint8_t>(source)
   16852      461483 :                          : CountRequiredEscapes<uc16>(source);
   16853      461483 :   if (escapes == 0) return source;
   16854        1774 :   int length = source->length() + escapes;
   16855        1774 :   if (one_byte) {
   16856             :     Handle<SeqOneByteString> result;
   16857        3470 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   16858             :                                isolate->factory()->NewRawOneByteString(length),
   16859             :                                String);
   16860        1735 :     return WriteEscapedRegExpSource<uint8_t>(source, result);
   16861             :   } else {
   16862             :     Handle<SeqTwoByteString> result;
   16863          78 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   16864             :                                isolate->factory()->NewRawTwoByteString(length),
   16865             :                                String);
   16866          39 :     return WriteEscapedRegExpSource<uc16>(source, result);
   16867             :   }
   16868             : }
   16869             : 
   16870             : }  // namespace
   16871             : 
   16872             : // static
   16873      379521 : MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
   16874             :                                            Handle<String> source,
   16875             :                                            Handle<String> flags_string) {
   16876             :   Isolate* isolate = regexp->GetIsolate();
   16877      379521 :   bool success = false;
   16878      379521 :   Flags flags = RegExpFlagsFromString(isolate, flags_string, &success);
   16879      379521 :   if (!success) {
   16880         144 :     THROW_NEW_ERROR(
   16881             :         isolate,
   16882             :         NewSyntaxError(MessageTemplate::kInvalidRegExpFlags, flags_string),
   16883             :         JSRegExp);
   16884             :   }
   16885      379377 :   return Initialize(regexp, source, flags);
   16886             : }
   16887             : 
   16888             : 
   16889             : // static
   16890      461483 : MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
   16891             :                                            Handle<String> source, Flags flags) {
   16892             :   Isolate* isolate = regexp->GetIsolate();
   16893             :   Factory* factory = isolate->factory();
   16894             :   // If source is the empty string we set it to "(?:)" instead as
   16895             :   // suggested by ECMA-262, 5th, section 15.10.4.1.
   16896      461483 :   if (source->length() == 0) source = factory->query_colon_string();
   16897             : 
   16898      461483 :   source = String::Flatten(isolate, source);
   16899             : 
   16900             :   Handle<String> escaped_source;
   16901      922966 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, escaped_source,
   16902             :                              EscapeRegExpSource(isolate, source), JSRegExp);
   16903             : 
   16904      922966 :   RETURN_ON_EXCEPTION(
   16905             :       isolate, RegExpImpl::Compile(isolate, regexp, source, flags), JSRegExp);
   16906             : 
   16907      917314 :   regexp->set_source(*escaped_source);
   16908      917314 :   regexp->set_flags(Smi::FromInt(flags));
   16909             : 
   16910      458657 :   Map map = regexp->map();
   16911      458657 :   Object constructor = map->GetConstructor();
   16912     1375971 :   if (constructor->IsJSFunction() &&
   16913     1375971 :       JSFunction::cast(constructor)->initial_map() == map) {
   16914             :     // If we still have the original map, set in-object properties directly.
   16915      916778 :     regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, Smi::kZero,
   16916      458389 :                                   SKIP_WRITE_BARRIER);
   16917             :   } else {
   16918             :     // Map has changed, so use generic, but slower, method.
   16919         536 :     RETURN_ON_EXCEPTION(
   16920             :         isolate,
   16921             :         Object::SetProperty(isolate, regexp, factory->lastIndex_string(),
   16922             :                             Handle<Smi>(Smi::zero(), isolate),
   16923             :                             LanguageMode::kStrict),
   16924             :         JSRegExp);
   16925             :   }
   16926             : 
   16927      458657 :   return regexp;
   16928             : }
   16929             : 
   16930             : 
   16931             : // RegExpKey carries the source and flags of a regular expression as key.
   16932           0 : class RegExpKey : public HashTableKey {
   16933             :  public:
   16934     1043180 :   RegExpKey(Handle<String> string, JSRegExp::Flags flags)
   16935             :       : HashTableKey(
   16936             :             CompilationCacheShape::RegExpHash(*string, Smi::FromInt(flags))),
   16937             :         string_(string),
   16938     1043180 :         flags_(Smi::FromInt(flags)) {}
   16939             : 
   16940             :   // Rather than storing the key in the hash table, a pointer to the
   16941             :   // stored value is stored where the key should be.  IsMatch then
   16942             :   // compares the search key to the found object, rather than comparing
   16943             :   // a key to a key.
   16944      551205 :   bool IsMatch(Object obj) override {
   16945             :     FixedArray val = FixedArray::cast(obj);
   16946     1102410 :     return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex)))
   16947     1270333 :         && (flags_ == val->get(JSRegExp::kFlagsIndex));
   16948             :   }
   16949             : 
   16950             :   Handle<String> string_;
   16951             :   Smi flags_;
   16952             : };
   16953             : 
   16954       42689 : Handle<String> OneByteStringKey::AsHandle(Isolate* isolate) {
   16955       42689 :   return isolate->factory()->NewOneByteInternalizedString(string_, HashField());
   16956             : }
   16957             : 
   16958           0 : Handle<String> TwoByteStringKey::AsHandle(Isolate* isolate) {
   16959           0 :   return isolate->factory()->NewTwoByteInternalizedString(string_, HashField());
   16960             : }
   16961             : 
   16962      473684 : Handle<String> SeqOneByteSubStringKey::AsHandle(Isolate* isolate) {
   16963             :   return isolate->factory()->NewOneByteInternalizedSubString(
   16964      473684 :       string_, from_, length_, HashField());
   16965             : }
   16966             : 
   16967     1813132 : bool SeqOneByteSubStringKey::IsMatch(Object string) {
   16968             :   DisallowHeapAllocation no_gc;
   16969     3626264 :   Vector<const uint8_t> chars(string_->GetChars(no_gc) + from_, length_);
   16970     1813132 :   return String::cast(string)->IsOneByteEqualTo(chars);
   16971             : }
   16972             : 
   16973             : // InternalizedStringKey carries a string/internalized-string object as key.
   16974           0 : class InternalizedStringKey : public StringTableKey {
   16975             :  public:
   16976    10644883 :   explicit InternalizedStringKey(Handle<String> string)
   16977    10644883 :       : StringTableKey(0), string_(string) {
   16978             :     DCHECK(!string->IsInternalizedString());
   16979             :     DCHECK(string->IsFlat());
   16980             :     // Make sure hash_field is computed.
   16981    10644893 :     string->Hash();
   16982             :     set_hash_field(string->hash_field());
   16983    10644882 :   }
   16984             : 
   16985    14343226 :   bool IsMatch(Object string) override {
   16986    14343227 :     return string_->SlowEquals(String::cast(string));
   16987             :   }
   16988             : 
   16989     4809208 :   Handle<String> AsHandle(Isolate* isolate) override {
   16990             :     // Internalize the string if possible.
   16991             :     MaybeHandle<Map> maybe_map =
   16992     4809208 :         isolate->factory()->InternalizedStringMapForString(string_);
   16993             :     Handle<Map> map;
   16994     4809207 :     if (maybe_map.ToHandle(&map)) {
   16995             :       string_->set_map_no_write_barrier(*map);
   16996             :       DCHECK(string_->IsInternalizedString());
   16997       50377 :       return string_;
   16998             :     }
   16999     4758830 :     if (FLAG_thin_strings) {
   17000             :       // External strings get special treatment, to avoid copying their
   17001             :       // contents.
   17002     9517664 :       if (string_->IsExternalOneByteString()) {
   17003             :         return isolate->factory()
   17004           5 :             ->InternalizeExternalString<ExternalOneByteString>(string_);
   17005     9517656 :       } else if (string_->IsExternalTwoByteString()) {
   17006             :         return isolate->factory()
   17007           0 :             ->InternalizeExternalString<ExternalTwoByteString>(string_);
   17008             :       }
   17009             :     }
   17010             :     // Otherwise allocate a new internalized string.
   17011             :     return isolate->factory()->NewInternalizedStringImpl(
   17012     4758828 :         string_, string_->length(), string_->hash_field());
   17013             :   }
   17014             : 
   17015             :  private:
   17016             :   Handle<String> string_;
   17017             : };
   17018             : 
   17019             : template <typename Derived, typename Shape>
   17020       83116 : void HashTable<Derived, Shape>::IteratePrefix(ObjectVisitor* v) {
   17021             :   BodyDescriptorBase::IteratePointers(*this, 0, kElementsStartOffset, v);
   17022       83116 : }
   17023             : 
   17024             : template <typename Derived, typename Shape>
   17025       83492 : void HashTable<Derived, Shape>::IterateElements(ObjectVisitor* v) {
   17026             :   BodyDescriptorBase::IteratePointers(*this, kElementsStartOffset,
   17027             :                                       SizeFor(length()), v);
   17028       83492 : }
   17029             : 
   17030             : template <typename Derived, typename Shape>
   17031     1464139 : Handle<Derived> HashTable<Derived, Shape>::New(
   17032             :     Isolate* isolate, int at_least_space_for, PretenureFlag pretenure,
   17033             :     MinimumCapacity capacity_option) {
   17034             :   DCHECK_LE(0, at_least_space_for);
   17035             :   DCHECK_IMPLIES(capacity_option == USE_CUSTOM_MINIMUM_CAPACITY,
   17036             :                  base::bits::IsPowerOfTwo(at_least_space_for));
   17037             : 
   17038             :   int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
   17039             :                      ? at_least_space_for
   17040     1464139 :                      : ComputeCapacity(at_least_space_for);
   17041     1464142 :   if (capacity > HashTable::kMaxCapacity) {
   17042           0 :     isolate->heap()->FatalProcessOutOfMemory("invalid table size");
   17043             :   }
   17044     1464142 :   return NewInternal(isolate, capacity, pretenure);
   17045             : }
   17046             : 
   17047             : template <typename Derived, typename Shape>
   17048     1464144 : Handle<Derived> HashTable<Derived, Shape>::NewInternal(
   17049             :     Isolate* isolate, int capacity, PretenureFlag pretenure) {
   17050             :   Factory* factory = isolate->factory();
   17051             :   int length = EntryToIndex(capacity);
   17052             :   RootIndex map_root_index = Shape::GetMapRootIndex();
   17053             :   Handle<FixedArray> array =
   17054     1464144 :       factory->NewFixedArrayWithMap(map_root_index, length, pretenure);
   17055     1464141 :   Handle<Derived> table = Handle<Derived>::cast(array);
   17056             : 
   17057             :   table->SetNumberOfElements(0);
   17058             :   table->SetNumberOfDeletedElements(0);
   17059             :   table->SetCapacity(capacity);
   17060     1464143 :   return table;
   17061             : }
   17062             : 
   17063             : template <typename Derived, typename Shape>
   17064      239881 : void HashTable<Derived, Shape>::Rehash(Isolate* isolate, Derived new_table) {
   17065             :   DisallowHeapAllocation no_gc;
   17066             :   WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc);
   17067             : 
   17068             :   DCHECK_LT(NumberOfElements(), new_table->Capacity());
   17069             : 
   17070             :   // Copy prefix to new array.
   17071      681672 :   for (int i = kPrefixStartIndex; i < kElementsStartIndex; i++) {
   17072      452029 :     new_table->set(i, get(i), mode);
   17073             :   }
   17074             : 
   17075             :   // Rehash the elements.
   17076      239881 :   int capacity = this->Capacity();
   17077             :   ReadOnlyRoots roots(isolate);
   17078    45315532 :   for (int i = 0; i < capacity; i++) {
   17079    45073340 :     uint32_t from_index = EntryToIndex(i);
   17080    44982616 :     Object k = this->get(from_index);
   17081    63398318 :     if (!Shape::IsLive(roots, k)) continue;
   17082    26657793 :     uint32_t hash = Shape::HashForObject(isolate, k);
   17083             :     uint32_t insertion_index =
   17084    53436340 :         EntryToIndex(new_table->FindInsertionEntry(hash));
   17085    71038568 :     for (int j = 0; j < Shape::kEntrySize; j++) {
   17086    88640888 :       new_table->set(insertion_index + j, get(from_index + j), mode);
   17087             :     }
   17088             :   }
   17089      239881 :   new_table->SetNumberOfElements(NumberOfElements());
   17090             :   new_table->SetNumberOfDeletedElements(0);
   17091      239881 : }
   17092             : 
   17093             : template <typename Derived, typename Shape>
   17094   532425234 : uint32_t HashTable<Derived, Shape>::EntryForProbe(Isolate* isolate, Object k,
   17095             :                                                   int probe,
   17096             :                                                   uint32_t expected) {
   17097   532262399 :   uint32_t hash = Shape::HashForObject(isolate, k);
   17098   532428848 :   uint32_t capacity = this->Capacity();
   17099             :   uint32_t entry = FirstProbe(hash, capacity);
   17100   647619076 :   for (int i = 1; i < probe; i++) {
   17101   522133392 :     if (entry == expected) return expected;
   17102   136500369 :     entry = NextProbe(entry, i, capacity);
   17103             :   }
   17104             :   return entry;
   17105             : }
   17106             : 
   17107             : template <typename Derived, typename Shape>
   17108    59680760 : void HashTable<Derived, Shape>::Swap(uint32_t entry1, uint32_t entry2,
   17109             :                                      WriteBarrierMode mode) {
   17110    59680760 :   int index1 = EntryToIndex(entry1);
   17111    59680760 :   int index2 = EntryToIndex(entry2);
   17112   119363480 :   Object temp[Shape::kEntrySize];
   17113    59682724 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   17114   119365448 :     temp[j] = get(index1 + j);
   17115             :   }
   17116    59682575 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   17117   119365460 :     set(index1 + j, get(index2 + j), mode);
   17118             :   }
   17119    59682371 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   17120    59682578 :     set(index2 + j, temp[j], mode);
   17121             :   }
   17122    59680398 : }
   17123             : 
   17124             : template <typename Derived, typename Shape>
   17125      371926 : void HashTable<Derived, Shape>::Rehash(Isolate* isolate) {
   17126             :   DisallowHeapAllocation no_gc;
   17127             :   WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
   17128             :   ReadOnlyRoots roots(isolate);
   17129      371926 :   uint32_t capacity = Capacity();
   17130             :   bool done = false;
   17131     1373641 :   for (int probe = 1; !done; probe++) {
   17132             :     // All elements at entries given by one of the first _probe_ probes
   17133             :     // are placed correctly. Other elements might need to be moved.
   17134             :     done = true;
   17135  1175996748 :     for (uint32_t current = 0; current < capacity; current++) {
   17136  1175996748 :       Object current_key = KeyAt(current);
   17137  2268994751 :       if (!Shape::IsLive(roots, current_key)) continue;
   17138   494987686 :       uint32_t target = EntryForProbe(isolate, current_key, probe, current);
   17139   494993917 :       if (current == target) continue;
   17140    83005251 :       Object target_key = KeyAt(target);
   17141   120444891 :       if (!Shape::IsLive(roots, target_key) ||
   17142    37439572 :           EntryForProbe(isolate, target_key, probe, target) != target) {
   17143             :         // Put the current element into the correct position.
   17144    59680684 :         Swap(current, target, mode);
   17145             :         // The other element will be processed on the next iteration.
   17146    59680395 :         current--;
   17147             :       } else {
   17148             :         // The place for the current element is occupied. Leave the element
   17149             :         // for the next probe.
   17150             :         done = false;
   17151             :       }
   17152             :     }
   17153             :   }
   17154             :   // Wipe deleted entries.
   17155             :   Object the_hole = roots.the_hole_value();
   17156      371927 :   Object undefined = roots.undefined_value();
   17157   187783407 :   for (uint32_t current = 0; current < capacity; current++) {
   17158   374822961 :     if (KeyAt(current) == the_hole) {
   17159     1627317 :       set(EntryToIndex(current) + kEntryKeyIndex, undefined);
   17160             :     }
   17161             :   }
   17162             :   SetNumberOfDeletedElements(0);
   17163      371926 : }
   17164             : 
   17165             : template <typename Derived, typename Shape>
   17166    34051988 : Handle<Derived> HashTable<Derived, Shape>::EnsureCapacity(
   17167             :     Isolate* isolate, Handle<Derived> table, int n, PretenureFlag pretenure) {
   17168    34051986 :   if (table->HasSufficientCapacityToAdd(n)) return table;
   17169             : 
   17170      239374 :   int capacity = table->Capacity();
   17171      239374 :   int new_nof = table->NumberOfElements() + n;
   17172             : 
   17173             :   const int kMinCapacityForPretenure = 256;
   17174             :   bool should_pretenure =
   17175             :       pretenure == TENURED ||
   17176      248366 :       ((capacity > kMinCapacityForPretenure) && !Heap::InNewSpace(*table));
   17177             :   Handle<Derived> new_table = HashTable::New(
   17178      239374 :       isolate, new_nof, should_pretenure ? TENURED : NOT_TENURED);
   17179             : 
   17180      239374 :   table->Rehash(isolate, *new_table);
   17181      239374 :   return new_table;
   17182             : }
   17183             : 
   17184             : template bool
   17185             : HashTable<NameDictionary, NameDictionaryShape>::HasSufficientCapacityToAdd(int);
   17186             : 
   17187             : template <typename Derived, typename Shape>
   17188    34084900 : bool HashTable<Derived, Shape>::HasSufficientCapacityToAdd(
   17189             :     int number_of_additional_elements) {
   17190    34084900 :   int capacity = Capacity();
   17191    34084903 :   int nof = NumberOfElements() + number_of_additional_elements;
   17192    34084903 :   int nod = NumberOfDeletedElements();
   17193             :   // Return true if:
   17194             :   //   50% is still free after adding number_of_additional_elements elements and
   17195             :   //   at most 50% of the free elements are deleted elements.
   17196    34084910 :   if ((nof < capacity) && ((nod <= (capacity - nof) >> 1))) {
   17197    34023675 :     int needed_free = nof >> 1;
   17198    34023675 :     if (nof + needed_free <= capacity) return true;
   17199             :   }
   17200      239826 :   return false;
   17201             : }
   17202             : 
   17203             : template <typename Derived, typename Shape>
   17204       78345 : Handle<Derived> HashTable<Derived, Shape>::Shrink(Isolate* isolate,
   17205             :                                                   Handle<Derived> table,
   17206             :                                                   int additionalCapacity) {
   17207       78345 :   int capacity = table->Capacity();
   17208       78345 :   int nof = table->NumberOfElements();
   17209             : 
   17210             :   // Shrink to fit the number of elements if only a quarter of the
   17211             :   // capacity is filled with elements.
   17212       78345 :   if (nof > (capacity >> 2)) return table;
   17213             :   // Allocate a new dictionary with room for at least the current number of
   17214             :   // elements + {additionalCapacity}. The allocation method will make sure that
   17215             :   // there is extra room in the dictionary for additions. Don't go lower than
   17216             :   // room for {kMinShrinkCapacity} elements.
   17217       59864 :   int at_least_room_for = nof + additionalCapacity;
   17218             :   int new_capacity = ComputeCapacity(at_least_room_for);
   17219       59864 :   if (new_capacity < Derived::kMinShrinkCapacity) return table;
   17220         507 :   if (new_capacity == capacity) return table;
   17221             : 
   17222             :   const int kMinCapacityForPretenure = 256;
   17223             :   bool pretenure = (at_least_room_for > kMinCapacityForPretenure) &&
   17224         744 :                    !Heap::InNewSpace(*table);
   17225             :   Handle<Derived> new_table =
   17226             :       HashTable::New(isolate, new_capacity, pretenure ? TENURED : NOT_TENURED,
   17227         507 :                      USE_CUSTOM_MINIMUM_CAPACITY);
   17228             : 
   17229         507 :   table->Rehash(isolate, *new_table);
   17230         507 :   return new_table;
   17231             : }
   17232             : 
   17233             : template <typename Derived, typename Shape>
   17234    60774762 : uint32_t HashTable<Derived, Shape>::FindInsertionEntry(uint32_t hash) {
   17235    60774762 :   uint32_t capacity = Capacity();
   17236             :   uint32_t entry = FirstProbe(hash, capacity);
   17237             :   uint32_t count = 1;
   17238             :   // EnsureCapacity will guarantee the hash table is never full.
   17239    60774767 :   ReadOnlyRoots roots = GetReadOnlyRoots();
   17240             :   while (true) {
   17241   142206850 :     if (!Shape::IsLive(roots, KeyAt(entry))) break;
   17242    81432088 :     entry = NextProbe(entry, count++, capacity);
   17243             :   }
   17244    81432088 :   return entry;
   17245             : }
   17246             : 
   17247      881215 : void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
   17248             :                                             Handle<Name> name) {
   17249             :   // Regardless of whether the property is there or not invalidate
   17250             :   // Load/StoreGlobalICs that load/store through global object's prototype.
   17251      881215 :   JSObject::InvalidatePrototypeValidityCell(*global);
   17252             : 
   17253             :   DCHECK(!global->HasFastProperties());
   17254     1762430 :   auto dictionary = handle(global->global_dictionary(), global->GetIsolate());
   17255      881215 :   int entry = dictionary->FindEntry(global->GetIsolate(), name);
   17256     1762430 :   if (entry == GlobalDictionary::kNotFound) return;
   17257          87 :   PropertyCell::InvalidateEntry(global->GetIsolate(), dictionary, entry);
   17258             : }
   17259             : 
   17260     8238112 : Handle<PropertyCell> JSGlobalObject::EnsureEmptyPropertyCell(
   17261             :     Handle<JSGlobalObject> global, Handle<Name> name,
   17262             :     PropertyCellType cell_type, int* entry_out) {
   17263             :   Isolate* isolate = global->GetIsolate();
   17264             :   DCHECK(!global->HasFastProperties());
   17265    16476223 :   Handle<GlobalDictionary> dictionary(global->global_dictionary(), isolate);
   17266     8238112 :   int entry = dictionary->FindEntry(isolate, name);
   17267             :   Handle<PropertyCell> cell;
   17268     8238116 :   if (entry != GlobalDictionary::kNotFound) {
   17269        3046 :     if (entry_out) *entry_out = entry;
   17270        6092 :     cell = handle(dictionary->CellAt(entry), isolate);
   17271        6092 :     PropertyCellType original_cell_type = cell->property_details().cell_type();
   17272             :     DCHECK(original_cell_type == PropertyCellType::kInvalidated ||
   17273             :            original_cell_type == PropertyCellType::kUninitialized);
   17274             :     DCHECK(cell->value()->IsTheHole(isolate));
   17275        3046 :     if (original_cell_type == PropertyCellType::kInvalidated) {
   17276         482 :       cell = PropertyCell::InvalidateEntry(isolate, dictionary, entry);
   17277             :     }
   17278             :     PropertyDetails details(kData, NONE, cell_type);
   17279        6092 :     cell->set_property_details(details);
   17280        3046 :     return cell;
   17281             :   }
   17282     8235070 :   cell = isolate->factory()->NewPropertyCell(name);
   17283             :   PropertyDetails details(kData, NONE, cell_type);
   17284             :   dictionary = GlobalDictionary::Add(isolate, dictionary, name, cell, details,
   17285     8235061 :                                      entry_out);
   17286             :   // {*entry_out} is initialized inside GlobalDictionary::Add().
   17287    16470140 :   global->SetProperties(*dictionary);
   17288     8235068 :   return cell;
   17289             : }
   17290             : 
   17291             : 
   17292             : // This class is used for looking up two character strings in the string table.
   17293             : // If we don't have a hit we don't want to waste much time so we unroll the
   17294             : // string hash calculation loop here for speed.  Doesn't work if the two
   17295             : // characters form a decimal integer, since such strings have a different hash
   17296             : // algorithm.
   17297           0 : class TwoCharHashTableKey : public StringTableKey {
   17298             :  public:
   17299             :   TwoCharHashTableKey(uint16_t c1, uint16_t c2, uint64_t seed)
   17300     3412136 :       : StringTableKey(ComputeHashField(c1, c2, seed)), c1_(c1), c2_(c2) {}
   17301             : 
   17302     2588981 :   bool IsMatch(Object o) override {
   17303     2588981 :     String other = String::cast(o);
   17304     2588981 :     if (other->length() != 2) return false;
   17305       96397 :     if (other->Get(0) != c1_) return false;
   17306       15853 :     return other->Get(1) == c2_;
   17307             :   }
   17308             : 
   17309           0 :   Handle<String> AsHandle(Isolate* isolate) override {
   17310             :     // The TwoCharHashTableKey is only used for looking in the string
   17311             :     // table, not for adding to it.
   17312           0 :     UNREACHABLE();
   17313             :   }
   17314             : 
   17315             :  private:
   17316     1706068 :   uint32_t ComputeHashField(uint16_t c1, uint16_t c2, uint64_t seed) {
   17317             :     // Char 1.
   17318     1706068 :     uint32_t hash = static_cast<uint32_t>(seed);
   17319     1706068 :     hash += c1;
   17320     1706068 :     hash += hash << 10;
   17321     1706068 :     hash ^= hash >> 6;
   17322             :     // Char 2.
   17323     1706068 :     hash += c2;
   17324     1706068 :     hash += hash << 10;
   17325     1706068 :     hash ^= hash >> 6;
   17326             :     // GetHash.
   17327     1706068 :     hash += hash << 3;
   17328     1706068 :     hash ^= hash >> 11;
   17329     1706068 :     hash += hash << 15;
   17330     1706068 :     if ((hash & String::kHashBitMask) == 0) hash = StringHasher::kZeroHash;
   17331     1706068 :     hash = (hash << String::kHashShift) | String::kIsNotArrayIndexMask;
   17332             : #ifdef DEBUG
   17333             :     // If this assert fails then we failed to reproduce the two-character
   17334             :     // version of the string hashing algorithm above.  One reason could be
   17335             :     // that we were passed two digits as characters, since the hash
   17336             :     // algorithm is different in that case.
   17337             :     uint16_t chars[2] = {c1, c2};
   17338             :     uint32_t check_hash = StringHasher::HashSequentialString(chars, 2, seed);
   17339             :     DCHECK_EQ(hash, check_hash);
   17340             : #endif
   17341     1706068 :     return hash;
   17342             :   }
   17343             : 
   17344             :   uint16_t c1_;
   17345             :   uint16_t c2_;
   17346             : };
   17347             : 
   17348     1706068 : MaybeHandle<String> StringTable::LookupTwoCharsStringIfExists(
   17349             :     Isolate* isolate,
   17350             :     uint16_t c1,
   17351             :     uint16_t c2) {
   17352     1706068 :   TwoCharHashTableKey key(c1, c2, isolate->heap()->HashSeed());
   17353             :   Handle<StringTable> string_table = isolate->factory()->string_table();
   17354     1706068 :   int entry = string_table->FindEntry(isolate, &key);
   17355     1706068 :   if (entry == kNotFound) return MaybeHandle<String>();
   17356             : 
   17357       27382 :   Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
   17358             :   DCHECK(StringShape(*result).IsInternalized());
   17359             :   DCHECK_EQ(result->Hash(), key.Hash());
   17360       13691 :   return result;
   17361             : }
   17362             : 
   17363         214 : void StringTable::EnsureCapacityForDeserialization(Isolate* isolate,
   17364             :                                                    int expected) {
   17365             :   Handle<StringTable> table = isolate->factory()->string_table();
   17366             :   // We need a key instance for the virtual hash function.
   17367         214 :   table = StringTable::EnsureCapacity(isolate, table, expected);
   17368         214 :   isolate->heap()->SetRootStringTable(*table);
   17369         214 : }
   17370             : 
   17371             : namespace {
   17372             : 
   17373             : template <class StringClass>
   17374          14 : void MigrateExternalStringResource(Isolate* isolate, String from, String to) {
   17375          14 :   StringClass cast_from = StringClass::cast(from);
   17376          14 :   StringClass cast_to = StringClass::cast(to);
   17377             :   const typename StringClass::Resource* to_resource = cast_to->resource();
   17378          14 :   if (to_resource == nullptr) {
   17379             :     // |to| is a just-created internalized copy of |from|. Migrate the resource.
   17380           5 :     cast_to->SetResource(isolate, cast_from->resource());
   17381             :     // Zap |from|'s resource pointer to reflect the fact that |from| has
   17382             :     // relinquished ownership of its resource.
   17383           5 :     isolate->heap()->UpdateExternalString(
   17384          10 :         from, ExternalString::cast(from)->ExternalPayloadSize(), 0);
   17385           5 :     cast_from->SetResource(isolate, nullptr);
   17386           9 :   } else if (to_resource != cast_from->resource()) {
   17387             :     // |to| already existed and has its own resource. Finalize |from|.
   17388           9 :     isolate->heap()->FinalizeExternalString(from);
   17389             :   }
   17390          14 : }
   17391             : 
   17392    12160696 : void MakeStringThin(String string, String internalized, Isolate* isolate) {
   17393             :   DCHECK_NE(string, internalized);
   17394             :   DCHECK(internalized->IsInternalizedString());
   17395             : 
   17396    12160713 :   if (string->IsExternalString()) {
   17397          14 :     if (internalized->IsExternalOneByteString()) {
   17398             :       MigrateExternalStringResource<ExternalOneByteString>(isolate, string,
   17399          14 :                                                            internalized);
   17400           0 :     } else if (internalized->IsExternalTwoByteString()) {
   17401             :       MigrateExternalStringResource<ExternalTwoByteString>(isolate, string,
   17402           0 :                                                            internalized);
   17403             :     } else {
   17404             :       // If the external string is duped into an existing non-external
   17405             :       // internalized string, free its resource (it's about to be rewritten
   17406             :       // into a ThinString below).
   17407           0 :       isolate->heap()->FinalizeExternalString(string);
   17408             :     }
   17409             :   }
   17410             : 
   17411             :   DisallowHeapAllocation no_gc;
   17412    12160713 :   int old_size = string->Size();
   17413    12160696 :   isolate->heap()->NotifyObjectLayoutChange(string, old_size, no_gc);
   17414    12160707 :   bool one_byte = internalized->IsOneByteRepresentation();
   17415             :   Handle<Map> map = one_byte ? isolate->factory()->thin_one_byte_string_map()
   17416    12160709 :                              : isolate->factory()->thin_string_map();
   17417             :   DCHECK_GE(old_size, ThinString::kSize);
   17418    12160713 :   string->synchronized_set_map(*map);
   17419    12160711 :   ThinString thin = ThinString::cast(string);
   17420    12160711 :   thin->set_actual(internalized);
   17421    12160711 :   Address thin_end = thin->address() + ThinString::kSize;
   17422    12160711 :   int size_delta = old_size - ThinString::kSize;
   17423    12160711 :   if (size_delta != 0) {
   17424             :     Heap* heap = isolate->heap();
   17425     5382933 :     heap->CreateFillerObjectAt(thin_end, size_delta, ClearRecordedSlots::kNo);
   17426             :   }
   17427    12160711 : }
   17428             : 
   17429             : }  // namespace
   17430             : 
   17431             : // static
   17432    11497821 : Handle<String> StringTable::LookupString(Isolate* isolate,
   17433             :                                          Handle<String> string) {
   17434    11497821 :   string = String::Flatten(isolate, string);
   17435    22995677 :   if (string->IsInternalizedString()) return string;
   17436             : 
   17437    10644892 :   InternalizedStringKey key(string);
   17438    10644881 :   Handle<String> result = LookupKey(isolate, &key);
   17439             : 
   17440    10644878 :   if (FLAG_thin_strings) {
   17441    21289771 :     if (!string->IsInternalizedString()) {
   17442    10594514 :       MakeStringThin(*string, *result, isolate);
   17443             :     }
   17444             :   } else {  // !FLAG_thin_strings
   17445           0 :     if (string->IsConsString()) {
   17446           0 :       Handle<ConsString> cons = Handle<ConsString>::cast(string);
   17447           0 :       cons->set_first(isolate, *result);
   17448           0 :       cons->set_second(isolate, ReadOnlyRoots(isolate).empty_string());
   17449           0 :     } else if (string->IsSlicedString()) {
   17450             :       STATIC_ASSERT(static_cast<int>(ConsString::kSize) ==
   17451             :                     static_cast<int>(SlicedString::kSize));
   17452             :       DisallowHeapAllocation no_gc;
   17453           0 :       bool one_byte = result->IsOneByteRepresentation();
   17454             :       Handle<Map> map = one_byte
   17455             :                             ? isolate->factory()->cons_one_byte_string_map()
   17456           0 :                             : isolate->factory()->cons_string_map();
   17457           0 :       string->set_map(*map);
   17458           0 :       Handle<ConsString> cons = Handle<ConsString>::cast(string);
   17459           0 :       cons->set_first(isolate, *result);
   17460           0 :       cons->set_second(isolate, ReadOnlyRoots(isolate).empty_string());
   17461             :     }
   17462             :   }
   17463    10644892 :   return result;
   17464             : }
   17465             : 
   17466             : // static
   17467    53669580 : Handle<String> StringTable::LookupKey(Isolate* isolate, StringTableKey* key) {
   17468             :   Handle<StringTable> table = isolate->factory()->string_table();
   17469    53669582 :   int entry = table->FindEntry(isolate, key);
   17470             : 
   17471             :   // String already in table.
   17472    53669661 :   if (entry != kNotFound) {
   17473    77780369 :     return handle(String::cast(table->KeyAt(entry)), isolate);
   17474             :   }
   17475             : 
   17476    14779466 :   table = StringTable::CautiousShrink(isolate, table);
   17477             :   // Adding new string. Grow table if needed.
   17478    14779457 :   table = StringTable::EnsureCapacity(isolate, table, 1);
   17479    14779462 :   isolate->heap()->SetRootStringTable(*table);
   17480             : 
   17481    14779454 :   return AddKeyNoResize(isolate, key);
   17482             : }
   17483             : 
   17484    14784208 : Handle<String> StringTable::AddKeyNoResize(Isolate* isolate,
   17485             :                                            StringTableKey* key) {
   17486             :   Handle<StringTable> table = isolate->factory()->string_table();
   17487             :   DCHECK(table->HasSufficientCapacityToAdd(1));
   17488             :   // Create string object.
   17489    14784208 :   Handle<String> string = key->AsHandle(isolate);
   17490             :   // There must be no attempts to internalize strings that could throw
   17491             :   // InvalidStringLength error.
   17492    14784203 :   CHECK(!string.is_null());
   17493             :   DCHECK(string->HasHashCode());
   17494             :   DCHECK_EQ(table->FindEntry(isolate, key), kNotFound);
   17495             : 
   17496             :   // Add the new string and return it along with the string table.
   17497    29568411 :   int entry = table->FindInsertionEntry(key->Hash());
   17498    29568405 :   table->set(EntryToIndex(entry), *string);
   17499    14784211 :   table->ElementAdded();
   17500             : 
   17501    14784210 :   return Handle<String>::cast(string);
   17502             : }
   17503             : 
   17504    14779465 : Handle<StringTable> StringTable::CautiousShrink(Isolate* isolate,
   17505             :                                                 Handle<StringTable> table) {
   17506             :   // Only shrink if the table is very empty to avoid performance penalty.
   17507    14779465 :   int capacity = table->Capacity();
   17508    14779463 :   int nof = table->NumberOfElements();
   17509    14779466 :   if (capacity <= StringTable::kMinCapacity) return table;
   17510     7413229 :   if (nof > (capacity / kMaxEmptyFactor)) return table;
   17511             :   // Keep capacity for at least half of the current nof elements.
   17512       30907 :   int slack_capacity = nof >> 2;
   17513       30907 :   return Shrink(isolate, table, slack_capacity);
   17514             : }
   17515             : 
   17516             : namespace {
   17517             : 
   17518             : class StringTableNoAllocateKey : public StringTableKey {
   17519             :  public:
   17520     1955588 :   StringTableNoAllocateKey(String string, uint64_t seed)
   17521     1955588 :       : StringTableKey(0), string_(string) {
   17522             :     StringShape shape(string);
   17523     1955588 :     one_byte_ = shape.HasOnlyOneByteChars();
   17524             :     DCHECK(!shape.IsInternalized());
   17525             :     DCHECK(!shape.IsThin());
   17526             :     int length = string->length();
   17527     1955588 :     if (shape.IsCons() && length <= String::kMaxHashCalcLength) {
   17528      287805 :       special_flattening_ = true;
   17529             :       uint32_t hash_field = 0;
   17530      287805 :       if (one_byte_) {
   17531      287805 :         if (V8_LIKELY(length <=
   17532             :                       static_cast<int>(arraysize(one_byte_buffer_)))) {
   17533      287805 :           one_byte_content_ = one_byte_buffer_;
   17534             :         } else {
   17535           0 :           one_byte_content_ = new uint8_t[length];
   17536             :         }
   17537      287805 :         String::WriteToFlat(string, one_byte_content_, 0, length);
   17538             :         hash_field =
   17539      287805 :             StringHasher::HashSequentialString(one_byte_content_, length, seed);
   17540             :       } else {
   17541           0 :         if (V8_LIKELY(length <=
   17542             :                       static_cast<int>(arraysize(two_byte_buffer_)))) {
   17543           0 :           two_byte_content_ = two_byte_buffer_;
   17544             :         } else {
   17545           0 :           two_byte_content_ = new uint16_t[length];
   17546             :         }
   17547           0 :         String::WriteToFlat(string, two_byte_content_, 0, length);
   17548             :         hash_field =
   17549           0 :             StringHasher::HashSequentialString(two_byte_content_, length, seed);
   17550             :       }
   17551             :       string->set_hash_field(hash_field);
   17552             :     } else {
   17553     1667783 :       special_flattening_ = false;
   17554     1667783 :       one_byte_content_ = nullptr;
   17555     1667783 :       string->Hash();
   17556             :     }
   17557             : 
   17558             :     DCHECK(string->HasHashCode());
   17559             :     set_hash_field(string->hash_field());
   17560     1955588 :   }
   17561             : 
   17562     1955588 :   ~StringTableNoAllocateKey() override {
   17563     1955588 :     if (one_byte_) {
   17564     1214599 :       if (one_byte_content_ != one_byte_buffer_) delete[] one_byte_content_;
   17565             :     } else {
   17566      740989 :       if (two_byte_content_ != two_byte_buffer_) delete[] two_byte_content_;
   17567             :     }
   17568     1955588 :   }
   17569             : 
   17570     3524660 :   bool IsMatch(Object otherstring) override {
   17571     3524660 :     String other = String::cast(otherstring);
   17572             :     DCHECK(other->IsInternalizedString());
   17573             :     DCHECK(other->IsFlat());
   17574     3524660 :     if (Hash() != other->Hash()) return false;
   17575             :     int len = string_->length();
   17576     1565584 :     if (len != other->length()) return false;
   17577             : 
   17578             :     DisallowHeapAllocation no_gc;
   17579     1565584 :     if (!special_flattening_) {
   17580     2858476 :       if (string_->Get(0) != other->Get(0)) return false;
   17581     1429238 :       if (string_->IsFlat()) {
   17582             :         StringShape shape1(string_);
   17583             :         StringShape shape2(other);
   17584     2135781 :         if (shape1.encoding_tag() == kOneByteStringTag &&
   17585             :             shape2.encoding_tag() == kOneByteStringTag) {
   17586      706543 :           String::FlatContent flat1 = string_->GetFlatContent(no_gc);
   17587      706543 :           String::FlatContent flat2 = other->GetFlatContent(no_gc);
   17588      706543 :           return CompareRawStringContents(flat1.ToOneByteVector().start(),
   17589      706543 :                                           flat2.ToOneByteVector().start(), len);
   17590             :         }
   17591     1445390 :         if (shape1.encoding_tag() == kTwoByteStringTag &&
   17592             :             shape2.encoding_tag() == kTwoByteStringTag) {
   17593      722695 :           String::FlatContent flat1 = string_->GetFlatContent(no_gc);
   17594      722695 :           String::FlatContent flat2 = other->GetFlatContent(no_gc);
   17595      722695 :           return CompareRawStringContents(flat1.ToUC16Vector().start(),
   17596      722695 :                                           flat2.ToUC16Vector().start(), len);
   17597             :         }
   17598             :       }
   17599           0 :       StringComparator comparator;
   17600           0 :       return comparator.Equals(string_, other);
   17601             :     }
   17602             : 
   17603      136346 :     String::FlatContent flat_content = other->GetFlatContent(no_gc);
   17604      136346 :     if (one_byte_) {
   17605      136346 :       if (flat_content.IsOneByte()) {
   17606             :         return CompareRawStringContents(
   17607      136346 :             one_byte_content_, flat_content.ToOneByteVector().start(), len);
   17608             :       } else {
   17609             :         DCHECK(flat_content.IsTwoByte());
   17610           0 :         for (int i = 0; i < len; i++) {
   17611           0 :           if (flat_content.Get(i) != one_byte_content_[i]) return false;
   17612             :         }
   17613             :         return true;
   17614             :       }
   17615             :     } else {
   17616           0 :       if (flat_content.IsTwoByte()) {
   17617             :         return CompareRawStringContents(
   17618           0 :             two_byte_content_, flat_content.ToUC16Vector().start(), len);
   17619             :       } else {
   17620             :         DCHECK(flat_content.IsOneByte());
   17621           0 :         for (int i = 0; i < len; i++) {
   17622           0 :           if (flat_content.Get(i) != two_byte_content_[i]) return false;
   17623             :         }
   17624             :         return true;
   17625             :       }
   17626             :     }
   17627             :   }
   17628             : 
   17629           0 :   V8_WARN_UNUSED_RESULT Handle<String> AsHandle(Isolate* isolate) override {
   17630           0 :     UNREACHABLE();
   17631             :   }
   17632             : 
   17633             :  private:
   17634             :   String string_;
   17635             :   bool one_byte_;
   17636             :   bool special_flattening_;
   17637             :   union {
   17638             :     uint8_t* one_byte_content_;
   17639             :     uint16_t* two_byte_content_;
   17640             :   };
   17641             :   union {
   17642             :     uint8_t one_byte_buffer_[256];
   17643             :     uint16_t two_byte_buffer_[128];
   17644             :   };
   17645             : };
   17646             : 
   17647             : }  // namespace
   17648             : 
   17649             : // static
   17650     1955588 : Address StringTable::LookupStringIfExists_NoAllocate(Isolate* isolate,
   17651             :                                                      Address raw_string) {
   17652             :   DisallowHeapAllocation no_gc;
   17653             :   String string = String::cast(Object(raw_string));
   17654     1955588 :   Heap* heap = isolate->heap();
   17655     1955588 :   StringTable table = heap->string_table();
   17656             : 
   17657     1955588 :   StringTableNoAllocateKey key(string, heap->HashSeed());
   17658             : 
   17659             :   // String could be an array index.
   17660             :   uint32_t hash = string->hash_field();
   17661             : 
   17662             :   // Valid array indices are >= 0, so they cannot be mixed up with any of
   17663             :   // the result sentinels, which are negative.
   17664             :   STATIC_ASSERT(
   17665             :       !String::ArrayIndexValueBits::is_valid(ResultSentinel::kUnsupported));
   17666             :   STATIC_ASSERT(
   17667             :       !String::ArrayIndexValueBits::is_valid(ResultSentinel::kNotFound));
   17668             : 
   17669     1955588 :   if (Name::ContainsCachedArrayIndex(hash)) {
   17670          50 :     return Smi::FromInt(String::ArrayIndexValueBits::decode(hash)).ptr();
   17671             :   }
   17672     1955538 :   if ((hash & Name::kIsNotArrayIndexMask) == 0) {
   17673             :     // It is an indexed, but it's not cached.
   17674             :     return Smi::FromInt(ResultSentinel::kUnsupported).ptr();
   17675             :   }
   17676             : 
   17677             :   DCHECK(!string->IsInternalizedString());
   17678     3910928 :   int entry = table->FindEntry(ReadOnlyRoots(isolate), &key, key.Hash());
   17679     1955464 :   if (entry != kNotFound) {
   17680     1565584 :     String internalized = String::cast(table->KeyAt(entry));
   17681     1565584 :     if (FLAG_thin_strings) {
   17682     1565584 :       MakeStringThin(string, internalized, isolate);
   17683             :     }
   17684             :     return internalized.ptr();
   17685             :   }
   17686             :   // A string that's not an array index, and not in the string table,
   17687             :   // cannot have been used as a property name before.
   17688     1955588 :   return Smi::FromInt(ResultSentinel::kNotFound).ptr();
   17689             : }
   17690             : 
   17691        5364 : String StringTable::ForwardStringIfExists(Isolate* isolate, StringTableKey* key,
   17692             :                                           String string) {
   17693             :   Handle<StringTable> table = isolate->factory()->string_table();
   17694        5364 :   int entry = table->FindEntry(isolate, key);
   17695        5364 :   if (entry == kNotFound) return String();
   17696             : 
   17697        1224 :   String canonical = String::cast(table->KeyAt(entry));
   17698         612 :   if (canonical != string) MakeStringThin(string, canonical, isolate);
   17699         612 :   return canonical;
   17700             : }
   17701             : 
   17702       12333 : Handle<StringSet> StringSet::New(Isolate* isolate) {
   17703       12333 :   return HashTable::New(isolate, 0);
   17704             : }
   17705             : 
   17706       16507 : Handle<StringSet> StringSet::Add(Isolate* isolate, Handle<StringSet> stringset,
   17707             :                                  Handle<String> name) {
   17708       16507 :   if (!stringset->Has(isolate, name)) {
   17709       11613 :     stringset = EnsureCapacity(isolate, stringset, 1);
   17710             :     uint32_t hash = ShapeT::Hash(isolate, *name);
   17711       11613 :     int entry = stringset->FindInsertionEntry(hash);
   17712       23226 :     stringset->set(EntryToIndex(entry), *name);
   17713       11613 :     stringset->ElementAdded();
   17714             :   }
   17715       16507 :   return stringset;
   17716             : }
   17717             : 
   17718       22219 : bool StringSet::Has(Isolate* isolate, Handle<String> name) {
   17719       22219 :   return FindEntry(isolate, *name) != kNotFound;
   17720             : }
   17721             : 
   17722      106186 : Handle<ObjectHashSet> ObjectHashSet::Add(Isolate* isolate,
   17723             :                                          Handle<ObjectHashSet> set,
   17724             :                                          Handle<Object> key) {
   17725      212372 :   int32_t hash = key->GetOrCreateHash(isolate)->value();
   17726      106186 :   if (!set->Has(isolate, key, hash)) {
   17727      104587 :     set = EnsureCapacity(isolate, set, 1);
   17728      209174 :     int entry = set->FindInsertionEntry(hash);
   17729      104587 :     set->set(EntryToIndex(entry), *key);
   17730      104587 :     set->ElementAdded();
   17731             :   }
   17732      106186 :   return set;
   17733             : }
   17734             : 
   17735             : namespace {
   17736             : 
   17737             : const int kLiteralEntryLength = 2;
   17738             : const int kLiteralInitialLength = 2;
   17739             : const int kLiteralContextOffset = 0;
   17740             : const int kLiteralLiteralsOffset = 1;
   17741             : 
   17742     2971619 : int SearchLiteralsMapEntry(CompilationCacheTable cache, int cache_entry,
   17743             :                            Context native_context) {
   17744             :   DisallowHeapAllocation no_gc;
   17745             :   DCHECK(native_context->IsNativeContext());
   17746     2971619 :   Object obj = cache->get(cache_entry);
   17747             : 
   17748             :   // Check that there's no confusion between FixedArray and WeakFixedArray (the
   17749             :   // object used to be a FixedArray here).
   17750             :   DCHECK(!obj->IsFixedArray());
   17751     2971619 :   if (obj->IsWeakFixedArray()) {
   17752     2971619 :     WeakFixedArray literals_map = WeakFixedArray::cast(obj);
   17753             :     int length = literals_map->length();
   17754     7003417 :     for (int i = 0; i < length; i += kLiteralEntryLength) {
   17755             :       DCHECK(literals_map->Get(i + kLiteralContextOffset)->IsWeakOrCleared());
   17756    12539298 :       if (literals_map->Get(i + kLiteralContextOffset) ==
   17757             :           HeapObjectReference::Weak(native_context)) {
   17758     2237851 :         return i;
   17759             :       }
   17760             :     }
   17761             :   }
   17762             :   return -1;
   17763             : }
   17764             : 
   17765      559169 : void AddToFeedbackCellsMap(Handle<CompilationCacheTable> cache, int cache_entry,
   17766             :                            Handle<Context> native_context,
   17767             :                            Handle<FeedbackCell> feedback_cell) {
   17768             :   Isolate* isolate = native_context->GetIsolate();
   17769             :   DCHECK(native_context->IsNativeContext());
   17770             :   STATIC_ASSERT(kLiteralEntryLength == 2);
   17771             :   Handle<WeakFixedArray> new_literals_map;
   17772             :   int entry;
   17773             : 
   17774      559169 :   Object obj = cache->get(cache_entry);
   17775             : 
   17776             :   // Check that there's no confusion between FixedArray and WeakFixedArray (the
   17777             :   // object used to be a FixedArray here).
   17778             :   DCHECK(!obj->IsFixedArray());
   17779      933818 :   if (!obj->IsWeakFixedArray() || WeakFixedArray::cast(obj)->length() == 0) {
   17780             :     new_literals_map =
   17781      184520 :         isolate->factory()->NewWeakFixedArray(kLiteralInitialLength, TENURED);
   17782             :     entry = 0;
   17783             :   } else {
   17784             :     Handle<WeakFixedArray> old_literals_map(WeakFixedArray::cast(obj), isolate);
   17785      374649 :     entry = SearchLiteralsMapEntry(*cache, cache_entry, *native_context);
   17786      374649 :     if (entry >= 0) {
   17787             :       // Just set the code of the entry.
   17788             :       old_literals_map->Set(entry + kLiteralLiteralsOffset,
   17789        8154 :                             HeapObjectReference::Weak(*feedback_cell));
   17790      559169 :       return;
   17791             :     }
   17792             : 
   17793             :     // Can we reuse an entry?
   17794             :     DCHECK_LT(entry, 0);
   17795             :     int length = old_literals_map->length();
   17796     1077491 :     for (int i = 0; i < length; i += kLiteralEntryLength) {
   17797     1458896 :       if (old_literals_map->Get(i + kLiteralContextOffset)->IsCleared()) {
   17798             :         new_literals_map = old_literals_map;
   17799             :         entry = i;
   17800             :         break;
   17801             :       }
   17802             :     }
   17803             : 
   17804      370572 :     if (entry < 0) {
   17805             :       // Copy old optimized code map and append one new entry.
   17806             :       new_literals_map = isolate->factory()->CopyWeakFixedArrayAndGrow(
   17807      348043 :           old_literals_map, kLiteralEntryLength, TENURED);
   17808             :       entry = old_literals_map->length();
   17809             :     }
   17810             :   }
   17811             : 
   17812             :   new_literals_map->Set(entry + kLiteralContextOffset,
   17813     1110184 :                         HeapObjectReference::Weak(*native_context));
   17814             :   new_literals_map->Set(entry + kLiteralLiteralsOffset,
   17815     1110184 :                         HeapObjectReference::Weak(*feedback_cell));
   17816             : 
   17817             : #ifdef DEBUG
   17818             :   for (int i = 0; i < new_literals_map->length(); i += kLiteralEntryLength) {
   17819             :     MaybeObject object = new_literals_map->Get(i + kLiteralContextOffset);
   17820             :     DCHECK(object->IsCleared() ||
   17821             :            object->GetHeapObjectAssumeWeak()->IsNativeContext());
   17822             :     object = new_literals_map->Get(i + kLiteralLiteralsOffset);
   17823             :     DCHECK(object->IsCleared() ||
   17824             :            object->GetHeapObjectAssumeWeak()->IsFeedbackCell());
   17825             :   }
   17826             : #endif
   17827             : 
   17828             :   Object old_literals_map = cache->get(cache_entry);
   17829      555092 :   if (old_literals_map != *new_literals_map) {
   17830     1065126 :     cache->set(cache_entry, *new_literals_map);
   17831             :   }
   17832             : }
   17833             : 
   17834     2596970 : FeedbackCell SearchLiteralsMap(CompilationCacheTable cache, int cache_entry,
   17835             :                                Context native_context) {
   17836             :   FeedbackCell result;
   17837     2596970 :   int entry = SearchLiteralsMapEntry(cache, cache_entry, native_context);
   17838     2596970 :   if (entry >= 0) {
   17839     2233774 :     WeakFixedArray literals_map = WeakFixedArray::cast(cache->get(cache_entry));
   17840             :     DCHECK_LE(entry + kLiteralEntryLength, literals_map->length());
   17841     2233774 :     MaybeObject object = literals_map->Get(entry + kLiteralLiteralsOffset);
   17842             : 
   17843     2233774 :     if (!object->IsCleared()) {
   17844             :       result = FeedbackCell::cast(object->GetHeapObjectAssumeWeak());
   17845             :     }
   17846             :   }
   17847             :   DCHECK(result.is_null() || result->IsFeedbackCell());
   17848     2596970 :   return result;
   17849             : }
   17850             : 
   17851             : }  // namespace
   17852             : 
   17853      271788 : MaybeHandle<SharedFunctionInfo> CompilationCacheTable::LookupScript(
   17854             :     Handle<CompilationCacheTable> table, Handle<String> src,
   17855             :     Handle<Context> native_context, LanguageMode language_mode) {
   17856             :   // We use the empty function SFI as part of the key. Although the
   17857             :   // empty_function is native context dependent, the SFI is de-duped on
   17858             :   // snapshot builds by the PartialSnapshotCache, and so this does not prevent
   17859             :   // reuse of scripts in the compilation cache across native contexts.
   17860      543576 :   Handle<SharedFunctionInfo> shared(native_context->empty_function()->shared(),
   17861      543576 :                                     native_context->GetIsolate());
   17862             :   Isolate* isolate = native_context->GetIsolate();
   17863      271788 :   src = String::Flatten(isolate, src);
   17864      271788 :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17865      271788 :   int entry = table->FindEntry(isolate, &key);
   17866      271788 :   if (entry == kNotFound) return MaybeHandle<SharedFunctionInfo>();
   17867             :   int index = EntryToIndex(entry);
   17868      261348 :   if (!table->get(index)->IsFixedArray()) {
   17869           0 :     return MaybeHandle<SharedFunctionInfo>();
   17870             :   }
   17871      261348 :   Object obj = table->get(index + 1);
   17872      130674 :   if (obj->IsSharedFunctionInfo()) {
   17873      130674 :     return handle(SharedFunctionInfo::cast(obj), native_context->GetIsolate());
   17874             :   }
   17875           0 :   return MaybeHandle<SharedFunctionInfo>();
   17876             : }
   17877             : 
   17878     3521393 : InfoCellPair CompilationCacheTable::LookupEval(
   17879             :     Handle<CompilationCacheTable> table, Handle<String> src,
   17880             :     Handle<SharedFunctionInfo> outer_info, Handle<Context> native_context,
   17881             :     LanguageMode language_mode, int position) {
   17882             :   InfoCellPair empty_result;
   17883             :   Isolate* isolate = native_context->GetIsolate();
   17884     3521393 :   src = String::Flatten(isolate, src);
   17885     3521393 :   StringSharedKey key(src, outer_info, language_mode, position);
   17886     3521393 :   int entry = table->FindEntry(isolate, &key);
   17887     3521393 :   if (entry == kNotFound) return empty_result;
   17888             :   int index = EntryToIndex(entry);
   17889     5558416 :   if (!table->get(index)->IsFixedArray()) return empty_result;
   17890     5193940 :   Object obj = table->get(EntryToIndex(entry) + 1);
   17891     2596970 :   if (obj->IsSharedFunctionInfo()) {
   17892             :     FeedbackCell feedback_cell =
   17893     5193940 :         SearchLiteralsMap(*table, EntryToIndex(entry) + 2, *native_context);
   17894     2596970 :     return InfoCellPair(SharedFunctionInfo::cast(obj), feedback_cell);
   17895             :   }
   17896           0 :   return empty_result;
   17897             : }
   17898             : 
   17899      753104 : Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src,
   17900             :                                                    JSRegExp::Flags flags) {
   17901             :   Isolate* isolate = GetIsolate();
   17902             :   DisallowHeapAllocation no_allocation;
   17903      753104 :   RegExpKey key(src, flags);
   17904      753104 :   int entry = FindEntry(isolate, &key);
   17905     1338366 :   if (entry == kNotFound) return isolate->factory()->undefined_value();
   17906      335684 :   return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
   17907             : }
   17908             : 
   17909      140120 : Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
   17910             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   17911             :     Handle<Context> native_context, LanguageMode language_mode,
   17912             :     Handle<SharedFunctionInfo> value) {
   17913             :   Isolate* isolate = native_context->GetIsolate();
   17914             :   // We use the empty function SFI as part of the key. Although the
   17915             :   // empty_function is native context dependent, the SFI is de-duped on
   17916             :   // snapshot builds by the PartialSnapshotCache, and so this does not prevent
   17917             :   // reuse of scripts in the compilation cache across native contexts.
   17918      280240 :   Handle<SharedFunctionInfo> shared(native_context->empty_function()->shared(),
   17919      280240 :                                     isolate);
   17920      140120 :   src = String::Flatten(isolate, src);
   17921      140120 :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17922      140120 :   Handle<Object> k = key.AsHandle(isolate);
   17923      140120 :   cache = EnsureCapacity(isolate, cache, 1);
   17924      280240 :   int entry = cache->FindInsertionEntry(key.Hash());
   17925      140120 :   cache->set(EntryToIndex(entry), *k);
   17926      280240 :   cache->set(EntryToIndex(entry) + 1, *value);
   17927      140120 :   cache->ElementAdded();
   17928      140120 :   return cache;
   17929             : }
   17930             : 
   17931     1187312 : Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
   17932             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   17933             :     Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
   17934             :     Handle<Context> native_context, Handle<FeedbackCell> feedback_cell,
   17935             :     int position) {
   17936             :   Isolate* isolate = native_context->GetIsolate();
   17937     1187312 :   src = String::Flatten(isolate, src);
   17938     1187312 :   StringSharedKey key(src, outer_info, value->language_mode(), position);
   17939             :   {
   17940     1187312 :     Handle<Object> k = key.AsHandle(isolate);
   17941     1187312 :     int entry = cache->FindEntry(isolate, &key);
   17942     1187312 :     if (entry != kNotFound) {
   17943      559169 :       cache->set(EntryToIndex(entry), *k);
   17944     1118338 :       cache->set(EntryToIndex(entry) + 1, *value);
   17945             :       // AddToFeedbackCellsMap may allocate a new sub-array to live in the
   17946             :       // entry, but it won't change the cache array. Therefore EntryToIndex
   17947             :       // and entry remains correct.
   17948             :       AddToFeedbackCellsMap(cache, EntryToIndex(entry) + 2, native_context,
   17949      559169 :                             feedback_cell);
   17950      559169 :       return cache;
   17951             :     }
   17952             :   }
   17953             : 
   17954      628143 :   cache = EnsureCapacity(isolate, cache, 1);
   17955     1256286 :   int entry = cache->FindInsertionEntry(key.Hash());
   17956             :   Handle<Object> k =
   17957      628143 :       isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
   17958      628143 :   cache->set(EntryToIndex(entry), *k);
   17959             :   cache->set(EntryToIndex(entry) + 1, Smi::FromInt(kHashGenerations));
   17960      628143 :   cache->ElementAdded();
   17961      628143 :   return cache;
   17962             : }
   17963             : 
   17964      290076 : Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
   17965             :     Isolate* isolate, Handle<CompilationCacheTable> cache, Handle<String> src,
   17966             :     JSRegExp::Flags flags, Handle<FixedArray> value) {
   17967      290076 :   RegExpKey key(src, flags);
   17968      290076 :   cache = EnsureCapacity(isolate, cache, 1);
   17969      580152 :   int entry = cache->FindInsertionEntry(key.Hash());
   17970             :   // We store the value in the key slot, and compare the search key
   17971             :   // to the stored value with a custon IsMatch function during lookups.
   17972      580152 :   cache->set(EntryToIndex(entry), *value);
   17973      580152 :   cache->set(EntryToIndex(entry) + 1, *value);
   17974      290076 :   cache->ElementAdded();
   17975      290076 :   return cache;
   17976             : }
   17977             : 
   17978             : 
   17979       76391 : void CompilationCacheTable::Age() {
   17980             :   DisallowHeapAllocation no_allocation;
   17981      152782 :   Object the_hole_value = GetReadOnlyRoots().the_hole_value();
   17982    12336526 :   for (int entry = 0, size = Capacity(); entry < size; entry++) {
   17983             :     int entry_index = EntryToIndex(entry);
   17984    12183744 :     int value_index = entry_index + 1;
   17985             : 
   17986    24367488 :     if (get(entry_index)->IsNumber()) {
   17987             :       Smi count = Smi::cast(get(value_index));
   17988      967970 :       count = Smi::FromInt(count->value() - 1);
   17989      967970 :       if (count->value() == 0) {
   17990             :         NoWriteBarrierSet(*this, entry_index, the_hole_value);
   17991             :         NoWriteBarrierSet(*this, value_index, the_hole_value);
   17992       75420 :         ElementRemoved();
   17993             :       } else {
   17994             :         NoWriteBarrierSet(*this, value_index, count);
   17995             :       }
   17996    22431548 :     } else if (get(entry_index)->IsFixedArray()) {
   17997      393236 :       SharedFunctionInfo info = SharedFunctionInfo::cast(get(value_index));
   17998      786472 :       if (info->IsInterpreted() && info->GetBytecodeArray()->IsOld()) {
   17999       76845 :         for (int i = 0; i < kEntrySize; i++) {
   18000       76845 :           NoWriteBarrierSet(*this, entry_index + i, the_hole_value);
   18001             :         }
   18002       25615 :         ElementRemoved();
   18003             :       }
   18004             :     }
   18005             :   }
   18006       76391 : }
   18007             : 
   18008         804 : void CompilationCacheTable::Remove(Object value) {
   18009             :   DisallowHeapAllocation no_allocation;
   18010        1608 :   Object the_hole_value = GetReadOnlyRoots().the_hole_value();
   18011      104520 :   for (int entry = 0, size = Capacity(); entry < size; entry++) {
   18012             :     int entry_index = EntryToIndex(entry);
   18013      102912 :     int value_index = entry_index + 1;
   18014      102912 :     if (get(value_index) == value) {
   18015         426 :       for (int i = 0; i < kEntrySize; i++) {
   18016         426 :         NoWriteBarrierSet(*this, entry_index + i, the_hole_value);
   18017             :       }
   18018         142 :       ElementRemoved();
   18019             :     }
   18020             :   }
   18021         804 :   return;
   18022             : }
   18023             : 
   18024             : template <typename Derived, typename Shape>
   18025      780554 : Handle<Derived> BaseNameDictionary<Derived, Shape>::New(
   18026             :     Isolate* isolate, int at_least_space_for, PretenureFlag pretenure,
   18027             :     MinimumCapacity capacity_option) {
   18028             :   DCHECK_LE(0, at_least_space_for);
   18029             :   Handle<Derived> dict = Dictionary<Derived, Shape>::New(
   18030      780554 :       isolate, at_least_space_for, pretenure, capacity_option);
   18031             :   dict->SetHash(PropertyArray::kNoHashSentinel);
   18032             :   dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
   18033      780559 :   return dict;
   18034             : }
   18035             : 
   18036             : template <typename Derived, typename Shape>
   18037    14210588 : Handle<Derived> BaseNameDictionary<Derived, Shape>::EnsureCapacity(
   18038             :     Isolate* isolate, Handle<Derived> dictionary, int n) {
   18039             :   // Check whether there are enough enumeration indices to add n elements.
   18040    28421172 :   if (!PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) {
   18041             :     // If not, we generate new indices for the properties.
   18042           0 :     int length = dictionary->NumberOfElements();
   18043             : 
   18044           0 :     Handle<FixedArray> iteration_order = IterationIndices(isolate, dictionary);
   18045             :     DCHECK_EQ(length, iteration_order->length());
   18046             : 
   18047             :     // Iterate over the dictionary using the enumeration order and update
   18048             :     // the dictionary with new enumeration indices.
   18049           0 :     for (int i = 0; i < length; i++) {
   18050           0 :       int index = Smi::ToInt(iteration_order->get(i));
   18051             :       DCHECK(dictionary->IsKey(dictionary->GetReadOnlyRoots(),
   18052             :                                dictionary->KeyAt(index)));
   18053             : 
   18054           0 :       int enum_index = PropertyDetails::kInitialIndex + i;
   18055             : 
   18056           0 :       PropertyDetails details = dictionary->DetailsAt(index);
   18057           0 :       PropertyDetails new_details = details.set_index(enum_index);
   18058           0 :       dictionary->DetailsAtPut(isolate, index, new_details);
   18059             :     }
   18060             : 
   18061             :     // Set the next enumeration index.
   18062           0 :     dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex +
   18063             :                                         length);
   18064             :   }
   18065    14210586 :   return HashTable<Derived, Shape>::EnsureCapacity(isolate, dictionary, n);
   18066             : }
   18067             : 
   18068             : template <typename Derived, typename Shape>
   18069       47172 : Handle<Derived> Dictionary<Derived, Shape>::DeleteEntry(
   18070             :     Isolate* isolate, Handle<Derived> dictionary, int entry) {
   18071             :   DCHECK(Shape::kEntrySize != 3 ||
   18072             :          dictionary->DetailsAt(entry).IsConfigurable());
   18073       47172 :   dictionary->ClearEntry(isolate, entry);
   18074       47172 :   dictionary->ElementRemoved();
   18075       47172 :   return Shrink(isolate, dictionary);
   18076             : }
   18077             : 
   18078             : template <typename Derived, typename Shape>
   18079      491422 : Handle<Derived> Dictionary<Derived, Shape>::AtPut(Isolate* isolate,
   18080             :                                                   Handle<Derived> dictionary,
   18081             :                                                   Key key, Handle<Object> value,
   18082             :                                                   PropertyDetails details) {
   18083      491422 :   int entry = dictionary->FindEntry(isolate, key);
   18084             : 
   18085             :   // If the entry is present set the value;
   18086      491422 :   if (entry == Dictionary::kNotFound) {
   18087      489002 :     return Derived::Add(isolate, dictionary, key, value, details);
   18088             :   }
   18089             : 
   18090             :   // We don't need to copy over the enumeration index.
   18091        4840 :   dictionary->ValueAtPut(entry, *value);
   18092        2360 :   if (Shape::kEntrySize == 3) dictionary->DetailsAtPut(isolate, entry, details);
   18093        2420 :   return dictionary;
   18094             : }
   18095             : 
   18096             : template <typename Derived, typename Shape>
   18097             : Handle<Derived>
   18098     5974452 : BaseNameDictionary<Derived, Shape>::AddNoUpdateNextEnumerationIndex(
   18099             :     Isolate* isolate, Handle<Derived> dictionary, Key key, Handle<Object> value,
   18100             :     PropertyDetails details, int* entry_out) {
   18101             :   // Insert element at empty or deleted entry
   18102             :   return Dictionary<Derived, Shape>::Add(isolate, dictionary, key, value,
   18103    14210576 :                                          details, entry_out);
   18104             : }
   18105             : 
   18106             : // GCC workaround: Explicitly instantiate template method for NameDictionary
   18107             : // to avoid "undefined reference" issues during linking.
   18108             : template Handle<NameDictionary>
   18109             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::
   18110             :     AddNoUpdateNextEnumerationIndex(Isolate* isolate, Handle<NameDictionary>,
   18111             :                                     Handle<Name>, Handle<Object>,
   18112             :                                     PropertyDetails, int*);
   18113             : 
   18114             : template <typename Derived, typename Shape>
   18115    14174865 : Handle<Derived> BaseNameDictionary<Derived, Shape>::Add(
   18116             :     Isolate* isolate, Handle<Derived> dictionary, Key key, Handle<Object> value,
   18117             :     PropertyDetails details, int* entry_out) {
   18118             :   // Insert element at empty or deleted entry
   18119             :   DCHECK_EQ(0, details.dictionary_index());
   18120             :   // Assign an enumeration index to the property and update
   18121             :   // SetNextEnumerationIndex.
   18122    14174865 :   int index = dictionary->NextEnumerationIndex();
   18123             :   details = details.set_index(index);
   18124     5938758 :   dictionary = AddNoUpdateNextEnumerationIndex(isolate, dictionary, key, value,
   18125             :                                                details, entry_out);
   18126             :   // Update enumeration index here in order to avoid potential modification of
   18127             :   // the canonical empty dictionary which lives in read only space.
   18128    14174893 :   dictionary->SetNextEnumerationIndex(index + 1);
   18129    14174893 :   return dictionary;
   18130             : }
   18131             : 
   18132             : template <typename Derived, typename Shape>
   18133    18064860 : Handle<Derived> Dictionary<Derived, Shape>::Add(Isolate* isolate,
   18134             :                                                 Handle<Derived> dictionary,
   18135             :                                                 Key key, Handle<Object> value,
   18136             :                                                 PropertyDetails details,
   18137             :                                                 int* entry_out) {
   18138    18064860 :   uint32_t hash = Shape::Hash(isolate, key);
   18139             :   // Valdate key is absent.
   18140             :   SLOW_DCHECK((dictionary->FindEntry(isolate, key) == Dictionary::kNotFound));
   18141             :   // Check whether the dictionary should be extended.
   18142    18064869 :   dictionary = Derived::EnsureCapacity(isolate, dictionary, 1);
   18143             : 
   18144             :   // Compute the key object.
   18145             :   Handle<Object> k = Shape::AsHandle(isolate, key);
   18146             : 
   18147    18064875 :   uint32_t entry = dictionary->FindInsertionEntry(hash);
   18148    36129732 :   dictionary->SetEntry(isolate, entry, *k, *value, details);
   18149             :   DCHECK(dictionary->KeyAt(entry)->IsNumber() ||
   18150             :          Shape::Unwrap(dictionary->KeyAt(entry))->IsUniqueName());
   18151    18064872 :   dictionary->ElementAdded();
   18152    18064873 :   if (entry_out) *entry_out = entry;
   18153    18064873 :   return dictionary;
   18154             : }
   18155             : 
   18156             : // static
   18157       85337 : Handle<SimpleNumberDictionary> SimpleNumberDictionary::Set(
   18158             :     Isolate* isolate, Handle<SimpleNumberDictionary> dictionary, uint32_t key,
   18159             :     Handle<Object> value) {
   18160       85337 :   return AtPut(isolate, dictionary, key, value, PropertyDetails::Empty());
   18161             : }
   18162             : 
   18163           0 : bool NumberDictionary::HasComplexElements() {
   18164           0 :   if (!requires_slow_elements()) return false;
   18165           0 :   ReadOnlyRoots roots = GetReadOnlyRoots();
   18166           0 :   int capacity = this->Capacity();
   18167           0 :   for (int i = 0; i < capacity; i++) {
   18168           0 :     Object k;
   18169           0 :     if (!this->ToKey(roots, i, &k)) continue;
   18170           0 :     PropertyDetails details = this->DetailsAt(i);
   18171           0 :     if (details.kind() == kAccessor) return true;
   18172             :     PropertyAttributes attr = details.attributes();
   18173           0 :     if (attr & ALL_ATTRIBUTES_MASK) return true;
   18174             :   }
   18175             :   return false;
   18176             : }
   18177             : 
   18178     1481387 : void NumberDictionary::UpdateMaxNumberKey(uint32_t key,
   18179             :                                           Handle<JSObject> dictionary_holder) {
   18180             :   DisallowHeapAllocation no_allocation;
   18181             :   // If the dictionary requires slow elements an element has already
   18182             :   // been added at a high index.
   18183     1528914 :   if (requires_slow_elements()) return;
   18184             :   // Check if this index is high enough that we should require slow
   18185             :   // elements.
   18186     1435561 :   if (key > kRequiresSlowElementsLimit) {
   18187        1701 :     if (!dictionary_holder.is_null()) {
   18188        1449 :       dictionary_holder->RequireSlowElements(*this);
   18189             :     }
   18190             :     set_requires_slow_elements();
   18191             :     return;
   18192             :   }
   18193             :   // Update max key value.
   18194     1433860 :   Object max_index_object = get(kMaxNumberKeyIndex);
   18195     1433860 :   if (!max_index_object->IsSmi() || max_number_key() < key) {
   18196             :     FixedArray::set(kMaxNumberKeyIndex,
   18197     1146661 :                     Smi::FromInt(key << kRequiresSlowElementsTagSize));
   18198             :   }
   18199             : }
   18200             : 
   18201      406085 : Handle<NumberDictionary> NumberDictionary::Set(
   18202             :     Isolate* isolate, Handle<NumberDictionary> dictionary, uint32_t key,
   18203             :     Handle<Object> value, Handle<JSObject> dictionary_holder,
   18204             :     PropertyDetails details) {
   18205      406085 :   dictionary->UpdateMaxNumberKey(key, dictionary_holder);
   18206      406085 :   return AtPut(isolate, dictionary, key, value, details);
   18207             : }
   18208             : 
   18209          36 : void NumberDictionary::CopyValuesTo(FixedArray elements) {
   18210          36 :   ReadOnlyRoots roots = GetReadOnlyRoots();
   18211             :   int pos = 0;
   18212          36 :   int capacity = this->Capacity();
   18213             :   DisallowHeapAllocation no_gc;
   18214             :   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
   18215         612 :   for (int i = 0; i < capacity; i++) {
   18216         576 :     Object k;
   18217         576 :     if (this->ToKey(roots, i, &k)) {
   18218         270 :       elements->set(pos++, this->ValueAt(i), mode);
   18219             :     }
   18220             :   }
   18221             :   DCHECK_EQ(pos, elements->length());
   18222          36 : }
   18223             : 
   18224             : template <typename Derived, typename Shape>
   18225       43091 : int Dictionary<Derived, Shape>::NumberOfEnumerableProperties() {
   18226       43091 :   ReadOnlyRoots roots = this->GetReadOnlyRoots();
   18227       43091 :   int capacity = this->Capacity();
   18228             :   int result = 0;
   18229    14611039 :   for (int i = 0; i < capacity; i++) {
   18230    14567948 :     Object k;
   18231    22191343 :     if (!this->ToKey(roots, i, &k)) continue;
   18232     6981055 :     if (k->FilterKey(ENUMERABLE_STRINGS)) continue;
   18233     6944553 :     PropertyDetails details = this->DetailsAt(i);
   18234             :     PropertyAttributes attr = details.attributes();
   18235     6944553 :     if ((attr & ONLY_ENUMERABLE) == 0) result++;
   18236             :   }
   18237       43091 :   return result;
   18238             : }
   18239             : 
   18240             : 
   18241             : template <typename Dictionary>
   18242             : struct EnumIndexComparator {
   18243      492997 :   explicit EnumIndexComparator(Dictionary dict) : dict(dict) {}
   18244   119557023 :   bool operator()(Tagged_t a, Tagged_t b) {
   18245             :     // TODO(ishell): revisit the code below
   18246             :     STATIC_ASSERT(kTaggedSize == kSystemPointerSize);
   18247   119557023 :     PropertyDetails da(dict->DetailsAt(Smi(a).value()));
   18248   119557043 :     PropertyDetails db(dict->DetailsAt(Smi(b).value()));
   18249   119557043 :     return da.dictionary_index() < db.dictionary_index();
   18250             :   }
   18251             :   Dictionary dict;
   18252             : };
   18253             : 
   18254             : template <typename Derived, typename Shape>
   18255       42875 : void BaseNameDictionary<Derived, Shape>::CopyEnumKeysTo(
   18256             :     Isolate* isolate, Handle<Derived> dictionary, Handle<FixedArray> storage,
   18257             :     KeyCollectionMode mode, KeyAccumulator* accumulator) {
   18258             :   DCHECK_IMPLIES(mode != KeyCollectionMode::kOwnOnly, accumulator != nullptr);
   18259             :   int length = storage->length();
   18260       42875 :   int capacity = dictionary->Capacity();
   18261             :   int properties = 0;
   18262             :   ReadOnlyRoots roots(isolate);
   18263    14037761 :   for (int i = 0; i < capacity; i++) {
   18264    14037323 :     Object key;
   18265    23281682 :     if (!dictionary->ToKey(roots, i, &key)) continue;
   18266             :     bool is_shadowing_key = false;
   18267     6911840 :     if (key->IsSymbol()) continue;
   18268     6875359 :     PropertyDetails details = dictionary->DetailsAt(i);
   18269     6875359 :     if (details.IsDontEnum()) {
   18270     2082395 :       if (mode == KeyCollectionMode::kIncludePrototypes) {
   18271             :         is_shadowing_key = true;
   18272             :       } else {
   18273             :         continue;
   18274             :       }
   18275             :     }
   18276     4805236 :     if (is_shadowing_key) {
   18277       12272 :       accumulator->AddShadowingKey(key);
   18278       12272 :       continue;
   18279             :     } else {
   18280             :       storage->set(properties, Smi::FromInt(i));
   18281             :     }
   18282     4792964 :     properties++;
   18283     4792964 :     if (mode == KeyCollectionMode::kOwnOnly && properties == length) break;
   18284             :   }
   18285             : 
   18286       42875 :   CHECK_EQ(length, properties);
   18287             :   DisallowHeapAllocation no_gc;
   18288       42875 :   Derived raw_dictionary = *dictionary;
   18289       42875 :   FixedArray raw_storage = *storage;
   18290             :   EnumIndexComparator<Derived> cmp(raw_dictionary);
   18291             :   // Use AtomicSlot wrapper to ensure that std::sort uses atomic load and
   18292             :   // store operations that are safe for concurrent marking.
   18293             :   AtomicSlot start(storage->GetFirstElementAddress());
   18294       42875 :   std::sort(start, start + length, cmp);
   18295     4835839 :   for (int i = 0; i < length; i++) {
   18296     4792964 :     int index = Smi::ToInt(raw_storage->get(i));
   18297     4792964 :     raw_storage->set(i, raw_dictionary->NameAt(index));
   18298             :   }
   18299       42875 : }
   18300             : 
   18301             : template <typename Derived, typename Shape>
   18302      426685 : Handle<FixedArray> BaseNameDictionary<Derived, Shape>::IterationIndices(
   18303             :     Isolate* isolate, Handle<Derived> dictionary) {
   18304      426685 :   int capacity = dictionary->Capacity();
   18305      426686 :   int length = dictionary->NumberOfElements();
   18306      426688 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
   18307             :   ReadOnlyRoots roots(isolate);
   18308             :   int array_size = 0;
   18309             :   {
   18310             :     DisallowHeapAllocation no_gc;
   18311      426679 :     Derived raw_dictionary = *dictionary;
   18312    16228252 :     for (int i = 0; i < capacity; i++) {
   18313    15801563 :       Object k;
   18314    24877767 :       if (!raw_dictionary->ToKey(roots, i, &k)) continue;
   18315     6725379 :       array->set(array_size++, Smi::FromInt(i));
   18316             :     }
   18317             : 
   18318             :     DCHECK_EQ(array_size, length);
   18319             : 
   18320             :     EnumIndexComparator<Derived> cmp(raw_dictionary);
   18321             :     // Use AtomicSlot wrapper to ensure that std::sort uses atomic load and
   18322             :     // store operations that are safe for concurrent marking.
   18323             :     AtomicSlot start(array->GetFirstElementAddress());
   18324      426689 :     std::sort(start, start + array_size, cmp);
   18325             :   }
   18326      426689 :   return FixedArray::ShrinkOrEmpty(isolate, array, array_size);
   18327             : }
   18328             : 
   18329             : template <typename Derived, typename Shape>
   18330       23433 : void BaseNameDictionary<Derived, Shape>::CollectKeysTo(
   18331             :     Handle<Derived> dictionary, KeyAccumulator* keys) {
   18332             :   Isolate* isolate = keys->isolate();
   18333             :   ReadOnlyRoots roots(isolate);
   18334       23433 :   int capacity = dictionary->Capacity();
   18335             :   Handle<FixedArray> array =
   18336       23433 :       isolate->factory()->NewFixedArray(dictionary->NumberOfElements());
   18337             :   int array_size = 0;
   18338             :   PropertyFilter filter = keys->filter();
   18339             :   {
   18340             :     DisallowHeapAllocation no_gc;
   18341       23433 :     Derived raw_dictionary = *dictionary;
   18342     6304905 :     for (int i = 0; i < capacity; i++) {
   18343     6281472 :       Object k;
   18344     9660993 :       if (!raw_dictionary->ToKey(roots, i, &k)) continue;
   18345     2917344 :       if (k->FilterKey(filter)) continue;
   18346     2902911 :       PropertyDetails details = raw_dictionary->DetailsAt(i);
   18347     2902911 :       if ((details.attributes() & filter) != 0) {
   18348         590 :         keys->AddShadowingKey(k);
   18349         590 :         continue;
   18350             :       }
   18351     2902321 :       if (filter & ONLY_ALL_CAN_READ) {
   18352         756 :         if (details.kind() != kAccessor) continue;
   18353          26 :         Object accessors = raw_dictionary->ValueAt(i);
   18354          26 :         if (!accessors->IsAccessorInfo()) continue;
   18355          26 :         if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
   18356             :       }
   18357     2901951 :       array->set(array_size++, Smi::FromInt(i));
   18358             :     }
   18359             : 
   18360             :     EnumIndexComparator<Derived> cmp(raw_dictionary);
   18361             :     // Use AtomicSlot wrapper to ensure that std::sort uses atomic load and
   18362             :     // store operations that are safe for concurrent marking.
   18363             :     AtomicSlot start(array->GetFirstElementAddress());
   18364       23433 :     std::sort(start, start + array_size, cmp);
   18365             :   }
   18366             : 
   18367             :   bool has_seen_symbol = false;
   18368     2925384 :   for (int i = 0; i < array_size; i++) {
   18369     2901951 :     int index = Smi::ToInt(array->get(i));
   18370     5736567 :     Object key = dictionary->NameAt(index);
   18371     2901951 :     if (key->IsSymbol()) {
   18372             :       has_seen_symbol = true;
   18373       18219 :       continue;
   18374             :     }
   18375     2883732 :     keys->AddKey(key, DO_NOT_CONVERT);
   18376             :   }
   18377       23433 :   if (has_seen_symbol) {
   18378     2288242 :     for (int i = 0; i < array_size; i++) {
   18379     2288242 :       int index = Smi::ToInt(array->get(i));
   18380     4575943 :       Object key = dictionary->NameAt(index);
   18381     4558265 :       if (!key->IsSymbol()) continue;
   18382       18219 :       keys->AddKey(key, DO_NOT_CONVERT);
   18383             :     }
   18384             :   }
   18385       23433 : }
   18386             : 
   18387             : // Backwards lookup (slow).
   18388             : template <typename Derived, typename Shape>
   18389          27 : Object Dictionary<Derived, Shape>::SlowReverseLookup(Object value) {
   18390          27 :   Derived dictionary = Derived::cast(*this);
   18391          27 :   ReadOnlyRoots roots = dictionary->GetReadOnlyRoots();
   18392          27 :   int capacity = dictionary->Capacity();
   18393        6939 :   for (int i = 0; i < capacity; i++) {
   18394        6912 :     Object k;
   18395       10224 :     if (!dictionary->ToKey(roots, i, &k)) continue;
   18396           0 :     Object e = dictionary->ValueAt(i);
   18397        3600 :     if (e == value) return k;
   18398             :   }
   18399          27 :   return roots.undefined_value();
   18400             : }
   18401             : 
   18402             : template <typename Derived, typename Shape>
   18403         352 : void ObjectHashTableBase<Derived, Shape>::FillEntriesWithHoles(
   18404             :     Handle<Derived> table) {
   18405             :   int length = table->length();
   18406       49144 :   for (int i = Derived::EntryToIndex(0); i < length; i++) {
   18407       48792 :     table->set_the_hole(i);
   18408             :   }
   18409         352 : }
   18410             : 
   18411             : template <typename Derived, typename Shape>
   18412       36477 : Object ObjectHashTableBase<Derived, Shape>::Lookup(ReadOnlyRoots roots,
   18413             :                                                    Handle<Object> key,
   18414             :                                                    int32_t hash) {
   18415             :   DisallowHeapAllocation no_gc;
   18416             :   DCHECK(this->IsKey(roots, *key));
   18417             : 
   18418       36477 :   int entry = this->FindEntry(roots, key, hash);
   18419       37230 :   if (entry == kNotFound) return roots.the_hole_value();
   18420       35724 :   return this->get(Derived::EntryToIndex(entry) + 1);
   18421             : }
   18422             : 
   18423             : template <typename Derived, typename Shape>
   18424       36980 : Object ObjectHashTableBase<Derived, Shape>::Lookup(Handle<Object> key) {
   18425             :   DisallowHeapAllocation no_gc;
   18426             : 
   18427       36980 :   ReadOnlyRoots roots = this->GetReadOnlyRoots();
   18428             :   DCHECK(this->IsKey(roots, *key));
   18429             : 
   18430             :   // If the object does not have an identity hash, it was never used as a key.
   18431       36980 :   Object hash = key->GetHash();
   18432       36980 :   if (hash->IsUndefined(roots)) {
   18433         510 :     return roots.the_hole_value();
   18434             :   }
   18435       36470 :   return Lookup(roots, key, Smi::ToInt(hash));
   18436             : }
   18437             : 
   18438             : template <typename Derived, typename Shape>
   18439           0 : Object ObjectHashTableBase<Derived, Shape>::Lookup(Handle<Object> key,
   18440             :                                                    int32_t hash) {
   18441           0 :   return Lookup(this->GetReadOnlyRoots(), key, hash);
   18442             : }
   18443             : 
   18444             : template <typename Derived, typename Shape>
   18445         205 : Object ObjectHashTableBase<Derived, Shape>::ValueAt(int entry) {
   18446         205 :   return this->get(EntryToValueIndex(entry));
   18447             : }
   18448             : 
   18449             : template <typename Derived, typename Shape>
   18450       32379 : Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Handle<Derived> table,
   18451             :                                                          Handle<Object> key,
   18452             :                                                          Handle<Object> value) {
   18453             :   Isolate* isolate = Heap::FromWritableHeapObject(*table)->isolate();
   18454             :   DCHECK(table->IsKey(ReadOnlyRoots(isolate), *key));
   18455             :   DCHECK(!value->IsTheHole(ReadOnlyRoots(isolate)));
   18456             : 
   18457             :   // Make sure the key object has an identity hash code.
   18458       64758 :   int32_t hash = key->GetOrCreateHash(isolate)->value();
   18459             : 
   18460             :   return ObjectHashTableBase<Derived, Shape>::Put(isolate, table, key, value,
   18461       32379 :                                                   hash);
   18462             : }
   18463             : 
   18464             : template <typename Derived, typename Shape>
   18465       33351 : Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Isolate* isolate,
   18466             :                                                          Handle<Derived> table,
   18467             :                                                          Handle<Object> key,
   18468             :                                                          Handle<Object> value,
   18469             :                                                          int32_t hash) {
   18470             :   ReadOnlyRoots roots(isolate);
   18471             :   DCHECK(table->IsKey(roots, *key));
   18472             :   DCHECK(!value->IsTheHole(roots));
   18473             : 
   18474       33351 :   int entry = table->FindEntry(roots, key, hash);
   18475             : 
   18476             :   // Key is already in table, just overwrite value.
   18477       33351 :   if (entry != kNotFound) {
   18478         882 :     table->set(Derived::EntryToIndex(entry) + 1, *value);
   18479         441 :     return table;
   18480             :   }
   18481             : 
   18482             :   // Rehash if more than 33% of the entries are deleted entries.
   18483             :   // TODO(jochen): Consider to shrink the fixed array in place.
   18484       65820 :   if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) {
   18485           5 :     table->Rehash(isolate);
   18486             :   }
   18487             :   // If we're out of luck, we didn't get a GC recently, and so rehashing
   18488             :   // isn't enough to avoid a crash.
   18489       32910 :   if (!table->HasSufficientCapacityToAdd(1)) {
   18490         452 :     int nof = table->NumberOfElements() + 1;
   18491         452 :     int capacity = ObjectHashTable::ComputeCapacity(nof * 2);
   18492         452 :     if (capacity > ObjectHashTable::kMaxCapacity) {
   18493           0 :       for (size_t i = 0; i < 2; ++i) {
   18494           0 :         isolate->heap()->CollectAllGarbage(
   18495           0 :             Heap::kNoGCFlags, GarbageCollectionReason::kFullHashtable);
   18496             :       }
   18497           0 :       table->Rehash(isolate);
   18498             :     }
   18499             :   }
   18500             : 
   18501             :   // Check whether the hash table should be extended.
   18502       32910 :   table = Derived::EnsureCapacity(isolate, table, 1);
   18503       98730 :   table->AddEntry(table->FindInsertionEntry(hash), *key, *value);
   18504       32910 :   return table;
   18505             : }
   18506             : 
   18507             : template <typename Derived, typename Shape>
   18508           5 : Handle<Derived> ObjectHashTableBase<Derived, Shape>::Remove(
   18509             :     Isolate* isolate, Handle<Derived> table, Handle<Object> key,
   18510             :     bool* was_present) {
   18511             :   DCHECK(table->IsKey(table->GetReadOnlyRoots(), *key));
   18512             : 
   18513           5 :   Object hash = key->GetHash();
   18514           5 :   if (hash->IsUndefined()) {
   18515           0 :     *was_present = false;
   18516           0 :     return table;
   18517             :   }
   18518             : 
   18519           5 :   return Remove(isolate, table, key, was_present, Smi::ToInt(hash));
   18520             : }
   18521             : 
   18522             : template <typename Derived, typename Shape>
   18523           5 : Handle<Derived> ObjectHashTableBase<Derived, Shape>::Remove(
   18524             :     Isolate* isolate, Handle<Derived> table, Handle<Object> key,
   18525             :     bool* was_present, int32_t hash) {
   18526           5 :   ReadOnlyRoots roots = table->GetReadOnlyRoots();
   18527             :   DCHECK(table->IsKey(roots, *key));
   18528             : 
   18529           5 :   int entry = table->FindEntry(roots, key, hash);
   18530           5 :   if (entry == kNotFound) {
   18531           0 :     *was_present = false;
   18532           0 :     return table;
   18533             :   }
   18534             : 
   18535           5 :   *was_present = true;
   18536           5 :   table->RemoveEntry(entry);
   18537           5 :   return Derived::Shrink(isolate, table);
   18538             : }
   18539             : 
   18540             : template <typename Derived, typename Shape>
   18541       32910 : void ObjectHashTableBase<Derived, Shape>::AddEntry(int entry, Object key,
   18542             :                                                    Object value) {
   18543       32910 :   this->set(Derived::EntryToIndex(entry), key);
   18544       32910 :   this->set(Derived::EntryToIndex(entry) + 1, value);
   18545       32910 :   this->ElementAdded();
   18546       32910 : }
   18547             : 
   18548             : template <typename Derived, typename Shape>
   18549          83 : void ObjectHashTableBase<Derived, Shape>::RemoveEntry(int entry) {
   18550          83 :   this->set_the_hole(Derived::EntryToIndex(entry));
   18551          83 :   this->set_the_hole(Derived::EntryToIndex(entry) + 1);
   18552          83 :   this->ElementRemoved();
   18553          83 : }
   18554             : 
   18555             : 
   18556       79595 : void JSSet::Initialize(Handle<JSSet> set, Isolate* isolate) {
   18557       79595 :   Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
   18558      159190 :   set->set_table(*table);
   18559       79595 : }
   18560             : 
   18561          42 : void JSSet::Clear(Isolate* isolate, Handle<JSSet> set) {
   18562          84 :   Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()), isolate);
   18563          42 :   table = OrderedHashSet::Clear(isolate, table);
   18564          84 :   set->set_table(*table);
   18565          42 : }
   18566             : 
   18567             : 
   18568          13 : void JSMap::Initialize(Handle<JSMap> map, Isolate* isolate) {
   18569          13 :   Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
   18570          26 :   map->set_table(*table);
   18571          13 : }
   18572             : 
   18573         212 : void JSMap::Clear(Isolate* isolate, Handle<JSMap> map) {
   18574         424 :   Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()), isolate);
   18575         212 :   table = OrderedHashMap::Clear(isolate, table);
   18576         424 :   map->set_table(*table);
   18577         212 : }
   18578             : 
   18579             : 
   18580       50089 : void JSWeakCollection::Initialize(Handle<JSWeakCollection> weak_collection,
   18581             :                                   Isolate* isolate) {
   18582       50089 :   Handle<EphemeronHashTable> table = EphemeronHashTable::New(isolate, 0);
   18583      100178 :   weak_collection->set_table(*table);
   18584       50089 : }
   18585             : 
   18586             : 
   18587         972 : void JSWeakCollection::Set(Handle<JSWeakCollection> weak_collection,
   18588             :                            Handle<Object> key, Handle<Object> value,
   18589             :                            int32_t hash) {
   18590             :   DCHECK(key->IsJSReceiver() || key->IsSymbol());
   18591             :   Handle<EphemeronHashTable> table(
   18592             :       EphemeronHashTable::cast(weak_collection->table()),
   18593        1944 :       weak_collection->GetIsolate());
   18594             :   DCHECK(table->IsKey(weak_collection->GetReadOnlyRoots(), *key));
   18595             :   Handle<EphemeronHashTable> new_table = EphemeronHashTable::Put(
   18596         972 :       weak_collection->GetIsolate(), table, key, value, hash);
   18597        1944 :   weak_collection->set_table(*new_table);
   18598         972 :   if (*table != *new_table) {
   18599             :     // Zap the old table since we didn't record slots for its elements.
   18600         352 :     EphemeronHashTable::FillEntriesWithHoles(table);
   18601             :   }
   18602         972 : }
   18603             : 
   18604             : 
   18605           0 : bool JSWeakCollection::Delete(Handle<JSWeakCollection> weak_collection,
   18606             :                               Handle<Object> key, int32_t hash) {
   18607             :   DCHECK(key->IsJSReceiver() || key->IsSymbol());
   18608             :   Handle<EphemeronHashTable> table(
   18609             :       EphemeronHashTable::cast(weak_collection->table()),
   18610           0 :       weak_collection->GetIsolate());
   18611             :   DCHECK(table->IsKey(weak_collection->GetReadOnlyRoots(), *key));
   18612           0 :   bool was_present = false;
   18613             :   Handle<EphemeronHashTable> new_table = EphemeronHashTable::Remove(
   18614           0 :       weak_collection->GetIsolate(), table, key, &was_present, hash);
   18615           0 :   weak_collection->set_table(*new_table);
   18616           0 :   if (*table != *new_table) {
   18617             :     // Zap the old table since we didn't record slots for its elements.
   18618           0 :     EphemeronHashTable::FillEntriesWithHoles(table);
   18619             :   }
   18620           0 :   return was_present;
   18621             : }
   18622             : 
   18623          98 : Handle<JSArray> JSWeakCollection::GetEntries(Handle<JSWeakCollection> holder,
   18624             :                                              int max_entries) {
   18625             :   Isolate* isolate = holder->GetIsolate();
   18626             :   Handle<EphemeronHashTable> table(EphemeronHashTable::cast(holder->table()),
   18627         196 :                                    isolate);
   18628          98 :   if (max_entries == 0 || max_entries > table->NumberOfElements()) {
   18629          98 :     max_entries = table->NumberOfElements();
   18630             :   }
   18631         196 :   int values_per_entry = holder->IsJSWeakMap() ? 2 : 1;
   18632             :   Handle<FixedArray> entries =
   18633          98 :       isolate->factory()->NewFixedArray(max_entries * values_per_entry);
   18634             :   // Recompute max_values because GC could have removed elements from the table.
   18635          98 :   if (max_entries > table->NumberOfElements()) {
   18636           0 :     max_entries = table->NumberOfElements();
   18637             :   }
   18638             : 
   18639             :   {
   18640             :     DisallowHeapAllocation no_gc;
   18641             :     ReadOnlyRoots roots = ReadOnlyRoots(isolate);
   18642             :     int count = 0;
   18643         504 :     for (int i = 0;
   18644         413 :          count / values_per_entry < max_entries && i < table->Capacity(); i++) {
   18645         105 :       Object key;
   18646         105 :       if (table->ToKey(roots, i, &key)) {
   18647         100 :         entries->set(count++, key);
   18648          50 :         if (values_per_entry > 1) {
   18649          25 :           Object value = table->Lookup(handle(key, isolate));
   18650          50 :           entries->set(count++, value);
   18651             :         }
   18652             :       }
   18653             :     }
   18654             :     DCHECK_EQ(max_entries * values_per_entry, count);
   18655             :   }
   18656          98 :   return isolate->factory()->NewJSArrayWithElements(entries);
   18657             : }
   18658             : 
   18659             : // static
   18660      148924 : MaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor,
   18661             :                                 Handle<JSReceiver> new_target, double tv) {
   18662             :   Isolate* const isolate = constructor->GetIsolate();
   18663             :   Handle<JSObject> result;
   18664      297848 :   ASSIGN_RETURN_ON_EXCEPTION(
   18665             :       isolate, result,
   18666             :       JSObject::New(constructor, new_target, Handle<AllocationSite>::null()),
   18667             :       JSDate);
   18668      148924 :   if (-DateCache::kMaxTimeInMs <= tv && tv <= DateCache::kMaxTimeInMs) {
   18669      148429 :     tv = DoubleToInteger(tv) + 0.0;
   18670             :   } else {
   18671             :     tv = std::numeric_limits<double>::quiet_NaN();
   18672             :   }
   18673      148924 :   Handle<Object> value = isolate->factory()->NewNumber(tv);
   18674      446772 :   Handle<JSDate>::cast(result)->SetValue(*value, std::isnan(tv));
   18675      148924 :   return Handle<JSDate>::cast(result);
   18676             : }
   18677             : 
   18678             : 
   18679             : // static
   18680      144393 : double JSDate::CurrentTimeValue(Isolate* isolate) {
   18681      144393 :   if (FLAG_log_internal_timer_events) LOG(isolate, CurrentTimeEvent());
   18682             : 
   18683             :   // According to ECMA-262, section 15.9.1, page 117, the precision of
   18684             :   // the number in a Date object representing a particular instant in
   18685             :   // time is milliseconds. Therefore, we floor the result of getting
   18686             :   // the OS time.
   18687      288786 :   return Floor(V8::GetCurrentPlatform()->CurrentClockTimeMillis());
   18688             : }
   18689             : 
   18690             : 
   18691             : // static
   18692       11142 : Address JSDate::GetField(Address raw_object, Address smi_index) {
   18693             :   Object object(raw_object);
   18694             :   Smi index(smi_index);
   18695             :   return JSDate::cast(object)
   18696       33426 :       ->DoGetField(static_cast<FieldIndex>(index->value()))
   18697       33426 :       ->ptr();
   18698             : }
   18699             : 
   18700       11142 : Object JSDate::DoGetField(FieldIndex index) {
   18701             :   DCHECK_NE(index, kDateValue);
   18702             : 
   18703       11142 :   DateCache* date_cache = GetIsolate()->date_cache();
   18704             : 
   18705       11142 :   if (index < kFirstUncachedField) {
   18706        5427 :     Object stamp = cache_stamp();
   18707       10854 :     if (stamp != date_cache->stamp() && stamp->IsSmi()) {
   18708             :       // Since the stamp is not NaN, the value is also not NaN.
   18709             :       int64_t local_time_ms =
   18710         756 :           date_cache->ToLocal(static_cast<int64_t>(value()->Number()));
   18711         378 :       SetCachedFields(local_time_ms, date_cache);
   18712             :     }
   18713        5427 :     switch (index) {
   18714         891 :       case kYear: return year();
   18715         243 :       case kMonth: return month();
   18716          72 :       case kDay: return day();
   18717           0 :       case kWeekday: return weekday();
   18718        3150 :       case kHour: return hour();
   18719         846 :       case kMinute: return min();
   18720         225 :       case kSecond: return sec();
   18721           0 :       default: UNREACHABLE();
   18722             :     }
   18723             :   }
   18724             : 
   18725        5715 :   if (index >= kFirstUTCField) {
   18726        5553 :     return GetUTCField(index, value()->Number(), date_cache);
   18727             :   }
   18728             : 
   18729         162 :   double time = value()->Number();
   18730         216 :   if (std::isnan(time)) return GetReadOnlyRoots().nan_value();
   18731             : 
   18732         108 :   int64_t local_time_ms = date_cache->ToLocal(static_cast<int64_t>(time));
   18733             :   int days = DateCache::DaysFromTime(local_time_ms);
   18734             : 
   18735         108 :   if (index == kDays) return Smi::FromInt(days);
   18736             : 
   18737             :   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
   18738         216 :   if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000);
   18739             :   DCHECK_EQ(index, kTimeInDay);
   18740           0 :   return Smi::FromInt(time_in_day_ms);
   18741             : }
   18742             : 
   18743        5553 : Object JSDate::GetUTCField(FieldIndex index, double value,
   18744             :                            DateCache* date_cache) {
   18745             :   DCHECK_GE(index, kFirstUTCField);
   18746             : 
   18747       10656 :   if (std::isnan(value)) return GetReadOnlyRoots().nan_value();
   18748             : 
   18749         450 :   int64_t time_ms = static_cast<int64_t>(value);
   18750             : 
   18751         450 :   if (index == kTimezoneOffset) {
   18752         126 :     GetIsolate()->CountUsage(v8::Isolate::kDateGetTimezoneOffset);
   18753         126 :     return Smi::FromInt(date_cache->TimezoneOffset(time_ms));
   18754             :   }
   18755             : 
   18756             :   int days = DateCache::DaysFromTime(time_ms);
   18757             : 
   18758         333 :   if (index == kWeekdayUTC) return Smi::FromInt(date_cache->Weekday(days));
   18759             : 
   18760         315 :   if (index <= kDayUTC) {
   18761             :     int year, month, day;
   18762         117 :     date_cache->YearMonthDayFromDays(days, &year, &month, &day);
   18763         153 :     if (index == kYearUTC) return Smi::FromInt(year);
   18764         117 :     if (index == kMonthUTC) return Smi::FromInt(month);
   18765             :     DCHECK_EQ(index, kDayUTC);
   18766          90 :     return Smi::FromInt(day);
   18767             :   }
   18768             : 
   18769             :   int time_in_day_ms = DateCache::TimeInDay(time_ms, days);
   18770         198 :   switch (index) {
   18771         180 :     case kHourUTC: return Smi::FromInt(time_in_day_ms / (60 * 60 * 1000));
   18772          90 :     case kMinuteUTC: return Smi::FromInt((time_in_day_ms / (60 * 1000)) % 60);
   18773          72 :     case kSecondUTC: return Smi::FromInt((time_in_day_ms / 1000) % 60);
   18774          54 :     case kMillisecondUTC: return Smi::FromInt(time_in_day_ms % 1000);
   18775           0 :     case kDaysUTC: return Smi::FromInt(days);
   18776           0 :     case kTimeInDayUTC: return Smi::FromInt(time_in_day_ms);
   18777           0 :     default: UNREACHABLE();
   18778             :   }
   18779             : 
   18780             :   UNREACHABLE();
   18781             : }
   18782             : 
   18783             : // static
   18784       11151 : Handle<Object> JSDate::SetValue(Handle<JSDate> date, double v) {
   18785             :   Isolate* const isolate = date->GetIsolate();
   18786       11151 :   Handle<Object> value = isolate->factory()->NewNumber(v);
   18787             :   bool value_is_nan = std::isnan(v);
   18788       22302 :   date->SetValue(*value, value_is_nan);
   18789       11151 :   return value;
   18790             : }
   18791             : 
   18792      160075 : void JSDate::SetValue(Object value, bool is_value_nan) {
   18793      160075 :   set_value(value);
   18794      160075 :   if (is_value_nan) {
   18795       22320 :     HeapNumber nan = GetReadOnlyRoots().nan_value();
   18796       11160 :     set_cache_stamp(nan, SKIP_WRITE_BARRIER);
   18797       11160 :     set_year(nan, SKIP_WRITE_BARRIER);
   18798       11160 :     set_month(nan, SKIP_WRITE_BARRIER);
   18799       11160 :     set_day(nan, SKIP_WRITE_BARRIER);
   18800       11160 :     set_hour(nan, SKIP_WRITE_BARRIER);
   18801       11160 :     set_min(nan, SKIP_WRITE_BARRIER);
   18802       11160 :     set_sec(nan, SKIP_WRITE_BARRIER);
   18803       11160 :     set_weekday(nan, SKIP_WRITE_BARRIER);
   18804             :   } else {
   18805      148915 :     set_cache_stamp(Smi::FromInt(DateCache::kInvalidStamp), SKIP_WRITE_BARRIER);
   18806             :   }
   18807      160075 : }
   18808             : 
   18809         378 : void JSDate::SetCachedFields(int64_t local_time_ms, DateCache* date_cache) {
   18810             :   int days = DateCache::DaysFromTime(local_time_ms);
   18811             :   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
   18812             :   int year, month, day;
   18813         378 :   date_cache->YearMonthDayFromDays(days, &year, &month, &day);
   18814             :   int weekday = date_cache->Weekday(days);
   18815         378 :   int hour = time_in_day_ms / (60 * 60 * 1000);
   18816         378 :   int min = (time_in_day_ms / (60 * 1000)) % 60;
   18817         378 :   int sec = (time_in_day_ms / 1000) % 60;
   18818         378 :   set_cache_stamp(date_cache->stamp());
   18819         756 :   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
   18820         756 :   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
   18821         756 :   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
   18822         378 :   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
   18823         378 :   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
   18824         378 :   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
   18825         378 :   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
   18826         378 : }
   18827             : 
   18828        8410 : int JSMessageObject::GetLineNumber() const {
   18829        8410 :   if (start_position() == -1) return Message::kNoLineNumberInfo;
   18830             : 
   18831        8290 :   Handle<Script> the_script(script(), GetIsolate());
   18832             : 
   18833             :   Script::PositionInfo info;
   18834             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   18835        8290 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   18836        8290 :                                offset_flag)) {
   18837             :     return Message::kNoLineNumberInfo;
   18838             :   }
   18839             : 
   18840        8290 :   return info.line + 1;
   18841             : }
   18842             : 
   18843       13386 : int JSMessageObject::GetColumnNumber() const {
   18844       13386 :   if (start_position() == -1) return -1;
   18845             : 
   18846       13211 :   Handle<Script> the_script(script(), GetIsolate());
   18847             : 
   18848             :   Script::PositionInfo info;
   18849             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   18850       13211 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   18851       13211 :                                offset_flag)) {
   18852             :     return -1;
   18853             :   }
   18854             : 
   18855       13211 :   return info.column;  // Note: No '+1' in contrast to GetLineNumber.
   18856             : }
   18857             : 
   18858        5423 : Handle<String> JSMessageObject::GetSourceLine() const {
   18859             :   Isolate* isolate = GetIsolate();
   18860        5423 :   Handle<Script> the_script(script(), isolate);
   18861             : 
   18862        5423 :   if (the_script->type() == Script::TYPE_WASM) {
   18863             :     return isolate->factory()->empty_string();
   18864             :   }
   18865             : 
   18866             :   Script::PositionInfo info;
   18867             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   18868        5423 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   18869        5423 :                                offset_flag)) {
   18870             :     return isolate->factory()->empty_string();
   18871             :   }
   18872             : 
   18873       10846 :   Handle<String> src = handle(String::cast(the_script->source()), isolate);
   18874        5423 :   return isolate->factory()->NewSubString(src, info.line_start, info.line_end);
   18875             : }
   18876             : 
   18877       20000 : Handle<PropertyCell> PropertyCell::InvalidateEntry(
   18878             :     Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry) {
   18879             :   // Swap with a copy.
   18880       40000 :   Handle<PropertyCell> cell(dictionary->CellAt(entry), isolate);
   18881       40000 :   Handle<Name> name(cell->name(), isolate);
   18882       20000 :   Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell(name);
   18883       40000 :   new_cell->set_value(cell->value());
   18884       40000 :   dictionary->ValueAtPut(entry, *new_cell);
   18885       40000 :   bool is_the_hole = cell->value()->IsTheHole(isolate);
   18886             :   // Cell is officially mutable henceforth.
   18887       20000 :   PropertyDetails details = cell->property_details();
   18888             :   details = details.set_cell_type(is_the_hole ? PropertyCellType::kUninitialized
   18889       20000 :                                               : PropertyCellType::kMutable);
   18890       40000 :   new_cell->set_property_details(details);
   18891             :   // Old cell is ready for invalidation.
   18892       20000 :   if (is_the_hole) {
   18893       16596 :     cell->set_value(ReadOnlyRoots(isolate).undefined_value());
   18894             :   } else {
   18895       23404 :     cell->set_value(ReadOnlyRoots(isolate).the_hole_value());
   18896             :   }
   18897             :   details = details.set_cell_type(PropertyCellType::kInvalidated);
   18898       40000 :   cell->set_property_details(details);
   18899       40000 :   cell->dependent_code()->DeoptimizeDependentCodeGroup(
   18900       20000 :       isolate, DependentCode::kPropertyCellChangedGroup);
   18901       20000 :   return new_cell;
   18902             : }
   18903             : 
   18904             : 
   18905           0 : PropertyCellConstantType PropertyCell::GetConstantType() {
   18906           0 :   if (value()->IsSmi()) return PropertyCellConstantType::kSmi;
   18907           0 :   return PropertyCellConstantType::kStableMap;
   18908             : }
   18909             : 
   18910             : 
   18911     1085916 : static bool RemainsConstantType(Handle<PropertyCell> cell,
   18912             :                                 Handle<Object> value) {
   18913             :   // TODO(dcarney): double->smi and smi->double transition from kConstant
   18914     3978896 :   if (cell->value()->IsSmi() && value->IsSmi()) {
   18915             :     return true;
   18916      732922 :   } else if (cell->value()->IsHeapObject() && value->IsHeapObject()) {
   18917      363358 :     return HeapObject::cast(cell->value())->map() ==
   18918      354477 :                HeapObject::cast(*value)->map() &&
   18919      354477 :            HeapObject::cast(*value)->map()->is_stable();
   18920             :   }
   18921             :   return false;
   18922             : }
   18923             : 
   18924    12746102 : PropertyCellType PropertyCell::UpdatedType(Isolate* isolate,
   18925             :                                            Handle<PropertyCell> cell,
   18926             :                                            Handle<Object> value,
   18927             :                                            PropertyDetails details) {
   18928             :   PropertyCellType type = details.cell_type();
   18929             :   DCHECK(!value->IsTheHole(isolate));
   18930    25492207 :   if (cell->value()->IsTheHole(isolate)) {
   18931     8245930 :     switch (type) {
   18932             :       // Only allow a cell to transition once into constant state.
   18933             :       case PropertyCellType::kUninitialized:
   18934    16491859 :         if (value->IsUndefined(isolate)) return PropertyCellType::kUndefined;
   18935     6572991 :         return PropertyCellType::kConstant;
   18936             :       case PropertyCellType::kInvalidated:
   18937             :         return PropertyCellType::kMutable;
   18938             :       default:
   18939           0 :         UNREACHABLE();
   18940             :     }
   18941             :   }
   18942     4500174 :   switch (type) {
   18943             :     case PropertyCellType::kUndefined:
   18944             :       return PropertyCellType::kConstant;
   18945             :     case PropertyCellType::kConstant:
   18946     3172236 :       if (*value == cell->value()) return PropertyCellType::kConstant;
   18947             :       V8_FALLTHROUGH;
   18948             :     case PropertyCellType::kConstantType:
   18949     1085916 :       if (RemainsConstantType(cell, value)) {
   18950             :         return PropertyCellType::kConstantType;
   18951             :       }
   18952             :       V8_FALLTHROUGH;
   18953             :     case PropertyCellType::kMutable:
   18954             :       return PropertyCellType::kMutable;
   18955             :   }
   18956           0 :   UNREACHABLE();
   18957             : }
   18958             : 
   18959     4507990 : Handle<PropertyCell> PropertyCell::PrepareForValue(
   18960             :     Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry,
   18961             :     Handle<Object> value, PropertyDetails details) {
   18962             :   DCHECK(!value->IsTheHole(isolate));
   18963     9015980 :   Handle<PropertyCell> cell(dictionary->CellAt(entry), isolate);
   18964     4507990 :   const PropertyDetails original_details = cell->property_details();
   18965             :   // Data accesses could be cached in ics or optimized code.
   18966             :   bool invalidate =
   18967    13515282 :       (original_details.kind() == kData && details.kind() == kAccessor) ||
   18968     4499907 :       (!original_details.IsReadOnly() && details.IsReadOnly());
   18969             :   int index;
   18970             :   PropertyCellType old_type = original_details.cell_type();
   18971             :   // Preserve the enumeration index unless the property was deleted or never
   18972             :   // initialized.
   18973     9015980 :   if (cell->value()->IsTheHole(isolate)) {
   18974        7816 :     index = dictionary->NextEnumerationIndex();
   18975        7816 :     dictionary->SetNextEnumerationIndex(index + 1);
   18976             :   } else {
   18977             :     index = original_details.dictionary_index();
   18978             :   }
   18979             :   DCHECK_LT(0, index);
   18980             :   details = details.set_index(index);
   18981             : 
   18982             :   PropertyCellType new_type =
   18983     4507990 :       UpdatedType(isolate, cell, value, original_details);
   18984     4507990 :   if (invalidate) {
   18985        8143 :     cell = PropertyCell::InvalidateEntry(isolate, dictionary, entry);
   18986             :   }
   18987             : 
   18988             :   // Install new property details.
   18989             :   details = details.set_cell_type(new_type);
   18990     9015980 :   cell->set_property_details(details);
   18991             : 
   18992     4507990 :   if (new_type == PropertyCellType::kConstant ||
   18993             :       new_type == PropertyCellType::kConstantType) {
   18994             :     // Store the value now to ensure that the cell contains the constant or
   18995             :     // type information. Otherwise subsequent store operation will turn
   18996             :     // the cell to mutable.
   18997     4157403 :     cell->set_value(*value);
   18998             :   }
   18999             : 
   19000             :   // Deopt when transitioning from a constant type.
   19001     7424229 :   if (!invalidate && (old_type != new_type ||
   19002             :                       original_details.IsReadOnly() != details.IsReadOnly())) {
   19003     3167234 :     cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19004     1583617 :         isolate, DependentCode::kPropertyCellChangedGroup);
   19005             :   }
   19006     4507990 :   return cell;
   19007             : }
   19008             : 
   19009             : 
   19010             : // static
   19011        4888 : void PropertyCell::SetValueWithInvalidation(Isolate* isolate,
   19012             :                                             Handle<PropertyCell> cell,
   19013             :                                             Handle<Object> new_value) {
   19014        9776 :   if (cell->value() != *new_value) {
   19015        4888 :     cell->set_value(*new_value);
   19016        9776 :     cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19017        4888 :         isolate, DependentCode::kPropertyCellChangedGroup);
   19018             :   }
   19019        4888 : }
   19020             : 
   19021        1430 : int JSGeneratorObject::source_position() const {
   19022        1430 :   CHECK(is_suspended());
   19023             :   DCHECK(function()->shared()->HasBytecodeArray());
   19024             : 
   19025        1430 :   int code_offset = Smi::ToInt(input_or_debug_pos());
   19026             : 
   19027             :   // The stored bytecode offset is relative to a different base than what
   19028             :   // is used in the source position table, hence the subtraction.
   19029        1430 :   code_offset -= BytecodeArray::kHeaderSize - kHeapObjectTag;
   19030             :   AbstractCode code =
   19031        2860 :       AbstractCode::cast(function()->shared()->GetBytecodeArray());
   19032        1430 :   return code->SourcePosition(code_offset);
   19033             : }
   19034             : 
   19035             : // static
   19036        4707 : AccessCheckInfo AccessCheckInfo::Get(Isolate* isolate,
   19037             :                                      Handle<JSObject> receiver) {
   19038             :   DisallowHeapAllocation no_gc;
   19039             :   DCHECK(receiver->map()->is_access_check_needed());
   19040        4707 :   Object maybe_constructor = receiver->map()->GetConstructor();
   19041        4707 :   if (maybe_constructor->IsFunctionTemplateInfo()) {
   19042             :     Object data_obj =
   19043         145 :         FunctionTemplateInfo::cast(maybe_constructor)->GetAccessCheckInfo();
   19044         145 :     if (data_obj->IsUndefined(isolate)) return AccessCheckInfo();
   19045             :     return AccessCheckInfo::cast(data_obj);
   19046             :   }
   19047             :   // Might happen for a detached context.
   19048        4562 :   if (!maybe_constructor->IsJSFunction()) return AccessCheckInfo();
   19049        4537 :   JSFunction constructor = JSFunction::cast(maybe_constructor);
   19050             :   // Might happen for the debug context.
   19051        4537 :   if (!constructor->shared()->IsApiFunction()) return AccessCheckInfo();
   19052             : 
   19053             :   Object data_obj =
   19054        4113 :       constructor->shared()->get_api_func_data()->GetAccessCheckInfo();
   19055        4113 :   if (data_obj->IsUndefined(isolate)) return AccessCheckInfo();
   19056             : 
   19057             :   return AccessCheckInfo::cast(data_obj);
   19058             : }
   19059             : 
   19060        4128 : bool JSReceiver::HasProxyInPrototype(Isolate* isolate) {
   19061       17052 :   for (PrototypeIterator iter(isolate, *this, kStartAtReceiver,
   19062             :                               PrototypeIterator::END_AT_NULL);
   19063       12924 :        !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) {
   19064       25902 :     if (iter.GetCurrent()->IsJSProxy()) return true;
   19065             :   }
   19066        4101 :   return false;
   19067             : }
   19068             : 
   19069           0 : bool JSReceiver::HasComplexElements() {
   19070           0 :   if (IsJSProxy()) return true;
   19071           0 :   JSObject this_object = JSObject::cast(*this);
   19072           0 :   if (this_object->HasIndexedInterceptor()) {
   19073             :     return true;
   19074             :   }
   19075           0 :   if (!this_object->HasDictionaryElements()) return false;
   19076           0 :   return this_object->element_dictionary()->HasComplexElements();
   19077             : }
   19078             : 
   19079      350039 : MaybeHandle<Name> FunctionTemplateInfo::TryGetCachedPropertyName(
   19080             :     Isolate* isolate, Handle<Object> getter) {
   19081      700078 :   if (getter->IsFunctionTemplateInfo()) {
   19082             :     Handle<FunctionTemplateInfo> fti =
   19083      114254 :         Handle<FunctionTemplateInfo>::cast(getter);
   19084             :     // Check if the accessor uses a cached property.
   19085      228508 :     if (!fti->cached_property_name()->IsTheHole(isolate)) {
   19086         174 :       return handle(Name::cast(fti->cached_property_name()), isolate);
   19087             :     }
   19088             :   }
   19089      349952 :   return MaybeHandle<Name>();
   19090             : }
   19091             : 
   19092     4459142 : Address Smi::LexicographicCompare(Isolate* isolate, Smi x, Smi y) {
   19093             :   DisallowHeapAllocation no_allocation;
   19094     4459142 :   DisallowJavascriptExecution no_js(isolate);
   19095             : 
   19096     4459142 :   int x_value = Smi::ToInt(x);
   19097     4459142 :   int y_value = Smi::ToInt(y);
   19098             : 
   19099             :   // If the integers are equal so are the string representations.
   19100     4459142 :   if (x_value == y_value) return Smi::FromInt(0).ptr();
   19101             : 
   19102             :   // If one of the integers is zero the normal integer order is the
   19103             :   // same as the lexicographic order of the string representations.
   19104     4455120 :   if (x_value == 0 || y_value == 0) {
   19105        7764 :     return Smi::FromInt(x_value < y_value ? -1 : 1).ptr();
   19106             :   }
   19107             : 
   19108             :   // If only one of the integers is negative the negative number is
   19109             :   // smallest because the char code of '-' is less than the char code
   19110             :   // of any digit.  Otherwise, we make both values positive.
   19111             : 
   19112             :   // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
   19113             :   // architectures using 32-bit Smis.
   19114     4447356 :   uint32_t x_scaled = x_value;
   19115     4447356 :   uint32_t y_scaled = y_value;
   19116     4447356 :   if (x_value < 0 || y_value < 0) {
   19117     1974828 :     if (y_value >= 0) return Smi::FromInt(-1).ptr();
   19118     1315974 :     if (x_value >= 0) return Smi::FromInt(1).ptr();
   19119      657120 :     x_scaled = -x_value;
   19120      657120 :     y_scaled = -y_value;
   19121             :   }
   19122             : 
   19123             :   // clang-format off
   19124             :   static const uint32_t kPowersOf10[] = {
   19125             :       1,                 10,                100,         1000,
   19126             :       10 * 1000,         100 * 1000,        1000 * 1000, 10 * 1000 * 1000,
   19127             :       100 * 1000 * 1000, 1000 * 1000 * 1000};
   19128             :   // clang-format on
   19129             : 
   19130             :   // If the integers have the same number of decimal digits they can be
   19131             :   // compared directly as the numeric order is the same as the
   19132             :   // lexicographic order.  If one integer has fewer digits, it is scaled
   19133             :   // by some power of 10 to have the same number of digits as the longer
   19134             :   // integer.  If the scaled integers are equal it means the shorter
   19135             :   // integer comes first in the lexicographic order.
   19136             : 
   19137             :   // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
   19138     3129648 :   int x_log2 = 31 - base::bits::CountLeadingZeros(x_scaled);
   19139     3129648 :   int x_log10 = ((x_log2 + 1) * 1233) >> 12;
   19140     3129648 :   x_log10 -= x_scaled < kPowersOf10[x_log10];
   19141             : 
   19142     3129648 :   int y_log2 = 31 - base::bits::CountLeadingZeros(y_scaled);
   19143     3129648 :   int y_log10 = ((y_log2 + 1) * 1233) >> 12;
   19144     3129648 :   y_log10 -= y_scaled < kPowersOf10[y_log10];
   19145             : 
   19146             :   int tie = 0;
   19147             : 
   19148     3129648 :   if (x_log10 < y_log10) {
   19149             :     // X has fewer digits.  We would like to simply scale up X but that
   19150             :     // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
   19151             :     // be scaled up to 9_000_000_000. So we scale up by the next
   19152             :     // smallest power and scale down Y to drop one digit. It is OK to
   19153             :     // drop one digit from the longer integer since the final digit is
   19154             :     // past the length of the shorter integer.
   19155      585100 :     x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
   19156      585100 :     y_scaled /= 10;
   19157             :     tie = -1;
   19158     2544548 :   } else if (y_log10 < x_log10) {
   19159     1447453 :     y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
   19160     1447453 :     x_scaled /= 10;
   19161             :     tie = 1;
   19162             :   }
   19163             : 
   19164     3129648 :   if (x_scaled < y_scaled) return Smi::FromInt(-1).ptr();
   19165     1908040 :   if (x_scaled > y_scaled) return Smi::FromInt(1).ptr();
   19166     4459142 :   return Smi::FromInt(tie).ptr();
   19167             : }
   19168             : 
   19169             : // Force instantiation of template instances class.
   19170             : // Please note this list is compiler dependent.
   19171             : // Keep this at the end of this file
   19172             : 
   19173             : template class HashTable<StringTable, StringTableShape>;
   19174             : 
   19175             : template class HashTable<CompilationCacheTable, CompilationCacheShape>;
   19176             : 
   19177             : template class HashTable<ObjectHashTable, ObjectHashTableShape>;
   19178             : 
   19179             : template class HashTable<EphemeronHashTable, EphemeronHashTableShape>;
   19180             : 
   19181             : template class ObjectHashTableBase<ObjectHashTable, ObjectHashTableShape>;
   19182             : 
   19183             : template class ObjectHashTableBase<EphemeronHashTable, EphemeronHashTableShape>;
   19184             : 
   19185             : template class Dictionary<NameDictionary, NameDictionaryShape>;
   19186             : 
   19187             : template class Dictionary<GlobalDictionary, GlobalDictionaryShape>;
   19188             : 
   19189             : template class EXPORT_TEMPLATE_DEFINE(
   19190             :     V8_EXPORT_PRIVATE) HashTable<NumberDictionary, NumberDictionaryShape>;
   19191             : 
   19192             : template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
   19193             :     Dictionary<NumberDictionary, NumberDictionaryShape>;
   19194             : 
   19195             : template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
   19196             :     HashTable<SimpleNumberDictionary, SimpleNumberDictionaryShape>;
   19197             : 
   19198             : template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
   19199             :     Dictionary<SimpleNumberDictionary, SimpleNumberDictionaryShape>;
   19200             : 
   19201             : template Handle<NameDictionary>
   19202             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::New(
   19203             :     Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
   19204             : 
   19205             : template Handle<GlobalDictionary>
   19206             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::New(
   19207             :     Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
   19208             : 
   19209             : template Handle<NameDictionary>
   19210             : HashTable<NameDictionary, NameDictionaryShape>::New(Isolate*, int,
   19211             :                                                     PretenureFlag,
   19212             :                                                     MinimumCapacity);
   19213             : 
   19214             : template Handle<ObjectHashSet>
   19215             : HashTable<ObjectHashSet, ObjectHashSetShape>::New(Isolate*, int n,
   19216             :                                                   PretenureFlag,
   19217             :                                                   MinimumCapacity);
   19218             : 
   19219             : template Handle<NameDictionary>
   19220             : HashTable<NameDictionary, NameDictionaryShape>::Shrink(Isolate* isolate,
   19221             :                                                        Handle<NameDictionary>,
   19222             :                                                        int additionalCapacity);
   19223             : 
   19224             : template Handle<NameDictionary>
   19225             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::Add(
   19226             :     Isolate* isolate, Handle<NameDictionary>, Handle<Name>, Handle<Object>,
   19227             :     PropertyDetails, int*);
   19228             : 
   19229             : template Handle<GlobalDictionary>
   19230             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::Add(
   19231             :     Isolate* isolate, Handle<GlobalDictionary>, Handle<Name>, Handle<Object>,
   19232             :     PropertyDetails, int*);
   19233             : 
   19234             : template void HashTable<GlobalDictionary, GlobalDictionaryShape>::Rehash(
   19235             :     Isolate* isolate);
   19236             : 
   19237             : template Handle<NameDictionary>
   19238             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::EnsureCapacity(
   19239             :     Isolate* isolate, Handle<NameDictionary>, int);
   19240             : 
   19241             : template void
   19242             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::CopyEnumKeysTo(
   19243             :     Isolate* isolate, Handle<GlobalDictionary> dictionary,
   19244             :     Handle<FixedArray> storage, KeyCollectionMode mode,
   19245             :     KeyAccumulator* accumulator);
   19246             : 
   19247             : template void
   19248             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::CopyEnumKeysTo(
   19249             :     Isolate* isolate, Handle<NameDictionary> dictionary,
   19250             :     Handle<FixedArray> storage, KeyCollectionMode mode,
   19251             :     KeyAccumulator* accumulator);
   19252             : 
   19253             : template Handle<FixedArray>
   19254             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::IterationIndices(
   19255             :     Isolate* isolate, Handle<GlobalDictionary> dictionary);
   19256             : template void
   19257             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::CollectKeysTo(
   19258             :     Handle<GlobalDictionary> dictionary, KeyAccumulator* keys);
   19259             : 
   19260             : template Handle<FixedArray>
   19261             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::IterationIndices(
   19262             :     Isolate* isolate, Handle<NameDictionary> dictionary);
   19263             : template void
   19264             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::CollectKeysTo(
   19265             :     Handle<NameDictionary> dictionary, KeyAccumulator* keys);
   19266             : 
   19267         243 : void JSWeakFactory::Cleanup(Handle<JSWeakFactory> weak_factory,
   19268             :                             Isolate* isolate) {
   19269             :   // It's possible that the cleared_cells list is empty, since
   19270             :   // WeakCell.clear() was called on all its elements before this task ran. In
   19271             :   // that case, don't call the cleanup function.
   19272         486 :   if (!weak_factory->cleared_cells()->IsUndefined(isolate)) {
   19273             :     // Construct the iterator.
   19274             :     Handle<JSWeakFactoryCleanupIterator> iterator;
   19275             :     {
   19276             :       Handle<Map> cleanup_iterator_map(
   19277         540 :           isolate->native_context()->js_weak_factory_cleanup_iterator_map(),
   19278         180 :           isolate);
   19279             :       iterator = Handle<JSWeakFactoryCleanupIterator>::cast(
   19280             :           isolate->factory()->NewJSObjectFromMap(
   19281             :               cleanup_iterator_map, NOT_TENURED,
   19282         180 :               Handle<AllocationSite>::null()));
   19283         180 :       iterator->set_factory(*weak_factory);
   19284             :     }
   19285         360 :     Handle<Object> cleanup(weak_factory->cleanup(), isolate);
   19286             : 
   19287         180 :     v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
   19288             :     v8::Local<v8::Value> result;
   19289         180 :     MaybeHandle<Object> exception;
   19290             :     Handle<Object> args[] = {iterator};
   19291             :     bool has_pending_exception = !ToLocal<Value>(
   19292             :         Execution::TryCall(
   19293             :             isolate, cleanup,
   19294             :             handle(ReadOnlyRoots(isolate).undefined_value(), isolate), 1, args,
   19295             :             Execution::MessageHandling::kReport, &exception),
   19296         360 :         &result);
   19297             :     // TODO(marja): (spec): What if there's an exception?
   19298         180 :     USE(has_pending_exception);
   19299             : 
   19300             :     // TODO(marja): (spec): Should the iterator be invalidated after the
   19301             :     // function returns?
   19302             :   }
   19303         243 : }
   19304             : 
   19305             : }  // namespace internal
   19306      183867 : }  // namespace v8

Generated by: LCOV version 1.10