LCOV - code coverage report
Current view: top level - src - objects.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 5627 6430 87.5 %
Date: 2017-10-20 Functions: 775 890 87.1 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/objects.h"
       6             : 
       7             : #include <cmath>
       8             : #include <iomanip>
       9             : #include <memory>
      10             : #include <sstream>
      11             : #include <vector>
      12             : 
      13             : #include "src/objects-inl.h"
      14             : 
      15             : #include "src/accessors.h"
      16             : #include "src/allocation-site-scopes.h"
      17             : #include "src/api-arguments-inl.h"
      18             : #include "src/api-natives.h"
      19             : #include "src/api.h"
      20             : #include "src/arguments.h"
      21             : #include "src/ast/ast.h"
      22             : #include "src/ast/scopes.h"
      23             : #include "src/base/bits.h"
      24             : #include "src/base/utils/random-number-generator.h"
      25             : #include "src/bootstrapper.h"
      26             : #include "src/builtins/builtins.h"
      27             : #include "src/code-stubs.h"
      28             : #include "src/compilation-dependencies.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-evaluate.h"
      34             : #include "src/debug/debug.h"
      35             : #include "src/deoptimizer.h"
      36             : #include "src/elements.h"
      37             : #include "src/execution.h"
      38             : #include "src/field-index-inl.h"
      39             : #include "src/field-index.h"
      40             : #include "src/field-type.h"
      41             : #include "src/frames-inl.h"
      42             : #include "src/globals.h"
      43             : #include "src/ic/ic.h"
      44             : #include "src/identity-map.h"
      45             : #include "src/interpreter/bytecode-array-iterator.h"
      46             : #include "src/interpreter/bytecode-decoder.h"
      47             : #include "src/interpreter/interpreter.h"
      48             : #include "src/isolate-inl.h"
      49             : #include "src/keys.h"
      50             : #include "src/log.h"
      51             : #include "src/lookup.h"
      52             : #include "src/macro-assembler.h"
      53             : #include "src/map-updater.h"
      54             : #include "src/messages.h"
      55             : #include "src/objects-body-descriptors-inl.h"
      56             : #include "src/objects/bigint.h"
      57             : #include "src/objects/code-inl.h"
      58             : #include "src/objects/compilation-cache-inl.h"
      59             : #include "src/objects/debug-objects-inl.h"
      60             : #include "src/objects/frame-array-inl.h"
      61             : #include "src/objects/hash-table.h"
      62             : #include "src/objects/map.h"
      63             : #include "src/parsing/preparsed-scope-data.h"
      64             : #include "src/property-descriptor.h"
      65             : #include "src/prototype.h"
      66             : #include "src/regexp/jsregexp.h"
      67             : #include "src/safepoint-table.h"
      68             : #include "src/snapshot/code-serializer.h"
      69             : #include "src/source-position-table.h"
      70             : #include "src/string-builder.h"
      71             : #include "src/string-search.h"
      72             : #include "src/string-stream.h"
      73             : #include "src/unicode-cache-inl.h"
      74             : #include "src/utils-inl.h"
      75             : #include "src/wasm/wasm-objects.h"
      76             : #include "src/zone/zone.h"
      77             : 
      78             : #ifdef ENABLE_DISASSEMBLER
      79             : #include "src/disasm.h"
      80             : #include "src/disassembler.h"
      81             : #include "src/eh-frame.h"
      82             : #endif
      83             : 
      84             : namespace v8 {
      85             : namespace internal {
      86             : 
      87       17418 : std::ostream& operator<<(std::ostream& os, InstanceType instance_type) {
      88       17418 :   switch (instance_type) {
      89             : #define WRITE_TYPE(TYPE) \
      90             :   case TYPE:             \
      91             :     return os << #TYPE;
      92           0 :     INSTANCE_TYPE_LIST(WRITE_TYPE)
      93             : #undef WRITE_TYPE
      94             :   }
      95           0 :   UNREACHABLE();
      96             : }
      97             : 
      98     7118503 : Handle<FieldType> Object::OptimalType(Isolate* isolate,
      99             :                                       Representation representation) {
     100     7118503 :   if (representation.IsNone()) return FieldType::None(isolate);
     101     6813578 :   if (FLAG_track_field_types) {
     102     9988308 :     if (representation.IsHeapObject() && IsHeapObject()) {
     103             :       // We can track only JavaScript objects with stable maps.
     104             :       Handle<Map> map(HeapObject::cast(this)->map(), isolate);
     105     5933847 :       if (map->is_stable() && map->IsJSReceiverMap()) {
     106      986339 :         return FieldType::Class(map, isolate);
     107             :       }
     108             :     }
     109             :   }
     110     5827240 :   return FieldType::Any(isolate);
     111             : }
     112             : 
     113        6361 : MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
     114             :                                          Handle<Object> object,
     115             :                                          Handle<Context> native_context,
     116             :                                          const char* method_name) {
     117        6361 :   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
     118             :   Handle<JSFunction> constructor;
     119        6361 :   if (object->IsSmi()) {
     120         431 :     constructor = handle(native_context->number_function(), isolate);
     121             :   } else {
     122             :     int constructor_function_index =
     123             :         Handle<HeapObject>::cast(object)->map()->GetConstructorFunctionIndex();
     124        5930 :     if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
     125        1133 :       if (method_name != nullptr) {
     126        1434 :         THROW_NEW_ERROR(
     127             :             isolate,
     128             :             NewTypeError(
     129             :                 MessageTemplate::kCalledOnNullOrUndefined,
     130             :                 isolate->factory()->NewStringFromAsciiChecked(method_name)),
     131             :             JSReceiver);
     132             :       }
     133        1310 :       THROW_NEW_ERROR(isolate,
     134             :                       NewTypeError(MessageTemplate::kUndefinedOrNullToObject),
     135             :                       JSReceiver);
     136             :     }
     137             :     constructor = handle(
     138             :         JSFunction::cast(native_context->get(constructor_function_index)),
     139        4797 :         isolate);
     140             :   }
     141        5228 :   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
     142        5228 :   Handle<JSValue>::cast(result)->set_value(*object);
     143        5228 :   return result;
     144             : }
     145             : 
     146             : // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
     147             : // static
     148         371 : MaybeHandle<JSReceiver> Object::ConvertReceiver(Isolate* isolate,
     149             :                                                 Handle<Object> object) {
     150         371 :   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
     151         670 :   if (*object == isolate->heap()->null_value() ||
     152             :       object->IsUndefined(isolate)) {
     153         151 :     return isolate->global_proxy();
     154             :   }
     155         184 :   return Object::ToObject(isolate, object);
     156             : }
     157             : 
     158             : // static
     159     2348333 : MaybeHandle<Object> Object::ConvertToNumberOrNumeric(Isolate* isolate,
     160             :                                                      Handle<Object> input,
     161             :                                                      Conversion mode) {
     162             :   while (true) {
     163     2352241 :     if (input->IsNumber()) {
     164       15786 :       return input;
     165             :     }
     166     2336455 :     if (input->IsString()) {
     167        4614 :       return String::ToNumber(Handle<String>::cast(input));
     168             :     }
     169     2331841 :     if (input->IsOddball()) {
     170     2323623 :       return Oddball::ToNumber(Handle<Oddball>::cast(input));
     171             :     }
     172        8218 :     if (input->IsSymbol()) {
     173        7094 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber),
     174             :                       Object);
     175             :     }
     176        4671 :     if (input->IsBigInt()) {
     177         108 :       if (mode == Conversion::kToNumeric) return input;
     178             :       DCHECK_EQ(mode, Conversion::kToNumber);
     179         216 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kBigIntToNumber),
     180             :                       Object);
     181             :     }
     182        9126 :     ASSIGN_RETURN_ON_EXCEPTION(
     183             :         isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
     184             :                                                 ToPrimitiveHint::kNumber),
     185             :         Object);
     186             :   }
     187             : }
     188             : 
     189             : // static
     190       19540 : MaybeHandle<Object> Object::ConvertToInteger(Isolate* isolate,
     191             :                                              Handle<Object> input) {
     192       39080 :   ASSIGN_RETURN_ON_EXCEPTION(
     193             :       isolate, input,
     194             :       ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber), Object);
     195       19208 :   if (input->IsSmi()) return input;
     196       17244 :   return isolate->factory()->NewNumber(DoubleToInteger(input->Number()));
     197             : }
     198             : 
     199             : // static
     200         456 : MaybeHandle<Object> Object::ConvertToInt32(Isolate* isolate,
     201             :                                            Handle<Object> input) {
     202         912 :   ASSIGN_RETURN_ON_EXCEPTION(
     203             :       isolate, input,
     204             :       ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber), Object);
     205         444 :   if (input->IsSmi()) return input;
     206         274 :   return isolate->factory()->NewNumberFromInt(DoubleToInt32(input->Number()));
     207             : }
     208             : 
     209             : // static
     210      473799 : MaybeHandle<Object> Object::ConvertToUint32(Isolate* isolate,
     211             :                                             Handle<Object> input) {
     212      947598 :   ASSIGN_RETURN_ON_EXCEPTION(
     213             :       isolate, input,
     214             :       ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber), Object);
     215      947306 :   if (input->IsSmi()) return handle(Smi::cast(*input)->ToUint32Smi(), isolate);
     216         248 :   return isolate->factory()->NewNumberFromUint(DoubleToUint32(input->Number()));
     217             : }
     218             : 
     219             : // static
     220     3048727 : MaybeHandle<Name> Object::ConvertToName(Isolate* isolate,
     221             :                                         Handle<Object> input) {
     222     6097454 :   ASSIGN_RETURN_ON_EXCEPTION(
     223             :       isolate, input, Object::ToPrimitive(input, ToPrimitiveHint::kString),
     224             :       Name);
     225     3048512 :   if (input->IsName()) return Handle<Name>::cast(input);
     226       44613 :   return ToString(isolate, input);
     227             : }
     228             : 
     229             : // ES6 7.1.14
     230             : // static
     231         479 : MaybeHandle<Object> Object::ConvertToPropertyKey(Isolate* isolate,
     232             :                                                  Handle<Object> value) {
     233             :   // 1. Let key be ToPrimitive(argument, hint String).
     234             :   MaybeHandle<Object> maybe_key =
     235         479 :       Object::ToPrimitive(value, ToPrimitiveHint::kString);
     236             :   // 2. ReturnIfAbrupt(key).
     237             :   Handle<Object> key;
     238         479 :   if (!maybe_key.ToHandle(&key)) return key;
     239             :   // 3. If Type(key) is Symbol, then return key.
     240         479 :   if (key->IsSymbol()) return key;
     241             :   // 4. Return ToString(key).
     242             :   // Extending spec'ed behavior, we'd be happy to return an element index.
     243         479 :   if (key->IsSmi()) return key;
     244         479 :   if (key->IsHeapNumber()) {
     245             :     uint32_t uint_value;
     246          28 :     if (value->ToArrayLength(&uint_value) &&
     247           9 :         uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) {
     248           0 :       return handle(Smi::FromInt(static_cast<int>(uint_value)), isolate);
     249             :     }
     250             :   }
     251         479 :   return Object::ToString(isolate, key);
     252             : }
     253             : 
     254             : // static
     255     5961382 : MaybeHandle<String> Object::ConvertToString(Isolate* isolate,
     256             :                                             Handle<Object> input) {
     257             :   while (true) {
     258     6142351 :     if (input->IsOddball()) {
     259     2094722 :       return handle(Handle<Oddball>::cast(input)->to_string(), isolate);
     260             :     }
     261     4047629 :     if (input->IsNumber()) {
     262      269234 :       return isolate->factory()->NumberToString(input);
     263             :     }
     264     3778395 :     if (input->IsSymbol()) {
     265        4154 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToString),
     266             :                       String);
     267             :     }
     268     3776318 :     if (input->IsBigInt()) {
     269          36 :       return BigInt::ToString(Handle<BigInt>::cast(input));
     270             :     }
     271     7552564 :     ASSIGN_RETURN_ON_EXCEPTION(
     272             :         isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
     273             :                                                 ToPrimitiveHint::kString),
     274             :         String);
     275             :     // The previous isString() check happened in Object::ToString and thus we
     276             :     // put it at the end of the loop in this helper.
     277     3763155 :     if (input->IsString()) {
     278     3582186 :       return Handle<String>::cast(input);
     279             :     }
     280             :   }
     281             : }
     282             : 
     283             : namespace {
     284             : 
     285       29239 : bool IsErrorObject(Isolate* isolate, Handle<Object> object) {
     286       29239 :   if (!object->IsJSReceiver()) return false;
     287             :   Handle<Symbol> symbol = isolate->factory()->stack_trace_symbol();
     288       29239 :   return JSReceiver::HasOwnProperty(Handle<JSReceiver>::cast(object), symbol)
     289       58478 :       .FromMaybe(false);
     290             : }
     291             : 
     292       27111 : Handle<String> AsStringOrEmpty(Isolate* isolate, Handle<Object> object) {
     293             :   return object->IsString() ? Handle<String>::cast(object)
     294       54222 :                             : isolate->factory()->empty_string();
     295             : }
     296             : 
     297        4333 : Handle<String> NoSideEffectsErrorToString(Isolate* isolate,
     298             :                                           Handle<Object> input) {
     299        4333 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
     300             : 
     301             :   Handle<Name> name_key = isolate->factory()->name_string();
     302        4333 :   Handle<Object> name = JSReceiver::GetDataProperty(receiver, name_key);
     303        4333 :   Handle<String> name_str = AsStringOrEmpty(isolate, name);
     304             : 
     305             :   Handle<Name> msg_key = isolate->factory()->message_string();
     306        4333 :   Handle<Object> msg = JSReceiver::GetDataProperty(receiver, msg_key);
     307        4333 :   Handle<String> msg_str = AsStringOrEmpty(isolate, msg);
     308             : 
     309        4333 :   if (name_str->length() == 0) return msg_str;
     310        4313 :   if (msg_str->length() == 0) return name_str;
     311             : 
     312        4194 :   IncrementalStringBuilder builder(isolate);
     313        4194 :   builder.AppendString(name_str);
     314             :   builder.AppendCString(": ");
     315        4194 :   builder.AppendString(msg_str);
     316             : 
     317        8388 :   return builder.Finish().ToHandleChecked();
     318             : }
     319             : 
     320             : }  // namespace
     321             : 
     322             : // static
     323     3074602 : Handle<String> Object::NoSideEffectsToString(Isolate* isolate,
     324             :                                              Handle<Object> input) {
     325     3074602 :   DisallowJavascriptExecution no_js(isolate);
     326             : 
     327     7333308 :   if (input->IsString() || input->IsNumber() || input->IsOddball()) {
     328     6087438 :     return Object::ToString(isolate, input).ToHandleChecked();
     329       30883 :   } else if (input->IsFunction()) {
     330             :     // -- F u n c t i o n
     331             :     Handle<String> fun_str;
     332         583 :     if (input->IsJSBoundFunction()) {
     333           0 :       fun_str = JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(input));
     334             :     } else {
     335             :       DCHECK(input->IsJSFunction());
     336         583 :       fun_str = JSFunction::ToString(Handle<JSFunction>::cast(input));
     337             :     }
     338             : 
     339         583 :     if (fun_str->length() > 128) {
     340          10 :       IncrementalStringBuilder builder(isolate);
     341          10 :       builder.AppendString(isolate->factory()->NewSubString(fun_str, 0, 111));
     342             :       builder.AppendCString("...<omitted>...");
     343             :       builder.AppendString(isolate->factory()->NewSubString(
     344          10 :           fun_str, fun_str->length() - 2, fun_str->length()));
     345             : 
     346          20 :       return builder.Finish().ToHandleChecked();
     347             :     }
     348         573 :     return fun_str;
     349       30300 :   } else if (input->IsSymbol()) {
     350             :     // -- S y m b o l
     351             :     Handle<Symbol> symbol = Handle<Symbol>::cast(input);
     352             : 
     353        1061 :     IncrementalStringBuilder builder(isolate);
     354             :     builder.AppendCString("Symbol(");
     355        1061 :     if (symbol->name()->IsString()) {
     356         557 :       builder.AppendString(handle(String::cast(symbol->name()), isolate));
     357             :     }
     358             :     builder.AppendCharacter(')');
     359             : 
     360        2122 :     return builder.Finish().ToHandleChecked();
     361       29239 :   } else if (input->IsJSReceiver()) {
     362             :     // -- J S R e c e i v e r
     363       29239 :     Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
     364             :     Handle<Object> to_string = JSReceiver::GetDataProperty(
     365       29239 :         receiver, isolate->factory()->toString_string());
     366             : 
     367       87717 :     if (IsErrorObject(isolate, input) ||
     368       79071 :         *to_string == *isolate->error_to_string()) {
     369             :       // When internally formatting error objects, use a side-effects-free
     370             :       // version of Error.prototype.toString independent of the actually
     371             :       // installed toString method.
     372       26593 :       return NoSideEffectsErrorToString(isolate, input);
     373       49812 :     } else if (*to_string == *isolate->object_to_string()) {
     374             :       Handle<Object> ctor = JSReceiver::GetDataProperty(
     375       18742 :           receiver, isolate->factory()->constructor_string());
     376       18742 :       if (ctor->IsFunction()) {
     377             :         Handle<String> ctor_name;
     378       18445 :         if (ctor->IsJSBoundFunction()) {
     379             :           ctor_name = JSBoundFunction::GetName(
     380             :                           isolate, Handle<JSBoundFunction>::cast(ctor))
     381           0 :                           .ToHandleChecked();
     382       18445 :         } else if (ctor->IsJSFunction()) {
     383             :           Handle<Object> ctor_name_obj =
     384       18445 :               JSFunction::GetName(isolate, Handle<JSFunction>::cast(ctor));
     385       18445 :           ctor_name = AsStringOrEmpty(isolate, ctor_name_obj);
     386             :         }
     387             : 
     388       18445 :         if (ctor_name->length() != 0) {
     389       17927 :           IncrementalStringBuilder builder(isolate);
     390             :           builder.AppendCString("#<");
     391       17927 :           builder.AppendString(ctor_name);
     392             :           builder.AppendCString(">");
     393             : 
     394       35854 :           return builder.Finish().ToHandleChecked();
     395             :         }
     396             :       }
     397             :     }
     398             :   }
     399             : 
     400             :   // At this point, input is either none of the above or a JSReceiver.
     401             : 
     402             :   Handle<JSReceiver> receiver;
     403        6979 :   if (input->IsJSReceiver()) {
     404             :     receiver = Handle<JSReceiver>::cast(input);
     405             :   } else {
     406             :     // This is the only case where Object::ToObject throws.
     407             :     DCHECK(!input->IsSmi());
     408             :     int constructor_function_index =
     409             :         Handle<HeapObject>::cast(input)->map()->GetConstructorFunctionIndex();
     410           0 :     if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
     411           0 :       return isolate->factory()->NewStringFromAsciiChecked("[object Unknown]");
     412             :     }
     413             : 
     414           0 :     receiver = Object::ToObject(isolate, input, isolate->native_context())
     415           0 :                    .ToHandleChecked();
     416             :   }
     417             : 
     418        6979 :   Handle<String> builtin_tag = handle(receiver->class_name(), isolate);
     419             :   Handle<Object> tag_obj = JSReceiver::GetDataProperty(
     420        6979 :       receiver, isolate->factory()->to_string_tag_symbol());
     421             :   Handle<String> tag =
     422        6979 :       tag_obj->IsString() ? Handle<String>::cast(tag_obj) : builtin_tag;
     423             : 
     424        6979 :   IncrementalStringBuilder builder(isolate);
     425             :   builder.AppendCString("[object ");
     426        6979 :   builder.AppendString(tag);
     427             :   builder.AppendCString("]");
     428             : 
     429       13958 :   return builder.Finish().ToHandleChecked();
     430             : }
     431             : 
     432             : // static
     433        1606 : MaybeHandle<Object> Object::ConvertToLength(Isolate* isolate,
     434             :                                             Handle<Object> input) {
     435        3212 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
     436        1435 :   if (input->IsSmi()) {
     437        1647 :     int value = std::max(Smi::ToInt(*input), 0);
     438         549 :     return handle(Smi::FromInt(value), isolate);
     439             :   }
     440         886 :   double len = DoubleToInteger(input->Number());
     441         886 :   if (len <= 0.0) {
     442         591 :     return handle(Smi::kZero, isolate);
     443         295 :   } else if (len >= kMaxSafeInteger) {
     444             :     len = kMaxSafeInteger;
     445             :   }
     446         295 :   return isolate->factory()->NewNumber(len);
     447             : }
     448             : 
     449             : // static
     450        3561 : MaybeHandle<Object> Object::ConvertToIndex(
     451             :     Isolate* isolate, Handle<Object> input,
     452             :     MessageTemplate::Template error_index) {
     453        5428 :   if (input->IsUndefined(isolate)) return handle(Smi::kZero, isolate);
     454        3388 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
     455        2150 :   if (input->IsSmi() && Smi::ToInt(*input) >= 0) return input;
     456        1656 :   double len = DoubleToInteger(input->Number()) + 0.0;
     457        1656 :   auto js_len = isolate->factory()->NewNumber(len);
     458        1656 :   if (len < 0.0 || len > kMaxSafeInteger) {
     459         900 :     THROW_NEW_ERROR(isolate, NewRangeError(error_index, js_len), Object);
     460             :   }
     461        1206 :   return js_len;
     462             : }
     463             : 
     464      868950 : bool Object::BooleanValue() {
     465      874444 :   if (IsSmi()) return Smi::ToInt(this) != 0;
     466             :   DCHECK(IsHeapObject());
     467             :   Isolate* isolate = HeapObject::cast(this)->GetIsolate();
     468     1652468 :   if (IsBoolean()) return IsTrue(isolate);
     469       74444 :   if (IsNullOrUndefined(isolate)) return false;
     470       13656 :   if (IsUndetectable()) return false;  // Undetectable object is false.
     471       19647 :   if (IsString()) return String::cast(this)->length() != 0;
     472       13341 :   if (IsHeapNumber()) return DoubleToBoolean(HeapNumber::cast(this)->value());
     473        2007 :   if (IsBigInt()) return BigInt::cast(this)->ToBoolean();
     474             :   return true;
     475             : }
     476             : 
     477             : 
     478             : namespace {
     479             : 
     480             : // TODO(bmeurer): Maybe we should introduce a marker interface Number,
     481             : // where we put all these methods at some point?
     482             : ComparisonResult NumberCompare(double x, double y) {
     483         792 :   if (std::isnan(x) || std::isnan(y)) {
     484             :     return ComparisonResult::kUndefined;
     485         576 :   } else if (x < y) {
     486             :     return ComparisonResult::kLessThan;
     487         312 :   } else if (x > y) {
     488             :     return ComparisonResult::kGreaterThan;
     489             :   } else {
     490             :     return ComparisonResult::kEqual;
     491             :   }
     492             : }
     493             : 
     494             : 
     495             : bool NumberEquals(double x, double y) {
     496             :   // Must check explicitly for NaN's on Windows, but -0 works fine.
     497        9139 :   if (std::isnan(x)) return false;
     498        9033 :   if (std::isnan(y)) return false;
     499        8955 :   return x == y;
     500             : }
     501             : 
     502             : 
     503        9139 : bool NumberEquals(const Object* x, const Object* y) {
     504        9139 :   return NumberEquals(x->Number(), y->Number());
     505             : }
     506             : 
     507             : 
     508             : bool NumberEquals(Handle<Object> x, Handle<Object> y) {
     509        4341 :   return NumberEquals(*x, *y);
     510             : }
     511             : 
     512             : }  // namespace
     513             : 
     514             : 
     515             : // static
     516         840 : Maybe<ComparisonResult> Object::Compare(Handle<Object> x, Handle<Object> y) {
     517             :   // ES6 section 7.2.11 Abstract Relational Comparison step 3 and 4.
     518        3360 :   if (!Object::ToPrimitive(x, ToPrimitiveHint::kNumber).ToHandle(&x) ||
     519        1680 :       !Object::ToPrimitive(y, ToPrimitiveHint::kNumber).ToHandle(&y)) {
     520             :     return Nothing<ComparisonResult>();
     521             :   }
     522        1008 :   if (x->IsString() && y->IsString()) {
     523             :     // ES6 section 7.2.11 Abstract Relational Comparison step 5.
     524             :     return Just(
     525          48 :         String::Compare(Handle<String>::cast(x), Handle<String>::cast(y)));
     526             :   }
     527             :   // ES6 section 7.2.11 Abstract Relational Comparison step 6.
     528        2376 :   if (!Object::ToNumber(x).ToHandle(&x) || !Object::ToNumber(y).ToHandle(&y)) {
     529             :     return Nothing<ComparisonResult>();
     530             :   }
     531             :   return Just(NumberCompare(x->Number(), y->Number()));
     532             : }
     533             : 
     534             : 
     535             : // static
     536      171507 : Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
     537             :   // This is the generic version of Abstract Equality Comparison. Must be in
     538             :   // sync with CodeStubAssembler::Equal.
     539             :   while (true) {
     540      171585 :     if (x->IsNumber()) {
     541        4600 :       if (y->IsNumber()) {
     542             :         return Just(NumberEquals(x, y));
     543         420 :       } else if (y->IsBoolean()) {
     544           0 :         return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
     545         420 :       } else if (y->IsString()) {
     546          96 :         return Just(NumberEquals(x, String::ToNumber(Handle<String>::cast(y))));
     547         324 :       } else if (y->IsBigInt()) {
     548         324 :         return Just(BigInt::EqualToNumber(Handle<BigInt>::cast(y), x));
     549           0 :       } else if (y->IsJSReceiver()) {
     550           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     551           0 :                  .ToHandle(&y)) {
     552             :           return Nothing<bool>();
     553             :         }
     554             :       } else {
     555             :         return Just(false);
     556             :       }
     557      166985 :     } else if (x->IsString()) {
     558      145291 :       if (y->IsString()) {
     559             :         return Just(
     560      145154 :             String::Equals(Handle<String>::cast(x), Handle<String>::cast(y)));
     561         137 :       } else if (y->IsNumber()) {
     562          65 :         x = String::ToNumber(Handle<String>::cast(x));
     563             :         return Just(NumberEquals(x, y));
     564          72 :       } else if (y->IsBoolean()) {
     565           0 :         x = String::ToNumber(Handle<String>::cast(x));
     566           0 :         return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
     567          72 :       } else if (y->IsBigInt()) {
     568             :         return Just(BigInt::EqualToString(Handle<BigInt>::cast(y),
     569          72 :                                           Handle<String>::cast(x)));
     570           0 :       } else if (y->IsJSReceiver()) {
     571           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     572           0 :                  .ToHandle(&y)) {
     573             :           return Nothing<bool>();
     574             :         }
     575             :       } else {
     576             :         return Just(false);
     577             :       }
     578       21694 :     } else if (x->IsBoolean()) {
     579         816 :       if (y->IsOddball()) {
     580             :         return Just(x.is_identical_to(y));
     581         216 :       } else if (y->IsNumber()) {
     582           0 :         return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
     583         216 :       } else if (y->IsString()) {
     584           0 :         y = String::ToNumber(Handle<String>::cast(y));
     585           0 :         return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
     586         216 :       } else if (y->IsBigInt()) {
     587         216 :         x = Oddball::ToNumber(Handle<Oddball>::cast(x));
     588         216 :         return Just(BigInt::EqualToNumber(Handle<BigInt>::cast(y), x));
     589           0 :       } else if (y->IsJSReceiver()) {
     590           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     591           0 :                  .ToHandle(&y)) {
     592             :           return Nothing<bool>();
     593             :         }
     594           0 :         x = Oddball::ToNumber(Handle<Oddball>::cast(x));
     595             :       } else {
     596             :         return Just(false);
     597             :       }
     598       20878 :     } else if (x->IsSymbol()) {
     599          90 :       if (y->IsSymbol()) {
     600             :         return Just(x.is_identical_to(y));
     601          36 :       } else if (y->IsJSReceiver()) {
     602           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     603           0 :                  .ToHandle(&y)) {
     604             :           return Nothing<bool>();
     605             :         }
     606             :       } else {
     607             :         return Just(false);
     608             :       }
     609       20788 :     } else if (x->IsBigInt()) {
     610         396 :       if (y->IsBigInt()) {
     611          72 :         return Just(BigInt::EqualToBigInt(BigInt::cast(*x), BigInt::cast(*y)));
     612             :       }
     613         324 :       return Equals(y, x);
     614       20392 :     } else if (x->IsJSReceiver()) {
     615       20290 :       if (y->IsJSReceiver()) {
     616             :         return Just(x.is_identical_to(y));
     617          78 :       } else if (y->IsUndetectable()) {
     618             :         return Just(x->IsUndetectable());
     619          78 :       } else if (y->IsBoolean()) {
     620           0 :         y = Oddball::ToNumber(Handle<Oddball>::cast(y));
     621          78 :       } else if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x))
     622         156 :                       .ToHandle(&x)) {
     623             :         return Nothing<bool>();
     624             :       }
     625             :     } else {
     626         204 :       return Just(x->IsUndetectable() && y->IsUndetectable());
     627             :     }
     628             :   }
     629             : }
     630             : 
     631             : 
     632       15883 : bool Object::StrictEquals(Object* that) {
     633       15883 :   if (this->IsNumber()) {
     634        5382 :     if (!that->IsNumber()) return false;
     635        4798 :     return NumberEquals(this, that);
     636       10501 :   } else if (this->IsString()) {
     637        9237 :     if (!that->IsString()) return false;
     638        9162 :     return String::cast(this)->Equals(String::cast(that));
     639        1264 :   } else if (this->IsBigInt()) {
     640          90 :     if (!that->IsBigInt()) return false;
     641          72 :     return BigInt::EqualToBigInt(BigInt::cast(this), BigInt::cast(that));
     642             :   }
     643        1174 :   return this == that;
     644             : }
     645             : 
     646             : 
     647             : // static
     648       14081 : Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
     649       14081 :   if (object->IsNumber()) return isolate->factory()->number_string();
     650       13557 :   if (object->IsOddball()) return handle(Oddball::cast(*object)->type_of());
     651       12175 :   if (object->IsUndetectable()) {
     652             :     return isolate->factory()->undefined_string();
     653             :   }
     654       12175 :   if (object->IsString()) return isolate->factory()->string_string();
     655       11812 :   if (object->IsSymbol()) return isolate->factory()->symbol_string();
     656       11759 :   if (object->IsBigInt()) return isolate->factory()->bigint_string();
     657       11741 :   if (object->IsCallable()) return isolate->factory()->function_string();
     658             :   return isolate->factory()->object_string();
     659             : }
     660             : 
     661             : 
     662             : // static
     663           0 : MaybeHandle<Object> Object::Multiply(Isolate* isolate, Handle<Object> lhs,
     664             :                                      Handle<Object> rhs) {
     665           0 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     666           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     667           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     668             :   }
     669           0 :   return isolate->factory()->NewNumber(lhs->Number() * rhs->Number());
     670             : }
     671             : 
     672             : 
     673             : // static
     674           0 : MaybeHandle<Object> Object::Divide(Isolate* isolate, Handle<Object> lhs,
     675             :                                    Handle<Object> rhs) {
     676           0 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     677           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     678           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     679             :   }
     680           0 :   return isolate->factory()->NewNumber(lhs->Number() / rhs->Number());
     681             : }
     682             : 
     683             : 
     684             : // static
     685           0 : MaybeHandle<Object> Object::Modulus(Isolate* isolate, Handle<Object> lhs,
     686             :                                     Handle<Object> rhs) {
     687           0 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     688           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     689           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     690             :   }
     691           0 :   return isolate->factory()->NewNumber(Modulo(lhs->Number(), rhs->Number()));
     692             : }
     693             : 
     694             : 
     695             : // static
     696          48 : MaybeHandle<Object> Object::Add(Isolate* isolate, Handle<Object> lhs,
     697             :                                 Handle<Object> rhs) {
     698          84 :   if (lhs->IsNumber() && rhs->IsNumber()) {
     699          36 :     return isolate->factory()->NewNumber(lhs->Number() + rhs->Number());
     700          12 :   } else if (lhs->IsString() && rhs->IsString()) {
     701             :     return isolate->factory()->NewConsString(Handle<String>::cast(lhs),
     702           0 :                                              Handle<String>::cast(rhs));
     703             :   }
     704          24 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToPrimitive(lhs), Object);
     705          24 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToPrimitive(rhs), Object);
     706          24 :   if (lhs->IsString() || rhs->IsString()) {
     707           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToString(isolate, rhs),
     708             :                                Object);
     709           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToString(isolate, lhs),
     710             :                                Object);
     711             :     return isolate->factory()->NewConsString(Handle<String>::cast(lhs),
     712           0 :                                              Handle<String>::cast(rhs));
     713             :   }
     714          24 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     715          24 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     716          12 :   return isolate->factory()->NewNumber(lhs->Number() + rhs->Number());
     717             : }
     718             : 
     719             : 
     720             : // static
     721           0 : MaybeHandle<Object> Object::Subtract(Isolate* isolate, Handle<Object> lhs,
     722             :                                      Handle<Object> rhs) {
     723           0 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     724           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     725           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     726             :   }
     727           0 :   return isolate->factory()->NewNumber(lhs->Number() - rhs->Number());
     728             : }
     729             : 
     730             : 
     731             : // static
     732           0 : MaybeHandle<Object> Object::ShiftLeft(Isolate* isolate, Handle<Object> lhs,
     733             :                                       Handle<Object> rhs) {
     734           0 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     735           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     736           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     737             :   }
     738           0 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs)
     739           0 :                                               << (NumberToUint32(*rhs) & 0x1F));
     740             : }
     741             : 
     742             : 
     743             : // static
     744           0 : MaybeHandle<Object> Object::ShiftRight(Isolate* isolate, Handle<Object> lhs,
     745             :                                        Handle<Object> rhs) {
     746           0 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     747           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     748           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     749             :   }
     750           0 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) >>
     751           0 :                                               (NumberToUint32(*rhs) & 0x1F));
     752             : }
     753             : 
     754             : 
     755             : // static
     756           0 : MaybeHandle<Object> Object::ShiftRightLogical(Isolate* isolate,
     757             :                                               Handle<Object> lhs,
     758             :                                               Handle<Object> rhs) {
     759           0 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     760           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     761           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     762             :   }
     763           0 :   return isolate->factory()->NewNumberFromUint(NumberToUint32(*lhs) >>
     764           0 :                                                (NumberToUint32(*rhs) & 0x1F));
     765             : }
     766             : 
     767             : 
     768             : // static
     769           0 : MaybeHandle<Object> Object::BitwiseAnd(Isolate* isolate, Handle<Object> lhs,
     770             :                                        Handle<Object> rhs) {
     771           0 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     772           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     773           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     774             :   }
     775           0 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) &
     776           0 :                                               NumberToInt32(*rhs));
     777             : }
     778             : 
     779             : 
     780             : // static
     781           0 : MaybeHandle<Object> Object::BitwiseOr(Isolate* isolate, Handle<Object> lhs,
     782             :                                       Handle<Object> rhs) {
     783           0 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     784           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     785           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     786             :   }
     787           0 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) |
     788           0 :                                               NumberToInt32(*rhs));
     789             : }
     790             : 
     791             : 
     792             : // static
     793           0 : MaybeHandle<Object> Object::BitwiseXor(Isolate* isolate, Handle<Object> lhs,
     794             :                                        Handle<Object> rhs) {
     795           0 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     796           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     797           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     798             :   }
     799           0 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) ^
     800           0 :                                               NumberToInt32(*rhs));
     801             : }
     802             : 
     803             : // static
     804      119654 : MaybeHandle<Object> Object::OrdinaryHasInstance(Isolate* isolate,
     805             :                                                 Handle<Object> callable,
     806             :                                                 Handle<Object> object) {
     807             :   // The {callable} must have a [[Call]] internal method.
     808      119689 :   if (!callable->IsCallable()) return isolate->factory()->false_value();
     809             : 
     810             :   // Check if {callable} is a bound function, and if so retrieve its
     811             :   // [[BoundTargetFunction]] and use that instead of {callable}.
     812      119619 :   if (callable->IsJSBoundFunction()) {
     813             :     Handle<Object> bound_callable(
     814             :         Handle<JSBoundFunction>::cast(callable)->bound_target_function(),
     815             :         isolate);
     816         263 :     return Object::InstanceOf(isolate, object, bound_callable);
     817             :   }
     818             : 
     819             :   // If {object} is not a receiver, return false.
     820      128006 :   if (!object->IsJSReceiver()) return isolate->factory()->false_value();
     821             : 
     822             :   // Get the "prototype" of {callable}; raise an error if it's not a receiver.
     823             :   Handle<Object> prototype;
     824      221412 :   ASSIGN_RETURN_ON_EXCEPTION(
     825             :       isolate, prototype,
     826             :       Object::GetProperty(callable, isolate->factory()->prototype_string()),
     827             :       Object);
     828      110706 :   if (!prototype->IsJSReceiver()) {
     829      220692 :     THROW_NEW_ERROR(
     830             :         isolate,
     831             :         NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype),
     832             :         Object);
     833             :   }
     834             : 
     835             :   // Return whether or not {prototype} is in the prototype chain of {object}.
     836             :   Maybe<bool> result = JSReceiver::HasInPrototypeChain(
     837         360 :       isolate, Handle<JSReceiver>::cast(object), prototype);
     838         360 :   if (result.IsNothing()) return MaybeHandle<Object>();
     839         360 :   return isolate->factory()->ToBoolean(result.FromJust());
     840             : }
     841             : 
     842             : // static
     843         335 : MaybeHandle<Object> Object::InstanceOf(Isolate* isolate, Handle<Object> object,
     844             :                                        Handle<Object> callable) {
     845             :   // The {callable} must be a receiver.
     846         335 :   if (!callable->IsJSReceiver()) {
     847           0 :     THROW_NEW_ERROR(isolate,
     848             :                     NewTypeError(MessageTemplate::kNonObjectInInstanceOfCheck),
     849             :                     Object);
     850             :   }
     851             : 
     852             :   // Lookup the @@hasInstance method on {callable}.
     853             :   Handle<Object> inst_of_handler;
     854         670 :   ASSIGN_RETURN_ON_EXCEPTION(
     855             :       isolate, inst_of_handler,
     856             :       JSReceiver::GetMethod(Handle<JSReceiver>::cast(callable),
     857             :                             isolate->factory()->has_instance_symbol()),
     858             :       Object);
     859         335 :   if (!inst_of_handler->IsUndefined(isolate)) {
     860             :     // Call the {inst_of_handler} on the {callable}.
     861             :     Handle<Object> result;
     862         658 :     ASSIGN_RETURN_ON_EXCEPTION(
     863             :         isolate, result,
     864             :         Execution::Call(isolate, inst_of_handler, callable, 1, &object),
     865             :         Object);
     866         323 :     return isolate->factory()->ToBoolean(result->BooleanValue());
     867             :   }
     868             : 
     869             :   // The {callable} must have a [[Call]] internal method.
     870           6 :   if (!callable->IsCallable()) {
     871          12 :     THROW_NEW_ERROR(
     872             :         isolate, NewTypeError(MessageTemplate::kNonCallableInInstanceOfCheck),
     873             :         Object);
     874             :   }
     875             : 
     876             :   // Fall back to OrdinaryHasInstance with {callable} and {object}.
     877             :   Handle<Object> result;
     878           0 :   ASSIGN_RETURN_ON_EXCEPTION(
     879             :       isolate, result,
     880             :       JSReceiver::OrdinaryHasInstance(isolate, callable, object), Object);
     881           0 :   return result;
     882             : }
     883             : 
     884             : // static
     885    11744922 : MaybeHandle<Object> Object::GetMethod(Handle<JSReceiver> receiver,
     886             :                                       Handle<Name> name) {
     887             :   Handle<Object> func;
     888             :   Isolate* isolate = receiver->GetIsolate();
     889    23489844 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, func,
     890             :                              JSReceiver::GetProperty(receiver, name), Object);
     891    11709418 :   if (func->IsNullOrUndefined(isolate)) {
     892    10630660 :     return isolate->factory()->undefined_value();
     893             :   }
     894     1078758 :   if (!func->IsCallable()) {
     895         468 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kPropertyNotFunction,
     896             :                                           func, name, receiver),
     897             :                     Object);
     898             :   }
     899     1078524 :   return func;
     900             : }
     901             : 
     902             : namespace {
     903             : 
     904       17548 : MaybeHandle<FixedArray> CreateListFromArrayLikeFastPath(
     905             :     Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
     906       17548 :   if (element_types == ElementTypes::kAll) {
     907       16447 :     if (object->IsJSArray()) {
     908             :       Handle<JSArray> array = Handle<JSArray>::cast(object);
     909             :       uint32_t length;
     910        2004 :       if (!array->HasArrayPrototype(isolate) ||
     911        1742 :           !array->length()->ToUint32(&length) || !array->HasFastElements() ||
     912         188 :           !JSObject::PrototypeHasNoElements(isolate, *array)) {
     913         702 :         return MaybeHandle<FixedArray>();
     914             :       }
     915         116 :       return array->GetElementsAccessor()->CreateListFromArrayLike(
     916         232 :           isolate, array, length);
     917       15629 :     } else if (object->IsJSTypedArray()) {
     918             :       Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(object);
     919         728 :       uint32_t length = array->length_value();
     920         728 :       if (array->WasNeutered() ||
     921             :           length > static_cast<uint32_t>(FixedArray::kMaxLength)) {
     922           0 :         return MaybeHandle<FixedArray>();
     923             :       }
     924         728 :       return array->GetElementsAccessor()->CreateListFromArrayLike(
     925        1456 :           isolate, array, length);
     926             :     }
     927             :   }
     928       16002 :   return MaybeHandle<FixedArray>();
     929             : }
     930             : 
     931             : }  // namespace
     932             : 
     933             : // static
     934       17548 : MaybeHandle<FixedArray> Object::CreateListFromArrayLike(
     935             :     Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
     936             :   // Fast-path for JSArray and JSTypedArray.
     937             :   MaybeHandle<FixedArray> fast_result =
     938       17548 :       CreateListFromArrayLikeFastPath(isolate, object, element_types);
     939       17548 :   if (!fast_result.is_null()) return fast_result;
     940             :   // 1. ReturnIfAbrupt(object).
     941             :   // 2. (default elementTypes -- not applicable.)
     942             :   // 3. If Type(obj) is not Object, throw a TypeError exception.
     943       16704 :   if (!object->IsJSReceiver()) {
     944        1386 :     THROW_NEW_ERROR(isolate,
     945             :                     NewTypeError(MessageTemplate::kCalledOnNonObject,
     946             :                                  isolate->factory()->NewStringFromAsciiChecked(
     947             :                                      "CreateListFromArrayLike")),
     948             :                     FixedArray);
     949             :   }
     950             : 
     951             :   // 4. Let len be ? ToLength(? Get(obj, "length")).
     952             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
     953             :   Handle<Object> raw_length_number;
     954       32484 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, raw_length_number,
     955             :                              Object::GetLengthFromArrayLike(isolate, receiver),
     956             :                              FixedArray);
     957             :   uint32_t len;
     958       32403 :   if (!raw_length_number->ToUint32(&len) ||
     959       16197 :       len > static_cast<uint32_t>(FixedArray::kMaxLength)) {
     960          54 :     THROW_NEW_ERROR(isolate,
     961             :                     NewRangeError(MessageTemplate::kInvalidArrayLength),
     962             :                     FixedArray);
     963             :   }
     964             :   // 5. Let list be an empty List.
     965       16179 :   Handle<FixedArray> list = isolate->factory()->NewFixedArray(len);
     966             :   // 6. Let index be 0.
     967             :   // 7. Repeat while index < len:
     968    40162205 :   for (uint32_t index = 0; index < len; ++index) {
     969             :     // 7a. Let indexName be ToString(index).
     970             :     // 7b. Let next be ? Get(obj, indexName).
     971             :     Handle<Object> next;
     972    80292196 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, next,
     973             :                                JSReceiver::GetElement(isolate, receiver, index),
     974             :                                FixedArray);
     975    40146062 :     switch (element_types) {
     976             :       case ElementTypes::kAll:
     977             :         // Nothing to do.
     978             :         break;
     979             :       case ElementTypes::kStringAndSymbol: {
     980             :         // 7c. If Type(next) is not an element of elementTypes, throw a
     981             :         //     TypeError exception.
     982        2732 :         if (!next->IsName()) {
     983          72 :           THROW_NEW_ERROR(isolate,
     984             :                           NewTypeError(MessageTemplate::kNotPropertyName, next),
     985             :                           FixedArray);
     986             :         }
     987             :         // 7d. Append next as the last element of list.
     988             :         // Internalize on the fly so we can use pointer identity later.
     989        2696 :         next = isolate->factory()->InternalizeName(Handle<Name>::cast(next));
     990        2696 :         break;
     991             :       }
     992             :     }
     993    80292052 :     list->set(index, *next);
     994             :     // 7e. Set index to index + 1. (See loop header.)
     995             :   }
     996             :   // 8. Return list.
     997       16107 :   return list;
     998             : }
     999             : 
    1000             : 
    1001             : // static
    1002       39464 : MaybeHandle<Object> Object::GetLengthFromArrayLike(Isolate* isolate,
    1003             :                                                    Handle<Object> object) {
    1004             :   Handle<Object> val;
    1005             :   Handle<Object> key = isolate->factory()->length_string();
    1006       78928 :   ASSIGN_RETURN_ON_EXCEPTION(
    1007             :       isolate, val, Runtime::GetObjectProperty(isolate, object, key), Object);
    1008       39390 :   return Object::ToLength(isolate, val);
    1009             : }
    1010             : 
    1011             : // static
    1012   108447985 : Maybe<bool> JSReceiver::HasProperty(LookupIterator* it) {
    1013   108434010 :   for (; it->IsFound(); it->Next()) {
    1014    26953248 :     switch (it->state()) {
    1015             :       case LookupIterator::NOT_FOUND:
    1016             :       case LookupIterator::TRANSITION:
    1017           0 :         UNREACHABLE();
    1018             :       case LookupIterator::JSPROXY:
    1019             :         return JSProxy::HasProperty(it->isolate(), it->GetHolder<JSProxy>(),
    1020       85190 :                                     it->GetName());
    1021             :       case LookupIterator::INTERCEPTOR: {
    1022             :         Maybe<PropertyAttributes> result =
    1023         213 :             JSObject::GetPropertyAttributesWithInterceptor(it);
    1024         281 :         if (result.IsNothing()) return Nothing<bool>();
    1025         213 :         if (result.FromJust() != ABSENT) return Just(true);
    1026         145 :         break;
    1027             :       }
    1028             :       case LookupIterator::ACCESS_CHECK: {
    1029       28515 :         if (it->HasAccess()) break;
    1030             :         Maybe<PropertyAttributes> result =
    1031          40 :             JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
    1032          80 :         if (result.IsNothing()) return Nothing<bool>();
    1033           0 :         return Just(result.FromJust() != ABSENT);
    1034             :       }
    1035             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1036             :         // TypedArray out-of-bounds access.
    1037             :         return Just(false);
    1038             :       case LookupIterator::ACCESSOR:
    1039             :       case LookupIterator::DATA:
    1040             :         return Just(true);
    1041             :     }
    1042             :   }
    1043             :   return Just(false);
    1044             : }
    1045             : 
    1046             : // static
    1047     7303357 : Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object,
    1048             :                                        Handle<Name> name) {
    1049     7303357 :   if (object->IsJSModuleNamespace()) {
    1050             :     PropertyDescriptor desc;
    1051             :     return JSReceiver::GetOwnPropertyDescriptor(object->GetIsolate(), object,
    1052          20 :                                                 name, &desc);
    1053             :   }
    1054             : 
    1055     7303337 :   if (object->IsJSObject()) {  // Shortcut.
    1056             :     LookupIterator it = LookupIterator::PropertyOrElement(
    1057     7302096 :         object->GetIsolate(), object, name, object, LookupIterator::OWN);
    1058     7302096 :     return HasProperty(&it);
    1059             :   }
    1060             : 
    1061             :   Maybe<PropertyAttributes> attributes =
    1062        1241 :       JSReceiver::GetOwnPropertyAttributes(object, name);
    1063        1241 :   MAYBE_RETURN(attributes, Nothing<bool>());
    1064        1151 :   return Just(attributes.FromJust() != ABSENT);
    1065             : }
    1066             : 
    1067             : // static
    1068   267103397 : MaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
    1069   245744882 :   for (; it->IsFound(); it->Next()) {
    1070   100818911 :     switch (it->state()) {
    1071             :       case LookupIterator::NOT_FOUND:
    1072             :       case LookupIterator::TRANSITION:
    1073           0 :         UNREACHABLE();
    1074             :       case LookupIterator::JSPROXY: {
    1075             :         bool was_found;
    1076             :         MaybeHandle<Object> result =
    1077             :             JSProxy::GetProperty(it->isolate(), it->GetHolder<JSProxy>(),
    1078      284672 :                                  it->GetName(), it->GetReceiver(), &was_found);
    1079      142336 :         if (!was_found) it->NotFound();
    1080      142336 :         return result;
    1081             :       }
    1082             :       case LookupIterator::INTERCEPTOR: {
    1083             :         bool done;
    1084             :         Handle<Object> result;
    1085       27878 :         ASSIGN_RETURN_ON_EXCEPTION(
    1086             :             it->isolate(), result,
    1087             :             JSObject::GetPropertyWithInterceptor(it, &done), Object);
    1088       13927 :         if (done) return result;
    1089       10765 :         break;
    1090             :       }
    1091             :       case LookupIterator::ACCESS_CHECK:
    1092      831582 :         if (it->HasAccess()) break;
    1093        1737 :         return JSObject::GetPropertyWithFailedAccessCheck(it);
    1094             :       case LookupIterator::ACCESSOR:
    1095     6747731 :         return GetPropertyWithAccessor(it);
    1096             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1097        3249 :         return it->isolate()->factory()->undefined_value();
    1098             :       case LookupIterator::DATA:
    1099    93080076 :         return it->GetDataValue();
    1100             :     }
    1101             :   }
    1102    22053538 :   return it->isolate()->factory()->undefined_value();
    1103             : }
    1104             : 
    1105             : 
    1106             : // static
    1107      142336 : MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate,
    1108             :                                          Handle<JSProxy> proxy,
    1109             :                                          Handle<Name> name,
    1110             :                                          Handle<Object> receiver,
    1111             :                                          bool* was_found) {
    1112      142336 :   *was_found = true;
    1113             : 
    1114             :   DCHECK(!name->IsPrivate());
    1115      142336 :   STACK_CHECK(isolate, MaybeHandle<Object>());
    1116             :   Handle<Name> trap_name = isolate->factory()->get_string();
    1117             :   // 1. Assert: IsPropertyKey(P) is true.
    1118             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    1119             :   Handle<Object> handler(proxy->handler(), isolate);
    1120             :   // 3. If handler is null, throw a TypeError exception.
    1121             :   // 4. Assert: Type(handler) is Object.
    1122      142192 :   if (proxy->IsRevoked()) {
    1123          72 :     THROW_NEW_ERROR(isolate,
    1124             :                     NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
    1125             :                     Object);
    1126             :   }
    1127             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    1128             :   Handle<JSReceiver> target(proxy->target(), isolate);
    1129             :   // 6. Let trap be ? GetMethod(handler, "get").
    1130             :   Handle<Object> trap;
    1131      284312 :   ASSIGN_RETURN_ON_EXCEPTION(
    1132             :       isolate, trap,
    1133             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), Object);
    1134             :   // 7. If trap is undefined, then
    1135      107026 :   if (trap->IsUndefined(isolate)) {
    1136             :     // 7.a Return target.[[Get]](P, Receiver).
    1137             :     LookupIterator it =
    1138       79948 :         LookupIterator::PropertyOrElement(isolate, receiver, name, target);
    1139       79948 :     MaybeHandle<Object> result = Object::GetProperty(&it);
    1140      159896 :     *was_found = it.IsFound();
    1141       79948 :     return result;
    1142             :   }
    1143             :   // 8. Let trapResult be ? Call(trap, handler, «target, P, Receiver»).
    1144             :   Handle<Object> trap_result;
    1145       27078 :   Handle<Object> args[] = {target, name, receiver};
    1146       54156 :   ASSIGN_RETURN_ON_EXCEPTION(
    1147             :       isolate, trap_result,
    1148             :       Execution::Call(isolate, trap, handler, arraysize(args), args), Object);
    1149             : 
    1150             :   MaybeHandle<Object> result =
    1151       25589 :       JSProxy::CheckGetSetTrapResult(isolate, name, target, trap_result, kGet);
    1152       25589 :   if (result.is_null()) {
    1153          30 :     return result;
    1154             :   }
    1155             : 
    1156             :   // 11. Return trap_result
    1157       25559 :   return trap_result;
    1158             : }
    1159             : 
    1160             : // static
    1161       27966 : MaybeHandle<Object> JSProxy::CheckGetSetTrapResult(Isolate* isolate,
    1162             :                                                    Handle<Name> name,
    1163             :                                                    Handle<JSReceiver> target,
    1164             :                                                    Handle<Object> trap_result,
    1165             :                                                    AccessKind access_kind) {
    1166             :   // 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
    1167             :   PropertyDescriptor target_desc;
    1168             :   Maybe<bool> target_found =
    1169       27966 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    1170       27966 :   MAYBE_RETURN_NULL(target_found);
    1171             :   // 10. If targetDesc is not undefined, then
    1172       27957 :   if (target_found.FromJust()) {
    1173             :     // 10.a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is
    1174             :     //       false and targetDesc.[[Writable]] is false, then
    1175             :     // 10.a.i. If SameValue(trapResult, targetDesc.[[Value]]) is false,
    1176             :     //        throw a TypeError exception.
    1177        7349 :     bool inconsistent = PropertyDescriptor::IsDataDescriptor(&target_desc) &&
    1178        3556 :                         !target_desc.configurable() &&
    1179       10517 :                         !target_desc.writable() &&
    1180        2799 :                         !trap_result->SameValue(*target_desc.value());
    1181        7718 :     if (inconsistent) {
    1182         219 :       if (access_kind == kGet) {
    1183          78 :         THROW_NEW_ERROR(
    1184             :             isolate,
    1185             :             NewTypeError(MessageTemplate::kProxyGetNonConfigurableData, name,
    1186             :                          target_desc.value(), trap_result),
    1187             :             Object);
    1188             :       } else {
    1189             :         isolate->Throw(*isolate->factory()->NewTypeError(
    1190         360 :             MessageTemplate::kProxySetFrozenData, name));
    1191         180 :         return MaybeHandle<Object>();
    1192             :       }
    1193             :     }
    1194             :     // 10.b. If IsAccessorDescriptor(targetDesc) and targetDesc.[[Configurable]]
    1195             :     //       is false and targetDesc.[[Get]] is undefined, then
    1196             :     // 10.b.i. If trapResult is not undefined, throw a TypeError exception.
    1197        7499 :     if (access_kind == kGet) {
    1198           0 :       inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
    1199           0 :                      !target_desc.configurable() &&
    1200        6122 :                      target_desc.get()->IsUndefined(isolate) &&
    1201        6122 :                      !trap_result->IsUndefined(isolate);
    1202             :     } else {
    1203         369 :       inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
    1204        1566 :                      !target_desc.configurable() &&
    1205        1377 :                      target_desc.set()->IsUndefined(isolate);
    1206             :     }
    1207        7499 :     if (inconsistent) {
    1208         189 :       if (access_kind == kGet) {
    1209           0 :         THROW_NEW_ERROR(
    1210             :             isolate,
    1211             :             NewTypeError(MessageTemplate::kProxyGetNonConfigurableAccessor,
    1212             :                          name, trap_result),
    1213             :             Object);
    1214             :       } else {
    1215             :         isolate->Throw(*isolate->factory()->NewTypeError(
    1216         378 :             MessageTemplate::kProxySetFrozenAccessor, name));
    1217         189 :         return MaybeHandle<Object>();
    1218             :       }
    1219             :     }
    1220             :   }
    1221       27549 :   return isolate->factory()->undefined_value();
    1222             : }
    1223             : 
    1224             : 
    1225     9519283 : Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) {
    1226     9013446 :   for (; it->IsFound(); it->Next()) {
    1227     4463671 :     switch (it->state()) {
    1228             :       case LookupIterator::INTERCEPTOR:
    1229             :       case LookupIterator::NOT_FOUND:
    1230             :       case LookupIterator::TRANSITION:
    1231           0 :         UNREACHABLE();
    1232             :       case LookupIterator::ACCESS_CHECK:
    1233             :         // Support calling this method without an active context, but refuse
    1234             :         // access to access-checked objects in that case.
    1235      485918 :         if (it->isolate()->context() != nullptr && it->HasAccess()) continue;
    1236             :       // Fall through.
    1237             :       case LookupIterator::JSPROXY:
    1238             :         it->NotFound();
    1239        2764 :         return it->isolate()->factory()->undefined_value();
    1240             :       case LookupIterator::ACCESSOR:
    1241             :         // TODO(verwaest): For now this doesn't call into AccessorInfo, since
    1242             :         // clients don't need it. Update once relevant.
    1243             :         it->NotFound();
    1244      459094 :         return it->isolate()->factory()->undefined_value();
    1245             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1246           0 :         return it->isolate()->factory()->undefined_value();
    1247             :       case LookupIterator::DATA:
    1248     3516822 :         return it->GetDataValue();
    1249             :     }
    1250             :   }
    1251       43052 :   return it->isolate()->factory()->undefined_value();
    1252             : }
    1253             : 
    1254             : 
    1255    12816461 : bool Object::ToInt32(int32_t* value) {
    1256    12816461 :   if (IsSmi()) {
    1257    12816461 :     *value = Smi::ToInt(this);
    1258    12816461 :     return true;
    1259             :   }
    1260           0 :   if (IsHeapNumber()) {
    1261             :     double num = HeapNumber::cast(this)->value();
    1262           0 :     if (FastI2D(FastD2I(num)) == num) {
    1263           0 :       *value = FastD2I(num);
    1264           0 :       return true;
    1265             :     }
    1266             :   }
    1267             :   return false;
    1268             : }
    1269             : 
    1270     3115288 : Handle<SharedFunctionInfo> FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(
    1271             :     Isolate* isolate, Handle<FunctionTemplateInfo> info,
    1272             :     MaybeHandle<Name> maybe_name) {
    1273             :   Object* current_info = info->shared_function_info();
    1274     3115288 :   if (current_info->IsSharedFunctionInfo()) {
    1275             :     return handle(SharedFunctionInfo::cast(current_info), isolate);
    1276             :   }
    1277             :   Handle<Object> class_name(info->class_name(), isolate);
    1278             :   Handle<Name> name;
    1279             :   Handle<String> name_string;
    1280     5655894 :   if (maybe_name.ToHandle(&name) && name->IsString()) {
    1281             :     name_string = Handle<String>::cast(name);
    1282             :   } else {
    1283             :     name_string = class_name->IsString() ? Handle<String>::cast(class_name)
    1284      382616 :                                          : isolate->factory()->empty_string();
    1285             :   }
    1286     3019252 :   Handle<Code> code = BUILTIN_CODE(isolate, HandleApiCall);
    1287             :   bool is_constructor;
    1288             :   FunctionKind function_kind;
    1289     3019252 :   if (!info->remove_prototype()) {
    1290             :     is_constructor = true;
    1291             :     function_kind = kNormalFunction;
    1292             :   } else {
    1293             :     is_constructor = false;
    1294             :     function_kind = kConciseMethod;
    1295             :   }
    1296             :   Handle<SharedFunctionInfo> result = isolate->factory()->NewSharedFunctionInfo(
    1297     6038504 :       name_string, code, is_constructor, function_kind);
    1298     3019252 :   if (is_constructor) {
    1299     5977748 :     result->SetConstructStub(*BUILTIN_CODE(isolate, JSConstructStubApi));
    1300             :   }
    1301             : 
    1302             :   result->set_length(info->length());
    1303     3064959 :   if (class_name->IsString()) result->set_instance_class_name(*class_name);
    1304             :   result->set_api_func_data(*info);
    1305             :   result->DontAdaptArguments();
    1306             :   DCHECK(result->IsApiFunction());
    1307             : 
    1308     3019252 :   info->set_shared_function_info(*result);
    1309     3019252 :   return result;
    1310             : }
    1311             : 
    1312       16521 : bool FunctionTemplateInfo::IsTemplateFor(Map* map) {
    1313             :   // There is a constraint on the object; check.
    1314       16521 :   if (!map->IsJSObjectMap()) return false;
    1315             :   // Fetch the constructor function of the object.
    1316       16521 :   Object* cons_obj = map->GetConstructor();
    1317             :   Object* type;
    1318       16521 :   if (cons_obj->IsJSFunction()) {
    1319             :     JSFunction* fun = JSFunction::cast(cons_obj);
    1320             :     type = fun->shared()->function_data();
    1321          16 :   } else if (cons_obj->IsFunctionTemplateInfo()) {
    1322             :     type = FunctionTemplateInfo::cast(cons_obj);
    1323             :   } else {
    1324             :     return false;
    1325             :   }
    1326             :   // Iterate through the chain of inheriting function templates to
    1327             :   // see if the required one occurs.
    1328       17593 :   while (type->IsFunctionTemplateInfo()) {
    1329       10272 :     if (type == this) return true;
    1330             :     type = FunctionTemplateInfo::cast(type)->parent_template();
    1331             :   }
    1332             :   // Didn't find the required type in the inheritance chain.
    1333             :   return false;
    1334             : }
    1335             : 
    1336             : 
    1337             : // static
    1338      324224 : Handle<TemplateList> TemplateList::New(Isolate* isolate, int size) {
    1339             :   Handle<FixedArray> list =
    1340      324224 :       isolate->factory()->NewFixedArray(kLengthIndex + size);
    1341             :   list->set(kLengthIndex, Smi::kZero);
    1342      324224 :   return Handle<TemplateList>::cast(list);
    1343             : }
    1344             : 
    1345             : // static
    1346     5249611 : Handle<TemplateList> TemplateList::Add(Isolate* isolate,
    1347             :                                        Handle<TemplateList> list,
    1348             :                                        Handle<i::Object> value) {
    1349             :   STATIC_ASSERT(kFirstElementIndex == 1);
    1350     5249611 :   int index = list->length() + 1;
    1351             :   Handle<i::FixedArray> fixed_array = Handle<FixedArray>::cast(list);
    1352     5249611 :   fixed_array = FixedArray::SetAndGrow(fixed_array, index, value);
    1353             :   fixed_array->set(kLengthIndex, Smi::FromInt(index));
    1354     5249611 :   return Handle<TemplateList>::cast(fixed_array);
    1355             : }
    1356             : 
    1357             : // static
    1358     2136901 : MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
    1359             :                                     Handle<JSReceiver> new_target,
    1360             :                                     Handle<AllocationSite> site) {
    1361             :   // If called through new, new.target can be:
    1362             :   // - a subclass of constructor,
    1363             :   // - a proxy wrapper around constructor, or
    1364             :   // - the constructor itself.
    1365             :   // If called through Reflect.construct, it's guaranteed to be a constructor.
    1366             :   Isolate* const isolate = constructor->GetIsolate();
    1367             :   DCHECK(constructor->IsConstructor());
    1368             :   DCHECK(new_target->IsConstructor());
    1369             :   DCHECK(!constructor->has_initial_map() ||
    1370             :          constructor->initial_map()->instance_type() != JS_FUNCTION_TYPE);
    1371             : 
    1372             :   Handle<Map> initial_map;
    1373     4273802 :   ASSIGN_RETURN_ON_EXCEPTION(
    1374             :       isolate, initial_map,
    1375             :       JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject);
    1376             :   Handle<JSObject> result =
    1377     2136841 :       isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site);
    1378     2136841 :   if (initial_map->is_dictionary_map()) {
    1379             :     Handle<NameDictionary> dictionary =
    1380           0 :         NameDictionary::New(isolate, NameDictionary::kInitialCapacity);
    1381           0 :     result->SetProperties(*dictionary);
    1382             :   }
    1383     2136841 :   isolate->counters()->constructed_objects()->Increment();
    1384     2136841 :   isolate->counters()->constructed_objects_runtime()->Increment();
    1385     2136841 :   return result;
    1386             : }
    1387             : 
    1388     4869754 : void JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
    1389             :   DCHECK(object->HasSmiOrObjectElements() ||
    1390             :          object->HasFastStringWrapperElements());
    1391             :   FixedArray* raw_elems = FixedArray::cast(object->elements());
    1392     4869754 :   Heap* heap = object->GetHeap();
    1393     9721243 :   if (raw_elems->map() != heap->fixed_cow_array_map()) return;
    1394             :   Isolate* isolate = heap->isolate();
    1395             :   Handle<FixedArray> elems(raw_elems, isolate);
    1396             :   Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap(
    1397       18265 :       elems, isolate->factory()->fixed_array_map());
    1398       18265 :   object->set_elements(*writable_elems);
    1399       18265 :   isolate->counters()->cow_arrays_converted()->Increment();
    1400             : }
    1401             : 
    1402     7151007 : int JSObject::GetHeaderSize(InstanceType type,
    1403             :                             bool function_has_prototype_slot) {
    1404     7151007 :   switch (type) {
    1405             :     case JS_OBJECT_TYPE:
    1406             :     case JS_API_OBJECT_TYPE:
    1407             :     case JS_SPECIAL_API_OBJECT_TYPE:
    1408             :       return JSObject::kHeaderSize;
    1409             :     case JS_GENERATOR_OBJECT_TYPE:
    1410       11072 :       return JSGeneratorObject::kSize;
    1411             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
    1412        1302 :       return JSAsyncGeneratorObject::kSize;
    1413             :     case JS_GLOBAL_PROXY_TYPE:
    1414          10 :       return JSGlobalProxy::kSize;
    1415             :     case JS_GLOBAL_OBJECT_TYPE:
    1416         622 :       return JSGlobalObject::kSize;
    1417             :     case JS_BOUND_FUNCTION_TYPE:
    1418          15 :       return JSBoundFunction::kSize;
    1419             :     case JS_FUNCTION_TYPE:
    1420             :       return function_has_prototype_slot ? JSFunction::kSizeWithPrototype
    1421     5950896 :                                          : JSFunction::kSizeWithoutPrototype;
    1422             :     case JS_VALUE_TYPE:
    1423        4591 :       return JSValue::kSize;
    1424             :     case JS_DATE_TYPE:
    1425        1740 :       return JSDate::kSize;
    1426             :     case JS_ARRAY_TYPE:
    1427       80574 :       return JSArray::kSize;
    1428             :     case JS_ARRAY_BUFFER_TYPE:
    1429      498590 :       return JSArrayBuffer::kSize;
    1430             :     case JS_TYPED_ARRAY_TYPE:
    1431        8817 :       return JSTypedArray::kSize;
    1432             :     case JS_DATA_VIEW_TYPE:
    1433        7580 :       return JSDataView::kSize;
    1434             :     case JS_SET_TYPE:
    1435        1439 :       return JSSet::kSize;
    1436             :     case JS_MAP_TYPE:
    1437        1285 :       return JSMap::kSize;
    1438             :     case JS_SET_KEY_VALUE_ITERATOR_TYPE:
    1439             :     case JS_SET_VALUE_ITERATOR_TYPE:
    1440           0 :       return JSSetIterator::kSize;
    1441             :     case JS_MAP_KEY_ITERATOR_TYPE:
    1442             :     case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
    1443             :     case JS_MAP_VALUE_ITERATOR_TYPE:
    1444           0 :       return JSMapIterator::kSize;
    1445             :     case JS_WEAK_MAP_TYPE:
    1446        1471 :       return JSWeakMap::kSize;
    1447             :     case JS_WEAK_SET_TYPE:
    1448        1473 :       return JSWeakSet::kSize;
    1449             :     case JS_PROMISE_TYPE:
    1450         275 :       return JSPromise::kSize;
    1451             :     case JS_REGEXP_TYPE:
    1452        1573 :       return JSRegExp::kSize;
    1453             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    1454             :       return JSObject::kHeaderSize;
    1455             :     case JS_MESSAGE_OBJECT_TYPE:
    1456           0 :       return JSMessageObject::kSize;
    1457             :     case JS_ARGUMENTS_TYPE:
    1458             :       return JSObject::kHeaderSize;
    1459             :     case JS_ERROR_TYPE:
    1460             :       return JSObject::kHeaderSize;
    1461             :     case JS_STRING_ITERATOR_TYPE:
    1462           0 :       return JSStringIterator::kSize;
    1463             :     case JS_MODULE_NAMESPACE_TYPE:
    1464         122 :       return JSModuleNamespace::kHeaderSize;
    1465             :     case WASM_INSTANCE_TYPE:
    1466           0 :       return WasmInstanceObject::kSize;
    1467             :     case WASM_MEMORY_TYPE:
    1468           0 :       return WasmMemoryObject::kSize;
    1469             :     case WASM_MODULE_TYPE:
    1470           0 :       return WasmModuleObject::kSize;
    1471             :     case WASM_TABLE_TYPE:
    1472           0 :       return WasmTableObject::kSize;
    1473             :     default:
    1474          20 :       if (type >= FIRST_ARRAY_ITERATOR_TYPE &&
    1475             :           type <= LAST_ARRAY_ITERATOR_TYPE) {
    1476             :         return JSArrayIterator::kSize;
    1477             :       }
    1478           0 :       UNREACHABLE();
    1479             :   }
    1480             : }
    1481             : 
    1482             : // ES6 9.5.1
    1483             : // static
    1484     3790593 : MaybeHandle<Object> JSProxy::GetPrototype(Handle<JSProxy> proxy) {
    1485             :   Isolate* isolate = proxy->GetIsolate();
    1486             :   Handle<String> trap_name = isolate->factory()->getPrototypeOf_string();
    1487             : 
    1488     3790593 :   STACK_CHECK(isolate, MaybeHandle<Object>());
    1489             : 
    1490             :   // 1. Let handler be the value of the [[ProxyHandler]] internal slot.
    1491             :   // 2. If handler is null, throw a TypeError exception.
    1492             :   // 3. Assert: Type(handler) is Object.
    1493             :   // 4. Let target be the value of the [[ProxyTarget]] internal slot.
    1494     3790593 :   if (proxy->IsRevoked()) {
    1495          36 :     THROW_NEW_ERROR(isolate,
    1496             :                     NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
    1497             :                     Object);
    1498             :   }
    1499             :   Handle<JSReceiver> target(proxy->target(), isolate);
    1500             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    1501             : 
    1502             :   // 5. Let trap be ? GetMethod(handler, "getPrototypeOf").
    1503             :   Handle<Object> trap;
    1504     7581150 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, trap, GetMethod(handler, trap_name),
    1505             :                              Object);
    1506             :   // 6. If trap is undefined, then return target.[[GetPrototypeOf]]().
    1507     3790575 :   if (trap->IsUndefined(isolate)) {
    1508     2766197 :     return JSReceiver::GetPrototype(isolate, target);
    1509             :   }
    1510             :   // 7. Let handlerProto be ? Call(trap, handler, «target»).
    1511             :   Handle<Object> argv[] = {target};
    1512             :   Handle<Object> handler_proto;
    1513     2048756 :   ASSIGN_RETURN_ON_EXCEPTION(
    1514             :       isolate, handler_proto,
    1515             :       Execution::Call(isolate, trap, handler, arraysize(argv), argv), Object);
    1516             :   // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError.
    1517     1024306 :   if (!(handler_proto->IsJSReceiver() || handler_proto->IsNull(isolate))) {
    1518          18 :     THROW_NEW_ERROR(isolate,
    1519             :                     NewTypeError(MessageTemplate::kProxyGetPrototypeOfInvalid),
    1520             :                     Object);
    1521             :   }
    1522             :   // 9. Let extensibleTarget be ? IsExtensible(target).
    1523     1024270 :   Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
    1524     1024270 :   MAYBE_RETURN_NULL(is_extensible);
    1525             :   // 10. If extensibleTarget is true, return handlerProto.
    1526     1024270 :   if (is_extensible.FromJust()) return handler_proto;
    1527             :   // 11. Let targetProto be ? target.[[GetPrototypeOf]]().
    1528             :   Handle<Object> target_proto;
    1529           0 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, target_proto,
    1530             :                              JSReceiver::GetPrototype(isolate, target), Object);
    1531             :   // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError.
    1532           0 :   if (!handler_proto->SameValue(*target_proto)) {
    1533           0 :     THROW_NEW_ERROR(
    1534             :         isolate,
    1535             :         NewTypeError(MessageTemplate::kProxyGetPrototypeOfNonExtensible),
    1536             :         Object);
    1537             :   }
    1538             :   // 13. Return handlerProto.
    1539           0 :   return handler_proto;
    1540             : }
    1541             : 
    1542     6748099 : MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
    1543             :   Isolate* isolate = it->isolate();
    1544     6748099 :   Handle<Object> structure = it->GetAccessors();
    1545             :   Handle<Object> receiver = it->GetReceiver();
    1546             :   // In case of global IC, the receiver is the global object. Replace by the
    1547             :   // global proxy.
    1548     6748099 :   if (receiver->IsJSGlobalObject()) {
    1549             :     receiver = handle(JSGlobalObject::cast(*receiver)->global_proxy(), isolate);
    1550             :   }
    1551             : 
    1552             :   // We should never get here to initialize a const with the hole value since a
    1553             :   // const declaration would conflict with the getter.
    1554             :   DCHECK(!structure->IsForeign());
    1555             : 
    1556             :   // API style callbacks.
    1557             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1558     6748099 :   if (structure->IsAccessorInfo()) {
    1559      559923 :     Handle<Name> name = it->GetName();
    1560             :     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
    1561      559923 :     if (!info->IsCompatibleReceiver(*receiver)) {
    1562         180 :       THROW_NEW_ERROR(isolate,
    1563             :                       NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
    1564             :                                    name, receiver),
    1565             :                       Object);
    1566             :     }
    1567             : 
    1568             :     v8::AccessorNameGetterCallback call_fun =
    1569             :         v8::ToCData<v8::AccessorNameGetterCallback>(info->getter());
    1570      559953 :     if (call_fun == nullptr) return isolate->factory()->undefined_value();
    1571             : 
    1572      572711 :     if (info->is_sloppy() && !receiver->IsJSReceiver()) {
    1573          30 :       ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
    1574             :                                  Object::ConvertReceiver(isolate, receiver),
    1575             :                                  Object);
    1576             :     }
    1577             : 
    1578             :     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
    1579             :                                    Object::DONT_THROW);
    1580      559713 :     Handle<Object> result = args.Call(call_fun, name);
    1581      559713 :     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1582      567079 :     if (result.is_null()) return isolate->factory()->undefined_value();
    1583             :     Handle<Object> reboxed_result = handle(*result, isolate);
    1584      551943 :     if (info->replace_on_access() && receiver->IsJSReceiver()) {
    1585             :       args.Call(reinterpret_cast<GenericNamedPropertySetterCallback>(
    1586             :                     &Accessors::ReconfigureToDataProperty),
    1587           0 :                 name, result);
    1588           0 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1589             :     }
    1590      551943 :     return reboxed_result;
    1591             :   }
    1592             : 
    1593             :   // AccessorPair with 'cached' private property.
    1594     6188176 :   if (it->TryLookupCachedProperty()) {
    1595          51 :     return Object::GetProperty(it);
    1596             :   }
    1597             : 
    1598             :   // Regular accessor.
    1599             :   Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate);
    1600     6188125 :   if (getter->IsFunctionTemplateInfo()) {
    1601         667 :     SaveContext save(isolate);
    1602        1334 :     isolate->set_context(*holder->GetCreationContext());
    1603             :     return Builtins::InvokeApiFunction(
    1604             :         isolate, false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0,
    1605         667 :         nullptr, isolate->factory()->undefined_value());
    1606     6187458 :   } else if (getter->IsCallable()) {
    1607             :     // TODO(rossberg): nicer would be to cast to some JSCallable here...
    1608             :     return Object::GetPropertyWithDefinedGetter(
    1609     6182161 :         receiver, Handle<JSReceiver>::cast(getter));
    1610             :   }
    1611             :   // Getter is not a function.
    1612        5297 :   return isolate->factory()->undefined_value();
    1613             : }
    1614             : 
    1615             : // static
    1616           0 : Address AccessorInfo::redirect(Isolate* isolate, Address address,
    1617             :                                AccessorComponent component) {
    1618             :   ApiFunction fun(address);
    1619             :   DCHECK_EQ(ACCESSOR_GETTER, component);
    1620             :   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
    1621      317262 :   return ExternalReference(&fun, type, isolate).address();
    1622             : }
    1623             : 
    1624      159830 : Address AccessorInfo::redirected_getter() const {
    1625             :   Address accessor = v8::ToCData<Address>(getter());
    1626      159830 :   if (accessor == nullptr) return nullptr;
    1627      158631 :   return redirect(GetIsolate(), accessor, ACCESSOR_GETTER);
    1628             : }
    1629             : 
    1630      108163 : bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate,
    1631             :                                            Handle<AccessorInfo> info,
    1632             :                                            Handle<Map> map) {
    1633      108163 :   if (!info->HasExpectedReceiverType()) return true;
    1634          60 :   if (!map->IsJSObjectMap()) return false;
    1635             :   return FunctionTemplateInfo::cast(info->expected_receiver_type())
    1636          60 :       ->IsTemplateFor(*map);
    1637             : }
    1638             : 
    1639      626670 : Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
    1640             :                                             Handle<Object> value,
    1641             :                                             ShouldThrow should_throw) {
    1642             :   Isolate* isolate = it->isolate();
    1643      626670 :   Handle<Object> structure = it->GetAccessors();
    1644             :   Handle<Object> receiver = it->GetReceiver();
    1645             :   // In case of global IC, the receiver is the global object. Replace by the
    1646             :   // global proxy.
    1647      626670 :   if (receiver->IsJSGlobalObject()) {
    1648             :     receiver = handle(JSGlobalObject::cast(*receiver)->global_proxy(), isolate);
    1649             :   }
    1650             : 
    1651             :   // We should never get here to initialize a const with the hole value since a
    1652             :   // const declaration would conflict with the setter.
    1653             :   DCHECK(!structure->IsForeign());
    1654             : 
    1655             :   // API style callbacks.
    1656             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1657      626670 :   if (structure->IsAccessorInfo()) {
    1658      348644 :     Handle<Name> name = it->GetName();
    1659             :     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
    1660      348644 :     if (!info->IsCompatibleReceiver(*receiver)) {
    1661             :       isolate->Throw(*isolate->factory()->NewTypeError(
    1662         180 :           MessageTemplate::kIncompatibleMethodReceiver, name, receiver));
    1663             :       return Nothing<bool>();
    1664             :     }
    1665             : 
    1666             :     // The actual type of call_fun is either v8::AccessorNameSetterCallback or
    1667             :     // i::Accesors::AccessorNameBooleanSetterCallback, depending on whether the
    1668             :     // AccessorInfo was created by the API or internally (see accessors.cc).
    1669             :     // Here we handle both cases using GenericNamedPropertySetterCallback and
    1670             :     // its Call method.
    1671             :     GenericNamedPropertySetterCallback call_fun =
    1672             :         v8::ToCData<GenericNamedPropertySetterCallback>(info->setter());
    1673             : 
    1674      348554 :     if (call_fun == nullptr) {
    1675             :       // TODO(verwaest): We should not get here anymore once all AccessorInfos
    1676             :       // are marked as special_data_property. They cannot both be writable and
    1677             :       // not have a setter.
    1678             :       return Just(true);
    1679             :     }
    1680             : 
    1681      469106 :     if (info->is_sloppy() && !receiver->IsJSReceiver()) {
    1682           0 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1683             :           isolate, receiver, Object::ConvertReceiver(isolate, receiver),
    1684             :           Nothing<bool>());
    1685             :     }
    1686             : 
    1687             :     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
    1688             :                                    should_throw);
    1689      348488 :     Handle<Object> result = args.Call(call_fun, name, value);
    1690             :     // In the case of AccessorNameSetterCallback, we know that the result value
    1691             :     // cannot have been set, so the result of Call will be null.  In the case of
    1692             :     // AccessorNameBooleanSetterCallback, the result will either be null
    1693             :     // (signalling an exception) or a boolean Oddball.
    1694      348488 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    1695      348310 :     if (result.is_null()) return Just(true);
    1696             :     DCHECK(result->BooleanValue() || should_throw == DONT_THROW);
    1697      227758 :     return Just(result->BooleanValue());
    1698             :   }
    1699             : 
    1700             :   // Regular accessor.
    1701             :   Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
    1702      278026 :   if (setter->IsFunctionTemplateInfo()) {
    1703         534 :     SaveContext save(isolate);
    1704        1068 :     isolate->set_context(*holder->GetCreationContext());
    1705         534 :     Handle<Object> argv[] = {value};
    1706        1068 :     RETURN_ON_EXCEPTION_VALUE(
    1707             :         isolate, Builtins::InvokeApiFunction(
    1708             :                      isolate, false, Handle<FunctionTemplateInfo>::cast(setter),
    1709             :                      receiver, arraysize(argv), argv,
    1710             :                      isolate->factory()->undefined_value()),
    1711             :         Nothing<bool>());
    1712         534 :     return Just(true);
    1713      277492 :   } else if (setter->IsCallable()) {
    1714             :     // TODO(rossberg): nicer would be to cast to some JSCallable here...
    1715             :     return SetPropertyWithDefinedSetter(
    1716      265025 :         receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
    1717             :   }
    1718             : 
    1719       30554 :   RETURN_FAILURE(isolate, should_throw,
    1720             :                  NewTypeError(MessageTemplate::kNoSetterInCallback,
    1721             :                               it->GetName(), it->GetHolder<JSObject>()));
    1722             : }
    1723             : 
    1724             : 
    1725     6182161 : MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
    1726             :     Handle<Object> receiver,
    1727             :     Handle<JSReceiver> getter) {
    1728             :   Isolate* isolate = getter->GetIsolate();
    1729             : 
    1730             :   // Platforms with simulators like arm/arm64 expose a funny issue. If the
    1731             :   // simulator has a separate JS stack pointer from the C++ stack pointer, it
    1732             :   // can miss C++ stack overflows in the stack guard at the start of JavaScript
    1733             :   // functions. It would be very expensive to check the C++ stack pointer at
    1734             :   // that location. The best solution seems to be to break the impasse by
    1735             :   // adding checks at possible recursion points. What's more, we don't put
    1736             :   // this stack check behind the USE_SIMULATOR define in order to keep
    1737             :   // behavior the same between hardware and simulators.
    1738             :   StackLimitCheck check(isolate);
    1739     6182161 :   if (check.JsHasOverflowed()) {
    1740          26 :     isolate->StackOverflow();
    1741          26 :     return MaybeHandle<Object>();
    1742             :   }
    1743             : 
    1744     6182135 :   return Execution::Call(isolate, getter, receiver, 0, nullptr);
    1745             : }
    1746             : 
    1747             : 
    1748      265025 : Maybe<bool> Object::SetPropertyWithDefinedSetter(Handle<Object> receiver,
    1749             :                                                  Handle<JSReceiver> setter,
    1750             :                                                  Handle<Object> value,
    1751             :                                                  ShouldThrow should_throw) {
    1752             :   Isolate* isolate = setter->GetIsolate();
    1753             : 
    1754      265025 :   Handle<Object> argv[] = { value };
    1755      530050 :   RETURN_ON_EXCEPTION_VALUE(isolate, Execution::Call(isolate, setter, receiver,
    1756             :                                                      arraysize(argv), argv),
    1757             :                             Nothing<bool>());
    1758             :   return Just(true);
    1759             : }
    1760             : 
    1761             : 
    1762             : // static
    1763        4700 : bool JSObject::AllCanRead(LookupIterator* it) {
    1764             :   // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
    1765             :   // which have already been checked.
    1766             :   DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
    1767             :          it->state() == LookupIterator::INTERCEPTOR);
    1768        5840 :   for (it->Next(); it->IsFound(); it->Next()) {
    1769        1210 :     if (it->state() == LookupIterator::ACCESSOR) {
    1770         122 :       auto accessors = it->GetAccessors();
    1771         122 :       if (accessors->IsAccessorInfo()) {
    1772          77 :         if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
    1773             :       }
    1774        1088 :     } else if (it->state() == LookupIterator::INTERCEPTOR) {
    1775        1260 :       if (it->GetInterceptor()->all_can_read()) return true;
    1776         458 :     } else if (it->state() == LookupIterator::JSPROXY) {
    1777             :       // Stop lookupiterating. And no, AllCanNotRead.
    1778             :       return false;
    1779             :     }
    1780             :   }
    1781             :   return false;
    1782             : }
    1783             : 
    1784             : namespace {
    1785             : 
    1786       14107 : MaybeHandle<Object> GetPropertyWithInterceptorInternal(
    1787       28056 :     LookupIterator* it, Handle<InterceptorInfo> interceptor, bool* done) {
    1788       14107 :   *done = false;
    1789             :   Isolate* isolate = it->isolate();
    1790             :   // Make sure that the top context does not change when doing callbacks or
    1791             :   // interceptor calls.
    1792             :   AssertNoContextChange ncc(isolate);
    1793             : 
    1794       14107 :   if (interceptor->getter()->IsUndefined(isolate)) {
    1795         158 :     return isolate->factory()->undefined_value();
    1796             :   }
    1797             : 
    1798             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1799             :   Handle<Object> result;
    1800             :   Handle<Object> receiver = it->GetReceiver();
    1801       13949 :   if (!receiver->IsJSReceiver()) {
    1802          32 :     ASSIGN_RETURN_ON_EXCEPTION(
    1803             :         isolate, receiver, Object::ConvertReceiver(isolate, receiver), Object);
    1804             :   }
    1805             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1806             :                                  *holder, Object::DONT_THROW);
    1807             : 
    1808       13949 :   if (it->IsElement()) {
    1809             :     uint32_t index = it->index();
    1810             :     v8::IndexedPropertyGetterCallback getter =
    1811             :         v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
    1812        2404 :     result = args.Call(getter, index);
    1813             :   } else {
    1814       11545 :     Handle<Name> name = it->name();
    1815             :     DCHECK(!name->IsPrivate());
    1816             : 
    1817             :     DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
    1818             : 
    1819             :     v8::GenericNamedPropertyGetterCallback getter =
    1820             :         v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
    1821             :             interceptor->getter());
    1822       11545 :     result = args.Call(getter, name);
    1823             :   }
    1824             : 
    1825       13949 :   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1826       24614 :   if (result.is_null()) return isolate->factory()->undefined_value();
    1827        3236 :   *done = true;
    1828             :   // Rebox handle before return
    1829        3236 :   return handle(*result, isolate);
    1830             : }
    1831             : 
    1832      250419 : Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptorInternal(
    1833      500692 :     LookupIterator* it, Handle<InterceptorInfo> interceptor) {
    1834             :   Isolate* isolate = it->isolate();
    1835             :   // Make sure that the top context does not change when doing
    1836             :   // callbacks or interceptor calls.
    1837             :   AssertNoContextChange ncc(isolate);
    1838             :   HandleScope scope(isolate);
    1839             : 
    1840             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1841             :   DCHECK_IMPLIES(!it->IsElement() && it->name()->IsSymbol(),
    1842             :                  interceptor->can_intercept_symbols());
    1843             :   Handle<Object> receiver = it->GetReceiver();
    1844      250419 :   if (!receiver->IsJSReceiver()) {
    1845          24 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1846             :                                      Object::ConvertReceiver(isolate, receiver),
    1847             :                                      Nothing<PropertyAttributes>());
    1848             :   }
    1849             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1850             :                                  *holder, Object::DONT_THROW);
    1851      250419 :   if (!interceptor->query()->IsUndefined(isolate)) {
    1852             :     Handle<Object> result;
    1853         545 :     if (it->IsElement()) {
    1854             :       uint32_t index = it->index();
    1855             :       v8::IndexedPropertyQueryCallback query =
    1856             :           v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
    1857         314 :       result = args.Call(query, index);
    1858             :     } else {
    1859         231 :       Handle<Name> name = it->name();
    1860             :       DCHECK(!name->IsPrivate());
    1861             :       v8::GenericNamedPropertyQueryCallback query =
    1862             :           v8::ToCData<v8::GenericNamedPropertyQueryCallback>(
    1863             :               interceptor->query());
    1864         231 :       result = args.Call(query, name);
    1865             :     }
    1866         545 :     if (!result.is_null()) {
    1867             :       int32_t value;
    1868         370 :       CHECK(result->ToInt32(&value));
    1869         370 :       return Just(static_cast<PropertyAttributes>(value));
    1870             :     }
    1871      249874 :   } else if (!interceptor->getter()->IsUndefined(isolate)) {
    1872             :     // TODO(verwaest): Use GetPropertyWithInterceptor?
    1873             :     Handle<Object> result;
    1874      249728 :     if (it->IsElement()) {
    1875             :       uint32_t index = it->index();
    1876             :       v8::IndexedPropertyGetterCallback getter =
    1877             :           v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
    1878      240213 :       result = args.Call(getter, index);
    1879             :     } else {
    1880        9515 :       Handle<Name> name = it->name();
    1881             :       DCHECK(!name->IsPrivate());
    1882             :       v8::GenericNamedPropertyGetterCallback getter =
    1883             :           v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
    1884             :               interceptor->getter());
    1885        9515 :       result = args.Call(getter, name);
    1886             :     }
    1887      249728 :     if (!result.is_null()) return Just(DONT_ENUM);
    1888             :   }
    1889             : 
    1890      240634 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
    1891             :   return Just(ABSENT);
    1892             : }
    1893             : 
    1894      193438 : Maybe<bool> SetPropertyWithInterceptorInternal(
    1895      566504 :     LookupIterator* it, Handle<InterceptorInfo> interceptor,
    1896             :     Object::ShouldThrow should_throw, Handle<Object> value) {
    1897             :   Isolate* isolate = it->isolate();
    1898             :   // Make sure that the top context does not change when doing callbacks or
    1899             :   // interceptor calls.
    1900             :   AssertNoContextChange ncc(isolate);
    1901             : 
    1902      193438 :   if (interceptor->setter()->IsUndefined(isolate)) return Just(false);
    1903             : 
    1904             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1905             :   bool result;
    1906             :   Handle<Object> receiver = it->GetReceiver();
    1907      186533 :   if (!receiver->IsJSReceiver()) {
    1908           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1909             :                                      Object::ConvertReceiver(isolate, receiver),
    1910             :                                      Nothing<bool>());
    1911             :   }
    1912             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1913             :                                  *holder, should_throw);
    1914             : 
    1915      186533 :   if (it->IsElement()) {
    1916             :     uint32_t index = it->index();
    1917             :     v8::IndexedPropertySetterCallback setter =
    1918             :         v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
    1919             :     // TODO(neis): In the future, we may want to actually return the
    1920             :     // interceptor's result, which then should be a boolean.
    1921      131336 :     result = !args.Call(setter, index, value).is_null();
    1922             :   } else {
    1923      120865 :     Handle<Name> name = it->name();
    1924             :     DCHECK(!name->IsPrivate());
    1925             : 
    1926             :     DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
    1927             : 
    1928             :     v8::GenericNamedPropertySetterCallback setter =
    1929             :         v8::ToCData<v8::GenericNamedPropertySetterCallback>(
    1930             :             interceptor->setter());
    1931      241730 :     result = !args.Call(setter, name, value).is_null();
    1932             :   }
    1933             : 
    1934      186533 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    1935             :   return Just(result);
    1936             : }
    1937             : 
    1938         178 : Maybe<bool> DefinePropertyWithInterceptorInternal(
    1939         342 :     LookupIterator* it, Handle<InterceptorInfo> interceptor,
    1940             :     Object::ShouldThrow should_throw, PropertyDescriptor& desc) {
    1941             :   Isolate* isolate = it->isolate();
    1942             :   // Make sure that the top context does not change when doing callbacks or
    1943             :   // interceptor calls.
    1944             :   AssertNoContextChange ncc(isolate);
    1945             : 
    1946         178 :   if (interceptor->definer()->IsUndefined(isolate)) return Just(false);
    1947             : 
    1948             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1949             :   bool result;
    1950             :   Handle<Object> receiver = it->GetReceiver();
    1951          82 :   if (!receiver->IsJSReceiver()) {
    1952           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1953             :                                      Object::ConvertReceiver(isolate, receiver),
    1954             :                                      Nothing<bool>());
    1955             :   }
    1956             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1957             :                                  *holder, should_throw);
    1958             : 
    1959             :   std::unique_ptr<v8::PropertyDescriptor> descriptor(
    1960          82 :       new v8::PropertyDescriptor());
    1961          82 :   if (PropertyDescriptor::IsAccessorDescriptor(&desc)) {
    1962             :     descriptor.reset(new v8::PropertyDescriptor(
    1963          60 :         v8::Utils::ToLocal(desc.get()), v8::Utils::ToLocal(desc.set())));
    1964          52 :   } else if (PropertyDescriptor::IsDataDescriptor(&desc)) {
    1965          42 :     if (desc.has_writable()) {
    1966             :       descriptor.reset(new v8::PropertyDescriptor(
    1967          18 :           v8::Utils::ToLocal(desc.value()), desc.writable()));
    1968             :     } else {
    1969             :       descriptor.reset(
    1970          72 :           new v8::PropertyDescriptor(v8::Utils::ToLocal(desc.value())));
    1971             :     }
    1972             :   }
    1973          82 :   if (desc.has_enumerable()) {
    1974          12 :     descriptor->set_enumerable(desc.enumerable());
    1975             :   }
    1976          82 :   if (desc.has_configurable()) {
    1977          12 :     descriptor->set_configurable(desc.configurable());
    1978             :   }
    1979             : 
    1980          82 :   if (it->IsElement()) {
    1981             :     uint32_t index = it->index();
    1982             :     v8::IndexedPropertyDefinerCallback definer =
    1983             :         v8::ToCData<v8::IndexedPropertyDefinerCallback>(interceptor->definer());
    1984          46 :     result = !args.Call(definer, index, *descriptor).is_null();
    1985             :   } else {
    1986          59 :     Handle<Name> name = it->name();
    1987             :     DCHECK(!name->IsPrivate());
    1988             : 
    1989             :     DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
    1990             : 
    1991             :     v8::GenericNamedPropertyDefinerCallback definer =
    1992             :         v8::ToCData<v8::GenericNamedPropertyDefinerCallback>(
    1993             :             interceptor->definer());
    1994         118 :     result = !args.Call(definer, name, *descriptor).is_null();
    1995             :   }
    1996             : 
    1997          82 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    1998             :   return Just(result);
    1999             : }
    2000             : 
    2001             : }  // namespace
    2002             : 
    2003        1737 : MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
    2004        1808 :     LookupIterator* it) {
    2005             :   Isolate* isolate = it->isolate();
    2006        1737 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    2007             :   Handle<InterceptorInfo> interceptor =
    2008        1737 :       it->GetInterceptorForFailedAccessCheck();
    2009        1737 :   if (interceptor.is_null()) {
    2010        1609 :     while (AllCanRead(it)) {
    2011          46 :       if (it->state() == LookupIterator::ACCESSOR) {
    2012          52 :         return GetPropertyWithAccessor(it);
    2013             :       }
    2014             :       DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    2015             :       bool done;
    2016             :       Handle<Object> result;
    2017          60 :       ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
    2018             :                                  GetPropertyWithInterceptor(it, &done), Object);
    2019          30 :       if (done) return result;
    2020             :     }
    2021             : 
    2022             :   } else {
    2023             :     Handle<Object> result;
    2024             :     bool done;
    2025         276 :     ASSIGN_RETURN_ON_EXCEPTION(
    2026             :         isolate, result,
    2027             :         GetPropertyWithInterceptorInternal(it, interceptor, &done), Object);
    2028         126 :     if (done) return result;
    2029             :   }
    2030             : 
    2031             :   // Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns
    2032             :   // undefined.
    2033        1635 :   Handle<Name> name = it->GetName();
    2034        1665 :   if (name->IsSymbol() && Symbol::cast(*name)->is_well_known_symbol()) {
    2035          25 :     return it->factory()->undefined_value();
    2036             :   }
    2037             : 
    2038        1610 :   isolate->ReportFailedAccessCheck(checked);
    2039        1610 :   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    2040           0 :   return it->factory()->undefined_value();
    2041             : }
    2042             : 
    2043             : 
    2044         121 : Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
    2045         131 :     LookupIterator* it) {
    2046             :   Isolate* isolate = it->isolate();
    2047         121 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    2048             :   Handle<InterceptorInfo> interceptor =
    2049         121 :       it->GetInterceptorForFailedAccessCheck();
    2050         121 :   if (interceptor.is_null()) {
    2051         121 :     while (AllCanRead(it)) {
    2052          10 :       if (it->state() == LookupIterator::ACCESSOR) {
    2053             :         return Just(it->property_attributes());
    2054             :       }
    2055             :       DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    2056           0 :       auto result = GetPropertyAttributesWithInterceptor(it);
    2057           0 :       if (isolate->has_scheduled_exception()) break;
    2058           0 :       if (result.IsJust() && result.FromJust() != ABSENT) return result;
    2059             :     }
    2060             :   } else {
    2061             :     Maybe<PropertyAttributes> result =
    2062           0 :         GetPropertyAttributesWithInterceptorInternal(it, interceptor);
    2063           0 :     if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>();
    2064           0 :     if (result.FromMaybe(ABSENT) != ABSENT) return result;
    2065             :   }
    2066         111 :   isolate->ReportFailedAccessCheck(checked);
    2067         111 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
    2068             :   return Just(ABSENT);
    2069             : }
    2070             : 
    2071             : 
    2072             : // static
    2073         257 : bool JSObject::AllCanWrite(LookupIterator* it) {
    2074         366 :   for (; it->IsFound() && it->state() != LookupIterator::JSPROXY; it->Next()) {
    2075         119 :     if (it->state() == LookupIterator::ACCESSOR) {
    2076          25 :       Handle<Object> accessors = it->GetAccessors();
    2077          25 :       if (accessors->IsAccessorInfo()) {
    2078          15 :         if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
    2079             :       }
    2080             :     }
    2081             :   }
    2082             :   return false;
    2083             : }
    2084             : 
    2085             : 
    2086         110 : Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck(
    2087         110 :     LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) {
    2088             :   Isolate* isolate = it->isolate();
    2089         110 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    2090             :   Handle<InterceptorInfo> interceptor =
    2091         110 :       it->GetInterceptorForFailedAccessCheck();
    2092         110 :   if (interceptor.is_null()) {
    2093          74 :     if (AllCanWrite(it)) {
    2094          10 :       return SetPropertyWithAccessor(it, value, should_throw);
    2095             :     }
    2096             :   } else {
    2097             :     Maybe<bool> result = SetPropertyWithInterceptorInternal(
    2098          36 :         it, interceptor, should_throw, value);
    2099          72 :     if (isolate->has_pending_exception()) return Nothing<bool>();
    2100          24 :     if (result.IsJust()) return result;
    2101             :   }
    2102          64 :   isolate->ReportFailedAccessCheck(checked);
    2103          64 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    2104             :   return Just(true);
    2105             : }
    2106             : 
    2107             : 
    2108      512493 : void JSObject::SetNormalizedProperty(Handle<JSObject> object,
    2109             :                                      Handle<Name> name,
    2110             :                                      Handle<Object> value,
    2111             :                                      PropertyDetails details) {
    2112             :   DCHECK(!object->HasFastProperties());
    2113             :   DCHECK(name->IsUniqueName());
    2114             :   Isolate* isolate = object->GetIsolate();
    2115             : 
    2116             :   uint32_t hash = name->Hash();
    2117             : 
    2118      512493 :   if (object->IsJSGlobalObject()) {
    2119             :     Handle<JSGlobalObject> global_obj(JSGlobalObject::cast(*object));
    2120             :     Handle<GlobalDictionary> dictionary(global_obj->global_dictionary());
    2121       18482 :     int entry = dictionary->FindEntry(isolate, name, hash);
    2122             : 
    2123        9241 :     if (entry == GlobalDictionary::kNotFound) {
    2124        1057 :       auto cell = isolate->factory()->NewPropertyCell(name);
    2125        1057 :       cell->set_value(*value);
    2126             :       auto cell_type = value->IsUndefined(isolate)
    2127             :                            ? PropertyCellType::kUndefined
    2128        1057 :                            : PropertyCellType::kConstant;
    2129             :       details = details.set_cell_type(cell_type);
    2130             :       value = cell;
    2131        1057 :       dictionary = GlobalDictionary::Add(dictionary, name, value, details);
    2132             :       global_obj->set_global_dictionary(*dictionary);
    2133             :     } else {
    2134             :       Handle<PropertyCell> cell =
    2135        8184 :           PropertyCell::PrepareForValue(dictionary, entry, value, details);
    2136        8184 :       cell->set_value(*value);
    2137             :     }
    2138             :   } else {
    2139             :     Handle<NameDictionary> dictionary(object->property_dictionary());
    2140             : 
    2141             :     int entry = dictionary->FindEntry(name);
    2142      503252 :     if (entry == NameDictionary::kNotFound) {
    2143      168520 :       dictionary = NameDictionary::Add(dictionary, name, value, details);
    2144      168520 :       object->SetProperties(*dictionary);
    2145             :     } else {
    2146             :       PropertyDetails original_details = dictionary->DetailsAt(entry);
    2147             :       int enumeration_index = original_details.dictionary_index();
    2148             :       DCHECK_GT(enumeration_index, 0);
    2149             :       details = details.set_index(enumeration_index);
    2150      334732 :       dictionary->SetEntry(entry, *name, *value, details);
    2151             :     }
    2152             :   }
    2153      512493 : }
    2154             : 
    2155             : // static
    2156        1280 : Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate,
    2157             :                                             Handle<JSReceiver> object,
    2158             :                                             Handle<Object> proto) {
    2159        1280 :   PrototypeIterator iter(isolate, object, kStartAtReceiver);
    2160             :   while (true) {
    2161     3893561 :     if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
    2162     3893452 :     if (iter.IsAtEnd()) return Just(false);
    2163     3892681 :     if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) {
    2164             :       return Just(true);
    2165             :     }
    2166             :   }
    2167             : }
    2168             : 
    2169             : namespace {
    2170             : 
    2171         450 : bool HasExcludedProperty(
    2172             :     const ScopedVector<Handle<Object>>* excluded_properties,
    2173             :     Handle<Object> search_element) {
    2174             :   // TODO(gsathya): Change this to be a hashtable.
    2175        1422 :   for (int i = 0; i < excluded_properties->length(); i++) {
    2176        1575 :     if (search_element->SameValue(*excluded_properties->at(i))) {
    2177             :       return true;
    2178             :     }
    2179             :   }
    2180             : 
    2181             :   return false;
    2182             : }
    2183             : 
    2184         879 : MUST_USE_RESULT Maybe<bool> FastAssign(
    2185             :     Handle<JSReceiver> target, Handle<Object> source,
    2186             :     const ScopedVector<Handle<Object>>* excluded_properties, bool use_set) {
    2187             :   // Non-empty strings are the only non-JSReceivers that need to be handled
    2188             :   // explicitly by Object.assign.
    2189         879 :   if (!source->IsJSReceiver()) {
    2190          45 :     return Just(!source->IsString() || String::cast(*source)->length() == 0);
    2191             :   }
    2192             : 
    2193             :   // If the target is deprecated, the object will be updated on first store. If
    2194             :   // the source for that store equals the target, this will invalidate the
    2195             :   // cached representation of the source. Preventively upgrade the target.
    2196             :   // Do this on each iteration since any property load could cause deprecation.
    2197         852 :   if (target->map()->is_deprecated()) {
    2198          20 :     JSObject::MigrateInstance(Handle<JSObject>::cast(target));
    2199             :   }
    2200             : 
    2201             :   Isolate* isolate = target->GetIsolate();
    2202             :   Handle<Map> map(JSReceiver::cast(*source)->map(), isolate);
    2203             : 
    2204         852 :   if (!map->IsJSObjectMap()) return Just(false);
    2205         762 :   if (!map->OnlyHasSimpleProperties()) return Just(false);
    2206             : 
    2207             :   Handle<JSObject> from = Handle<JSObject>::cast(source);
    2208         679 :   if (from->elements() != isolate->heap()->empty_fixed_array()) {
    2209             :     return Just(false);
    2210             :   }
    2211             : 
    2212             :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    2213             :   int length = map->NumberOfOwnDescriptors();
    2214             : 
    2215             :   bool stable = true;
    2216             : 
    2217        1952 :   for (int i = 0; i < length; i++) {
    2218             :     Handle<Name> next_key(descriptors->GetKey(i), isolate);
    2219             :     Handle<Object> prop_value;
    2220             :     // Directly decode from the descriptor array if |from| did not change shape.
    2221        1372 :     if (stable) {
    2222        1294 :       PropertyDetails details = descriptors->GetDetails(i);
    2223        1294 :       if (!details.IsEnumerable()) continue;
    2224        1216 :       if (details.kind() == kData) {
    2225        1216 :         if (details.location() == kDescriptor) {
    2226         420 :           prop_value = handle(descriptors->GetValue(i), isolate);
    2227             :         } else {
    2228         796 :           Representation representation = details.representation();
    2229         796 :           FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    2230         796 :           prop_value = JSObject::FastPropertyAt(from, representation, index);
    2231             :         }
    2232             :       } else {
    2233           0 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2234             :             isolate, prop_value, JSReceiver::GetProperty(from, next_key),
    2235             :             Nothing<bool>());
    2236           0 :         stable = from->map() == *map;
    2237             :       }
    2238             :     } else {
    2239             :       // If the map did change, do a slower lookup. We are still guaranteed that
    2240             :       // the object has a simple shape, and that the key is a name.
    2241             :       LookupIterator it(from, next_key, from,
    2242          78 :                         LookupIterator::OWN_SKIP_INTERCEPTOR);
    2243          87 :       if (!it.IsFound()) continue;
    2244             :       DCHECK(it.state() == LookupIterator::DATA ||
    2245             :              it.state() == LookupIterator::ACCESSOR);
    2246          78 :       if (!it.IsEnumerable()) continue;
    2247         138 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2248             :           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
    2249             :     }
    2250             : 
    2251        1285 :     if (use_set) {
    2252         763 :       LookupIterator it(target, next_key, target);
    2253             :       Maybe<bool> result =
    2254             :           Object::SetProperty(&it, prop_value, LanguageMode::kStrict,
    2255         763 :                               Object::CERTAINLY_NOT_STORE_FROM_KEYED);
    2256         763 :       if (result.IsNothing()) return result;
    2257        1403 :       if (stable) stable = from->map() == *map;
    2258             :     } else {
    2259        1566 :       if (excluded_properties != nullptr &&
    2260        1116 :           HasExcludedProperty(excluded_properties, next_key)) {
    2261          99 :         continue;
    2262             :       }
    2263             : 
    2264             :       // 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue).
    2265             :       bool success;
    2266             :       LookupIterator it = LookupIterator::PropertyOrElement(
    2267         423 :           isolate, target, next_key, &success, LookupIterator::OWN);
    2268         423 :       CHECK(success);
    2269         846 :       CHECK(
    2270             :           JSObject::CreateDataProperty(&it, prop_value, Object::THROW_ON_ERROR)
    2271             :               .FromJust());
    2272             :     }
    2273             :   }
    2274             : 
    2275             :   return Just(true);
    2276             : }
    2277             : }  // namespace
    2278             : 
    2279             : // static
    2280         879 : Maybe<bool> JSReceiver::SetOrCopyDataProperties(
    2281             :     Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
    2282             :     const ScopedVector<Handle<Object>>* excluded_properties, bool use_set) {
    2283             :   Maybe<bool> fast_assign =
    2284         879 :       FastAssign(target, source, excluded_properties, use_set);
    2285         879 :   if (fast_assign.IsNothing()) return Nothing<bool>();
    2286         852 :   if (fast_assign.FromJust()) return Just(true);
    2287             : 
    2288         526 :   Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked();
    2289             :   // 3b. Let keys be ? from.[[OwnPropertyKeys]]().
    2290             :   Handle<FixedArray> keys;
    2291         526 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2292             :       isolate, keys,
    2293             :       KeyAccumulator::GetKeys(from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
    2294             :                               GetKeysConversion::kKeepNumbers),
    2295             :       Nothing<bool>());
    2296             : 
    2297             :   // 4. Repeat for each element nextKey of keys in List order,
    2298        3153 :   for (int j = 0; j < keys->length(); ++j) {
    2299             :     Handle<Object> next_key(keys->get(j), isolate);
    2300             :     // 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey).
    2301             :     PropertyDescriptor desc;
    2302             :     Maybe<bool> found =
    2303        1499 :         JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc);
    2304        1526 :     if (found.IsNothing()) return Nothing<bool>();
    2305             :     // 4a ii. If desc is not undefined and desc.[[Enumerable]] is true, then
    2306        2998 :     if (found.FromJust() && desc.enumerable()) {
    2307             :       // 4a ii 1. Let propValue be ? Get(from, nextKey).
    2308             :       Handle<Object> prop_value;
    2309        1853 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2310             :           isolate, prop_value,
    2311             :           Runtime::GetObjectProperty(isolate, from, next_key), Nothing<bool>());
    2312             : 
    2313         886 :       if (use_set) {
    2314             :         // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true).
    2315             :         Handle<Object> status;
    2316        1340 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2317             :             isolate, status,
    2318             :             Runtime::SetObjectProperty(isolate, target, next_key, prop_value,
    2319             :                                        LanguageMode::kStrict),
    2320             :             Nothing<bool>());
    2321             :       } else {
    2322         369 :         if (excluded_properties != nullptr &&
    2323         153 :             HasExcludedProperty(excluded_properties, next_key)) {
    2324          72 :           continue;
    2325             :         }
    2326             : 
    2327             :         // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue).
    2328             :         bool success;
    2329             :         LookupIterator it = LookupIterator::PropertyOrElement(
    2330         144 :             isolate, target, next_key, &success, LookupIterator::OWN);
    2331         144 :         CHECK(success);
    2332         288 :         CHECK(JSObject::CreateDataProperty(&it, prop_value,
    2333             :                                            Object::THROW_ON_ERROR)
    2334             :                   .FromJust());
    2335             :       }
    2336             :     }
    2337             :   }
    2338             : 
    2339             :   return Just(true);
    2340             : }
    2341             : 
    2342      182833 : Map* Object::GetPrototypeChainRootMap(Isolate* isolate) const {
    2343             :   DisallowHeapAllocation no_alloc;
    2344      163925 :   if (IsSmi()) {
    2345             :     Context* native_context = isolate->context()->native_context();
    2346       18908 :     return native_context->number_function()->initial_map();
    2347             :   }
    2348             : 
    2349             :   const HeapObject* heap_object = HeapObject::cast(this);
    2350      145017 :   return heap_object->map()->GetPrototypeChainRootMap(isolate);
    2351             : }
    2352             : 
    2353     3909404 : Map* Map::GetPrototypeChainRootMap(Isolate* isolate) const {
    2354             :   DisallowHeapAllocation no_alloc;
    2355     3659132 :   if (IsJSReceiverMap()) {
    2356             :     return const_cast<Map*>(this);
    2357             :   }
    2358             :   int constructor_function_index = GetConstructorFunctionIndex();
    2359      250272 :   if (constructor_function_index != Map::kNoConstructorFunctionIndex) {
    2360             :     Context* native_context = isolate->context()->native_context();
    2361             :     JSFunction* constructor_function =
    2362             :         JSFunction::cast(native_context->get(constructor_function_index));
    2363      250272 :     return constructor_function->initial_map();
    2364             :   }
    2365           0 :   return isolate->heap()->null_value()->map();
    2366             : }
    2367             : 
    2368             : namespace {
    2369             : 
    2370             : // Returns a non-SMI for JSReceivers, but returns the hash code for simple
    2371             : // objects.  This avoids a double lookup in the cases where we know we will
    2372             : // add the hash to the JSReceiver if it does not already exist.
    2373    51590512 : Object* GetSimpleHash(Object* object) {
    2374             :   DisallowHeapAllocation no_gc;
    2375    51590512 :   if (object->IsSmi()) {
    2376      991850 :     uint32_t hash = ComputeIntegerHash(Smi::ToInt(object));
    2377     1983700 :     return Smi::FromInt(hash & Smi::kMaxValue);
    2378             :   }
    2379    50598658 :   if (object->IsHeapNumber()) {
    2380             :     double num = HeapNumber::cast(object)->value();
    2381        5901 :     if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue);
    2382        5446 :     if (i::IsMinusZero(num)) num = 0;
    2383        5446 :     if (IsSmiDouble(num)) {
    2384         476 :       return Smi::FromInt(FastD2I(num))->GetHash();
    2385             :     }
    2386             :     uint32_t hash = ComputeLongHash(double_to_uint64(num));
    2387        9940 :     return Smi::FromInt(hash & Smi::kMaxValue);
    2388             :   }
    2389    50592751 :   if (object->IsName()) {
    2390             :     uint32_t hash = Name::cast(object)->Hash();
    2391   101125300 :     return Smi::FromInt(hash);
    2392             :   }
    2393       30082 :   if (object->IsOddball()) {
    2394             :     uint32_t hash = Oddball::cast(object)->to_string()->Hash();
    2395        2826 :     return Smi::FromInt(hash);
    2396             :   }
    2397       28669 :   if (object->IsBigInt()) {
    2398         216 :     uint32_t hash = BigInt::cast(object)->Hash();
    2399         432 :     return Smi::FromInt(hash & Smi::kMaxValue);
    2400             :   }
    2401             :   DCHECK(object->IsJSReceiver());
    2402             :   return object;
    2403             : }
    2404             : 
    2405             : }  // namespace
    2406             : 
    2407     4703050 : Object* Object::GetHash() {
    2408             :   DisallowHeapAllocation no_gc;
    2409     4703050 :   Object* hash = GetSimpleHash(this);
    2410     4703050 :   if (hash->IsSmi()) return hash;
    2411             : 
    2412             :   DCHECK(IsJSReceiver());
    2413             :   JSReceiver* receiver = JSReceiver::cast(this);
    2414             :   Isolate* isolate = receiver->GetIsolate();
    2415       16960 :   return receiver->GetIdentityHash(isolate);
    2416             : }
    2417             : 
    2418             : // static
    2419        7938 : Smi* Object::GetOrCreateHash(Isolate* isolate, Object* key) {
    2420             :   DisallowHeapAllocation no_gc;
    2421        7938 :   return key->GetOrCreateHash(isolate);
    2422             : }
    2423             : 
    2424    46887464 : Smi* Object::GetOrCreateHash(Isolate* isolate) {
    2425             :   DisallowHeapAllocation no_gc;
    2426    46887464 :   Object* hash = GetSimpleHash(this);
    2427    46887464 :   if (hash->IsSmi()) return Smi::cast(hash);
    2428             : 
    2429             :   DCHECK(IsJSReceiver());
    2430       11493 :   return JSReceiver::cast(this)->GetOrCreateIdentityHash(isolate);
    2431             : }
    2432             : 
    2433             : 
    2434      938477 : bool Object::SameValue(Object* other) {
    2435      938477 :   if (other == this) return true;
    2436             : 
    2437      204304 :   if (IsNumber() && other->IsNumber()) {
    2438             :     double this_value = Number();
    2439             :     double other_value = other->Number();
    2440             :     // SameValue(NaN, NaN) is true.
    2441       23756 :     if (this_value != other_value) {
    2442       20904 :       return std::isnan(this_value) && std::isnan(other_value);
    2443             :     }
    2444             :     // SameValue(0.0, -0.0) is false.
    2445        2852 :     return (std::signbit(this_value) == std::signbit(other_value));
    2446             :   }
    2447      260075 :   if (IsString() && other->IsString()) {
    2448      112465 :     return String::cast(this)->Equals(String::cast(other));
    2449             :   }
    2450       34210 :   if (IsBigInt() && other->IsBigInt()) {
    2451          45 :     return BigInt::EqualToBigInt(BigInt::cast(this), BigInt::cast(other));
    2452             :   }
    2453             :   return false;
    2454             : }
    2455             : 
    2456             : 
    2457    19204640 : bool Object::SameValueZero(Object* other) {
    2458    19204640 :   if (other == this) return true;
    2459             : 
    2460    19566217 :   if (IsNumber() && other->IsNumber()) {
    2461             :     double this_value = Number();
    2462             :     double other_value = other->Number();
    2463             :     // +0 == -0 is true
    2464      366498 :     return this_value == other_value ||
    2465          14 :            (std::isnan(this_value) && std::isnan(other_value));
    2466             :   }
    2467    37650299 :   if (IsString() && other->IsString()) {
    2468    18819586 :     return String::cast(this)->Equals(String::cast(other));
    2469             :   }
    2470       10639 :   if (IsBigInt() && other->IsBigInt()) {
    2471          18 :     return BigInt::EqualToBigInt(BigInt::cast(this), BigInt::cast(other));
    2472             :   }
    2473             :   return false;
    2474             : }
    2475             : 
    2476             : 
    2477       11246 : MaybeHandle<Object> Object::ArraySpeciesConstructor(
    2478             :     Isolate* isolate, Handle<Object> original_array) {
    2479       11246 :   Handle<Object> default_species = isolate->array_function();
    2480       19214 :   if (original_array->IsJSArray() &&
    2481       26027 :       Handle<JSArray>::cast(original_array)->HasArrayPrototype(isolate) &&
    2482             :       isolate->IsArraySpeciesLookupChainIntact()) {
    2483        6271 :     return default_species;
    2484             :   }
    2485             :   Handle<Object> constructor = isolate->factory()->undefined_value();
    2486             :   Maybe<bool> is_array = Object::IsArray(original_array);
    2487        4975 :   MAYBE_RETURN_NULL(is_array);
    2488        4975 :   if (is_array.FromJust()) {
    2489        3486 :     ASSIGN_RETURN_ON_EXCEPTION(
    2490             :         isolate, constructor,
    2491             :         Object::GetProperty(original_array,
    2492             :                             isolate->factory()->constructor_string()),
    2493             :         Object);
    2494        1734 :     if (constructor->IsConstructor()) {
    2495             :       Handle<Context> constructor_context;
    2496        3060 :       ASSIGN_RETURN_ON_EXCEPTION(
    2497             :           isolate, constructor_context,
    2498             :           JSReceiver::GetFunctionRealm(Handle<JSReceiver>::cast(constructor)),
    2499             :           Object);
    2500        3078 :       if (*constructor_context != *isolate->native_context() &&
    2501             :           *constructor == constructor_context->array_function()) {
    2502             :         constructor = isolate->factory()->undefined_value();
    2503             :       }
    2504             :     }
    2505        1734 :     if (constructor->IsJSReceiver()) {
    2506        3076 :       ASSIGN_RETURN_ON_EXCEPTION(
    2507             :           isolate, constructor,
    2508             :           JSReceiver::GetProperty(Handle<JSReceiver>::cast(constructor),
    2509             :                                   isolate->factory()->species_symbol()),
    2510             :           Object);
    2511        1529 :       if (constructor->IsNull(isolate)) {
    2512             :         constructor = isolate->factory()->undefined_value();
    2513             :       }
    2514             :     }
    2515             :   }
    2516        4957 :   if (constructor->IsUndefined(isolate)) {
    2517        3457 :     return default_species;
    2518             :   } else {
    2519        1500 :     if (!constructor->IsConstructor()) {
    2520           0 :       THROW_NEW_ERROR(isolate,
    2521             :           NewTypeError(MessageTemplate::kSpeciesNotConstructor),
    2522             :           Object);
    2523             :     }
    2524        1500 :     return constructor;
    2525             :   }
    2526             : }
    2527             : 
    2528             : // ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
    2529       11494 : MUST_USE_RESULT MaybeHandle<Object> Object::SpeciesConstructor(
    2530             :     Isolate* isolate, Handle<JSReceiver> recv,
    2531             :     Handle<JSFunction> default_ctor) {
    2532             :   Handle<Object> ctor_obj;
    2533       22988 :   ASSIGN_RETURN_ON_EXCEPTION(
    2534             :       isolate, ctor_obj,
    2535             :       JSObject::GetProperty(recv, isolate->factory()->constructor_string()),
    2536             :       Object);
    2537             : 
    2538       11413 :   if (ctor_obj->IsUndefined(isolate)) return default_ctor;
    2539             : 
    2540       11323 :   if (!ctor_obj->IsJSReceiver()) {
    2541           0 :     THROW_NEW_ERROR(isolate,
    2542             :                     NewTypeError(MessageTemplate::kConstructorNotReceiver),
    2543             :                     Object);
    2544             :   }
    2545             : 
    2546       11323 :   Handle<JSReceiver> ctor = Handle<JSReceiver>::cast(ctor_obj);
    2547             : 
    2548             :   Handle<Object> species;
    2549       22646 :   ASSIGN_RETURN_ON_EXCEPTION(
    2550             :       isolate, species,
    2551             :       JSObject::GetProperty(ctor, isolate->factory()->species_symbol()),
    2552             :       Object);
    2553             : 
    2554       11242 :   if (species->IsNullOrUndefined(isolate)) {
    2555          81 :     return default_ctor;
    2556             :   }
    2557             : 
    2558       11161 :   if (species->IsConstructor()) return species;
    2559             : 
    2560           0 :   THROW_NEW_ERROR(
    2561             :       isolate, NewTypeError(MessageTemplate::kSpeciesNotConstructor), Object);
    2562             : }
    2563             : 
    2564       25453 : bool Object::IterationHasObservableEffects() {
    2565             :   // Check that this object is an array.
    2566       25453 :   if (!IsJSArray()) return true;
    2567             :   JSArray* array = JSArray::cast(this);
    2568             :   Isolate* isolate = array->GetIsolate();
    2569             : 
    2570             :   // Check that we have the original ArrayPrototype.
    2571       25453 :   if (!array->map()->prototype()->IsJSObject()) return true;
    2572             :   JSObject* array_proto = JSObject::cast(array->map()->prototype());
    2573       25443 :   if (!isolate->is_initial_array_prototype(array_proto)) return true;
    2574             : 
    2575             :   // Check that the ArrayPrototype hasn't been modified in a way that would
    2576             :   // affect iteration.
    2577       25281 :   if (!isolate->IsArrayIteratorLookupChainIntact()) return true;
    2578             : 
    2579             :   // Check that the map of the initial array iterator hasn't changed.
    2580       47812 :   Map* iterator_map = isolate->initial_array_iterator_prototype()->map();
    2581       23906 :   if (!isolate->is_initial_array_iterator_prototype_map(iterator_map)) {
    2582             :     return true;
    2583             :   }
    2584             : 
    2585             :   // For FastPacked kinds, iteration will have the same effect as simply
    2586             :   // accessing each property in order.
    2587             :   ElementsKind array_kind = array->GetElementsKind();
    2588       23906 :   if (IsFastPackedElementsKind(array_kind)) return false;
    2589             : 
    2590             :   // For FastHoley kinds, an element access on a hole would cause a lookup on
    2591             :   // the prototype. This could have different results if the prototype has been
    2592             :   // changed.
    2593        8056 :   if (IsHoleyElementsKind(array_kind) &&
    2594        4028 :       isolate->IsFastArrayConstructorPrototypeChainIntact()) {
    2595             :     return false;
    2596             :   }
    2597         175 :   return true;
    2598             : }
    2599             : 
    2600          24 : void Object::ShortPrint(FILE* out) {
    2601          24 :   OFStream os(out);
    2602          24 :   os << Brief(this);
    2603          24 : }
    2604             : 
    2605             : 
    2606          50 : void Object::ShortPrint(StringStream* accumulator) {
    2607          50 :   std::ostringstream os;
    2608          50 :   os << Brief(this);
    2609         100 :   accumulator->Add(os.str().c_str());
    2610          50 : }
    2611             : 
    2612             : 
    2613           0 : void Object::ShortPrint(std::ostream& os) { os << Brief(this); }
    2614             : 
    2615             : 
    2616        1125 : std::ostream& operator<<(std::ostream& os, const Brief& v) {
    2617        2250 :   if (v.value->IsSmi()) {
    2618             :     Smi::cast(v.value)->SmiPrint(os);
    2619             :   } else {
    2620             :     // TODO(svenpanne) Const-correct HeapObjectShortPrint!
    2621             :     HeapObject* obj = const_cast<HeapObject*>(HeapObject::cast(v.value));
    2622         933 :     obj->HeapObjectShortPrint(os);
    2623             :   }
    2624        1125 :   return os;
    2625             : }
    2626             : 
    2627        1056 : void Smi::SmiPrint(std::ostream& os) const {  // NOLINT
    2628        1248 :   os << value();
    2629        1056 : }
    2630             : 
    2631     4013358 : Handle<String> String::SlowFlatten(Handle<ConsString> cons,
    2632             :                                    PretenureFlag pretenure) {
    2633             :   DCHECK_NE(cons->second()->length(), 0);
    2634             : 
    2635             :   // TurboFan can create cons strings with empty first parts.
    2636     8026724 :   while (cons->first()->length() == 0) {
    2637             :     // We do not want to call this function recursively. Therefore we call
    2638             :     // String::Flatten only in those cases where String::SlowFlatten is not
    2639             :     // called again.
    2640          39 :     if (cons->second()->IsConsString() && !cons->second()->IsFlat()) {
    2641             :       cons = handle(ConsString::cast(cons->second()));
    2642             :     } else {
    2643          23 :       return String::Flatten(handle(cons->second()));
    2644             :     }
    2645             :   }
    2646             : 
    2647             :   DCHECK(AllowHeapAllocation::IsAllowed());
    2648             :   Isolate* isolate = cons->GetIsolate();
    2649             :   int length = cons->length();
    2650             :   PretenureFlag tenure = isolate->heap()->InNewSpace(*cons) ? pretenure
    2651     4013335 :                                                             : TENURED;
    2652             :   Handle<SeqString> result;
    2653     4013335 :   if (cons->IsOneByteRepresentation()) {
    2654             :     Handle<SeqOneByteString> flat = isolate->factory()->NewRawOneByteString(
    2655     7690742 :         length, tenure).ToHandleChecked();
    2656             :     DisallowHeapAllocation no_gc;
    2657     7690742 :     WriteToFlat(*cons, flat->GetChars(), 0, length);
    2658             :     result = flat;
    2659             :   } else {
    2660             :     Handle<SeqTwoByteString> flat = isolate->factory()->NewRawTwoByteString(
    2661      335928 :         length, tenure).ToHandleChecked();
    2662             :     DisallowHeapAllocation no_gc;
    2663      335928 :     WriteToFlat(*cons, flat->GetChars(), 0, length);
    2664             :     result = flat;
    2665             :   }
    2666     4013335 :   cons->set_first(*result);
    2667     8026670 :   cons->set_second(isolate->heap()->empty_string());
    2668             :   DCHECK(result->IsFlat());
    2669     4013335 :   return result;
    2670             : }
    2671             : 
    2672             : 
    2673             : 
    2674         335 : bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
    2675             :   DisallowHeapAllocation no_allocation;
    2676             :   // Externalizing twice leaks the external resource, so it's
    2677             :   // prohibited by the API.
    2678             :   DCHECK(!this->IsExternalString());
    2679             :   DCHECK(!resource->IsCompressible());
    2680             : #ifdef ENABLE_SLOW_DCHECKS
    2681             :   if (FLAG_enable_slow_asserts) {
    2682             :     // Assert that the resource and the string are equivalent.
    2683             :     DCHECK(static_cast<size_t>(this->length()) == resource->length());
    2684             :     ScopedVector<uc16> smart_chars(this->length());
    2685             :     String::WriteToFlat(this, smart_chars.start(), 0, this->length());
    2686             :     DCHECK_EQ(0, memcmp(smart_chars.start(), resource->data(),
    2687             :                         resource->length() * sizeof(smart_chars[0])));
    2688             :   }
    2689             : #endif  // DEBUG
    2690         335 :   int size = this->Size();  // Byte size of the original string.
    2691             :   // Abort if size does not allow in-place conversion.
    2692         335 :   if (size < ExternalString::kShortSize) return false;
    2693         203 :   Heap* heap = GetHeap();
    2694             :   bool is_one_byte = this->IsOneByteRepresentation();
    2695             :   bool is_internalized = this->IsInternalizedString();
    2696             :   bool has_pointers = StringShape(this).IsIndirect();
    2697         335 :   if (has_pointers) {
    2698          61 :     heap->NotifyObjectLayoutChange(this, size, no_allocation);
    2699             :   }
    2700             :   // Morph the string to an external string by replacing the map and
    2701             :   // reinitializing the fields.  This won't work if the space the existing
    2702             :   // string occupies is too small for a regular  external string.
    2703             :   // Instead, we resort to a short external string instead, omitting
    2704             :   // the field caching the address of the backing store.  When we encounter
    2705             :   // short external strings in generated code, we need to bailout to runtime.
    2706             :   Map* new_map;
    2707         335 :   if (size < ExternalString::kSize) {
    2708             :     new_map = is_internalized
    2709             :         ? (is_one_byte
    2710             :            ? heap->short_external_internalized_string_with_one_byte_data_map()
    2711             :            : heap->short_external_internalized_string_map())
    2712             :         : (is_one_byte ? heap->short_external_string_with_one_byte_data_map()
    2713         223 :                        : heap->short_external_string_map());
    2714             :   } else {
    2715             :     new_map = is_internalized
    2716             :         ? (is_one_byte
    2717             :            ? heap->external_internalized_string_with_one_byte_data_map()
    2718             :            : heap->external_internalized_string_map())
    2719             :         : (is_one_byte ? heap->external_string_with_one_byte_data_map()
    2720         385 :                        : heap->external_string_map());
    2721             :   }
    2722             : 
    2723             :   // Byte size of the external String object.
    2724         335 :   int new_size = this->SizeFromMap(new_map);
    2725         335 :   heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
    2726         670 :                              ClearRecordedSlots::kNo);
    2727         335 :   if (has_pointers) {
    2728          61 :     heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
    2729             :   }
    2730             : 
    2731             :   // We are storing the new map using release store after creating a filler for
    2732             :   // the left-over space to avoid races with the sweeper thread.
    2733         335 :   this->synchronized_set_map(new_map);
    2734             : 
    2735             :   ExternalTwoByteString* self = ExternalTwoByteString::cast(this);
    2736             :   self->set_resource(resource);
    2737         335 :   if (is_internalized) self->Hash();  // Force regeneration of the hash value.
    2738             :   return true;
    2739             : }
    2740             : 
    2741             : 
    2742         329 : bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
    2743             :   DisallowHeapAllocation no_allocation;
    2744             :   // Externalizing twice leaks the external resource, so it's
    2745             :   // prohibited by the API.
    2746             :   DCHECK(!this->IsExternalString());
    2747             :   DCHECK(!resource->IsCompressible());
    2748             : #ifdef ENABLE_SLOW_DCHECKS
    2749             :   if (FLAG_enable_slow_asserts) {
    2750             :     // Assert that the resource and the string are equivalent.
    2751             :     DCHECK(static_cast<size_t>(this->length()) == resource->length());
    2752             :     if (this->IsTwoByteRepresentation()) {
    2753             :       ScopedVector<uint16_t> smart_chars(this->length());
    2754             :       String::WriteToFlat(this, smart_chars.start(), 0, this->length());
    2755             :       DCHECK(String::IsOneByte(smart_chars.start(), this->length()));
    2756             :     }
    2757             :     ScopedVector<char> smart_chars(this->length());
    2758             :     String::WriteToFlat(this, smart_chars.start(), 0, this->length());
    2759             :     DCHECK_EQ(0, memcmp(smart_chars.start(), resource->data(),
    2760             :                         resource->length() * sizeof(smart_chars[0])));
    2761             :   }
    2762             : #endif  // DEBUG
    2763         329 :   int size = this->Size();  // Byte size of the original string.
    2764             :   // Abort if size does not allow in-place conversion.
    2765         329 :   if (size < ExternalString::kShortSize) return false;
    2766          44 :   Heap* heap = GetHeap();
    2767             :   bool is_internalized = this->IsInternalizedString();
    2768             :   bool has_pointers = StringShape(this).IsIndirect();
    2769             : 
    2770         329 :   if (has_pointers) {
    2771          30 :     heap->NotifyObjectLayoutChange(this, size, no_allocation);
    2772             :   }
    2773             : 
    2774             :   // Morph the string to an external string by replacing the map and
    2775             :   // reinitializing the fields.  This won't work if the space the existing
    2776             :   // string occupies is too small for a regular  external string.
    2777             :   // Instead, we resort to a short external string instead, omitting
    2778             :   // the field caching the address of the backing store.  When we encounter
    2779             :   // short external strings in generated code, we need to bailout to runtime.
    2780             :   Map* new_map;
    2781         329 :   if (size < ExternalString::kSize) {
    2782             :     new_map = is_internalized
    2783             :                   ? heap->short_external_one_byte_internalized_string_map()
    2784          20 :                   : heap->short_external_one_byte_string_map();
    2785             :   } else {
    2786             :     new_map = is_internalized
    2787             :                   ? heap->external_one_byte_internalized_string_map()
    2788         309 :                   : heap->external_one_byte_string_map();
    2789             :   }
    2790             : 
    2791             :   // Byte size of the external String object.
    2792         329 :   int new_size = this->SizeFromMap(new_map);
    2793         329 :   heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
    2794         658 :                              ClearRecordedSlots::kNo);
    2795         329 :   if (has_pointers) {
    2796          30 :     heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
    2797             :   }
    2798             : 
    2799             :   // We are storing the new map using release store after creating a filler for
    2800             :   // the left-over space to avoid races with the sweeper thread.
    2801         329 :   this->synchronized_set_map(new_map);
    2802             : 
    2803             :   ExternalOneByteString* self = ExternalOneByteString::cast(this);
    2804             :   self->set_resource(resource);
    2805         329 :   if (is_internalized) self->Hash();  // Force regeneration of the hash value.
    2806             :   return true;
    2807             : }
    2808             : 
    2809          64 : void String::StringShortPrint(StringStream* accumulator, bool show_details) {
    2810             :   int len = length();
    2811          64 :   if (len > kMaxShortPrintLength) {
    2812           0 :     accumulator->Add("<Very long string[%u]>", len);
    2813           0 :     return;
    2814             :   }
    2815             : 
    2816          64 :   if (!LooksValid()) {
    2817           0 :     accumulator->Add("<Invalid String>");
    2818           0 :     return;
    2819             :   }
    2820             : 
    2821             :   StringCharacterStream stream(this);
    2822             : 
    2823             :   bool truncated = false;
    2824          64 :   if (len > kMaxShortPrintLength) {
    2825             :     len = kMaxShortPrintLength;
    2826             :     truncated = true;
    2827             :   }
    2828             :   bool one_byte = true;
    2829         532 :   for (int i = 0; i < len; i++) {
    2830         468 :     uint16_t c = stream.GetNext();
    2831             : 
    2832         468 :     if (c < 32 || c >= 127) {
    2833             :       one_byte = false;
    2834             :     }
    2835             :   }
    2836          64 :   stream.Reset(this);
    2837          64 :   if (one_byte) {
    2838         116 :     if (show_details) accumulator->Add("<String[%u]: ", length());
    2839         468 :     for (int i = 0; i < len; i++) {
    2840         468 :       accumulator->Put(static_cast<char>(stream.GetNext()));
    2841             :     }
    2842          64 :     if (show_details) accumulator->Put('>');
    2843             :   } else {
    2844             :     // Backslash indicates that the string contains control
    2845             :     // characters and that backslashes are therefore escaped.
    2846           0 :     if (show_details) accumulator->Add("<String[%u]\\: ", length());
    2847           0 :     for (int i = 0; i < len; i++) {
    2848           0 :       uint16_t c = stream.GetNext();
    2849           0 :       if (c == '\n') {
    2850           0 :         accumulator->Add("\\n");
    2851           0 :       } else if (c == '\r') {
    2852           0 :         accumulator->Add("\\r");
    2853           0 :       } else if (c == '\\') {
    2854           0 :         accumulator->Add("\\\\");
    2855           0 :       } else if (c < 32 || c > 126) {
    2856           0 :         accumulator->Add("\\x%02x", c);
    2857             :       } else {
    2858           0 :         accumulator->Put(static_cast<char>(c));
    2859             :       }
    2860             :     }
    2861           0 :     if (truncated) {
    2862           0 :       accumulator->Put('.');
    2863           0 :       accumulator->Put('.');
    2864           0 :       accumulator->Put('.');
    2865             :     }
    2866           0 :     if (show_details) accumulator->Put('>');
    2867             :   }
    2868             :   return;
    2869             : }
    2870             : 
    2871             : 
    2872           0 : void String::PrintUC16(std::ostream& os, int start, int end) {  // NOLINT
    2873           0 :   if (end < 0) end = length();
    2874             :   StringCharacterStream stream(this, start);
    2875           0 :   for (int i = start; i < end && stream.HasMore(); i++) {
    2876           0 :     os << AsUC16(stream.GetNext());
    2877             :   }
    2878           0 : }
    2879             : 
    2880             : 
    2881         565 : void JSObject::JSObjectShortPrint(StringStream* accumulator) {
    2882         565 :   switch (map()->instance_type()) {
    2883             :     case JS_ARRAY_TYPE: {
    2884             :       double length = JSArray::cast(this)->length()->IsUndefined(GetIsolate())
    2885             :                           ? 0
    2886         131 :                           : JSArray::cast(this)->length()->Number();
    2887         131 :       accumulator->Add("<JSArray[%u]>", static_cast<uint32_t>(length));
    2888         131 :       break;
    2889             :     }
    2890             :     case JS_BOUND_FUNCTION_TYPE: {
    2891             :       JSBoundFunction* bound_function = JSBoundFunction::cast(this);
    2892           0 :       accumulator->Add("<JSBoundFunction");
    2893             :       accumulator->Add(
    2894             :           " (BoundTargetFunction %p)>",
    2895           0 :           reinterpret_cast<void*>(bound_function->bound_target_function()));
    2896           0 :       break;
    2897             :     }
    2898             :     case JS_WEAK_MAP_TYPE: {
    2899           0 :       accumulator->Add("<JSWeakMap>");
    2900           0 :       break;
    2901             :     }
    2902             :     case JS_WEAK_SET_TYPE: {
    2903           0 :       accumulator->Add("<JSWeakSet>");
    2904           0 :       break;
    2905             :     }
    2906             :     case JS_REGEXP_TYPE: {
    2907          20 :       accumulator->Add("<JSRegExp");
    2908             :       JSRegExp* regexp = JSRegExp::cast(this);
    2909          20 :       if (regexp->source()->IsString()) {
    2910          20 :         accumulator->Add(" ");
    2911          20 :         String::cast(regexp->source())->StringShortPrint(accumulator);
    2912             :       }
    2913          20 :       accumulator->Add(">");
    2914             : 
    2915          20 :       break;
    2916             :     }
    2917             :     case JS_FUNCTION_TYPE: {
    2918             :       JSFunction* function = JSFunction::cast(this);
    2919          30 :       Object* fun_name = function->shared()->DebugName();
    2920             :       bool printed = false;
    2921          30 :       if (fun_name->IsString()) {
    2922             :         String* str = String::cast(fun_name);
    2923          30 :         if (str->length() > 0) {
    2924          30 :           accumulator->Add("<JSFunction ");
    2925          30 :           accumulator->Put(str);
    2926             :           printed = true;
    2927             :         }
    2928             :       }
    2929          30 :       if (!printed) {
    2930           0 :         accumulator->Add("<JSFunction");
    2931             :       }
    2932          30 :       if (FLAG_trace_file_names) {
    2933             :         Object* source_name =
    2934             :             Script::cast(function->shared()->script())->name();
    2935           0 :         if (source_name->IsString()) {
    2936             :           String* str = String::cast(source_name);
    2937           0 :           if (str->length() > 0) {
    2938           0 :             accumulator->Add(" <");
    2939           0 :             accumulator->Put(str);
    2940           0 :             accumulator->Add(">");
    2941             :           }
    2942             :         }
    2943             :       }
    2944             :       accumulator->Add(" (sfi = %p)",
    2945          30 :                        reinterpret_cast<void*>(function->shared()));
    2946          30 :       accumulator->Put('>');
    2947          30 :       break;
    2948             :     }
    2949             :     case JS_GENERATOR_OBJECT_TYPE: {
    2950           0 :       accumulator->Add("<JSGenerator>");
    2951           0 :       break;
    2952             :     }
    2953             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE: {
    2954           0 :       accumulator->Add("<JS AsyncGenerator>");
    2955           0 :       break;
    2956             :     }
    2957             : 
    2958             :     // All other JSObjects are rather similar to each other (JSObject,
    2959             :     // JSGlobalProxy, JSGlobalObject, JSUndetectable, JSValue).
    2960             :     default: {
    2961             :       Map* map_of_this = map();
    2962             :       Heap* heap = GetHeap();
    2963         384 :       Object* constructor = map_of_this->GetConstructor();
    2964             :       bool printed = false;
    2965         768 :       if (constructor->IsHeapObject() &&
    2966         384 :           !heap->Contains(HeapObject::cast(constructor))) {
    2967           0 :         accumulator->Add("!!!INVALID CONSTRUCTOR!!!");
    2968             :       } else {
    2969             :         bool global_object = IsJSGlobalProxy();
    2970         384 :         if (constructor->IsJSFunction()) {
    2971         384 :           if (!heap->Contains(JSFunction::cast(constructor)->shared())) {
    2972           0 :             accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!");
    2973             :           } else {
    2974             :             String* constructor_name =
    2975             :                 JSFunction::cast(constructor)->shared()->name();
    2976         384 :             if (constructor_name->length() > 0) {
    2977         354 :               accumulator->Add(global_object ? "<GlobalObject " : "<");
    2978         354 :               accumulator->Put(constructor_name);
    2979             :               accumulator->Add(
    2980             :                   " %smap = %p",
    2981             :                   map_of_this->is_deprecated() ? "deprecated-" : "",
    2982         354 :                   map_of_this);
    2983             :               printed = true;
    2984             :             }
    2985             :           }
    2986           0 :         } else if (constructor->IsFunctionTemplateInfo()) {
    2987           0 :           accumulator->Add(global_object ? "<RemoteObject>" : "<RemoteObject>");
    2988             :           printed = true;
    2989             :         }
    2990         384 :         if (!printed) {
    2991          30 :           accumulator->Add("<JS%sObject", global_object ? "Global " : "");
    2992             :         }
    2993             :       }
    2994         384 :       if (IsJSValue()) {
    2995          10 :         accumulator->Add(" value = ");
    2996          10 :         JSValue::cast(this)->value()->ShortPrint(accumulator);
    2997             :       }
    2998         384 :       accumulator->Put('>');
    2999         384 :       break;
    3000             :     }
    3001             :   }
    3002         565 : }
    3003             : 
    3004             : 
    3005           0 : void JSObject::PrintElementsTransition(
    3006             :     FILE* file, Handle<JSObject> object,
    3007             :     ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
    3008             :     ElementsKind to_kind, Handle<FixedArrayBase> to_elements) {
    3009           0 :   if (from_kind != to_kind) {
    3010           0 :     OFStream os(file);
    3011           0 :     os << "elements transition [" << ElementsKindToString(from_kind) << " -> "
    3012           0 :        << ElementsKindToString(to_kind) << "] in ";
    3013           0 :     JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true);
    3014           0 :     PrintF(file, " for ");
    3015           0 :     object->ShortPrint(file);
    3016           0 :     PrintF(file, " from ");
    3017           0 :     from_elements->ShortPrint(file);
    3018           0 :     PrintF(file, " to ");
    3019           0 :     to_elements->ShortPrint(file);
    3020           0 :     PrintF(file, "\n");
    3021             :   }
    3022           0 : }
    3023             : 
    3024             : 
    3025             : // static
    3026       65961 : MaybeHandle<JSFunction> Map::GetConstructorFunction(
    3027             :     Handle<Map> map, Handle<Context> native_context) {
    3028       65961 :   if (map->IsPrimitiveMap()) {
    3029             :     int const constructor_function_index = map->GetConstructorFunctionIndex();
    3030        7014 :     if (constructor_function_index != kNoConstructorFunctionIndex) {
    3031             :       return handle(
    3032        7014 :           JSFunction::cast(native_context->get(constructor_function_index)));
    3033             :     }
    3034             :   }
    3035       58947 :   return MaybeHandle<JSFunction>();
    3036             : }
    3037             : 
    3038             : 
    3039           0 : void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
    3040             :                                PropertyAttributes attributes) {
    3041           0 :   OFStream os(file);
    3042           0 :   os << "[reconfiguring]";
    3043             :   Name* name = instance_descriptors()->GetKey(modify_index);
    3044           0 :   if (name->IsString()) {
    3045           0 :     String::cast(name)->PrintOn(file);
    3046             :   } else {
    3047           0 :     os << "{symbol " << static_cast<void*>(name) << "}";
    3048             :   }
    3049           0 :   os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: ";
    3050           0 :   os << attributes << " [";
    3051           0 :   JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
    3052           0 :   os << "]\n";
    3053           0 : }
    3054             : 
    3055    47663674 : VisitorId Map::GetVisitorId(Map* map) {
    3056             :   STATIC_ASSERT(kVisitorIdCount <= 256);
    3057             : 
    3058    47663674 :   const int instance_type = map->instance_type();
    3059             :   const bool has_unboxed_fields =
    3060             :       FLAG_unbox_double_fields && !map->HasFastPointerLayout();
    3061    47663674 :   if (instance_type < FIRST_NONSTRING_TYPE) {
    3062         713 :     switch (instance_type & kStringRepresentationMask) {
    3063             :       case kSeqStringTag:
    3064         124 :         if ((instance_type & kStringEncodingMask) == kOneByteStringTag) {
    3065             :           return kVisitSeqOneByteString;
    3066             :         } else {
    3067          62 :           return kVisitSeqTwoByteString;
    3068             :         }
    3069             : 
    3070             :       case kConsStringTag:
    3071          62 :         if (IsShortcutCandidate(instance_type)) {
    3072             :           return kVisitShortcutCandidate;
    3073             :         } else {
    3074           0 :           return kVisitConsString;
    3075             :         }
    3076             : 
    3077             :       case kSlicedStringTag:
    3078             :         return kVisitSlicedString;
    3079             : 
    3080             :       case kExternalStringTag:
    3081         403 :         return kVisitDataObject;
    3082             : 
    3083             :       case kThinStringTag:
    3084          62 :         return kVisitThinString;
    3085             :     }
    3086           0 :     UNREACHABLE();
    3087             :   }
    3088             : 
    3089    47662961 :   switch (instance_type) {
    3090             :     case BYTE_ARRAY_TYPE:
    3091             :       return kVisitByteArray;
    3092             : 
    3093             :     case BYTECODE_ARRAY_TYPE:
    3094          31 :       return kVisitBytecodeArray;
    3095             : 
    3096             :     case FREE_SPACE_TYPE:
    3097          31 :       return kVisitFreeSpace;
    3098             : 
    3099             :     case HASH_TABLE_TYPE:
    3100             :     case FIXED_ARRAY_TYPE:
    3101         558 :       return kVisitFixedArray;
    3102             : 
    3103             :     case FIXED_DOUBLE_ARRAY_TYPE:
    3104          31 :       return kVisitFixedDoubleArray;
    3105             : 
    3106             :     case PROPERTY_ARRAY_TYPE:
    3107          31 :       return kVisitPropertyArray;
    3108             : 
    3109             :     case FEEDBACK_VECTOR_TYPE:
    3110          31 :       return kVisitFeedbackVector;
    3111             : 
    3112             :     case ODDBALL_TYPE:
    3113         310 :       return kVisitOddball;
    3114             : 
    3115             :     case MAP_TYPE:
    3116          31 :       return kVisitMap;
    3117             : 
    3118             :     case CODE_TYPE:
    3119          31 :       return kVisitCode;
    3120             : 
    3121             :     case CELL_TYPE:
    3122         124 :       return kVisitCell;
    3123             : 
    3124             :     case PROPERTY_CELL_TYPE:
    3125          31 :       return kVisitPropertyCell;
    3126             : 
    3127             :     case WEAK_CELL_TYPE:
    3128          31 :       return kVisitWeakCell;
    3129             : 
    3130             :     case TRANSITION_ARRAY_TYPE:
    3131          31 :       return kVisitTransitionArray;
    3132             : 
    3133             :     case JS_WEAK_MAP_TYPE:
    3134             :     case JS_WEAK_SET_TYPE:
    3135       22961 :       return kVisitJSWeakCollection;
    3136             : 
    3137             :     case JS_REGEXP_TYPE:
    3138       14692 :       return kVisitJSRegExp;
    3139             : 
    3140             :     case SHARED_FUNCTION_INFO_TYPE:
    3141          31 :       return kVisitSharedFunctionInfo;
    3142             : 
    3143             :     case JS_PROXY_TYPE:
    3144         305 :       return kVisitStruct;
    3145             : 
    3146             :     case SYMBOL_TYPE:
    3147          31 :       return kVisitSymbol;
    3148             : 
    3149             :     case JS_ARRAY_BUFFER_TYPE:
    3150       12827 :       return kVisitJSArrayBuffer;
    3151             : 
    3152             :     case SMALL_ORDERED_HASH_MAP_TYPE:
    3153          31 :       return kVisitSmallOrderedHashMap;
    3154             : 
    3155             :     case SMALL_ORDERED_HASH_SET_TYPE:
    3156          31 :       return kVisitSmallOrderedHashSet;
    3157             : 
    3158             :     case JS_OBJECT_TYPE:
    3159             :     case JS_ERROR_TYPE:
    3160             :     case JS_ARGUMENTS_TYPE:
    3161             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
    3162             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    3163             :     case JS_GENERATOR_OBJECT_TYPE:
    3164             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
    3165             :     case JS_MODULE_NAMESPACE_TYPE:
    3166             :     case JS_VALUE_TYPE:
    3167             :     case JS_DATE_TYPE:
    3168             :     case JS_ARRAY_TYPE:
    3169             :     case JS_GLOBAL_PROXY_TYPE:
    3170             :     case JS_GLOBAL_OBJECT_TYPE:
    3171             :     case JS_MESSAGE_OBJECT_TYPE:
    3172             :     case JS_TYPED_ARRAY_TYPE:
    3173             :     case JS_DATA_VIEW_TYPE:
    3174             :     case JS_SET_TYPE:
    3175             :     case JS_MAP_TYPE:
    3176             :     case JS_SET_KEY_VALUE_ITERATOR_TYPE:
    3177             :     case JS_SET_VALUE_ITERATOR_TYPE:
    3178             :     case JS_MAP_KEY_ITERATOR_TYPE:
    3179             :     case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
    3180             :     case JS_MAP_VALUE_ITERATOR_TYPE:
    3181             :     case JS_STRING_ITERATOR_TYPE:
    3182             : 
    3183             : #define ARRAY_ITERATOR_CASE(type) case type:
    3184             :       ARRAY_ITERATOR_TYPE_LIST(ARRAY_ITERATOR_CASE)
    3185             : #undef ARRAY_ITERATOR_CASE
    3186             : 
    3187             :     case JS_PROMISE_TYPE:
    3188             :     case WASM_INSTANCE_TYPE:
    3189             :     case WASM_MEMORY_TYPE:
    3190             :     case WASM_MODULE_TYPE:
    3191             :     case WASM_TABLE_TYPE:
    3192             :     case JS_BOUND_FUNCTION_TYPE:
    3193    39981413 :       return has_unboxed_fields ? kVisitJSObject : kVisitJSObjectFast;
    3194             :     case JS_API_OBJECT_TYPE:
    3195             :     case JS_SPECIAL_API_OBJECT_TYPE:
    3196     6118312 :       return kVisitJSApiObject;
    3197             : 
    3198             :     case JS_FUNCTION_TYPE:
    3199     1509856 :       return kVisitJSFunction;
    3200             : 
    3201             :     case FILLER_TYPE:
    3202             :     case FOREIGN_TYPE:
    3203             :     case HEAP_NUMBER_TYPE:
    3204             :     case MUTABLE_HEAP_NUMBER_TYPE:
    3205         160 :       return kVisitDataObject;
    3206             : 
    3207             :     case BIGINT_TYPE:
    3208          31 :       return kVisitBigInt;
    3209             : 
    3210             :     case FIXED_UINT8_ARRAY_TYPE:
    3211             :     case FIXED_INT8_ARRAY_TYPE:
    3212             :     case FIXED_UINT16_ARRAY_TYPE:
    3213             :     case FIXED_INT16_ARRAY_TYPE:
    3214             :     case FIXED_UINT32_ARRAY_TYPE:
    3215             :     case FIXED_INT32_ARRAY_TYPE:
    3216             :     case FIXED_FLOAT32_ARRAY_TYPE:
    3217             :     case FIXED_UINT8_CLAMPED_ARRAY_TYPE:
    3218         248 :       return kVisitFixedTypedArrayBase;
    3219             : 
    3220             :     case FIXED_FLOAT64_ARRAY_TYPE:
    3221          31 :       return kVisitFixedFloat64Array;
    3222             : 
    3223             : #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
    3224             :       STRUCT_LIST(MAKE_STRUCT_CASE)
    3225             : #undef MAKE_STRUCT_CASE
    3226         682 :       if (instance_type == ALLOCATION_SITE_TYPE) {
    3227             :         return kVisitAllocationSite;
    3228             :       }
    3229             : 
    3230         651 :       return kVisitStruct;
    3231             : 
    3232             :     default:
    3233           0 :       UNREACHABLE();
    3234             :   }
    3235             : }
    3236             : 
    3237           0 : void Map::PrintGeneralization(
    3238             :     FILE* file, const char* reason, int modify_index, int split,
    3239             :     int descriptors, bool descriptor_to_field,
    3240             :     Representation old_representation, Representation new_representation,
    3241             :     MaybeHandle<FieldType> old_field_type, MaybeHandle<Object> old_value,
    3242             :     MaybeHandle<FieldType> new_field_type, MaybeHandle<Object> new_value) {
    3243           0 :   OFStream os(file);
    3244           0 :   os << "[generalizing]";
    3245             :   Name* name = instance_descriptors()->GetKey(modify_index);
    3246           0 :   if (name->IsString()) {
    3247           0 :     String::cast(name)->PrintOn(file);
    3248             :   } else {
    3249           0 :     os << "{symbol " << static_cast<void*>(name) << "}";
    3250             :   }
    3251           0 :   os << ":";
    3252           0 :   if (descriptor_to_field) {
    3253           0 :     os << "c";
    3254             :   } else {
    3255           0 :     os << old_representation.Mnemonic() << "{";
    3256           0 :     if (old_field_type.is_null()) {
    3257           0 :       os << Brief(*(old_value.ToHandleChecked()));
    3258             :     } else {
    3259           0 :       old_field_type.ToHandleChecked()->PrintTo(os);
    3260             :     }
    3261           0 :     os << "}";
    3262             :   }
    3263           0 :   os << "->" << new_representation.Mnemonic() << "{";
    3264           0 :   if (new_field_type.is_null()) {
    3265           0 :     os << Brief(*(new_value.ToHandleChecked()));
    3266             :   } else {
    3267           0 :     new_field_type.ToHandleChecked()->PrintTo(os);
    3268             :   }
    3269           0 :   os << "} (";
    3270           0 :   if (strlen(reason) > 0) {
    3271           0 :     os << reason;
    3272             :   } else {
    3273           0 :     os << "+" << (descriptors - split) << " maps";
    3274             :   }
    3275           0 :   os << ") [";
    3276           0 :   JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
    3277           0 :   os << "]\n";
    3278           0 : }
    3279             : 
    3280             : 
    3281           0 : void JSObject::PrintInstanceMigration(FILE* file,
    3282             :                                       Map* original_map,
    3283             :                                       Map* new_map) {
    3284           0 :   if (new_map->is_dictionary_map()) {
    3285           0 :     PrintF(file, "[migrating to slow]\n");
    3286           0 :     return;
    3287             :   }
    3288           0 :   PrintF(file, "[migrating]");
    3289             :   DescriptorArray* o = original_map->instance_descriptors();
    3290             :   DescriptorArray* n = new_map->instance_descriptors();
    3291           0 :   for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) {
    3292           0 :     Representation o_r = o->GetDetails(i).representation();
    3293           0 :     Representation n_r = n->GetDetails(i).representation();
    3294           0 :     if (!o_r.Equals(n_r)) {
    3295           0 :       String::cast(o->GetKey(i))->PrintOn(file);
    3296           0 :       PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic());
    3297           0 :     } else if (o->GetDetails(i).location() == kDescriptor &&
    3298           0 :                n->GetDetails(i).location() == kField) {
    3299             :       Name* name = o->GetKey(i);
    3300           0 :       if (name->IsString()) {
    3301           0 :         String::cast(name)->PrintOn(file);
    3302             :       } else {
    3303           0 :         PrintF(file, "{symbol %p}", static_cast<void*>(name));
    3304             :       }
    3305           0 :       PrintF(file, " ");
    3306             :     }
    3307             :   }
    3308           0 :   if (original_map->elements_kind() != new_map->elements_kind()) {
    3309             :     PrintF(file, "elements_kind[%i->%i]", original_map->elements_kind(),
    3310           0 :            new_map->elements_kind());
    3311             :   }
    3312           0 :   PrintF(file, "\n");
    3313             : }
    3314             : 
    3315      406434 : bool JSObject::IsUnmodifiedApiObject(Object** o) {
    3316      406434 :   Object* object = *o;
    3317      406434 :   if (object->IsSmi()) return false;
    3318             :   HeapObject* heap_object = HeapObject::cast(object);
    3319      406434 :   if (!object->IsJSObject()) return false;
    3320             :   JSObject* js_object = JSObject::cast(object);
    3321       31702 :   if (!js_object->WasConstructedFromApiFunction()) return false;
    3322          21 :   Object* maybe_constructor = js_object->map()->GetConstructor();
    3323          21 :   if (!maybe_constructor->IsJSFunction()) return false;
    3324             :   JSFunction* constructor = JSFunction::cast(maybe_constructor);
    3325          21 :   if (js_object->elements()->length() != 0) return false;
    3326             : 
    3327          16 :   return constructor->initial_map() == heap_object->map();
    3328             : }
    3329             : 
    3330         933 : void HeapObject::HeapObjectShortPrint(std::ostream& os) {  // NOLINT
    3331             :   Heap* heap = GetHeap();
    3332             :   Isolate* isolate = heap->isolate();
    3333         933 :   if (!heap->Contains(this)) {
    3334           0 :     os << "!!!INVALID POINTER!!!";
    3335           0 :     return;
    3336             :   }
    3337         933 :   if (!heap->Contains(map())) {
    3338           0 :     os << "!!!INVALID MAP!!!";
    3339           0 :     return;
    3340             :   }
    3341             : 
    3342         933 :   os << this << " ";
    3343             : 
    3344         933 :   if (IsString()) {
    3345             :     HeapStringAllocator allocator;
    3346             :     StringStream accumulator(&allocator);
    3347          32 :     String::cast(this)->StringShortPrint(&accumulator);
    3348          96 :     os << accumulator.ToCString().get();
    3349             :     return;
    3350             :   }
    3351         901 :   if (IsJSObject()) {
    3352             :     HeapStringAllocator allocator;
    3353             :     StringStream accumulator(&allocator);
    3354         565 :     JSObject::cast(this)->JSObjectShortPrint(&accumulator);
    3355        1695 :     os << accumulator.ToCString().get();
    3356             :     return;
    3357             :   }
    3358         336 :   switch (map()->instance_type()) {
    3359             :     case MAP_TYPE:
    3360           0 :       os << "<Map(" << ElementsKindToString(Map::cast(this)->elements_kind())
    3361           0 :          << ")>";
    3362           0 :       break;
    3363             :     case HASH_TABLE_TYPE:
    3364           0 :       os << "<HashTable[" << FixedArray::cast(this)->length() << "]>";
    3365           0 :       break;
    3366             :     case FIXED_ARRAY_TYPE:
    3367           0 :       os << "<FixedArray[" << FixedArray::cast(this)->length() << "]>";
    3368           0 :       break;
    3369             :     case FIXED_DOUBLE_ARRAY_TYPE:
    3370           0 :       os << "<FixedDoubleArray[" << FixedDoubleArray::cast(this)->length()
    3371           0 :          << "]>";
    3372           0 :       break;
    3373             :     case BYTE_ARRAY_TYPE:
    3374           0 :       os << "<ByteArray[" << ByteArray::cast(this)->length() << "]>";
    3375           0 :       break;
    3376             :     case BYTECODE_ARRAY_TYPE:
    3377           0 :       os << "<BytecodeArray[" << BytecodeArray::cast(this)->length() << "]>";
    3378           0 :       break;
    3379             :     case TRANSITION_ARRAY_TYPE:
    3380           0 :       os << "<TransitionArray[" << TransitionArray::cast(this)->length()
    3381           0 :          << "]>";
    3382           0 :       break;
    3383             :     case PROPERTY_ARRAY_TYPE:
    3384           0 :       os << "<PropertyArray[" << PropertyArray::cast(this)->length() << "]>";
    3385           0 :       break;
    3386             :     case FEEDBACK_VECTOR_TYPE:
    3387           0 :       os << "<FeedbackVector[" << FeedbackVector::cast(this)->length() << "]>";
    3388           0 :       break;
    3389             :     case FREE_SPACE_TYPE:
    3390           0 :       os << "<FreeSpace[" << FreeSpace::cast(this)->size() << "]>";
    3391           0 :       break;
    3392             : #define TYPED_ARRAY_SHORT_PRINT(Type, type, TYPE, ctype, size)                \
    3393             :   case FIXED_##TYPE##_ARRAY_TYPE:                                             \
    3394             :     os << "<Fixed" #Type "Array[" << Fixed##Type##Array::cast(this)->length() \
    3395             :        << "]>";                                                               \
    3396             :     break;
    3397             : 
    3398           0 :     TYPED_ARRAYS(TYPED_ARRAY_SHORT_PRINT)
    3399             : #undef TYPED_ARRAY_SHORT_PRINT
    3400             : 
    3401             :     case SHARED_FUNCTION_INFO_TYPE: {
    3402             :       SharedFunctionInfo* shared = SharedFunctionInfo::cast(this);
    3403           0 :       std::unique_ptr<char[]> debug_name = shared->DebugName()->ToCString();
    3404           0 :       if (debug_name[0] != 0) {
    3405           0 :         os << "<SharedFunctionInfo " << debug_name.get() << ">";
    3406             :       } else {
    3407           0 :         os << "<SharedFunctionInfo>";
    3408             :       }
    3409             :       break;
    3410             :     }
    3411             :     case JS_MESSAGE_OBJECT_TYPE:
    3412           0 :       os << "<JSMessageObject>";
    3413           0 :       break;
    3414             : #define MAKE_STRUCT_CASE(NAME, Name, name)   \
    3415             :   case NAME##_TYPE:                          \
    3416             :     os << "<" #Name;                         \
    3417             :     Name::cast(this)->BriefPrintDetails(os); \
    3418             :     os << ">";                               \
    3419             :     break;
    3420           0 :       STRUCT_LIST(MAKE_STRUCT_CASE)
    3421             : #undef MAKE_STRUCT_CASE
    3422             :     case CODE_TYPE: {
    3423             :       Code* code = Code::cast(this);
    3424           0 :       os << "<Code " << Code::Kind2String(code->kind()) << ">";
    3425           0 :       break;
    3426             :     }
    3427             :     case ODDBALL_TYPE: {
    3428          64 :       if (IsUndefined(isolate)) {
    3429          32 :         os << "<undefined>";
    3430          32 :       } else if (IsTheHole(isolate)) {
    3431           0 :         os << "<the_hole>";
    3432          32 :       } else if (IsNull(isolate)) {
    3433          12 :         os << "<null>";
    3434          20 :       } else if (IsTrue(isolate)) {
    3435          10 :         os << "<true>";
    3436          10 :       } else if (IsFalse(isolate)) {
    3437          10 :         os << "<false>";
    3438             :       } else {
    3439           0 :         os << "<Odd Oddball: ";
    3440           0 :         os << Oddball::cast(this)->to_string()->ToCString().get();
    3441           0 :         os << ">";
    3442             :       }
    3443             :       break;
    3444             :     }
    3445             :     case SYMBOL_TYPE: {
    3446             :       Symbol* symbol = Symbol::cast(this);
    3447         192 :       symbol->SymbolShortPrint(os);
    3448         192 :       break;
    3449             :     }
    3450             :     case HEAP_NUMBER_TYPE: {
    3451          70 :       os << "<Number ";
    3452             :       HeapNumber::cast(this)->HeapNumberPrint(os);
    3453          70 :       os << ">";
    3454          70 :       break;
    3455             :     }
    3456             :     case MUTABLE_HEAP_NUMBER_TYPE: {
    3457           0 :       os << "<MutableNumber ";
    3458             :       HeapNumber::cast(this)->HeapNumberPrint(os);
    3459             :       os << '>';
    3460             :       break;
    3461             :     }
    3462             :     case BIGINT_TYPE: {
    3463           0 :       os << "<BigInt ";
    3464           0 :       BigInt::cast(this)->BigIntShortPrint(os);
    3465           0 :       os << ">";
    3466           0 :       break;
    3467             :     }
    3468             :     case JS_PROXY_TYPE:
    3469          10 :       os << "<JSProxy>";
    3470          10 :       break;
    3471             :     case FOREIGN_TYPE:
    3472           0 :       os << "<Foreign>";
    3473           0 :       break;
    3474             :     case CELL_TYPE: {
    3475           0 :       os << "<Cell value= ";
    3476             :       HeapStringAllocator allocator;
    3477             :       StringStream accumulator(&allocator);
    3478           0 :       Cell::cast(this)->value()->ShortPrint(&accumulator);
    3479           0 :       os << accumulator.ToCString().get();
    3480             :       os << '>';
    3481             :       break;
    3482             :     }
    3483             :     case PROPERTY_CELL_TYPE: {
    3484             :       PropertyCell* cell = PropertyCell::cast(this);
    3485           0 :       os << "<PropertyCell name=";
    3486           0 :       cell->name()->ShortPrint(os);
    3487           0 :       os << " value=";
    3488             :       HeapStringAllocator allocator;
    3489             :       StringStream accumulator(&allocator);
    3490           0 :       cell->value()->ShortPrint(&accumulator);
    3491           0 :       os << accumulator.ToCString().get();
    3492             :       os << '>';
    3493             :       break;
    3494             :     }
    3495             :     case WEAK_CELL_TYPE: {
    3496           0 :       os << "<WeakCell value= ";
    3497             :       HeapStringAllocator allocator;
    3498             :       StringStream accumulator(&allocator);
    3499           0 :       WeakCell::cast(this)->value()->ShortPrint(&accumulator);
    3500           0 :       os << accumulator.ToCString().get();
    3501             :       os << '>';
    3502             :       break;
    3503             :     }
    3504             :     default:
    3505           0 :       os << "<Other heap object (" << map()->instance_type() << ")>";
    3506           0 :       break;
    3507             :   }
    3508             : }
    3509             : 
    3510           0 : void Struct::BriefPrintDetails(std::ostream& os) {}
    3511             : 
    3512           0 : void Tuple2::BriefPrintDetails(std::ostream& os) {
    3513           0 :   os << " " << Brief(value1()) << ", " << Brief(value2());
    3514           0 : }
    3515             : 
    3516           0 : void Tuple3::BriefPrintDetails(std::ostream& os) {
    3517           0 :   os << " " << Brief(value1()) << ", " << Brief(value2()) << ", "
    3518           0 :      << Brief(value3());
    3519           0 : }
    3520             : 
    3521    19937875 : void HeapObject::Iterate(ObjectVisitor* v) { IterateFast<ObjectVisitor>(v); }
    3522             : 
    3523             : 
    3524          58 : void HeapObject::IterateBody(ObjectVisitor* v) {
    3525             :   Map* m = map();
    3526          58 :   IterateBodyFast<ObjectVisitor>(m->instance_type(), SizeFromMap(m), v);
    3527          58 : }
    3528             : 
    3529             : 
    3530    56090874 : void HeapObject::IterateBody(InstanceType type, int object_size,
    3531             :                              ObjectVisitor* v) {
    3532             :   IterateBodyFast<ObjectVisitor>(type, object_size, v);
    3533    56065937 : }
    3534             : 
    3535             : 
    3536             : struct CallIsValidSlot {
    3537             :   template <typename BodyDescriptor>
    3538             :   static bool apply(HeapObject* obj, int offset, int) {
    3539           0 :     return BodyDescriptor::IsValidSlot(obj, offset);
    3540             :   }
    3541             : };
    3542             : 
    3543             : 
    3544      906338 : bool HeapObject::IsValidSlot(int offset) {
    3545             :   DCHECK_NE(0, offset);
    3546             :   return BodyDescriptorApply<CallIsValidSlot, bool>(map()->instance_type(),
    3547      906338 :                                                     this, offset, 0);
    3548             : }
    3549             : 
    3550       14202 : void HeapNumber::HeapNumberPrint(std::ostream& os) {  // NOLINT
    3551             :   os << value();
    3552       14202 : }
    3553             : 
    3554             : #define FIELD_ADDR(p, offset) \
    3555             :   (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
    3556             : 
    3557             : #define FIELD_ADDR_CONST(p, offset) \
    3558             :   (reinterpret_cast<const byte*>(p) + offset - kHeapObjectTag)
    3559             : 
    3560             : #define READ_INT32_FIELD(p, offset) \
    3561             :   (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset)))
    3562             : 
    3563             : #define READ_INT64_FIELD(p, offset) \
    3564             :   (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset)))
    3565             : 
    3566             : #define READ_BYTE_FIELD(p, offset) \
    3567             :   (*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset)))
    3568             : 
    3569    44808624 : String* JSReceiver::class_name() {
    3570    44808624 :   if (IsFunction()) {
    3571    20769818 :     return GetHeap()->Function_string();
    3572             :   }
    3573    24038806 :   Object* maybe_constructor = map()->GetConstructor();
    3574    24038806 :   if (maybe_constructor->IsJSFunction()) {
    3575             :     JSFunction* constructor = JSFunction::cast(maybe_constructor);
    3576    24038725 :     return String::cast(constructor->shared()->instance_class_name());
    3577          81 :   } else if (maybe_constructor->IsFunctionTemplateInfo()) {
    3578             :     FunctionTemplateInfo* info = FunctionTemplateInfo::cast(maybe_constructor);
    3579             :     return info->class_name()->IsString() ? String::cast(info->class_name())
    3580           1 :                                           : GetHeap()->empty_string();
    3581             :   }
    3582             : 
    3583             :   // If the constructor is not present, return "Object".
    3584          80 :   return GetHeap()->Object_string();
    3585             : }
    3586             : 
    3587             : 
    3588             : // static
    3589     5200026 : Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
    3590             :   Isolate* isolate = receiver->GetIsolate();
    3591             : 
    3592             :   // If the object was instantiated simply with base == new.target, the
    3593             :   // constructor on the map provides the most accurate name.
    3594             :   // Don't provide the info for prototypes, since their constructors are
    3595             :   // reclaimed and replaced by Object in OptimizeAsPrototype.
    3596    15599538 :   if (!receiver->IsJSProxy() && receiver->map()->new_target_is_base() &&
    3597             :       !receiver->map()->is_prototype_map()) {
    3598     5053404 :     Object* maybe_constructor = receiver->map()->GetConstructor();
    3599     5053404 :     if (maybe_constructor->IsJSFunction()) {
    3600             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
    3601             :       String* name = constructor->shared()->name();
    3602     4508564 :       if (name->length() == 0) name = constructor->shared()->inferred_name();
    3603     8532749 :       if (name->length() != 0 &&
    3604     4024185 :           !name->Equals(isolate->heap()->Object_string())) {
    3605             :         return handle(name, isolate);
    3606             :       }
    3607      544840 :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
    3608             :       FunctionTemplateInfo* info =
    3609             :           FunctionTemplateInfo::cast(maybe_constructor);
    3610           0 :       if (info->class_name()->IsString()) {
    3611             :         return handle(String::cast(info->class_name()), isolate);
    3612             :       }
    3613             :     }
    3614             :   }
    3615             : 
    3616             :   Handle<Object> maybe_tag = JSReceiver::GetDataProperty(
    3617     1984580 :       receiver, isolate->factory()->to_string_tag_symbol());
    3618     1984580 :   if (maybe_tag->IsString()) return Handle<String>::cast(maybe_tag);
    3619             : 
    3620     1423800 :   PrototypeIterator iter(isolate, receiver);
    3621     1833827 :   if (iter.IsAtEnd()) return handle(receiver->class_name());
    3622     1013773 :   Handle<JSReceiver> start = PrototypeIterator::GetCurrent<JSReceiver>(iter);
    3623             :   LookupIterator it(receiver, isolate->factory()->constructor_string(), start,
    3624     1013773 :                     LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
    3625     1013773 :   Handle<Object> maybe_constructor = JSReceiver::GetDataProperty(&it);
    3626             :   Handle<String> result = isolate->factory()->Object_string();
    3627     1013773 :   if (maybe_constructor->IsJSFunction()) {
    3628             :     JSFunction* constructor = JSFunction::cast(*maybe_constructor);
    3629             :     String* name = constructor->shared()->name();
    3630     1013643 :     if (name->length() == 0) name = constructor->shared()->inferred_name();
    3631     1013643 :     if (name->length() > 0) result = handle(name, isolate);
    3632             :   }
    3633             : 
    3634             :   return result.is_identical_to(isolate->factory()->Object_string())
    3635      392945 :              ? handle(receiver->class_name())
    3636     1634601 :              : result;
    3637             : }
    3638             : 
    3639      222979 : Handle<Context> JSReceiver::GetCreationContext() {
    3640             :   JSReceiver* receiver = this;
    3641      445970 :   while (receiver->IsJSBoundFunction()) {
    3642             :     receiver = JSBoundFunction::cast(receiver)->bound_target_function();
    3643             :   }
    3644             :   // Externals are JSObjects with null as a constructor.
    3645             :   DCHECK(!receiver->IsExternal());
    3646      222979 :   Object* constructor = receiver->map()->GetConstructor();
    3647             :   JSFunction* function;
    3648      222979 :   if (constructor->IsJSFunction()) {
    3649             :     function = JSFunction::cast(constructor);
    3650      126607 :   } else if (constructor->IsFunctionTemplateInfo()) {
    3651             :     // Remote objects don't have a creation context.
    3652           2 :     return Handle<Context>::null();
    3653             :   } else {
    3654             :     // Functions have null as a constructor,
    3655             :     // but any JSFunction knows its context immediately.
    3656      126605 :     CHECK(receiver->IsJSFunction());
    3657             :     function = JSFunction::cast(receiver);
    3658             :   }
    3659             : 
    3660      222977 :   return function->has_context()
    3661             :              ? Handle<Context>(function->context()->native_context())
    3662      222977 :              : Handle<Context>::null();
    3663             : }
    3664             : 
    3665             : // static
    3666     7162785 : Handle<Object> Map::WrapFieldType(Handle<FieldType> type) {
    3667     7728439 :   if (type->IsClass()) return Map::WeakCellForMap(type->AsClass());
    3668     6597130 :   return type;
    3669             : }
    3670             : 
    3671             : // static
    3672    40094350 : FieldType* Map::UnwrapFieldType(Object* wrapped_type) {
    3673             :   Object* value = wrapped_type;
    3674    40094350 :   if (value->IsWeakCell()) {
    3675     1351217 :     if (WeakCell::cast(value)->cleared()) return FieldType::None();
    3676             :     value = WeakCell::cast(value)->value();
    3677             :   }
    3678    40094166 :   return FieldType::cast(value);
    3679             : }
    3680             : 
    3681     6747388 : MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, Handle<Name> name,
    3682             :                                     Handle<FieldType> type,
    3683             :                                     PropertyAttributes attributes,
    3684             :                                     PropertyConstness constness,
    3685             :                                     Representation representation,
    3686             :                                     TransitionFlag flag) {
    3687             :   DCHECK(DescriptorArray::kNotFound ==
    3688             :          map->instance_descriptors()->Search(
    3689             :              *name, map->NumberOfOwnDescriptors()));
    3690             : 
    3691             :   // Ensure the descriptor array does not get too big.
    3692     6747388 :   if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
    3693          78 :     return MaybeHandle<Map>();
    3694             :   }
    3695             : 
    3696             :   Isolate* isolate = map->GetIsolate();
    3697             : 
    3698             :   // Compute the new index for new field.
    3699     6747310 :   int index = map->NextFreePropertyIndex();
    3700             : 
    3701     6747310 :   if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) {
    3702             :     representation = Representation::Tagged();
    3703        3003 :     type = FieldType::Any(isolate);
    3704     7287693 :   } else if (IsTransitionableFastElementsKind(map->elements_kind()) &&
    3705             :              IsInplaceGeneralizableField(constness, representation, *type)) {
    3706             :     // We don't support propagation of field generalization through elements
    3707             :     // kind transitions because they are inserted into the transition tree
    3708             :     // before field transitions. In order to avoid complexity of handling
    3709             :     // such a case we ensure that all maps with transitionable elements kinds
    3710             :     // do not have fields that can be generalized in-place (without creation
    3711             :     // of a new map).
    3712             :     DCHECK(representation.IsHeapObject());
    3713      389663 :     type = FieldType::Any(isolate);
    3714             :   }
    3715             : 
    3716     6747310 :   Handle<Object> wrapped_type(WrapFieldType(type));
    3717             : 
    3718             :   DCHECK_IMPLIES(!FLAG_track_constant_fields, constness == kMutable);
    3719             :   Descriptor d = Descriptor::DataField(name, index, attributes, constness,
    3720     6747310 :                                        representation, wrapped_type);
    3721     6747310 :   Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag);
    3722     6747311 :   new_map->AccountAddedPropertyField();
    3723     6747311 :   return new_map;
    3724             : }
    3725             : 
    3726             : 
    3727     8384989 : MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map,
    3728             :                                        Handle<Name> name,
    3729             :                                        Handle<Object> constant,
    3730             :                                        PropertyAttributes attributes,
    3731             :                                        TransitionFlag flag) {
    3732             :   // Ensure the descriptor array does not get too big.
    3733     8384989 :   if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
    3734           0 :     return MaybeHandle<Map>();
    3735             :   }
    3736             : 
    3737             :   if (FLAG_track_constant_fields) {
    3738             :     Isolate* isolate = map->GetIsolate();
    3739             :     Representation representation = constant->OptimalRepresentation();
    3740             :     Handle<FieldType> type = constant->OptimalType(isolate, representation);
    3741             :     return CopyWithField(map, name, type, attributes, kConst, representation,
    3742             :                          flag);
    3743             :   } else {
    3744             :     // Allocate new instance descriptors with (name, constant) added.
    3745     8384989 :     Descriptor d = Descriptor::DataConstant(name, 0, constant, attributes);
    3746     8384989 :     Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag);
    3747     8384987 :     return new_map;
    3748             :   }
    3749             : }
    3750             : 
    3751           0 : const char* Representation::Mnemonic() const {
    3752           0 :   switch (kind_) {
    3753             :     case kNone: return "v";
    3754           0 :     case kTagged: return "t";
    3755           0 :     case kSmi: return "s";
    3756           0 :     case kDouble: return "d";
    3757           0 :     case kInteger32: return "i";
    3758           0 :     case kHeapObject: return "h";
    3759           0 :     case kExternal: return "x";
    3760             :     default:
    3761           0 :       UNREACHABLE();
    3762             :   }
    3763             : }
    3764             : 
    3765           0 : bool Map::TransitionRemovesTaggedField(Map* target) const {
    3766           0 :   int inobject = NumberOfFields();
    3767           0 :   int target_inobject = target->NumberOfFields();
    3768           0 :   for (int i = target_inobject; i < inobject; i++) {
    3769           0 :     FieldIndex index = FieldIndex::ForPropertyIndex(this, i);
    3770           0 :     if (!IsUnboxedDoubleField(index)) return true;
    3771             :   }
    3772             :   return false;
    3773             : }
    3774             : 
    3775           0 : bool Map::TransitionChangesTaggedFieldToUntaggedField(Map* target) const {
    3776           0 :   int inobject = NumberOfFields();
    3777           0 :   int target_inobject = target->NumberOfFields();
    3778             :   int limit = Min(inobject, target_inobject);
    3779           0 :   for (int i = 0; i < limit; i++) {
    3780           0 :     FieldIndex index = FieldIndex::ForPropertyIndex(target, i);
    3781           0 :     if (!IsUnboxedDoubleField(index) && target->IsUnboxedDoubleField(index)) {
    3782           0 :       return true;
    3783             :     }
    3784             :   }
    3785             :   return false;
    3786             : }
    3787             : 
    3788           0 : bool Map::TransitionRequiresSynchronizationWithGC(Map* target) const {
    3789           0 :   return TransitionRemovesTaggedField(target) ||
    3790           0 :          TransitionChangesTaggedFieldToUntaggedField(target);
    3791             : }
    3792             : 
    3793       92091 : bool Map::InstancesNeedRewriting(Map* target) const {
    3794       92091 :   int target_number_of_fields = target->NumberOfFields();
    3795             :   int target_inobject = target->GetInObjectProperties();
    3796             :   int target_unused = target->UnusedPropertyFields();
    3797             :   int old_number_of_fields;
    3798             : 
    3799             :   return InstancesNeedRewriting(target, target_number_of_fields,
    3800             :                                 target_inobject, target_unused,
    3801       92091 :                                 &old_number_of_fields);
    3802             : }
    3803             : 
    3804    17496415 : bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
    3805             :                                  int target_inobject, int target_unused,
    3806             :                                  int* old_number_of_fields) const {
    3807             :   // If fields were added (or removed), rewrite the instance.
    3808    17496415 :   *old_number_of_fields = NumberOfFields();
    3809             :   DCHECK(target_number_of_fields >= *old_number_of_fields);
    3810    17496416 :   if (target_number_of_fields != *old_number_of_fields) return true;
    3811             : 
    3812             :   // If smi descriptors were replaced by double descriptors, rewrite.
    3813             :   DescriptorArray* old_desc = instance_descriptors();
    3814             :   DescriptorArray* new_desc = target->instance_descriptors();
    3815             :   int limit = NumberOfOwnDescriptors();
    3816    58813524 :   for (int i = 0; i < limit; i++) {
    3817    86028232 :     if (new_desc->GetDetails(i).representation().IsDouble() !=
    3818    86028234 :         old_desc->GetDetails(i).representation().IsDouble()) {
    3819             :       return true;
    3820             :     }
    3821             :   }
    3822             : 
    3823             :   // If no fields were added, and no inobject properties were removed, setting
    3824             :   // the map is sufficient.
    3825    15799409 :   if (target_inobject == GetInObjectProperties()) return false;
    3826             :   // In-object slack tracking may have reduced the object size of the new map.
    3827             :   // In that case, succeed if all existing fields were inobject, and they still
    3828             :   // fit within the new inobject size.
    3829             :   DCHECK(target_inobject < GetInObjectProperties());
    3830           1 :   if (target_number_of_fields <= target_inobject) {
    3831             :     DCHECK(target_number_of_fields + target_unused == target_inobject);
    3832             :     return false;
    3833             :   }
    3834             :   // Otherwise, properties will need to be moved to the backing store.
    3835           0 :   return true;
    3836             : }
    3837             : 
    3838             : 
    3839             : // static
    3840     3888596 : void JSObject::UpdatePrototypeUserRegistration(Handle<Map> old_map,
    3841             :                                                Handle<Map> new_map,
    3842             :                                                Isolate* isolate) {
    3843             :   DCHECK(old_map->is_prototype_map());
    3844             :   DCHECK(new_map->is_prototype_map());
    3845     3888596 :   bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
    3846     3888596 :   new_map->set_prototype_info(old_map->prototype_info());
    3847     3888596 :   old_map->set_prototype_info(Smi::kZero);
    3848     3888596 :   if (FLAG_trace_prototype_users) {
    3849             :     PrintF("Moving prototype_info %p from map %p to map %p.\n",
    3850             :            reinterpret_cast<void*>(new_map->prototype_info()),
    3851             :            reinterpret_cast<void*>(*old_map),
    3852           0 :            reinterpret_cast<void*>(*new_map));
    3853             :   }
    3854     3888596 :   if (was_registered) {
    3855      154799 :     if (new_map->prototype_info()->IsPrototypeInfo()) {
    3856             :       // The new map isn't registered with its prototype yet; reflect this fact
    3857             :       // in the PrototypeInfo it just inherited from the old map.
    3858             :       PrototypeInfo::cast(new_map->prototype_info())
    3859             :           ->set_registry_slot(PrototypeInfo::UNREGISTERED);
    3860             :     }
    3861      154799 :     JSObject::LazyRegisterPrototypeUser(new_map, isolate);
    3862             :   }
    3863     3888596 : }
    3864             : 
    3865             : namespace {
    3866             : // To migrate a fast instance to a fast map:
    3867             : // - First check whether the instance needs to be rewritten. If not, simply
    3868             : //   change the map.
    3869             : // - Otherwise, allocate a fixed array large enough to hold all fields, in
    3870             : //   addition to unused space.
    3871             : // - Copy all existing properties in, in the following order: backing store
    3872             : //   properties, unused fields, inobject properties.
    3873             : // - If all allocation succeeded, commit the state atomically:
    3874             : //   * Copy inobject properties from the backing store back into the object.
    3875             : //   * Trim the difference in instance size of the object. This also cleanly
    3876             : //     frees inobject properties that moved to the backing store.
    3877             : //   * If there are properties left in the backing store, trim of the space used
    3878             : //     to temporarily store the inobject properties.
    3879             : //   * If there are properties left in the backing store, install the backing
    3880             : //     store.
    3881    29336856 : void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
    3882             :   Isolate* isolate = object->GetIsolate();
    3883             :   Handle<Map> old_map(object->map());
    3884             :   // In case of a regular transition.
    3885    58673712 :   if (new_map->GetBackPointer() == *old_map) {
    3886             :     // If the map does not add named properties, simply set the map.
    3887    11932532 :     if (old_map->NumberOfOwnDescriptors() ==
    3888             :         new_map->NumberOfOwnDescriptors()) {
    3889      544169 :       object->synchronized_set_map(*new_map);
    3890      544169 :       return;
    3891             :     }
    3892             : 
    3893             :     PropertyDetails details = new_map->GetLastDescriptorDetails();
    3894    11388365 :     int target_index = details.field_index() - new_map->GetInObjectProperties();
    3895             :     int property_array_length = object->property_array()->length();
    3896    14557581 :     bool have_space = old_map->UnusedPropertyFields() > 0 ||
    3897     6008988 :                       (details.location() == kField && target_index >= 0 &&
    3898     3004494 :                        property_array_length > target_index);
    3899             :     // Either new_map adds an kDescriptor property, or a kField property for
    3900             :     // which there is still space, and which does not require a mutable double
    3901             :     // box (an out-of-object double).
    3902    22776730 :     if (details.location() == kDescriptor ||
    3903    11537651 :         (have_space && ((FLAG_unbox_double_fields && target_index < 0) ||
    3904             :                         !details.representation().IsDouble()))) {
    3905     8381256 :       object->synchronized_set_map(*new_map);
    3906     8381256 :       return;
    3907             :     }
    3908             : 
    3909             :     // If there is still space in the object, we need to allocate a mutable
    3910             :     // double box.
    3911     3007109 :     if (have_space) {
    3912             :       FieldIndex index =
    3913        3468 :           FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
    3914             :       DCHECK(details.representation().IsDouble());
    3915             :       DCHECK(!new_map->IsUnboxedDoubleField(index));
    3916             :       Handle<Object> value = isolate->factory()->NewMutableHeapNumber();
    3917        3468 :       object->RawFastPropertyAtPut(index, *value);
    3918        3468 :       object->synchronized_set_map(*new_map);
    3919             :       return;
    3920             :     }
    3921             : 
    3922             :     // This migration is a transition from a map that has run out of property
    3923             :     // space. Extend the backing store.
    3924     3003641 :     int grow_by = new_map->UnusedPropertyFields() + 1;
    3925             :     Handle<PropertyArray> old_storage(object->property_array());
    3926             :     Handle<PropertyArray> new_storage =
    3927     3003641 :         isolate->factory()->CopyPropertyArrayAndGrow(old_storage, grow_by);
    3928             : 
    3929             :     // Properly initialize newly added property.
    3930             :     Handle<Object> value;
    3931     3003641 :     if (details.representation().IsDouble()) {
    3932             :       value = isolate->factory()->NewMutableHeapNumber();
    3933             :     } else {
    3934             :       value = isolate->factory()->uninitialized_value();
    3935             :     }
    3936             :     DCHECK_EQ(kField, details.location());
    3937             :     DCHECK_EQ(kData, details.kind());
    3938             :     DCHECK_GE(target_index, 0);  // Must be a backing store index.
    3939     3003641 :     new_storage->set(target_index, *value);
    3940             : 
    3941             :     // From here on we cannot fail and we shouldn't GC anymore.
    3942             :     DisallowHeapAllocation no_allocation;
    3943             : 
    3944             :     // Set the new property value and do the map transition.
    3945     3003641 :     object->SetProperties(*new_storage);
    3946     3003641 :     object->synchronized_set_map(*new_map);
    3947     3003641 :     return;
    3948             :   }
    3949             : 
    3950             :   int old_number_of_fields;
    3951    17404325 :   int number_of_fields = new_map->NumberOfFields();
    3952             :   int inobject = new_map->GetInObjectProperties();
    3953             :   int unused = new_map->UnusedPropertyFields();
    3954             : 
    3955             :   // Nothing to do if no functions were converted to fields and no smis were
    3956             :   // converted to doubles.
    3957    17404323 :   if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
    3958    17404324 :                                        unused, &old_number_of_fields)) {
    3959    15707366 :     object->synchronized_set_map(*new_map);
    3960    15707367 :     return;
    3961             :   }
    3962             : 
    3963     1696957 :   int total_size = number_of_fields + unused;
    3964     1696957 :   int external = total_size - inobject;
    3965     1696957 :   Handle<PropertyArray> array = isolate->factory()->NewPropertyArray(external);
    3966             : 
    3967             :   // We use this array to temporarily store the inobject properties.
    3968             :   Handle<FixedArray> inobject_props =
    3969     1696958 :       isolate->factory()->NewFixedArray(inobject);
    3970             : 
    3971             :   Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
    3972             :   Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors());
    3973             :   int old_nof = old_map->NumberOfOwnDescriptors();
    3974             :   int new_nof = new_map->NumberOfOwnDescriptors();
    3975             : 
    3976             :   // This method only supports generalizing instances to at least the same
    3977             :   // number of properties.
    3978             :   DCHECK(old_nof <= new_nof);
    3979             : 
    3980    53762535 :   for (int i = 0; i < old_nof; i++) {
    3981    52065577 :     PropertyDetails details = new_descriptors->GetDetails(i);
    3982    52065577 :     if (details.location() != kField) continue;
    3983             :     DCHECK_EQ(kData, details.kind());
    3984    42990590 :     PropertyDetails old_details = old_descriptors->GetDetails(i);
    3985             :     Representation old_representation = old_details.representation();
    3986             :     Representation representation = details.representation();
    3987             :     Handle<Object> value;
    3988    42990590 :     if (old_details.location() == kDescriptor) {
    3989       18570 :       if (old_details.kind() == kAccessor) {
    3990             :         // In case of kAccessor -> kData property reconfiguration, the property
    3991             :         // must already be prepared for data of certain type.
    3992             :         DCHECK(!details.representation().IsNone());
    3993       12080 :         if (details.representation().IsDouble()) {
    3994             :           value = isolate->factory()->NewMutableHeapNumber();
    3995             :         } else {
    3996             :           value = isolate->factory()->uninitialized_value();
    3997             :         }
    3998             :       } else {
    3999             :         DCHECK_EQ(kData, old_details.kind());
    4000             :         value = handle(old_descriptors->GetValue(i), isolate);
    4001             :         DCHECK(!old_representation.IsDouble() && !representation.IsDouble());
    4002             :       }
    4003             :     } else {
    4004             :       DCHECK_EQ(kField, old_details.location());
    4005    42972020 :       FieldIndex index = FieldIndex::ForDescriptor(*old_map, i);
    4006    42972020 :       if (object->IsUnboxedDoubleField(index)) {
    4007             :         uint64_t old_bits = object->RawFastDoublePropertyAsBitsAt(index);
    4008             :         value = isolate->factory()->NewHeapNumberFromBits(
    4009        5075 :             old_bits, representation.IsDouble() ? MUTABLE : IMMUTABLE);
    4010             : 
    4011             :       } else {
    4012    42966945 :         value = handle(object->RawFastPropertyAt(index), isolate);
    4013    42966945 :         if (!old_representation.IsDouble() && representation.IsDouble()) {
    4014             :           DCHECK_IMPLIES(old_representation.IsNone(),
    4015             :                          value->IsUninitialized(isolate));
    4016        1945 :           value = Object::NewStorageFor(isolate, value, representation);
    4017    42965000 :         } else if (old_representation.IsDouble() &&
    4018             :                    !representation.IsDouble()) {
    4019         318 :           value = Object::WrapForRead(isolate, value, old_representation);
    4020             :         }
    4021             :       }
    4022             :     }
    4023             :     DCHECK(!(representation.IsDouble() && value->IsSmi()));
    4024             :     int target_index = new_descriptors->GetFieldIndex(i);
    4025    42990590 :     if (target_index < inobject) {
    4026     1640228 :       inobject_props->set(target_index, *value);
    4027             :     } else {
    4028    82700724 :       array->set(target_index - inobject, *value);
    4029             :     }
    4030             :   }
    4031             : 
    4032     1676693 :   for (int i = old_nof; i < new_nof; i++) {
    4033     1676693 :     PropertyDetails details = new_descriptors->GetDetails(i);
    4034     1676693 :     if (details.location() != kField) continue;
    4035             :     DCHECK_EQ(kData, details.kind());
    4036             :     Handle<Object> value;
    4037     1676693 :     if (details.representation().IsDouble()) {
    4038             :       value = isolate->factory()->NewMutableHeapNumber();
    4039             :     } else {
    4040             :       value = isolate->factory()->uninitialized_value();
    4041             :     }
    4042             :     int target_index = new_descriptors->GetFieldIndex(i);
    4043     1676693 :     if (target_index < inobject) {
    4044      757062 :       inobject_props->set(target_index, *value);
    4045             :     } else {
    4046     1839262 :       array->set(target_index - inobject, *value);
    4047             :     }
    4048             :   }
    4049             : 
    4050             :   // From here on we cannot fail and we shouldn't GC anymore.
    4051             :   DisallowHeapAllocation no_allocation;
    4052             : 
    4053     1696958 :   Heap* heap = isolate->heap();
    4054             : 
    4055             :   int old_instance_size = old_map->instance_size();
    4056             : 
    4057     1696958 :   heap->NotifyObjectLayoutChange(*object, old_instance_size, no_allocation);
    4058             : 
    4059             :   // Copy (real) inobject properties. If necessary, stop at number_of_fields to
    4060             :   // avoid overwriting |one_pointer_filler_map|.
    4061             :   int limit = Min(inobject, number_of_fields);
    4062     4094248 :   for (int i = 0; i < limit; i++) {
    4063     2397290 :     FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
    4064             :     Object* value = inobject_props->get(i);
    4065             :     // Can't use JSObject::FastPropertyAtPut() because proper map was not set
    4066             :     // yet.
    4067     2397290 :     if (new_map->IsUnboxedDoubleField(index)) {
    4068             :       DCHECK(value->IsMutableHeapNumber());
    4069             :       // Ensure that all bits of the double value are preserved.
    4070             :       object->RawFastDoublePropertyAsBitsAtPut(
    4071             :           index, HeapNumber::cast(value)->value_as_bits());
    4072       11618 :       if (i < old_number_of_fields && !old_map->IsUnboxedDoubleField(index)) {
    4073             :         // Transition from tagged to untagged slot.
    4074             :         heap->ClearRecordedSlot(*object,
    4075        1307 :                                 HeapObject::RawField(*object, index.offset()));
    4076             :       } else {
    4077             :         DCHECK(!heap->HasRecordedSlot(
    4078             :             *object, HeapObject::RawField(*object, index.offset())));
    4079             :       }
    4080             :     } else {
    4081     2391354 :       object->RawFastPropertyAtPut(index, value);
    4082             :     }
    4083             :   }
    4084             : 
    4085     1696958 :   if (external > 0) {
    4086      936361 :     object->SetProperties(*array);
    4087             :   }
    4088             : 
    4089             :   // Create filler object past the new instance size.
    4090             :   int new_instance_size = new_map->instance_size();
    4091     1696958 :   int instance_size_delta = old_instance_size - new_instance_size;
    4092             :   DCHECK_GE(instance_size_delta, 0);
    4093             : 
    4094     1696958 :   if (instance_size_delta > 0) {
    4095          13 :     Address address = object->address();
    4096             :     heap->CreateFillerObjectAt(address + new_instance_size, instance_size_delta,
    4097          13 :                                ClearRecordedSlots::kYes);
    4098             :   }
    4099             : 
    4100             :   // We are storing the new map using release store after creating a filler for
    4101             :   // the left-over space to avoid races with the sweeper thread.
    4102     1696958 :   object->synchronized_set_map(*new_map);
    4103             : }
    4104             : 
    4105      918333 : void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
    4106             :                        int expected_additional_properties) {
    4107             :   // The global object is always normalized.
    4108             :   DCHECK(!object->IsJSGlobalObject());
    4109             :   // JSGlobalProxy must never be normalized
    4110             :   DCHECK(!object->IsJSGlobalProxy());
    4111             : 
    4112             :   Isolate* isolate = object->GetIsolate();
    4113             :   HandleScope scope(isolate);
    4114             :   Handle<Map> map(object->map());
    4115             : 
    4116             :   // Allocate new content.
    4117             :   int real_size = map->NumberOfOwnDescriptors();
    4118             :   int property_count = real_size;
    4119      918333 :   if (expected_additional_properties > 0) {
    4120        8569 :     property_count += expected_additional_properties;
    4121             :   } else {
    4122             :     // Make space for two more properties.
    4123      909764 :     property_count += NameDictionary::kInitialCapacity;
    4124             :   }
    4125             :   Handle<NameDictionary> dictionary =
    4126      918333 :       NameDictionary::New(isolate, property_count);
    4127             : 
    4128             :   Handle<DescriptorArray> descs(map->instance_descriptors());
    4129     3960506 :   for (int i = 0; i < real_size; i++) {
    4130     3042173 :     PropertyDetails details = descs->GetDetails(i);
    4131             :     Handle<Name> key(descs->GetKey(i));
    4132             :     Handle<Object> value;
    4133     3042173 :     if (details.location() == kField) {
    4134     2161922 :       FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    4135     2161922 :       if (details.kind() == kData) {
    4136     2161922 :         if (object->IsUnboxedDoubleField(index)) {
    4137             :           double old_value = object->RawFastDoublePropertyAt(index);
    4138             :           value = isolate->factory()->NewHeapNumber(old_value);
    4139             :         } else {
    4140     2160984 :           value = handle(object->RawFastPropertyAt(index), isolate);
    4141     2160984 :           if (details.representation().IsDouble()) {
    4142             :             DCHECK(value->IsMutableHeapNumber());
    4143             :             Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
    4144             :             value = isolate->factory()->NewHeapNumber(old->value());
    4145             :           }
    4146             :         }
    4147             :       } else {
    4148             :         DCHECK_EQ(kAccessor, details.kind());
    4149           0 :         value = handle(object->RawFastPropertyAt(index), isolate);
    4150             :       }
    4151             : 
    4152             :     } else {
    4153             :       DCHECK_EQ(kDescriptor, details.location());
    4154             :       value = handle(descs->GetValue(i), isolate);
    4155             :     }
    4156             :     DCHECK(!value.is_null());
    4157             :     PropertyDetails d(details.kind(), details.attributes(),
    4158             :                       PropertyCellType::kNoCell);
    4159     3042173 :     dictionary = NameDictionary::Add(dictionary, key, value, d);
    4160             :   }
    4161             : 
    4162             :   // Copy the next enumeration index from instance descriptor.
    4163      918333 :   dictionary->SetNextEnumerationIndex(real_size + 1);
    4164             : 
    4165             :   // From here on we cannot fail and we shouldn't GC anymore.
    4166             :   DisallowHeapAllocation no_allocation;
    4167             : 
    4168      918333 :   Heap* heap = isolate->heap();
    4169             :   int old_instance_size = map->instance_size();
    4170      918333 :   heap->NotifyObjectLayoutChange(*object, old_instance_size, no_allocation);
    4171             : 
    4172             :   // Resize the object in the heap if necessary.
    4173             :   int new_instance_size = new_map->instance_size();
    4174      918333 :   int instance_size_delta = old_instance_size - new_instance_size;
    4175             :   DCHECK_GE(instance_size_delta, 0);
    4176             : 
    4177      918333 :   if (instance_size_delta > 0) {
    4178      344814 :     heap->CreateFillerObjectAt(object->address() + new_instance_size,
    4179      344814 :                                instance_size_delta, ClearRecordedSlots::kYes);
    4180             :   }
    4181             : 
    4182             :   // We are storing the new map using release store after creating a filler for
    4183             :   // the left-over space to avoid races with the sweeper thread.
    4184      918333 :   object->synchronized_set_map(*new_map);
    4185             : 
    4186      918333 :   object->SetProperties(*dictionary);
    4187             : 
    4188             :   // Ensure that in-object space of slow-mode object does not contain random
    4189             :   // garbage.
    4190             :   int inobject_properties = new_map->GetInObjectProperties();
    4191      918333 :   if (inobject_properties) {
    4192             :     Heap* heap = isolate->heap();
    4193             :     heap->ClearRecordedSlotRange(
    4194      323672 :         object->address() + map->GetInObjectPropertyOffset(0),
    4195      647344 :         object->address() + new_instance_size);
    4196             : 
    4197     1778845 :     for (int i = 0; i < inobject_properties; i++) {
    4198     1455173 :       FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
    4199     1455173 :       object->RawFastPropertyAtPut(index, Smi::kZero);
    4200             :     }
    4201             :   }
    4202             : 
    4203      918333 :   isolate->counters()->props_to_dictionary()->Increment();
    4204             : 
    4205             : #ifdef DEBUG
    4206             :   if (FLAG_trace_normalization) {
    4207             :     OFStream os(stdout);
    4208             :     os << "Object properties have been normalized:\n";
    4209             :     object->Print(os);
    4210             :   }
    4211             : #endif
    4212      918333 : }
    4213             : 
    4214             : }  // namespace
    4215             : 
    4216             : // static
    4217    31368350 : void JSObject::NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
    4218             :                                Isolate* isolate) {
    4219    62736700 :   if (!old_map->is_prototype_map()) return;
    4220             : 
    4221             :   InvalidatePrototypeChains(*old_map);
    4222             : 
    4223             :   // If the map was registered with its prototype before, ensure that it
    4224             :   // registers with its new prototype now. This preserves the invariant that
    4225             :   // when a map on a prototype chain is registered with its prototype, then
    4226             :   // all prototypes further up the chain are also registered with their
    4227             :   // respective prototypes.
    4228     3888596 :   UpdatePrototypeUserRegistration(old_map, new_map, isolate);
    4229             : }
    4230             : 
    4231    39970952 : void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
    4232             :                             int expected_additional_properties) {
    4233    79941909 :   if (object->map() == *new_map) return;
    4234             :   Handle<Map> old_map(object->map());
    4235    30840086 :   NotifyMapChange(old_map, new_map, new_map->GetIsolate());
    4236             : 
    4237    30840088 :   if (old_map->is_dictionary_map()) {
    4238             :     // For slow-to-fast migrations JSObject::MigrateSlowToFast()
    4239             :     // must be used instead.
    4240      584899 :     CHECK(new_map->is_dictionary_map());
    4241             : 
    4242             :     // Slow-to-slow migration is trivial.
    4243      584899 :     object->synchronized_set_map(*new_map);
    4244    30255189 :   } else if (!new_map->is_dictionary_map()) {
    4245    29336856 :     MigrateFastToFast(object, new_map);
    4246    29336859 :     if (old_map->is_prototype_map()) {
    4247             :       DCHECK(!old_map->is_stable());
    4248             :       DCHECK(new_map->is_stable());
    4249             :       DCHECK(new_map->owns_descriptors());
    4250             :       DCHECK(old_map->owns_descriptors());
    4251             :       // Transfer ownership to the new map. Keep the descriptor pointer of the
    4252             :       // old map intact because the concurrent marker might be iterating the
    4253             :       // object with the old map.
    4254             :       old_map->set_owns_descriptors(false);
    4255             :       DCHECK(old_map->is_abandoned_prototype_map());
    4256             :       // Ensure that no transition was inserted for prototype migrations.
    4257             :       DCHECK_EQ(0, TransitionsAccessor(old_map).NumberOfTransitions());
    4258             :       DCHECK(new_map->GetBackPointer()->IsUndefined(new_map->GetIsolate()));
    4259             :       DCHECK(object->map() != *old_map);
    4260             :     }
    4261             :   } else {
    4262      918333 :     MigrateFastToSlow(object, new_map, expected_additional_properties);
    4263             :   }
    4264             : 
    4265             :   // Careful: Don't allocate here!
    4266             :   // For some callers of this method, |object| might be in an inconsistent
    4267             :   // state now: the new map might have a new elements_kind, but the object's
    4268             :   // elements pointer hasn't been updated yet. Callers will fix this, but in
    4269             :   // the meantime, (indirectly) calling JSObjectVerify() must be avoided.
    4270             :   // When adding code here, add a DisallowHeapAllocation too.
    4271             : }
    4272             : 
    4273      180568 : void JSObject::ForceSetPrototype(Handle<JSObject> object,
    4274             :                                  Handle<Object> proto) {
    4275             :   // object.__proto__ = proto;
    4276             :   Handle<Map> old_map = Handle<Map>(object->map());
    4277      180568 :   Handle<Map> new_map = Map::Copy(old_map, "ForceSetPrototype");
    4278      180568 :   Map::SetPrototype(new_map, proto);
    4279      180568 :   JSObject::MigrateToMap(object, new_map);
    4280      180568 : }
    4281             : 
    4282    43208621 : int Map::NumberOfFields() const {
    4283             :   DescriptorArray* descriptors = instance_descriptors();
    4284             :   int result = 0;
    4285   645738662 :   for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
    4286   559321415 :     if (descriptors->GetDetails(i).location() == kField) result++;
    4287             :   }
    4288    43208626 :   return result;
    4289             : }
    4290             : 
    4291     4827989 : void DescriptorArray::GeneralizeAllFields() {
    4292             :   int length = number_of_descriptors();
    4293    13215663 :   for (int i = 0; i < length; i++) {
    4294     3559685 :     PropertyDetails details = GetDetails(i);
    4295             :     details = details.CopyWithRepresentation(Representation::Tagged());
    4296     3559685 :     if (details.location() == kField) {
    4297             :       DCHECK_EQ(kData, details.kind());
    4298             :       details = details.CopyWithConstness(kMutable);
    4299      142549 :       SetValue(i, FieldType::Any());
    4300             :     }
    4301             :     set(ToDetailsIndex(i), details.AsSmi());
    4302             :   }
    4303     4827989 : }
    4304             : 
    4305       18130 : Handle<Map> Map::CopyGeneralizeAllFields(Handle<Map> map,
    4306             :                                          ElementsKind elements_kind,
    4307             :                                          int modify_index, PropertyKind kind,
    4308             :                                          PropertyAttributes attributes,
    4309             :                                          const char* reason) {
    4310             :   Isolate* isolate = map->GetIsolate();
    4311             :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
    4312             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    4313             :   Handle<DescriptorArray> descriptors =
    4314             :       DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors);
    4315       18130 :   descriptors->GeneralizeAllFields();
    4316             : 
    4317             :   Handle<LayoutDescriptor> new_layout_descriptor(
    4318             :       LayoutDescriptor::FastPointerLayout(), isolate);
    4319             :   Handle<Map> new_map = CopyReplaceDescriptors(
    4320             :       map, descriptors, new_layout_descriptor, OMIT_TRANSITION,
    4321       18130 :       MaybeHandle<Name>(), reason, SPECIAL_TRANSITION);
    4322             : 
    4323             :   // Unless the instance is being migrated, ensure that modify_index is a field.
    4324       18130 :   if (modify_index >= 0) {
    4325       18046 :     PropertyDetails details = descriptors->GetDetails(modify_index);
    4326       20142 :     if (details.constness() != kMutable || details.location() != kField ||
    4327             :         details.attributes() != attributes) {
    4328             :       int field_index = details.location() == kField
    4329             :                             ? details.field_index()
    4330       34269 :                             : new_map->NumberOfFields();
    4331             :       Descriptor d = Descriptor::DataField(
    4332             :           handle(descriptors->GetKey(modify_index), isolate), field_index,
    4333       17271 :           attributes, Representation::Tagged());
    4334       17271 :       descriptors->Replace(modify_index, &d);
    4335       17271 :       if (details.location() != kField) {
    4336       16998 :         new_map->AccountAddedPropertyField();
    4337             :       }
    4338             :     } else {
    4339             :       DCHECK(details.attributes() == attributes);
    4340             :     }
    4341             : 
    4342       18046 :     if (FLAG_trace_generalization) {
    4343           0 :       MaybeHandle<FieldType> field_type = FieldType::None(isolate);
    4344           0 :       if (details.location() == kField) {
    4345             :         field_type = handle(
    4346           0 :             map->instance_descriptors()->GetFieldType(modify_index), isolate);
    4347             :       }
    4348             :       map->PrintGeneralization(
    4349             :           stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(),
    4350             :           new_map->NumberOfOwnDescriptors(), details.location() == kDescriptor,
    4351             :           details.representation(), Representation::Tagged(), field_type,
    4352             :           MaybeHandle<Object>(), FieldType::Any(isolate),
    4353           0 :           MaybeHandle<Object>());
    4354             :     }
    4355             :   }
    4356             :   new_map->set_elements_kind(elements_kind);
    4357       18130 :   return new_map;
    4358             : }
    4359             : 
    4360       58549 : void Map::DeprecateTransitionTree() {
    4361       58549 :   if (is_deprecated()) return;
    4362             :   DisallowHeapAllocation no_gc;
    4363             :   TransitionsAccessor transitions(this, &no_gc);
    4364       58549 :   int num_transitions = transitions.NumberOfTransitions();
    4365       93897 :   for (int i = 0; i < num_transitions; ++i) {
    4366       35348 :     transitions.GetTarget(i)->DeprecateTransitionTree();
    4367             :   }
    4368             :   DCHECK(!constructor_or_backpointer()->IsFunctionTemplateInfo());
    4369             :   deprecate();
    4370             :   dependent_code()->DeoptimizeDependentCodeGroup(
    4371       58549 :       GetIsolate(), DependentCode::kTransitionGroup);
    4372       58549 :   NotifyLeafMapLayoutChange();
    4373             : }
    4374             : 
    4375             : 
    4376             : // Installs |new_descriptors| over the current instance_descriptors to ensure
    4377             : // proper sharing of descriptor arrays.
    4378       24825 : void Map::ReplaceDescriptors(DescriptorArray* new_descriptors,
    4379             :                              LayoutDescriptor* new_layout_descriptor) {
    4380             :   Isolate* isolate = GetIsolate();
    4381             :   // Don't overwrite the empty descriptor array or initial map's descriptors.
    4382       36552 :   if (NumberOfOwnDescriptors() == 0 || GetBackPointer()->IsUndefined(isolate)) {
    4383       24825 :     return;
    4384             :   }
    4385             : 
    4386             :   DescriptorArray* to_replace = instance_descriptors();
    4387             :   // Replace descriptors by new_descriptors in all maps that share it. The old
    4388             :   // descriptors will not be trimmed in the mark-compactor, we need to mark
    4389             :   // all its elements.
    4390       11444 :   isolate->heap()->incremental_marking()->RecordWrites(to_replace);
    4391             :   Map* current = this;
    4392       74888 :   while (current->instance_descriptors() == to_replace) {
    4393       52337 :     Object* next = current->GetBackPointer();
    4394       52337 :     if (next->IsUndefined(isolate)) break;  // Stop overwriting at initial map.
    4395             :     current->SetEnumLength(kInvalidEnumCacheSentinel);
    4396       52000 :     current->UpdateDescriptors(new_descriptors, new_layout_descriptor);
    4397             :     current = Map::cast(next);
    4398             :   }
    4399             :   set_owns_descriptors(false);
    4400             : }
    4401             : 
    4402     1031085 : Map* Map::FindRootMap() const {
    4403             :   const Map* result = this;
    4404             :   Isolate* isolate = GetIsolate();
    4405             :   while (true) {
    4406     1368783 :     Object* back = result->GetBackPointer();
    4407     1368783 :     if (back->IsUndefined(isolate)) {
    4408             :       // Initial map always owns descriptors and doesn't have unused entries
    4409             :       // in the descriptor array.
    4410             :       DCHECK(result->owns_descriptors());
    4411             :       DCHECK_EQ(result->NumberOfOwnDescriptors(),
    4412             :                 result->instance_descriptors()->number_of_descriptors());
    4413     1031085 :       return const_cast<Map*>(result);
    4414             :     }
    4415             :     result = Map::cast(back);
    4416             :   }
    4417             : }
    4418             : 
    4419      591053 : Map* Map::FindFieldOwner(int descriptor) const {
    4420             :   DisallowHeapAllocation no_allocation;
    4421             :   DCHECK_EQ(kField, instance_descriptors()->GetDetails(descriptor).location());
    4422             :   const Map* result = this;
    4423             :   Isolate* isolate = GetIsolate();
    4424             :   while (true) {
    4425     2139829 :     Object* back = result->GetBackPointer();
    4426     2139829 :     if (back->IsUndefined(isolate)) break;
    4427             :     const Map* parent = Map::cast(back);
    4428     2043763 :     if (parent->NumberOfOwnDescriptors() <= descriptor) break;
    4429             :     result = parent;
    4430             :   }
    4431      591053 :   return const_cast<Map*>(result);
    4432             : }
    4433             : 
    4434      311973 : void Map::UpdateFieldType(int descriptor, Handle<Name> name,
    4435             :                           PropertyConstness new_constness,
    4436             :                           Representation new_representation,
    4437             :                           Handle<Object> new_wrapped_type) {
    4438             :   DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell());
    4439             :   // We store raw pointers in the queue, so no allocations are allowed.
    4440             :   DisallowHeapAllocation no_allocation;
    4441      311973 :   PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
    4442      311973 :   if (details.location() != kField) return;
    4443             :   DCHECK_EQ(kData, details.kind());
    4444             : 
    4445      311973 :   Zone zone(GetIsolate()->allocator(), ZONE_NAME);
    4446      311973 :   ZoneQueue<Map*> backlog(&zone);
    4447      623946 :   backlog.push(this);
    4448             : 
    4449     2501385 :   while (!backlog.empty()) {
    4450     1877439 :     Map* current = backlog.front();
    4451             :     backlog.pop();
    4452             : 
    4453             :     TransitionsAccessor transitions(current, &no_allocation);
    4454     1877439 :     int num_transitions = transitions.NumberOfTransitions();
    4455     3442905 :     for (int i = 0; i < num_transitions; ++i) {
    4456     1565466 :       Map* target = transitions.GetTarget(i);
    4457             :       backlog.push(target);
    4458             :     }
    4459             :     DescriptorArray* descriptors = current->instance_descriptors();
    4460     1877439 :     PropertyDetails details = descriptors->GetDetails(descriptor);
    4461             : 
    4462             :     // Currently constness change implies map change.
    4463             :     DCHECK_IMPLIES(new_constness != details.constness(),
    4464             :                    FLAG_modify_map_inplace);
    4465             : 
    4466             :     // It is allowed to change representation here only from None to something.
    4467             :     DCHECK(details.representation().Equals(new_representation) ||
    4468             :            details.representation().IsNone());
    4469             : 
    4470             :     // Skip if already updated the shared descriptor.
    4471     1877439 :     if ((FLAG_modify_map_inplace && new_constness != details.constness()) ||
    4472             :         descriptors->GetValue(descriptor) != *new_wrapped_type) {
    4473             :       DCHECK_IMPLIES(!FLAG_track_constant_fields, new_constness == kMutable);
    4474             :       Descriptor d = Descriptor::DataField(
    4475             :           name, descriptors->GetFieldIndex(descriptor), details.attributes(),
    4476      312021 :           new_constness, new_representation, new_wrapped_type);
    4477      312021 :       descriptors->Replace(descriptor, &d);
    4478             :     }
    4479      311973 :   }
    4480             : }
    4481             : 
    4482           0 : bool FieldTypeIsCleared(Representation rep, FieldType* type) {
    4483     1733161 :   return type->IsNone() && rep.IsHeapObject();
    4484             : }
    4485             : 
    4486             : 
    4487             : // static
    4488      762537 : Handle<FieldType> Map::GeneralizeFieldType(Representation rep1,
    4489             :                                            Handle<FieldType> type1,
    4490             :                                            Representation rep2,
    4491             :                                            Handle<FieldType> type2,
    4492             :                                            Isolate* isolate) {
    4493             :   // Cleared field types need special treatment. They represent lost knowledge,
    4494             :   // so we must be conservative, so their generalization with any other type
    4495             :   // is "Any".
    4496     1524958 :   if (FieldTypeIsCleared(rep1, *type1) || FieldTypeIsCleared(rep2, *type2)) {
    4497        6153 :     return FieldType::Any(isolate);
    4498             :   }
    4499      756384 :   if (type1->NowIs(type2)) return type2;
    4500       42472 :   if (type2->NowIs(type1)) return type1;
    4501       20098 :   return FieldType::Any(isolate);
    4502             : }
    4503             : 
    4504             : // static
    4505      475511 : void Map::GeneralizeField(Handle<Map> map, int modify_index,
    4506             :                           PropertyConstness new_constness,
    4507             :                           Representation new_representation,
    4508             :                           Handle<FieldType> new_field_type) {
    4509             :   Isolate* isolate = map->GetIsolate();
    4510             : 
    4511             :   // Check if we actually need to generalize the field type at all.
    4512             :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
    4513      475511 :   PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
    4514             :   PropertyConstness old_constness = old_details.constness();
    4515             :   Representation old_representation = old_details.representation();
    4516             :   Handle<FieldType> old_field_type(old_descriptors->GetFieldType(modify_index),
    4517      475511 :                                    isolate);
    4518             : 
    4519             :   // Return if the current map is general enough to hold requested contness and
    4520             :   // representation/field type.
    4521      475511 :   if (((FLAG_modify_map_inplace &&
    4522             :         IsGeneralizableTo(new_constness, old_constness)) ||
    4523      475511 :        (!FLAG_modify_map_inplace && (old_constness == new_constness))) &&
    4524      197943 :       old_representation.Equals(new_representation) &&
    4525      673435 :       !FieldTypeIsCleared(new_representation, *new_field_type) &&
    4526             :       // Checking old_field_type for being cleared is not necessary because
    4527             :       // the NowIs check below would fail anyway in that case.
    4528      197924 :       new_field_type->NowIs(old_field_type)) {
    4529             :     DCHECK(GeneralizeFieldType(old_representation, old_field_type,
    4530             :                                new_representation, new_field_type, isolate)
    4531             :                ->NowIs(old_field_type));
    4532      163538 :     return;
    4533             :   }
    4534             : 
    4535             :   // Determine the field owner.
    4536      311973 :   Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
    4537             :   Handle<DescriptorArray> descriptors(field_owner->instance_descriptors(),
    4538             :                                       isolate);
    4539             :   DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index));
    4540             : 
    4541             :   new_field_type =
    4542             :       Map::GeneralizeFieldType(old_representation, old_field_type,
    4543      311973 :                                new_representation, new_field_type, isolate);
    4544             :   if (FLAG_modify_map_inplace) {
    4545             :     new_constness = GeneralizeConstness(old_constness, new_constness);
    4546             :   }
    4547             : 
    4548      311973 :   PropertyDetails details = descriptors->GetDetails(modify_index);
    4549             :   Handle<Name> name(descriptors->GetKey(modify_index));
    4550             : 
    4551      311973 :   Handle<Object> wrapped_type(WrapFieldType(new_field_type));
    4552             :   field_owner->UpdateFieldType(modify_index, name, new_constness,
    4553      311973 :                                new_representation, wrapped_type);
    4554             :   field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
    4555      311973 :       isolate, DependentCode::kFieldOwnerGroup);
    4556             : 
    4557      311973 :   if (FLAG_trace_generalization) {
    4558             :     map->PrintGeneralization(
    4559             :         stdout, "field type generalization", modify_index,
    4560             :         map->NumberOfOwnDescriptors(), map->NumberOfOwnDescriptors(), false,
    4561             :         details.representation(), details.representation(), old_field_type,
    4562           0 :         MaybeHandle<Object>(), new_field_type, MaybeHandle<Object>());
    4563             :   }
    4564             : }
    4565             : 
    4566             : // TODO(ishell): remove.
    4567             : // static
    4568         497 : Handle<Map> Map::ReconfigureProperty(Handle<Map> map, int modify_index,
    4569             :                                      PropertyKind new_kind,
    4570             :                                      PropertyAttributes new_attributes,
    4571             :                                      Representation new_representation,
    4572             :                                      Handle<FieldType> new_field_type) {
    4573             :   DCHECK_EQ(kData, new_kind);  // Only kData case is supported.
    4574         497 :   MapUpdater mu(map->GetIsolate(), map);
    4575             :   return mu.ReconfigureToDataField(modify_index, new_attributes, kConst,
    4576         497 :                                    new_representation, new_field_type);
    4577             : }
    4578             : 
    4579             : // TODO(ishell): remove.
    4580             : // static
    4581      427557 : Handle<Map> Map::ReconfigureElementsKind(Handle<Map> map,
    4582             :                                          ElementsKind new_elements_kind) {
    4583      427557 :   MapUpdater mu(map->GetIsolate(), map);
    4584      427557 :   return mu.ReconfigureElementsKind(new_elements_kind);
    4585             : }
    4586             : 
    4587             : // Generalize all fields and update the transition tree.
    4588       35095 : Handle<Map> Map::GeneralizeAllFields(Handle<Map> map) {
    4589             :   Isolate* isolate = map->GetIsolate();
    4590       35095 :   Handle<FieldType> any_type = FieldType::Any(isolate);
    4591             : 
    4592             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    4593       97154 :   for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) {
    4594       13482 :     PropertyDetails details = descriptors->GetDetails(i);
    4595       13482 :     if (details.location() == kField) {
    4596             :       DCHECK_EQ(kData, details.kind());
    4597        1326 :       MapUpdater mu(isolate, map);
    4598             :       map = mu.ReconfigureToDataField(i, details.attributes(), kMutable,
    4599        1326 :                                       Representation::Tagged(), any_type);
    4600             :     }
    4601             :   }
    4602       35095 :   return map;
    4603             : }
    4604             : 
    4605             : 
    4606             : // static
    4607      160915 : MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) {
    4608             :   DisallowHeapAllocation no_allocation;
    4609             :   DisallowDeoptimization no_deoptimization(old_map->GetIsolate());
    4610             : 
    4611      160915 :   if (!old_map->is_deprecated()) return old_map;
    4612             : 
    4613             :   // Check the state of the root map.
    4614        4169 :   Map* root_map = old_map->FindRootMap();
    4615        4169 :   if (root_map->is_deprecated()) {
    4616           0 :     JSFunction* constructor = JSFunction::cast(root_map->GetConstructor());
    4617             :     DCHECK(constructor->has_initial_map());
    4618             :     DCHECK(constructor->initial_map()->is_dictionary_map());
    4619           0 :     if (constructor->initial_map()->elements_kind() !=
    4620             :         old_map->elements_kind()) {
    4621           0 :       return MaybeHandle<Map>();
    4622             :     }
    4623           0 :     return handle(constructor->initial_map());
    4624             :   }
    4625        4169 :   if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>();
    4626             : 
    4627             :   ElementsKind from_kind = root_map->elements_kind();
    4628             :   ElementsKind to_kind = old_map->elements_kind();
    4629        4099 :   if (from_kind != to_kind) {
    4630             :     // Try to follow existing elements kind transitions.
    4631             :     root_map = root_map->LookupElementsTransitionMap(to_kind);
    4632           8 :     if (root_map == nullptr) return MaybeHandle<Map>();
    4633             :     // From here on, use the map with correct elements kind as root map.
    4634             :   }
    4635        4099 :   Map* new_map = root_map->TryReplayPropertyTransitions(*old_map);
    4636        4099 :   if (new_map == nullptr) return MaybeHandle<Map>();
    4637        4081 :   return handle(new_map);
    4638             : }
    4639             : 
    4640      100422 : Map* Map::TryReplayPropertyTransitions(Map* old_map) {
    4641             :   DisallowHeapAllocation no_allocation;
    4642             :   DisallowDeoptimization no_deoptimization(GetIsolate());
    4643             : 
    4644             :   int root_nof = NumberOfOwnDescriptors();
    4645             : 
    4646             :   int old_nof = old_map->NumberOfOwnDescriptors();
    4647             :   DescriptorArray* old_descriptors = old_map->instance_descriptors();
    4648             : 
    4649             :   Map* new_map = this;
    4650      105748 :   for (int i = root_nof; i < old_nof; ++i) {
    4651        9576 :     PropertyDetails old_details = old_descriptors->GetDetails(i);
    4652             :     Map* transition =
    4653             :         TransitionsAccessor(new_map, &no_allocation)
    4654             :             .SearchTransition(old_descriptors->GetKey(i), old_details.kind(),
    4655        9576 :                               old_details.attributes());
    4656        9576 :     if (transition == nullptr) return nullptr;
    4657             :     new_map = transition;
    4658             :     DescriptorArray* new_descriptors = new_map->instance_descriptors();
    4659             : 
    4660        5381 :     PropertyDetails new_details = new_descriptors->GetDetails(i);
    4661             :     DCHECK_EQ(old_details.kind(), new_details.kind());
    4662             :     DCHECK_EQ(old_details.attributes(), new_details.attributes());
    4663        5381 :     if (!IsGeneralizableTo(old_details.constness(), new_details.constness())) {
    4664             :       return nullptr;
    4665             :     }
    4666             :     DCHECK(IsGeneralizableTo(old_details.location(), new_details.location()));
    4667       16143 :     if (!old_details.representation().fits_into(new_details.representation())) {
    4668             :       return nullptr;
    4669             :     }
    4670        5336 :     if (new_details.location() == kField) {
    4671        5210 :       if (new_details.kind() == kData) {
    4672        5210 :         FieldType* new_type = new_descriptors->GetFieldType(i);
    4673             :         // Cleared field types need special treatment. They represent lost
    4674             :         // knowledge, so we must first generalize the new_type to "Any".
    4675        5210 :         if (FieldTypeIsCleared(new_details.representation(), new_type)) {
    4676             :           return nullptr;
    4677             :         }
    4678             :         DCHECK_EQ(kData, old_details.kind());
    4679        5210 :         if (old_details.location() == kField) {
    4680        5050 :           FieldType* old_type = old_descriptors->GetFieldType(i);
    4681       10100 :           if (FieldTypeIsCleared(old_details.representation(), old_type) ||
    4682        5050 :               !old_type->NowIs(new_type)) {
    4683             :             return nullptr;
    4684             :           }
    4685             :         } else {
    4686             :           DCHECK_EQ(kDescriptor, old_details.location());
    4687             :           DCHECK(!FLAG_track_constant_fields);
    4688             :           Object* old_value = old_descriptors->GetValue(i);
    4689         160 :           if (!new_type->NowContains(old_value)) {
    4690             :             return nullptr;
    4691             :           }
    4692             :         }
    4693             : 
    4694             :       } else {
    4695             :         DCHECK_EQ(kAccessor, new_details.kind());
    4696             : #ifdef DEBUG
    4697             :         FieldType* new_type = new_descriptors->GetFieldType(i);
    4698             :         DCHECK(new_type->IsAny());
    4699             : #endif
    4700           0 :         UNREACHABLE();
    4701             :       }
    4702             :     } else {
    4703             :       DCHECK_EQ(kDescriptor, new_details.location());
    4704             :       Object* old_value = old_descriptors->GetValue(i);
    4705             :       Object* new_value = new_descriptors->GetValue(i);
    4706         126 :       if (old_details.location() == kField || old_value != new_value) {
    4707             :         return nullptr;
    4708             :       }
    4709             :     }
    4710             :   }
    4711       96172 :   if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr;
    4712       96172 :   return new_map;
    4713             : }
    4714             : 
    4715             : 
    4716             : // static
    4717    26982874 : Handle<Map> Map::Update(Handle<Map> map) {
    4718    26982874 :   if (!map->is_deprecated()) return map;
    4719        4167 :   MapUpdater mu(map->GetIsolate(), map);
    4720        4167 :   return mu.Update();
    4721             : }
    4722             : 
    4723      193402 : Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
    4724             :                                                  ShouldThrow should_throw,
    4725             :                                                  Handle<Object> value) {
    4726             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    4727             :   return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(),
    4728      193402 :                                             should_throw, value);
    4729             : }
    4730             : 
    4731     3152772 : MaybeHandle<Object> Object::SetProperty(Handle<Object> object,
    4732             :                                         Handle<Name> name, Handle<Object> value,
    4733             :                                         LanguageMode language_mode,
    4734             :                                         StoreFromKeyed store_mode) {
    4735     3152772 :   LookupIterator it(object, name);
    4736     3152772 :   MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode));
    4737     3152680 :   return value;
    4738             : }
    4739             : 
    4740             : 
    4741    20091656 : Maybe<bool> Object::SetPropertyInternal(LookupIterator* it,
    4742             :                                         Handle<Object> value,
    4743             :                                         LanguageMode language_mode,
    4744             :                                         StoreFromKeyed store_mode,
    4745             :                                         bool* found) {
    4746     9841084 :   it->UpdateProtector();
    4747             :   DCHECK(it->IsFound());
    4748             :   ShouldThrow should_throw =
    4749     9841084 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    4750             : 
    4751             :   // Make sure that the top context does not change when doing callbacks or
    4752             :   // interceptor calls.
    4753             :   AssertNoContextChange ncc(it->isolate());
    4754             : 
    4755      266180 :   do {
    4756     9984392 :     switch (it->state()) {
    4757             :       case LookupIterator::NOT_FOUND:
    4758           0 :         UNREACHABLE();
    4759             : 
    4760             :       case LookupIterator::ACCESS_CHECK:
    4761       73273 :         if (it->HasAccess()) break;
    4762             :         // Check whether it makes sense to reuse the lookup iterator. Here it
    4763             :         // might still call into setters up the prototype chain.
    4764             :         return JSObject::SetPropertyWithFailedAccessCheck(it, value,
    4765         105 :                                                           should_throw);
    4766             : 
    4767             :       case LookupIterator::JSPROXY:
    4768             :         return JSProxy::SetProperty(it->GetHolder<JSProxy>(), it->GetName(),
    4769       41571 :                                     value, it->GetReceiver(), language_mode);
    4770             : 
    4771             :       case LookupIterator::INTERCEPTOR: {
    4772      202423 :         if (it->HolderIsReceiverOrHiddenPrototype()) {
    4773             :           Maybe<bool> result =
    4774      193182 :               JSObject::SetPropertyWithInterceptor(it, should_throw, value);
    4775      386364 :           if (result.IsNothing() || result.FromJust()) return result;
    4776             :         } else {
    4777             :           Maybe<PropertyAttributes> maybe_attributes =
    4778        9241 :               JSObject::GetPropertyAttributesWithInterceptor(it);
    4779       18384 :           if (!maybe_attributes.IsJust()) return Nothing<bool>();
    4780        9241 :           if ((maybe_attributes.FromJust() & READ_ONLY) != 0) {
    4781           0 :             return WriteToReadOnlyProperty(it, value, should_throw);
    4782             :           }
    4783        9241 :           if (maybe_attributes.FromJust() == ABSENT) break;
    4784        9143 :           *found = false;
    4785             :           return Nothing<bool>();
    4786             :         }
    4787             :         break;
    4788             :       }
    4789             : 
    4790             :       case LookupIterator::ACCESSOR: {
    4791      529489 :         if (it->IsReadOnly()) {
    4792        1585 :           return WriteToReadOnlyProperty(it, value, should_throw);
    4793             :         }
    4794      527904 :         Handle<Object> accessors = it->GetAccessors();
    4795      777782 :         if (accessors->IsAccessorInfo() &&
    4796      648640 :             !it->HolderIsReceiverOrHiddenPrototype() &&
    4797             :             AccessorInfo::cast(*accessors)->is_special_data_property()) {
    4798         498 :           *found = false;
    4799             :           return Nothing<bool>();
    4800             :         }
    4801      527406 :         return SetPropertyWithAccessor(it, value, should_throw);
    4802             :       }
    4803             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    4804             :         // TODO(verwaest): We should throw an exception if holder is receiver.
    4805             :         return Just(true);
    4806             : 
    4807             :       case LookupIterator::DATA:
    4808     8531821 :         if (it->IsReadOnly()) {
    4809       29553 :           return WriteToReadOnlyProperty(it, value, should_throw);
    4810             :         }
    4811     8502268 :         if (it->HolderIsReceiverOrHiddenPrototype()) {
    4812     8396852 :           return SetDataProperty(it, value);
    4813             :         }
    4814             :       // Fall through.
    4815             :       case LookupIterator::TRANSITION:
    4816      709033 :         *found = false;
    4817             :         return Nothing<bool>();
    4818             :     }
    4819      266180 :     it->Next();
    4820             :   } while (it->IsFound());
    4821             : 
    4822      122872 :   *found = false;
    4823             :   return Nothing<bool>();
    4824             : }
    4825             : 
    4826             : 
    4827    20851320 : Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
    4828             :                                 LanguageMode language_mode,
    4829             :                                 StoreFromKeyed store_mode) {
    4830    20850084 :   if (it->IsFound()) {
    4831     9795993 :     bool found = true;
    4832             :     Maybe<bool> result =
    4833     9795993 :         SetPropertyInternal(it, value, language_mode, store_mode, &found);
    4834     9795993 :     if (found) return result;
    4835             :   }
    4836             : 
    4837             :   // If the receiver is the JSGlobalObject, the store was contextual. In case
    4838             :   // the property did not exist yet on the global object itself, we have to
    4839             :   // throw a reference error in strict mode.  In sloppy mode, we continue.
    4840    19802574 :   if (is_strict(language_mode) && it->GetReceiver()->IsJSGlobalObject()) {
    4841             :     it->isolate()->Throw(*it->isolate()->factory()->NewReferenceError(
    4842        1236 :         MessageTemplate::kNotDefined, it->name()));
    4843             :     return Nothing<bool>();
    4844             :   }
    4845             : 
    4846             :   ShouldThrow should_throw =
    4847    11892817 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    4848    11892817 :   return AddDataProperty(it, value, NONE, should_throw, store_mode);
    4849             : }
    4850             : 
    4851             : 
    4852       54822 : Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
    4853             :                                      LanguageMode language_mode,
    4854             :                                      StoreFromKeyed store_mode) {
    4855             :   Isolate* isolate = it->isolate();
    4856             : 
    4857       49220 :   if (it->IsFound()) {
    4858       45091 :     bool found = true;
    4859             :     Maybe<bool> result =
    4860       45091 :         SetPropertyInternal(it, value, language_mode, store_mode, &found);
    4861       45091 :     if (found) return result;
    4862             :   }
    4863             : 
    4864        6331 :   it->UpdateProtector();
    4865             : 
    4866             :   // The property either doesn't exist on the holder or exists there as a data
    4867             :   // property.
    4868             : 
    4869             :   ShouldThrow should_throw =
    4870        6331 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    4871             : 
    4872        6331 :   if (!it->GetReceiver()->IsJSReceiver()) {
    4873         729 :     return WriteToReadOnlyProperty(it, value, should_throw);
    4874             :   }
    4875             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    4876             : 
    4877             :   LookupIterator::Configuration c = LookupIterator::OWN;
    4878             :   LookupIterator own_lookup =
    4879             :       it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
    4880       11204 :                       : LookupIterator(receiver, it->name(), c);
    4881             : 
    4882          28 :   for (; own_lookup.IsFound(); own_lookup.Next()) {
    4883        4221 :     switch (own_lookup.state()) {
    4884             :       case LookupIterator::ACCESS_CHECK:
    4885          33 :         if (!own_lookup.HasAccess()) {
    4886             :           return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value,
    4887           5 :                                                             should_throw);
    4888             :         }
    4889             :         break;
    4890             : 
    4891             :       case LookupIterator::ACCESSOR:
    4892        1962 :         if (own_lookup.GetAccessors()->IsAccessorInfo()) {
    4893           9 :           if (own_lookup.IsReadOnly()) {
    4894           0 :             return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
    4895             :           }
    4896             :           return JSObject::SetPropertyWithAccessor(&own_lookup, value,
    4897           9 :                                                    should_throw);
    4898             :         }
    4899             :       // Fall through.
    4900             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    4901             :         return RedefineIncompatibleProperty(isolate, it->GetName(), value,
    4902        1944 :                                             should_throw);
    4903             : 
    4904             :       case LookupIterator::DATA: {
    4905         981 :         if (own_lookup.IsReadOnly()) {
    4906         297 :           return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
    4907             :         }
    4908         684 :         return SetDataProperty(&own_lookup, value);
    4909             :       }
    4910             : 
    4911             :       case LookupIterator::INTERCEPTOR:
    4912             :       case LookupIterator::JSPROXY: {
    4913             :         PropertyDescriptor desc;
    4914             :         Maybe<bool> owned =
    4915        2226 :             JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc);
    4916        2226 :         MAYBE_RETURN(owned, Nothing<bool>());
    4917        1776 :         if (!owned.FromJust()) {
    4918             :           return JSReceiver::CreateDataProperty(&own_lookup, value,
    4919         871 :                                                 should_throw);
    4920             :         }
    4921        1810 :         if (PropertyDescriptor::IsAccessorDescriptor(&desc) ||
    4922             :             !desc.writable()) {
    4923             :           return RedefineIncompatibleProperty(isolate, it->GetName(), value,
    4924           0 :                                               should_throw);
    4925             :         }
    4926             : 
    4927             :         PropertyDescriptor value_desc;
    4928             :         value_desc.set_value(value);
    4929             :         return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
    4930        1810 :                                              &value_desc, should_throw);
    4931             :       }
    4932             : 
    4933             :       case LookupIterator::NOT_FOUND:
    4934             :       case LookupIterator::TRANSITION:
    4935           0 :         UNREACHABLE();
    4936             :     }
    4937             :   }
    4938             : 
    4939        1409 :   return AddDataProperty(&own_lookup, value, NONE, should_throw, store_mode);
    4940             : }
    4941             : 
    4942        6223 : Maybe<bool> Object::CannotCreateProperty(Isolate* isolate,
    4943             :                                          Handle<Object> receiver,
    4944             :                                          Handle<Object> name,
    4945             :                                          Handle<Object> value,
    4946             :                                          ShouldThrow should_throw) {
    4947        6469 :   RETURN_FAILURE(
    4948             :       isolate, should_throw,
    4949             :       NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name,
    4950             :                    Object::TypeOf(isolate, receiver), receiver));
    4951             : }
    4952             : 
    4953             : 
    4954       64328 : Maybe<bool> Object::WriteToReadOnlyProperty(LookupIterator* it,
    4955             :                                             Handle<Object> value,
    4956             :                                             ShouldThrow should_throw) {
    4957             :   return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
    4958       64328 :                                  it->GetName(), value, should_throw);
    4959             : }
    4960             : 
    4961             : 
    4962       32164 : Maybe<bool> Object::WriteToReadOnlyProperty(Isolate* isolate,
    4963             :                                             Handle<Object> receiver,
    4964             :                                             Handle<Object> name,
    4965             :                                             Handle<Object> value,
    4966             :                                             ShouldThrow should_throw) {
    4967       52532 :   RETURN_FAILURE(isolate, should_throw,
    4968             :                  NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
    4969             :                               Object::TypeOf(isolate, receiver), receiver));
    4970             : }
    4971             : 
    4972             : 
    4973         982 : Maybe<bool> Object::RedefineIncompatibleProperty(Isolate* isolate,
    4974             :                                                  Handle<Object> name,
    4975             :                                                  Handle<Object> value,
    4976             :                                                  ShouldThrow should_throw) {
    4977        1218 :   RETURN_FAILURE(isolate, should_throw,
    4978             :                  NewTypeError(MessageTemplate::kRedefineDisallowed, name));
    4979             : }
    4980             : 
    4981             : 
    4982    17469524 : Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) {
    4983             :   // Proxies are handled elsewhere. Other non-JSObjects cannot have own
    4984             :   // properties.
    4985             :   Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
    4986             : 
    4987             :   // Store on the holder which may be hidden behind the receiver.
    4988             :   DCHECK(it->HolderIsReceiverOrHiddenPrototype());
    4989             : 
    4990     8733506 :   Handle<Object> to_assign = value;
    4991             :   // Convert the incoming value to a number for storing into typed arrays.
    4992     9613567 :   if (it->IsElement() && receiver->HasFixedTypedArrayElements()) {
    4993      745470 :     if (!value->IsNumber() && !value->IsUndefined(it->isolate())) {
    4994        3886 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    4995             :           it->isolate(), to_assign, Object::ToNumber(value), Nothing<bool>());
    4996             :       // We have to recheck the length. However, it can only change if the
    4997             :       // underlying buffer was neutered, so just check that.
    4998        1943 :       if (Handle<JSArrayBufferView>::cast(receiver)->WasNeutered()) {
    4999             :         return Just(true);
    5000             :         // TODO(neis): According to the spec, this should throw a TypeError.
    5001             :       }
    5002             :     }
    5003             :   }
    5004             : 
    5005             :   // Possibly migrate to the most up-to-date map that will be able to store
    5006             :   // |value| under it->name().
    5007     8733506 :   it->PrepareForDataProperty(to_assign);
    5008             : 
    5009             :   // Write the property value.
    5010     8733506 :   it->WriteDataValue(to_assign, false);
    5011             : 
    5012             : #if VERIFY_HEAP
    5013             :   if (FLAG_verify_heap) {
    5014             :     receiver->JSObjectVerify();
    5015             :   }
    5016             : #endif
    5017             :   return Just(true);
    5018             : }
    5019             : 
    5020             : 
    5021   134173622 : Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
    5022             :                                     PropertyAttributes attributes,
    5023             :                                     ShouldThrow should_throw,
    5024             :                                     StoreFromKeyed store_mode) {
    5025    42223091 :   if (!it->GetReceiver()->IsJSObject()) {
    5026        6277 :     if (it->GetReceiver()->IsJSProxy() && it->GetName()->IsPrivate()) {
    5027          45 :       RETURN_FAILURE(it->isolate(), should_throw,
    5028             :                      NewTypeError(MessageTemplate::kProxyPrivate));
    5029             :     }
    5030             :     return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
    5031       12446 :                                 value, should_throw);
    5032             :   }
    5033             : 
    5034             :   DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
    5035             : 
    5036    42216841 :   Handle<JSObject> receiver = it->GetStoreTarget();
    5037             : 
    5038             :   // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
    5039             :   // instead. If the prototype is Null, the proxy is detached.
    5040    42216836 :   if (receiver->IsJSGlobalProxy()) return Just(true);
    5041             : 
    5042             :   Isolate* isolate = it->isolate();
    5043             : 
    5044    42216836 :   if (it->ExtendingNonExtensible(receiver)) {
    5045      404941 :     RETURN_FAILURE(
    5046             :         isolate, should_throw,
    5047             :         NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName()));
    5048             :   }
    5049             : 
    5050    42113418 :   if (it->IsElement()) {
    5051     5808117 :     if (receiver->IsJSArray()) {
    5052             :       Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    5053     1806226 :       if (JSArray::WouldChangeReadOnlyLength(array, it->index())) {
    5054        1144 :         RETURN_FAILURE(array->GetIsolate(), should_throw,
    5055             :                        NewTypeError(MessageTemplate::kStrictReadOnlyProperty,
    5056             :                                     isolate->factory()->length_string(),
    5057             :                                     Object::TypeOf(isolate, array), array));
    5058             :       }
    5059             : 
    5060     1805919 :       if (FLAG_trace_external_array_abuse &&
    5061           0 :           array->HasFixedTypedArrayElements()) {
    5062           0 :         CheckArrayAbuse(array, "typed elements write", it->index(), true);
    5063             :       }
    5064             : 
    5065     1805919 :       if (FLAG_trace_js_array_abuse && !array->HasFixedTypedArrayElements()) {
    5066           0 :         CheckArrayAbuse(array, "elements write", it->index(), false);
    5067             :       }
    5068             :     }
    5069             : 
    5070             :     Maybe<bool> result = JSObject::AddDataElement(receiver, it->index(), value,
    5071     5807810 :                                                   attributes, should_throw);
    5072             :     JSObject::ValidateElements(*receiver);
    5073     5807810 :     return result;
    5074             :   } else {
    5075    36305301 :     it->UpdateProtector();
    5076             :     // Migrate to the most up-to-date map that will be able to store |value|
    5077             :     // under it->name() with |attributes|.
    5078             :     it->PrepareTransitionToDataProperty(receiver, value, attributes,
    5079    36305303 :                                         store_mode);
    5080             :     DCHECK_EQ(LookupIterator::TRANSITION, it->state());
    5081    36305303 :     it->ApplyTransitionToDataProperty(receiver);
    5082             : 
    5083             :     // Write the property value.
    5084    36305305 :     it->WriteDataValue(value, true);
    5085             : 
    5086             : #if VERIFY_HEAP
    5087             :     if (FLAG_verify_heap) {
    5088             :       receiver->JSObjectVerify();
    5089             :     }
    5090             : #endif
    5091             :   }
    5092             : 
    5093             :   return Just(true);
    5094             : }
    5095             : 
    5096             : 
    5097     2416908 : void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
    5098             :   // Only supports adding slack to owned descriptors.
    5099             :   DCHECK(map->owns_descriptors());
    5100             : 
    5101             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    5102             :   int old_size = map->NumberOfOwnDescriptors();
    5103     2416908 :   if (slack <= descriptors->NumberOfSlackDescriptors()) return;
    5104             : 
    5105             :   Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
    5106             :       descriptors, old_size, slack);
    5107             : 
    5108             :   DisallowHeapAllocation no_allocation;
    5109             :   // The descriptors are still the same, so keep the layout descriptor.
    5110             :   LayoutDescriptor* layout_descriptor = map->GetLayoutDescriptor();
    5111             : 
    5112     2416908 :   if (old_size == 0) {
    5113        2385 :     map->UpdateDescriptors(*new_descriptors, layout_descriptor);
    5114        2385 :     return;
    5115             :   }
    5116             : 
    5117             :   // If the source descriptors had an enum cache we copy it. This ensures
    5118             :   // that the maps to which we push the new descriptor array back can rely
    5119             :   // on a cache always being available once it is set. If the map has more
    5120             :   // enumerated descriptors than available in the original cache, the cache
    5121             :   // will be lazily replaced by the extended cache when needed.
    5122     2414523 :   new_descriptors->CopyEnumCacheFrom(*descriptors);
    5123             : 
    5124             :   Isolate* isolate = map->GetIsolate();
    5125             :   // Replace descriptors by new_descriptors in all maps that share it. The old
    5126             :   // descriptors will not be trimmed in the mark-compactor, we need to mark
    5127             :   // all its elements.
    5128     2414523 :   isolate->heap()->incremental_marking()->RecordWrites(*descriptors);
    5129             : 
    5130             :   Map* current = *map;
    5131    24534985 :   while (current->instance_descriptors() == *descriptors) {
    5132    19706423 :     Object* next = current->GetBackPointer();
    5133    19706423 :     if (next->IsUndefined(isolate)) break;  // Stop overwriting at initial map.
    5134    19705939 :     current->UpdateDescriptors(*new_descriptors, layout_descriptor);
    5135             :     current = Map::cast(next);
    5136             :   }
    5137     2414523 :   map->UpdateDescriptors(*new_descriptors, layout_descriptor);
    5138             : }
    5139             : 
    5140             : // static
    5141      122721 : Handle<Map> Map::GetObjectCreateMap(Handle<HeapObject> prototype) {
    5142             :   Isolate* isolate = prototype->GetIsolate();
    5143             :   Handle<Map> map(isolate->native_context()->object_function()->initial_map(),
    5144      245442 :                   isolate);
    5145      122721 :   if (map->prototype() == *prototype) return map;
    5146      122702 :   if (prototype->IsNull(isolate)) {
    5147         368 :     return isolate->slow_object_with_null_prototype_map();
    5148             :   }
    5149      122334 :   if (prototype->IsJSObject()) {
    5150             :     Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype);
    5151      121603 :     if (!js_prototype->map()->is_prototype_map()) {
    5152      119045 :       JSObject::OptimizeAsPrototype(js_prototype);
    5153             :     }
    5154             :     Handle<PrototypeInfo> info =
    5155      121603 :         Map::GetOrCreatePrototypeInfo(js_prototype, isolate);
    5156             :     // TODO(verwaest): Use inobject slack tracking for this map.
    5157      121603 :     if (info->HasObjectCreateMap()) {
    5158             :       map = handle(info->ObjectCreateMap(), isolate);
    5159             :     } else {
    5160      121562 :       map = Map::CopyInitialMap(map);
    5161      121562 :       Map::SetPrototype(map, prototype);
    5162      121562 :       PrototypeInfo::SetObjectCreateMap(info, map);
    5163             :     }
    5164      121603 :     return map;
    5165             :   }
    5166             : 
    5167         731 :   return Map::TransitionToPrototype(map, prototype);
    5168             : }
    5169             : 
    5170             : template <class T>
    5171       46261 : static int AppendUniqueCallbacks(Handle<TemplateList> callbacks,
    5172             :                                  Handle<typename T::Array> array,
    5173             :                                  int valid_descriptors) {
    5174             :   int nof_callbacks = callbacks->length();
    5175             : 
    5176             :   Isolate* isolate = array->GetIsolate();
    5177             :   // Ensure the keys are unique names before writing them into the
    5178             :   // instance descriptor. Since it may cause a GC, it has to be done before we
    5179             :   // temporarily put the heap in an invalid state while appending descriptors.
    5180      139066 :   for (int i = 0; i < nof_callbacks; ++i) {
    5181             :     Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)));
    5182       47053 :     if (entry->name()->IsUniqueName()) continue;
    5183             :     Handle<String> key =
    5184             :         isolate->factory()->InternalizeString(
    5185       46035 :             Handle<String>(String::cast(entry->name())));
    5186       46035 :     entry->set_name(*key);
    5187             :   }
    5188             : 
    5189             :   // Fill in new callback descriptors.  Process the callbacks from
    5190             :   // back to front so that the last callback with a given name takes
    5191             :   // precedence over previously added callbacks with that name.
    5192       92805 :   for (int i = nof_callbacks - 1; i >= 0; i--) {
    5193             :     Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)));
    5194             :     Handle<Name> key(Name::cast(entry->name()));
    5195             :     // Check if a descriptor with this name already exists before writing.
    5196       46544 :     if (!T::Contains(key, entry, valid_descriptors, array)) {
    5197           0 :       T::Insert(key, entry, valid_descriptors, array);
    5198       46532 :       valid_descriptors++;
    5199             :     }
    5200             :   }
    5201             : 
    5202       46261 :   return valid_descriptors;
    5203             : }
    5204             : 
    5205             : struct DescriptorArrayAppender {
    5206             :   typedef DescriptorArray Array;
    5207             :   static bool Contains(Handle<Name> key,
    5208             :                        Handle<AccessorInfo> entry,
    5209             :                        int valid_descriptors,
    5210             :                        Handle<DescriptorArray> array) {
    5211             :     DisallowHeapAllocation no_gc;
    5212             :     return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound;
    5213             :   }
    5214           0 :   static void Insert(Handle<Name> key,
    5215             :                      Handle<AccessorInfo> entry,
    5216             :                      int valid_descriptors,
    5217             :                      Handle<DescriptorArray> array) {
    5218             :     DisallowHeapAllocation no_gc;
    5219             :     Descriptor d =
    5220             :         Descriptor::AccessorConstant(key, entry, entry->property_attributes());
    5221           0 :     array->Append(&d);
    5222           0 :   }
    5223             : };
    5224             : 
    5225             : 
    5226             : struct FixedArrayAppender {
    5227             :   typedef FixedArray Array;
    5228       46544 :   static bool Contains(Handle<Name> key,
    5229             :                        Handle<AccessorInfo> entry,
    5230             :                        int valid_descriptors,
    5231             :                        Handle<FixedArray> array) {
    5232         523 :     for (int i = 0; i < valid_descriptors; i++) {
    5233         535 :       if (*key == AccessorInfo::cast(array->get(i))->name()) return true;
    5234             :     }
    5235             :     return false;
    5236             :   }
    5237             :   static void Insert(Handle<Name> key,
    5238             :                      Handle<AccessorInfo> entry,
    5239             :                      int valid_descriptors,
    5240             :                      Handle<FixedArray> array) {
    5241             :     DisallowHeapAllocation no_gc;
    5242       46532 :     array->set(valid_descriptors, *entry);
    5243             :   }
    5244             : };
    5245             : 
    5246             : 
    5247           0 : void Map::AppendCallbackDescriptors(Handle<Map> map,
    5248             :                                     Handle<Object> descriptors) {
    5249             :   int nof = map->NumberOfOwnDescriptors();
    5250             :   Handle<DescriptorArray> array(map->instance_descriptors());
    5251           0 :   Handle<TemplateList> callbacks = Handle<TemplateList>::cast(descriptors);
    5252             :   DCHECK_GE(array->NumberOfSlackDescriptors(), callbacks->length());
    5253           0 :   nof = AppendUniqueCallbacks<DescriptorArrayAppender>(callbacks, array, nof);
    5254             :   map->SetNumberOfOwnDescriptors(nof);
    5255           0 : }
    5256             : 
    5257             : 
    5258       46261 : int AccessorInfo::AppendUnique(Handle<Object> descriptors,
    5259             :                                Handle<FixedArray> array,
    5260             :                                int valid_descriptors) {
    5261       46261 :   Handle<TemplateList> callbacks = Handle<TemplateList>::cast(descriptors);
    5262             :   DCHECK_GE(array->length(), callbacks->length() + valid_descriptors);
    5263             :   return AppendUniqueCallbacks<FixedArrayAppender>(callbacks, array,
    5264       46261 :                                                    valid_descriptors);
    5265             : }
    5266             : 
    5267             : static bool ContainsMap(MapHandles const& maps, Map* map) {
    5268             :   DCHECK_NOT_NULL(map);
    5269      276348 :   for (Handle<Map> current : maps) {
    5270      212954 :     if (!current.is_null() && *current == map) return true;
    5271             :   }
    5272             :   return false;
    5273             : }
    5274             : 
    5275       60196 : Map* Map::FindElementsKindTransitionedMap(MapHandles const& candidates) {
    5276             :   DisallowHeapAllocation no_allocation;
    5277             :   DisallowDeoptimization no_deoptimization(GetIsolate());
    5278             : 
    5279       60196 :   if (is_prototype_map()) return nullptr;
    5280             : 
    5281             :   ElementsKind kind = elements_kind();
    5282             :   bool packed = IsFastPackedElementsKind(kind);
    5283             : 
    5284             :   Map* transition = nullptr;
    5285       59407 :   if (IsTransitionableFastElementsKind(kind)) {
    5286             :     // Check the state of the root map.
    5287       31825 :     Map* root_map = FindRootMap();
    5288       31825 :     if (!EquivalentToForElementsKindTransition(root_map)) return nullptr;
    5289             :     root_map = root_map->LookupElementsTransitionMap(kind);
    5290             :     DCHECK_NOT_NULL(root_map);
    5291             :     // Starting from the next existing elements kind transition try to
    5292             :     // replay the property transitions that does not involve instance rewriting
    5293             :     // (ElementsTransitionAndStoreStub does not support that).
    5294      256296 :     for (root_map = root_map->ElementsTransitionMap();
    5295      227070 :          root_map != nullptr && root_map->has_fast_elements();
    5296             :          root_map = root_map->ElementsTransitionMap()) {
    5297       96323 :       Map* current = root_map->TryReplayPropertyTransitions(this);
    5298       96323 :       if (current == nullptr) continue;
    5299       92091 :       if (InstancesNeedRewriting(current)) continue;
    5300             : 
    5301      184086 :       if (ContainsMap(candidates, current) &&
    5302        1672 :           (packed || !IsFastPackedElementsKind(current->elements_kind()))) {
    5303             :         transition = current;
    5304       26397 :         packed = packed && IsFastPackedElementsKind(current->elements_kind());
    5305             :       }
    5306             :     }
    5307             :   }
    5308       59407 :   return transition;
    5309             : }
    5310             : 
    5311             : 
    5312      790810 : static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
    5313             :   // Ensure we are requested to search elements kind transition "near the root".
    5314             :   DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(),
    5315             :             map->NumberOfOwnDescriptors());
    5316             :   Map* current_map = map;
    5317             : 
    5318             :   ElementsKind kind = map->elements_kind();
    5319     2762608 :   while (kind != to_kind) {
    5320     1350135 :     Map* next_map = current_map->ElementsTransitionMap();
    5321     1350135 :     if (next_map == nullptr) return current_map;
    5322             :     kind = next_map->elements_kind();
    5323             :     current_map = next_map;
    5324             :   }
    5325             : 
    5326             :   DCHECK_EQ(to_kind, current_map->elements_kind());
    5327             :   return current_map;
    5328             : }
    5329             : 
    5330             : 
    5331           0 : Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) {
    5332       31833 :   Map* to_map = FindClosestElementsTransition(this, to_kind);
    5333       31833 :   if (to_map->elements_kind() == to_kind) return to_map;
    5334             :   return nullptr;
    5335             : }
    5336             : 
    5337      268142 : bool Map::IsMapInArrayPrototypeChain() const {
    5338             :   Isolate* isolate = GetIsolate();
    5339      536284 :   if (isolate->initial_array_prototype()->map() == this) {
    5340             :     return true;
    5341             :   }
    5342             : 
    5343      535078 :   if (isolate->initial_object_prototype()->map() == this) {
    5344             :     return true;
    5345             :   }
    5346             : 
    5347      267355 :   return false;
    5348             : }
    5349             : 
    5350             : 
    5351    10803078 : Handle<WeakCell> Map::WeakCellForMap(Handle<Map> map) {
    5352             :   Isolate* isolate = map->GetIsolate();
    5353    10803078 :   if (map->weak_cell_cache()->IsWeakCell()) {
    5354     3456596 :     return Handle<WeakCell>(WeakCell::cast(map->weak_cell_cache()));
    5355             :   }
    5356     7346482 :   Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(map);
    5357     7346482 :   map->set_weak_cell_cache(*weak_cell);
    5358     7346483 :   return weak_cell;
    5359             : }
    5360             : 
    5361             : 
    5362      169147 : static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
    5363             :                                                  ElementsKind to_kind) {
    5364             :   DCHECK(IsTransitionElementsKind(map->elements_kind()));
    5365             : 
    5366             :   Handle<Map> current_map = map;
    5367             : 
    5368             :   ElementsKind kind = map->elements_kind();
    5369             :   TransitionFlag flag;
    5370      169147 :   if (map->is_prototype_map()) {
    5371             :     flag = OMIT_TRANSITION;
    5372             :   } else {
    5373             :     flag = INSERT_TRANSITION;
    5374      167268 :     if (IsFastElementsKind(kind)) {
    5375      344821 :       while (kind != to_kind && !IsTerminalElementsKind(kind)) {
    5376        6088 :         kind = GetNextTransitionElementsKind(kind);
    5377        6088 :         current_map = Map::CopyAsElementsKind(current_map, kind, flag);
    5378             :       }
    5379             :     }
    5380             :   }
    5381             : 
    5382             :   // In case we are exiting the fast elements kind system, just add the map in
    5383             :   // the end.
    5384      169147 :   if (kind != to_kind) {
    5385      167442 :     current_map = Map::CopyAsElementsKind(current_map, to_kind, flag);
    5386             :   }
    5387             : 
    5388             :   DCHECK(current_map->elements_kind() == to_kind);
    5389      169147 :   return current_map;
    5390             : }
    5391             : 
    5392             : 
    5393     1496774 : Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
    5394             :                                       ElementsKind to_kind) {
    5395             :   ElementsKind from_kind = map->elements_kind();
    5396     1496774 :   if (from_kind == to_kind) return map;
    5397             : 
    5398      803130 :   Isolate* isolate = map->GetIsolate();
    5399             :   Context* native_context = isolate->context()->native_context();
    5400      803130 :   if (from_kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
    5401         761 :     if (*map == native_context->fast_aliased_arguments_map()) {
    5402             :       DCHECK_EQ(SLOW_SLOPPY_ARGUMENTS_ELEMENTS, to_kind);
    5403             :       return handle(native_context->slow_aliased_arguments_map());
    5404             :     }
    5405      802369 :   } else if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
    5406           0 :     if (*map == native_context->slow_aliased_arguments_map()) {
    5407             :       DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, to_kind);
    5408             :       return handle(native_context->fast_aliased_arguments_map());
    5409             :     }
    5410     1603971 :   } else if (IsFastElementsKind(from_kind) && IsFastElementsKind(to_kind)) {
    5411             :     // Reuse map transitions for JSArrays.
    5412             :     DisallowHeapAllocation no_gc;
    5413     1000306 :     if (native_context->GetInitialJSArrayMap(from_kind) == *map) {
    5414             :       Object* maybe_transitioned_map =
    5415             :           native_context->get(Context::ArrayMapIndex(to_kind));
    5416      374317 :       if (maybe_transitioned_map->IsMap()) {
    5417             :         return handle(Map::cast(maybe_transitioned_map), isolate);
    5418             :       }
    5419             :     }
    5420             :   }
    5421             : 
    5422             :   DCHECK(!map->IsUndefined(isolate));
    5423             :   // Check if we can go back in the elements kind transition chain.
    5424      835541 :   if (IsHoleyOrDictionaryElementsKind(from_kind) &&
    5425           0 :       to_kind == GetPackedElementsKind(from_kind) &&
    5426      428122 :       map->GetBackPointer()->IsMap() &&
    5427           0 :       Map::cast(map->GetBackPointer())->elements_kind() == to_kind) {
    5428           0 :     return handle(Map::cast(map->GetBackPointer()));
    5429             :   }
    5430             : 
    5431             :   bool allow_store_transition = IsTransitionElementsKind(from_kind);
    5432             :   // Only store fast element maps in ascending generality.
    5433      428122 :   if (IsFastElementsKind(to_kind)) {
    5434             :     allow_store_transition =
    5435      378133 :         allow_store_transition && IsTransitionableFastElementsKind(from_kind) &&
    5436      125836 :         IsMoreGeneralElementsKindTransition(from_kind, to_kind);
    5437             :   }
    5438             : 
    5439      428122 :   if (!allow_store_transition) {
    5440         635 :     return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION);
    5441             :   }
    5442             : 
    5443      427487 :   return Map::ReconfigureElementsKind(map, to_kind);
    5444             : }
    5445             : 
    5446             : 
    5447             : // static
    5448      758977 : Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) {
    5449      758977 :   Handle<Map> closest_map(FindClosestElementsTransition(*map, kind));
    5450             : 
    5451      758977 :   if (closest_map->elements_kind() == kind) {
    5452      589830 :     return closest_map;
    5453             :   }
    5454             : 
    5455      169147 :   return AddMissingElementsTransitions(closest_map, kind);
    5456             : }
    5457             : 
    5458             : 
    5459     1474485 : Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
    5460             :                                                ElementsKind to_kind) {
    5461             :   Handle<Map> map(object->map());
    5462     1474485 :   return Map::TransitionElementsTo(map, to_kind);
    5463             : }
    5464             : 
    5465             : 
    5466         140 : void JSProxy::Revoke(Handle<JSProxy> proxy) {
    5467             :   Isolate* isolate = proxy->GetIsolate();
    5468         271 :   if (!proxy->IsRevoked()) proxy->set_handler(isolate->heap()->null_value());
    5469             :   DCHECK(proxy->IsRevoked());
    5470         140 : }
    5471             : 
    5472             : // static
    5473        1079 : Maybe<bool> JSProxy::IsArray(Handle<JSProxy> proxy) {
    5474             :   Isolate* isolate = proxy->GetIsolate();
    5475             :   Handle<JSReceiver> object = Handle<JSReceiver>::cast(proxy);
    5476     1025099 :   for (int i = 0; i < JSProxy::kMaxIterationLimit; i++) {
    5477             :     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
    5478     1025089 :     if (proxy->IsRevoked()) {
    5479             :       isolate->Throw(*isolate->factory()->NewTypeError(
    5480             :           MessageTemplate::kProxyRevoked,
    5481         162 :           isolate->factory()->NewStringFromAsciiChecked("IsArray")));
    5482             :       return Nothing<bool>();
    5483             :     }
    5484             :     object = handle(proxy->target(), isolate);
    5485     1025035 :     if (object->IsJSArray()) return Just(true);
    5486     1024715 :     if (!object->IsJSProxy()) return Just(false);
    5487             :   }
    5488             : 
    5489             :   // Too deep recursion, throw a RangeError.
    5490          10 :   isolate->StackOverflow();
    5491             :   return Nothing<bool>();
    5492             : }
    5493             : 
    5494       42595 : Maybe<bool> JSProxy::HasProperty(Isolate* isolate, Handle<JSProxy> proxy,
    5495             :                                  Handle<Name> name) {
    5496             :   DCHECK(!name->IsPrivate());
    5497       42595 :   STACK_CHECK(isolate, Nothing<bool>());
    5498             :   // 1. (Assert)
    5499             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    5500             :   Handle<Object> handler(proxy->handler(), isolate);
    5501             :   // 3. If handler is null, throw a TypeError exception.
    5502             :   // 4. Assert: Type(handler) is Object.
    5503       42586 :   if (proxy->IsRevoked()) {
    5504             :     isolate->Throw(*isolate->factory()->NewTypeError(
    5505           0 :         MessageTemplate::kProxyRevoked, isolate->factory()->has_string()));
    5506             :     return Nothing<bool>();
    5507             :   }
    5508             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    5509             :   Handle<JSReceiver> target(proxy->target(), isolate);
    5510             :   // 6. Let trap be ? GetMethod(handler, "has").
    5511             :   Handle<Object> trap;
    5512       85172 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5513             :       isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler),
    5514             :                                        isolate->factory()->has_string()),
    5515             :       Nothing<bool>());
    5516             :   // 7. If trap is undefined, then
    5517       42586 :   if (trap->IsUndefined(isolate)) {
    5518             :     // 7a. Return target.[[HasProperty]](P).
    5519       34212 :     return JSReceiver::HasProperty(target, name);
    5520             :   }
    5521             :   // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, P»)).
    5522             :   Handle<Object> trap_result_obj;
    5523             :   Handle<Object> args[] = {target, name};
    5524       16748 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5525             :       isolate, trap_result_obj,
    5526             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    5527             :       Nothing<bool>());
    5528        8328 :   bool boolean_trap_result = trap_result_obj->BooleanValue();
    5529             :   // 9. If booleanTrapResult is false, then:
    5530        8328 :   if (!boolean_trap_result) {
    5531        5447 :     MAYBE_RETURN(JSProxy::CheckHasTrap(isolate, name, target), Nothing<bool>());
    5532             :   }
    5533             :   // 10. Return booleanTrapResult.
    5534             :   return Just(boolean_trap_result);
    5535             : }
    5536             : 
    5537        5457 : Maybe<bool> JSProxy::CheckHasTrap(Isolate* isolate, Handle<Name> name,
    5538             :                                   Handle<JSReceiver> target) {
    5539             :   // 9a. Let targetDesc be ? target.[[GetOwnProperty]](P).
    5540             :   PropertyDescriptor target_desc;
    5541             :   Maybe<bool> target_found =
    5542        5457 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    5543        5457 :   MAYBE_RETURN(target_found, Nothing<bool>());
    5544             :   // 9b. If targetDesc is not undefined, then:
    5545        5457 :   if (target_found.FromJust()) {
    5546             :     // 9b i. If targetDesc.[[Configurable]] is false, throw a TypeError
    5547             :     //       exception.
    5548          30 :     if (!target_desc.configurable()) {
    5549             :       isolate->Throw(*isolate->factory()->NewTypeError(
    5550          20 :           MessageTemplate::kProxyHasNonConfigurable, name));
    5551          10 :       return Nothing<bool>();
    5552             :     }
    5553             :     // 9b ii. Let extensibleTarget be ? IsExtensible(target).
    5554          20 :     Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    5555          20 :     MAYBE_RETURN(extensible_target, Nothing<bool>());
    5556             :     // 9b iii. If extensibleTarget is false, throw a TypeError exception.
    5557          20 :     if (!extensible_target.FromJust()) {
    5558             :       isolate->Throw(*isolate->factory()->NewTypeError(
    5559           0 :           MessageTemplate::kProxyHasNonExtensible, name));
    5560             :       return Nothing<bool>();
    5561             :     }
    5562             :   }
    5563             :   return Just(true);
    5564             : }
    5565             : 
    5566       41571 : Maybe<bool> JSProxy::SetProperty(Handle<JSProxy> proxy, Handle<Name> name,
    5567             :                                  Handle<Object> value, Handle<Object> receiver,
    5568             :                                  LanguageMode language_mode) {
    5569             :   DCHECK(!name->IsPrivate());
    5570             :   Isolate* isolate = proxy->GetIsolate();
    5571       41571 :   STACK_CHECK(isolate, Nothing<bool>());
    5572             :   Factory* factory = isolate->factory();
    5573             :   Handle<String> trap_name = factory->set_string();
    5574             :   ShouldThrow should_throw =
    5575       41553 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    5576             : 
    5577       41553 :   if (proxy->IsRevoked()) {
    5578             :     isolate->Throw(
    5579          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    5580             :     return Nothing<bool>();
    5581             :   }
    5582             :   Handle<JSReceiver> target(proxy->target(), isolate);
    5583             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    5584             : 
    5585             :   Handle<Object> trap;
    5586       83070 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5587             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    5588       41283 :   if (trap->IsUndefined(isolate)) {
    5589             :     LookupIterator it =
    5590       38266 :         LookupIterator::PropertyOrElement(isolate, receiver, name, target);
    5591             :     return Object::SetSuperProperty(&it, value, language_mode,
    5592       38266 :                                     Object::MAY_BE_STORE_FROM_KEYED);
    5593             :   }
    5594             : 
    5595             :   Handle<Object> trap_result;
    5596        3017 :   Handle<Object> args[] = {target, name, value, receiver};
    5597        6034 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5598             :       isolate, trap_result,
    5599             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    5600             :       Nothing<bool>());
    5601        2774 :   if (!trap_result->BooleanValue()) {
    5602         587 :     RETURN_FAILURE(isolate, should_throw,
    5603             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    5604             :                                 trap_name, name));
    5605             :   }
    5606             : 
    5607             :   MaybeHandle<Object> result =
    5608        2277 :       JSProxy::CheckGetSetTrapResult(isolate, name, target, value, kSet);
    5609             : 
    5610        2277 :   if (result.is_null()) {
    5611             :     return Nothing<bool>();
    5612             :   }
    5613             :   return Just(true);
    5614             : }
    5615             : 
    5616             : 
    5617        3097 : Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy,
    5618             :                                              Handle<Name> name,
    5619             :                                              LanguageMode language_mode) {
    5620             :   DCHECK(!name->IsPrivate());
    5621             :   ShouldThrow should_throw =
    5622        3097 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    5623             :   Isolate* isolate = proxy->GetIsolate();
    5624        3097 :   STACK_CHECK(isolate, Nothing<bool>());
    5625             :   Factory* factory = isolate->factory();
    5626             :   Handle<String> trap_name = factory->deleteProperty_string();
    5627             : 
    5628        3097 :   if (proxy->IsRevoked()) {
    5629             :     isolate->Throw(
    5630          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    5631             :     return Nothing<bool>();
    5632             :   }
    5633             :   Handle<JSReceiver> target(proxy->target(), isolate);
    5634             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    5635             : 
    5636             :   Handle<Object> trap;
    5637        6158 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5638             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    5639        2944 :   if (trap->IsUndefined(isolate)) {
    5640         811 :     return JSReceiver::DeletePropertyOrElement(target, name, language_mode);
    5641             :   }
    5642             : 
    5643             :   Handle<Object> trap_result;
    5644             :   Handle<Object> args[] = {target, name};
    5645        4266 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5646             :       isolate, trap_result,
    5647             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    5648             :       Nothing<bool>());
    5649        1809 :   if (!trap_result->BooleanValue()) {
    5650        1242 :     RETURN_FAILURE(isolate, should_throw,
    5651             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    5652             :                                 trap_name, name));
    5653             :   }
    5654             : 
    5655             :   // Enforce the invariant.
    5656             :   PropertyDescriptor target_desc;
    5657             :   Maybe<bool> owned =
    5658        1053 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    5659        1053 :   MAYBE_RETURN(owned, Nothing<bool>());
    5660        1593 :   if (owned.FromJust() && !target_desc.configurable()) {
    5661             :     isolate->Throw(*factory->NewTypeError(
    5662         720 :         MessageTemplate::kProxyDeletePropertyNonConfigurable, name));
    5663             :     return Nothing<bool>();
    5664             :   }
    5665             :   return Just(true);
    5666             : }
    5667             : 
    5668             : 
    5669             : // static
    5670          17 : MaybeHandle<JSProxy> JSProxy::New(Isolate* isolate, Handle<Object> target,
    5671             :                                   Handle<Object> handler) {
    5672          17 :   if (!target->IsJSReceiver()) {
    5673           0 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject),
    5674             :                     JSProxy);
    5675             :   }
    5676          17 :   if (target->IsJSProxy() && JSProxy::cast(*target)->IsRevoked()) {
    5677           0 :     THROW_NEW_ERROR(isolate,
    5678             :                     NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
    5679             :                     JSProxy);
    5680             :   }
    5681          17 :   if (!handler->IsJSReceiver()) {
    5682           0 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject),
    5683             :                     JSProxy);
    5684             :   }
    5685          17 :   if (handler->IsJSProxy() && JSProxy::cast(*handler)->IsRevoked()) {
    5686           0 :     THROW_NEW_ERROR(isolate,
    5687             :                     NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
    5688             :                     JSProxy);
    5689             :   }
    5690             :   return isolate->factory()->NewJSProxy(Handle<JSReceiver>::cast(target),
    5691          17 :                                         Handle<JSReceiver>::cast(handler));
    5692             : }
    5693             : 
    5694             : 
    5695             : // static
    5696          19 : MaybeHandle<Context> JSProxy::GetFunctionRealm(Handle<JSProxy> proxy) {
    5697             :   DCHECK(proxy->map()->is_constructor());
    5698          19 :   if (proxy->IsRevoked()) {
    5699           0 :     THROW_NEW_ERROR(proxy->GetIsolate(),
    5700             :                     NewTypeError(MessageTemplate::kProxyRevoked), Context);
    5701             :   }
    5702             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()));
    5703          19 :   return JSReceiver::GetFunctionRealm(target);
    5704             : }
    5705             : 
    5706             : 
    5707             : // static
    5708           0 : MaybeHandle<Context> JSBoundFunction::GetFunctionRealm(
    5709             :     Handle<JSBoundFunction> function) {
    5710             :   DCHECK(function->map()->is_constructor());
    5711             :   return JSReceiver::GetFunctionRealm(
    5712           0 :       handle(function->bound_target_function()));
    5713             : }
    5714             : 
    5715             : // static
    5716          82 : MaybeHandle<String> JSBoundFunction::GetName(Isolate* isolate,
    5717             :                                              Handle<JSBoundFunction> function) {
    5718             :   Handle<String> prefix = isolate->factory()->bound__string();
    5719             :   Handle<String> target_name = prefix;
    5720             :   Factory* factory = isolate->factory();
    5721             :   // Concatenate the "bound " up to the last non-bound target.
    5722         164 :   while (function->bound_target_function()->IsJSBoundFunction()) {
    5723           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, target_name,
    5724             :                                factory->NewConsString(prefix, target_name),
    5725             :                                String);
    5726             :     function = handle(JSBoundFunction::cast(function->bound_target_function()),
    5727             :                       isolate);
    5728             :   }
    5729          82 :   if (function->bound_target_function()->IsJSFunction()) {
    5730             :     Handle<JSFunction> target(
    5731             :         JSFunction::cast(function->bound_target_function()), isolate);
    5732          82 :     Handle<Object> name = JSFunction::GetName(isolate, target);
    5733          82 :     if (!name->IsString()) return target_name;
    5734          82 :     return factory->NewConsString(target_name, Handle<String>::cast(name));
    5735             :   }
    5736             :   // This will omit the proper target name for bound JSProxies.
    5737           0 :   return target_name;
    5738             : }
    5739             : 
    5740             : // static
    5741         342 : Maybe<int> JSBoundFunction::GetLength(Isolate* isolate,
    5742             :                                       Handle<JSBoundFunction> function) {
    5743             :   int nof_bound_arguments = function->bound_arguments()->length();
    5744        1104 :   while (function->bound_target_function()->IsJSBoundFunction()) {
    5745             :     function = handle(JSBoundFunction::cast(function->bound_target_function()),
    5746             :                       isolate);
    5747             :     // Make sure we never overflow {nof_bound_arguments}, the number of
    5748             :     // arguments of a function is strictly limited by the max length of an
    5749             :     // JSAarray, Smi::kMaxValue is thus a reasonably good overestimate.
    5750             :     int length = function->bound_arguments()->length();
    5751         420 :     if (V8_LIKELY(Smi::kMaxValue - nof_bound_arguments > length)) {
    5752         420 :       nof_bound_arguments += length;
    5753             :     } else {
    5754             :       nof_bound_arguments = Smi::kMaxValue;
    5755             :     }
    5756             :   }
    5757             :   // All non JSFunction targets get a direct property and don't use this
    5758             :   // accessor.
    5759             :   Handle<JSFunction> target(JSFunction::cast(function->bound_target_function()),
    5760             :                             isolate);
    5761         342 :   Maybe<int> target_length = JSFunction::GetLength(isolate, target);
    5762         342 :   if (target_length.IsNothing()) return target_length;
    5763             : 
    5764         342 :   int length = Max(0, target_length.FromJust() - nof_bound_arguments);
    5765             :   return Just(length);
    5766             : }
    5767             : 
    5768             : // static
    5769       88005 : Handle<Object> JSFunction::GetName(Isolate* isolate,
    5770             :                                    Handle<JSFunction> function) {
    5771       88005 :   if (function->shared()->name_should_print_as_anonymous()) {
    5772           0 :     return isolate->factory()->anonymous_string();
    5773             :   }
    5774       88005 :   return handle(function->shared()->name(), isolate);
    5775             : }
    5776             : 
    5777             : // static
    5778       17576 : Maybe<int> JSFunction::GetLength(Isolate* isolate,
    5779             :                                  Handle<JSFunction> function) {
    5780             :   int length = 0;
    5781       17576 :   if (function->shared()->is_compiled()) {
    5782             :     length = function->shared()->GetLength();
    5783             :   } else {
    5784             :     // If the function isn't compiled yet, the length is not computed
    5785             :     // correctly yet. Compile it now and return the right length.
    5786        1890 :     if (Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) {
    5787             :       length = function->shared()->GetLength();
    5788             :     }
    5789        1890 :     if (isolate->has_pending_exception()) return Nothing<int>();
    5790             :   }
    5791             :   DCHECK_GE(length, 0);
    5792             :   return Just(length);
    5793             : }
    5794             : 
    5795             : // static
    5796        2809 : Handle<Context> JSFunction::GetFunctionRealm(Handle<JSFunction> function) {
    5797             :   DCHECK(function->map()->is_constructor());
    5798        2809 :   return handle(function->context()->native_context());
    5799             : }
    5800             : 
    5801             : 
    5802             : // static
    5803           0 : MaybeHandle<Context> JSObject::GetFunctionRealm(Handle<JSObject> object) {
    5804             :   DCHECK(object->map()->is_constructor());
    5805             :   DCHECK(!object->IsJSFunction());
    5806           0 :   return object->GetCreationContext();
    5807             : }
    5808             : 
    5809             : 
    5810             : // static
    5811        2828 : MaybeHandle<Context> JSReceiver::GetFunctionRealm(Handle<JSReceiver> receiver) {
    5812        2828 :   if (receiver->IsJSProxy()) {
    5813          19 :     return JSProxy::GetFunctionRealm(Handle<JSProxy>::cast(receiver));
    5814             :   }
    5815             : 
    5816        2809 :   if (receiver->IsJSFunction()) {
    5817        2809 :     return JSFunction::GetFunctionRealm(Handle<JSFunction>::cast(receiver));
    5818             :   }
    5819             : 
    5820           0 :   if (receiver->IsJSBoundFunction()) {
    5821             :     return JSBoundFunction::GetFunctionRealm(
    5822           0 :         Handle<JSBoundFunction>::cast(receiver));
    5823             :   }
    5824             : 
    5825             :   return JSObject::GetFunctionRealm(Handle<JSObject>::cast(receiver));
    5826             : }
    5827             : 
    5828             : 
    5829        3180 : Maybe<PropertyAttributes> JSProxy::GetPropertyAttributes(LookupIterator* it) {
    5830             :   PropertyDescriptor desc;
    5831             :   Maybe<bool> found = JSProxy::GetOwnPropertyDescriptor(
    5832        3180 :       it->isolate(), it->GetHolder<JSProxy>(), it->GetName(), &desc);
    5833        1590 :   MAYBE_RETURN(found, Nothing<PropertyAttributes>());
    5834        1290 :   if (!found.FromJust()) return Just(ABSENT);
    5835        1136 :   return Just(desc.ToAttributes());
    5836             : }
    5837             : 
    5838             : 
    5839     6882840 : void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
    5840             :   DCHECK(object->map()->GetInObjectProperties() ==
    5841             :          map->GetInObjectProperties());
    5842             :   ElementsKind obj_kind = object->map()->elements_kind();
    5843             :   ElementsKind map_kind = map->elements_kind();
    5844     6882840 :   if (map_kind != obj_kind) {
    5845             :     ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind);
    5846          40 :     if (IsDictionaryElementsKind(obj_kind)) {
    5847             :       to_kind = obj_kind;
    5848             :     }
    5849          40 :     if (IsDictionaryElementsKind(to_kind)) {
    5850          30 :       NormalizeElements(object);
    5851             :     } else {
    5852          10 :       TransitionElementsKind(object, to_kind);
    5853             :     }
    5854          40 :     map = Map::ReconfigureElementsKind(map, to_kind);
    5855             :   }
    5856     6882840 :   int number_of_fields = map->NumberOfFields();
    5857             :   int inobject = map->GetInObjectProperties();
    5858             :   int unused = map->UnusedPropertyFields();
    5859     6882840 :   int total_size = number_of_fields + unused;
    5860     6882840 :   int external = total_size - inobject;
    5861             :   // Allocate mutable double boxes if necessary. It is always necessary if we
    5862             :   // have external properties, but is also necessary if we only have inobject
    5863             :   // properties but don't unbox double fields.
    5864     6882840 :   if (!FLAG_unbox_double_fields || external > 0) {
    5865             :     Isolate* isolate = object->GetIsolate();
    5866             : 
    5867             :     Handle<DescriptorArray> descriptors(map->instance_descriptors());
    5868             :     Handle<FixedArray> storage;
    5869             :     if (!FLAG_unbox_double_fields) {
    5870             :       storage = isolate->factory()->NewFixedArray(inobject);
    5871             :     }
    5872             : 
    5873             :     Handle<PropertyArray> array;
    5874     2663276 :     if (external > 0) {
    5875     2663276 :       array = isolate->factory()->NewPropertyArray(external);
    5876             :     }
    5877             : 
    5878    37598386 :     for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
    5879    16135917 :       PropertyDetails details = descriptors->GetDetails(i);
    5880             :       Representation representation = details.representation();
    5881    32271714 :       if (!representation.IsDouble()) continue;
    5882        6055 :       FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    5883        6055 :       if (map->IsUnboxedDoubleField(index)) continue;
    5884             :       Handle<HeapNumber> box = isolate->factory()->NewMutableHeapNumber();
    5885         120 :       if (index.is_inobject()) {
    5886           0 :         storage->set(index.property_index(), *box);
    5887             :       } else {
    5888         120 :         array->set(index.outobject_array_index(), *box);
    5889             :       }
    5890             :     }
    5891             : 
    5892     2663276 :     if (external > 0) {
    5893     2663276 :       object->SetProperties(*array);
    5894             :     }
    5895             : 
    5896             :     if (!FLAG_unbox_double_fields) {
    5897             :       for (int i = 0; i < inobject; i++) {
    5898             :         FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
    5899             :         Object* value = storage->get(i);
    5900             :         object->RawFastPropertyAtPut(index, value);
    5901             :       }
    5902             :     }
    5903             :   }
    5904     6882840 :   object->synchronized_set_map(*map);
    5905     6882840 : }
    5906             : 
    5907             : 
    5908        3707 : void JSObject::MigrateInstance(Handle<JSObject> object) {
    5909             :   Handle<Map> original_map(object->map());
    5910        3707 :   Handle<Map> map = Map::Update(original_map);
    5911             :   map->set_migration_target(true);
    5912        3707 :   MigrateToMap(object, map);
    5913        3707 :   if (FLAG_trace_migration) {
    5914           0 :     object->PrintInstanceMigration(stdout, *original_map, *map);
    5915             :   }
    5916             : #if VERIFY_HEAP
    5917             :   if (FLAG_verify_heap) {
    5918             :     object->JSObjectVerify();
    5919             :   }
    5920             : #endif
    5921        3707 : }
    5922             : 
    5923             : 
    5924             : // static
    5925        5402 : bool JSObject::TryMigrateInstance(Handle<JSObject> object) {
    5926             :   Isolate* isolate = object->GetIsolate();
    5927             :   DisallowDeoptimization no_deoptimization(isolate);
    5928             :   Handle<Map> original_map(object->map(), isolate);
    5929             :   Handle<Map> new_map;
    5930       10804 :   if (!Map::TryUpdate(original_map).ToHandle(&new_map)) {
    5931             :     return false;
    5932             :   }
    5933        5384 :   JSObject::MigrateToMap(object, new_map);
    5934        5384 :   if (FLAG_trace_migration && *original_map != object->map()) {
    5935           0 :     object->PrintInstanceMigration(stdout, *original_map, object->map());
    5936             :   }
    5937             : #if VERIFY_HEAP
    5938             :   if (FLAG_verify_heap) {
    5939             :     object->JSObjectVerify();
    5940             :   }
    5941             : #endif
    5942             :   return true;
    5943             : }
    5944             : 
    5945             : 
    5946    12229355 : void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name,
    5947             :                            Handle<Object> value,
    5948             :                            PropertyAttributes attributes) {
    5949    12229355 :   LookupIterator it(object, name, object, LookupIterator::OWN_SKIP_INTERCEPTOR);
    5950    12229358 :   CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
    5951             : #ifdef DEBUG
    5952             :   uint32_t index;
    5953             :   DCHECK(!object->IsJSProxy());
    5954             :   DCHECK(!name->AsArrayIndex(&index));
    5955             :   Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
    5956             :   DCHECK(maybe.IsJust());
    5957             :   DCHECK(!it.IsFound());
    5958             :   DCHECK(object->map()->is_extensible() || name->IsPrivate());
    5959             : #endif
    5960    12229358 :   CHECK(AddDataProperty(&it, value, attributes, THROW_ON_ERROR,
    5961             :                         CERTAINLY_NOT_STORE_FROM_KEYED)
    5962             :             .IsJust());
    5963    12229358 : }
    5964             : 
    5965             : 
    5966             : // Reconfigures a property to a data property with attributes, even if it is not
    5967             : // reconfigurable.
    5968             : // Requires a LookupIterator that does not look at the prototype chain beyond
    5969             : // hidden prototypes.
    5970    15411732 : MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
    5971             :     LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
    5972             :     AccessorInfoHandling handling) {
    5973    15411732 :   MAYBE_RETURN_NULL(DefineOwnPropertyIgnoreAttributes(
    5974             :       it, value, attributes, THROW_ON_ERROR, handling));
    5975    15411707 :   return value;
    5976             : }
    5977             : 
    5978             : 
    5979    16102207 : Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
    5980    16126380 :     LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
    5981             :     ShouldThrow should_throw, AccessorInfoHandling handling) {
    5982    16102207 :   it->UpdateProtector();
    5983             :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    5984             : 
    5985    32205950 :   for (; it->IsFound(); it->Next()) {
    5986      459899 :     switch (it->state()) {
    5987             :       case LookupIterator::JSPROXY:
    5988             :       case LookupIterator::NOT_FOUND:
    5989             :       case LookupIterator::TRANSITION:
    5990           0 :         UNREACHABLE();
    5991             : 
    5992             :       case LookupIterator::ACCESS_CHECK:
    5993         559 :         if (!it->HasAccess()) {
    5994           5 :           it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    5995           5 :           RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    5996             :           return Just(true);
    5997             :         }
    5998             :         break;
    5999             : 
    6000             :       // If there's an interceptor, try to store the property with the
    6001             :       // interceptor.
    6002             :       // In case of success, the attributes will have been reset to the default
    6003             :       // attributes of the interceptor, rather than the incoming attributes.
    6004             :       //
    6005             :       // TODO(verwaest): JSProxy afterwards verify the attributes that the
    6006             :       // JSProxy claims it has, and verifies that they are compatible. If not,
    6007             :       // they throw. Here we should do the same.
    6008             :       case LookupIterator::INTERCEPTOR:
    6009         220 :         if (handling == DONT_FORCE_FIELD) {
    6010             :           Maybe<bool> result =
    6011         220 :               JSObject::SetPropertyWithInterceptor(it, should_throw, value);
    6012         440 :           if (result.IsNothing() || result.FromJust()) return result;
    6013             :         }
    6014             :         break;
    6015             : 
    6016             :       case LookupIterator::ACCESSOR: {
    6017       99755 :         Handle<Object> accessors = it->GetAccessors();
    6018             : 
    6019             :         // Special handling for AccessorInfo, which behaves like a data
    6020             :         // property.
    6021       99755 :         if (accessors->IsAccessorInfo() && handling == DONT_FORCE_FIELD) {
    6022             :           PropertyAttributes current_attributes = it->property_attributes();
    6023             :           // Ensure the context isn't changed after calling into accessors.
    6024             :           AssertNoContextChange ncc(it->isolate());
    6025             : 
    6026             :           // Update the attributes before calling the setter. The setter may
    6027             :           // later change the shape of the property.
    6028       99245 :           if (current_attributes != attributes) {
    6029       95560 :             it->TransitionToAccessorPair(accessors, attributes);
    6030             :           }
    6031             : 
    6032       99245 :           return JSObject::SetPropertyWithAccessor(it, value, should_throw);
    6033             :         }
    6034             : 
    6035         510 :         it->ReconfigureDataProperty(value, attributes);
    6036             :         return Just(true);
    6037             :       }
    6038             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    6039             :         return RedefineIncompatibleProperty(it->isolate(), it->GetName(), value,
    6040          20 :                                             should_throw);
    6041             : 
    6042             :       case LookupIterator::DATA: {
    6043             :         // Regular property update if the attributes match.
    6044      359355 :         if (it->property_attributes() == attributes) {
    6045      335970 :           return SetDataProperty(it, value);
    6046             :         }
    6047             : 
    6048             :         // Special case: properties of typed arrays cannot be reconfigured to
    6049             :         // non-writable nor to non-enumerable.
    6050       44809 :         if (it->IsElement() && object->HasFixedTypedArrayElements()) {
    6051             :           return RedefineIncompatibleProperty(it->isolate(), it->GetName(),
    6052           0 :                                               value, should_throw);
    6053             :         }
    6054             : 
    6055             :         // Reconfigure the data property if the attributes mismatch.
    6056       23385 :         it->ReconfigureDataProperty(value, attributes);
    6057             : 
    6058             :         return Just(true);
    6059             :       }
    6060             :     }
    6061             :   }
    6062             : 
    6063             :   return AddDataProperty(it, value, attributes, should_throw,
    6064    15643076 :                          CERTAINLY_NOT_STORE_FROM_KEYED);
    6065             : }
    6066             : 
    6067     8835683 : MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
    6068             :     Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
    6069             :     PropertyAttributes attributes) {
    6070             :   DCHECK(!value->IsTheHole(object->GetIsolate()));
    6071     8835683 :   LookupIterator it(object, name, object, LookupIterator::OWN);
    6072     8835683 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    6073             : }
    6074             : 
    6075     2751039 : MaybeHandle<Object> JSObject::SetOwnElementIgnoreAttributes(
    6076             :     Handle<JSObject> object, uint32_t index, Handle<Object> value,
    6077             :     PropertyAttributes attributes) {
    6078             :   Isolate* isolate = object->GetIsolate();
    6079             :   LookupIterator it(isolate, object, index, object, LookupIterator::OWN);
    6080     2751039 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    6081             : }
    6082             : 
    6083      400829 : MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes(
    6084             :     Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
    6085             :     PropertyAttributes attributes) {
    6086             :   Isolate* isolate = object->GetIsolate();
    6087             :   LookupIterator it = LookupIterator::PropertyOrElement(
    6088      400829 :       isolate, object, name, object, LookupIterator::OWN);
    6089      400829 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    6090             : }
    6091             : 
    6092      250419 : Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
    6093             :     LookupIterator* it) {
    6094      250419 :   return GetPropertyAttributesWithInterceptorInternal(it, it->GetInterceptor());
    6095             : }
    6096             : 
    6097     9859313 : Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
    6098    12032816 :     LookupIterator* it) {
    6099    24065632 :   for (; it->IsFound(); it->Next()) {
    6100     6666402 :     switch (it->state()) {
    6101             :       case LookupIterator::NOT_FOUND:
    6102             :       case LookupIterator::TRANSITION:
    6103           0 :         UNREACHABLE();
    6104             :       case LookupIterator::JSPROXY:
    6105         839 :         return JSProxy::GetPropertyAttributes(it);
    6106             :       case LookupIterator::INTERCEPTOR: {
    6107             :         Maybe<PropertyAttributes> result =
    6108         716 :             JSObject::GetPropertyAttributesWithInterceptor(it);
    6109        1075 :         if (!result.IsJust()) return result;
    6110         716 :         if (result.FromJust() != ABSENT) return result;
    6111         357 :         break;
    6112             :       }
    6113             :       case LookupIterator::ACCESS_CHECK:
    6114     2173227 :         if (it->HasAccess()) break;
    6115          81 :         return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
    6116             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    6117             :         return Just(ABSENT);
    6118             :       case LookupIterator::ACCESSOR:
    6119             :       case LookupIterator::DATA:
    6120             :         return Just(it->property_attributes());
    6121             :     }
    6122             :   }
    6123             :   return Just(ABSENT);
    6124             : }
    6125             : 
    6126             : 
    6127          61 : Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) {
    6128             :   Handle<FixedArray> array(
    6129          61 :       isolate->factory()->NewFixedArray(kEntries, TENURED));
    6130          61 :   return Handle<NormalizedMapCache>::cast(array);
    6131             : }
    6132             : 
    6133             : 
    6134      755249 : MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
    6135             :                                          PropertyNormalizationMode mode) {
    6136             :   DisallowHeapAllocation no_gc;
    6137             :   Object* value = FixedArray::get(GetIndex(fast_map));
    6138     1408287 :   if (!value->IsWeakCell() || WeakCell::cast(value)->cleared()) {
    6139      112260 :     return MaybeHandle<Map>();
    6140             :   }
    6141             : 
    6142             :   Map* normalized_map = Map::cast(WeakCell::cast(value)->value());
    6143      642989 :   if (!normalized_map->EquivalentToForNormalization(*fast_map, mode)) {
    6144       89992 :     return MaybeHandle<Map>();
    6145             :   }
    6146      552997 :   return handle(normalized_map);
    6147             : }
    6148             : 
    6149      202252 : void NormalizedMapCache::Set(Handle<Map> fast_map, Handle<Map> normalized_map,
    6150             :                              Handle<WeakCell> normalized_map_weak_cell) {
    6151             :   DisallowHeapAllocation no_gc;
    6152             :   DCHECK(normalized_map->is_dictionary_map());
    6153             :   DCHECK_EQ(normalized_map_weak_cell->value(), *normalized_map);
    6154      202252 :   FixedArray::set(GetIndex(fast_map), *normalized_map_weak_cell);
    6155      202252 : }
    6156             : 
    6157             : 
    6158           0 : void NormalizedMapCache::Clear() {
    6159             :   int entries = length();
    6160           0 :   for (int i = 0; i != entries; i++) {
    6161           0 :     set_undefined(i);
    6162             :   }
    6163           0 : }
    6164             : 
    6165             : 
    6166      992358 : void JSObject::NormalizeProperties(Handle<JSObject> object,
    6167             :                                    PropertyNormalizationMode mode,
    6168             :                                    int expected_additional_properties,
    6169             :                                    const char* reason) {
    6170     1333807 :   if (!object->HasFastProperties()) return;
    6171             : 
    6172             :   Handle<Map> map(object->map());
    6173      650909 :   Handle<Map> new_map = Map::Normalize(map, mode, reason);
    6174             : 
    6175      650909 :   MigrateToMap(object, new_map, expected_additional_properties);
    6176             : }
    6177             : 
    6178             : 
    6179      861475 : void JSObject::MigrateSlowToFast(Handle<JSObject> object,
    6180             :                                  int unused_property_fields,
    6181             :                                  const char* reason) {
    6182     1350565 :   if (object->HasFastProperties()) return;
    6183             :   DCHECK(!object->IsJSGlobalObject());
    6184             :   Isolate* isolate = object->GetIsolate();
    6185             :   Factory* factory = isolate->factory();
    6186             :   Handle<NameDictionary> dictionary(object->property_dictionary());
    6187             : 
    6188             :   // Make sure we preserve dictionary representation if there are too many
    6189             :   // descriptors.
    6190             :   int number_of_elements = dictionary->NumberOfElements();
    6191      445067 :   if (number_of_elements > kMaxNumberOfDescriptors) return;
    6192             : 
    6193             :   Handle<FixedArray> iteration_order =
    6194      444668 :       NameDictionary::IterationIndices(dictionary);
    6195             : 
    6196             :   int instance_descriptor_length = iteration_order->length();
    6197             :   int number_of_fields = 0;
    6198             : 
    6199             :   // Compute the length of the instance descriptor.
    6200     2694457 :   for (int i = 0; i < instance_descriptor_length; i++) {
    6201             :     int index = Smi::ToInt(iteration_order->get(i));
    6202             :     DCHECK(dictionary->IsKey(isolate, dictionary->KeyAt(index)));
    6203             : 
    6204             :     PropertyKind kind = dictionary->DetailsAt(index).kind();
    6205     2249789 :     if (kind == kData) {
    6206             :       if (FLAG_track_constant_fields) {
    6207             :         number_of_fields += 1;
    6208             :       } else {
    6209     1588423 :         Object* value = dictionary->ValueAt(index);
    6210     1588423 :         if (!value->IsJSFunction()) {
    6211      438229 :           number_of_fields += 1;
    6212             :         }
    6213             :       }
    6214             :     }
    6215             :   }
    6216             : 
    6217             :   Handle<Map> old_map(object->map(), isolate);
    6218             : 
    6219             :   int inobject_props = old_map->GetInObjectProperties();
    6220             : 
    6221             :   // Allocate new map.
    6222      444668 :   Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
    6223      889146 :   new_map->set_may_have_interesting_symbols(new_map->has_named_interceptor() ||
    6224             :                                             new_map->is_access_check_needed());
    6225             :   new_map->set_dictionary_map(false);
    6226             : 
    6227      444668 :   NotifyMapChange(old_map, new_map, isolate);
    6228             : 
    6229             : #if V8_TRACE_MAPS
    6230             :   if (FLAG_trace_maps) {
    6231             :     PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n",
    6232             :            reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map),
    6233             :            reason);
    6234             :   }
    6235             : #endif
    6236             : 
    6237      444668 :   if (instance_descriptor_length == 0) {
    6238             :     DisallowHeapAllocation no_gc;
    6239             :     DCHECK_LE(unused_property_fields, inobject_props);
    6240             :     // Transform the object.
    6241       72283 :     new_map->SetInObjectUnusedPropertyFields(inobject_props);
    6242       72283 :     object->synchronized_set_map(*new_map);
    6243      144566 :     object->SetProperties(isolate->heap()->empty_fixed_array());
    6244             :     // Check that it really works.
    6245             :     DCHECK(object->HasFastProperties());
    6246             :     return;
    6247             :   }
    6248             : 
    6249             :   // Allocate the instance descriptor.
    6250             :   Handle<DescriptorArray> descriptors = DescriptorArray::Allocate(
    6251      372385 :       isolate, instance_descriptor_length, 0, TENURED);
    6252             : 
    6253             :   int number_of_allocated_fields =
    6254      372385 :       number_of_fields + unused_property_fields - inobject_props;
    6255      372385 :   if (number_of_allocated_fields < 0) {
    6256             :     // There is enough inobject space for all fields (including unused).
    6257             :     number_of_allocated_fields = 0;
    6258       60051 :     unused_property_fields = inobject_props - number_of_fields;
    6259             :   }
    6260             : 
    6261             :   // Allocate the property array for the fields.
    6262             :   Handle<PropertyArray> fields =
    6263      372385 :       factory->NewPropertyArray(number_of_allocated_fields);
    6264             : 
    6265             :   // Fill in the instance descriptor and the fields.
    6266             :   int current_offset = 0;
    6267     2622174 :   for (int i = 0; i < instance_descriptor_length; i++) {
    6268             :     int index = Smi::ToInt(iteration_order->get(i));
    6269             :     Name* k = dictionary->NameAt(index);
    6270             :     // Dictionary keys are internalized upon insertion.
    6271             :     // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild.
    6272     2249789 :     CHECK(k->IsUniqueName());
    6273             :     Handle<Name> key(k, isolate);
    6274             : 
    6275             :     // Properly mark the {new_map} if the {key} is an "interesting symbol".
    6276     2249789 :     if (key->IsInterestingSymbol()) {
    6277             :       new_map->set_may_have_interesting_symbols(true);
    6278             :     }
    6279             : 
    6280     2249789 :     Object* value = dictionary->ValueAt(index);
    6281             : 
    6282             :     PropertyDetails details = dictionary->DetailsAt(index);
    6283             :     DCHECK_EQ(kField, details.location());
    6284             :     DCHECK_EQ(kMutable, details.constness());
    6285             : 
    6286             :     Descriptor d;
    6287     2249789 :     if (details.kind() == kData) {
    6288     1588423 :       if (!FLAG_track_constant_fields && value->IsJSFunction()) {
    6289             :         d = Descriptor::DataConstant(key, handle(value, isolate),
    6290     1150194 :                                      details.attributes());
    6291             :       } else {
    6292             :         d = Descriptor::DataField(
    6293             :             key, current_offset, details.attributes(), kDefaultFieldConstness,
    6294             :             // TODO(verwaest): value->OptimalRepresentation();
    6295      876458 :             Representation::Tagged(), FieldType::Any(isolate));
    6296             :       }
    6297             :     } else {
    6298             :       DCHECK_EQ(kAccessor, details.kind());
    6299             :       d = Descriptor::AccessorConstant(key, handle(value, isolate),
    6300      661366 :                                        details.attributes());
    6301             :     }
    6302             :     details = d.GetDetails();
    6303     2249789 :     if (details.location() == kField) {
    6304      438229 :       if (current_offset < inobject_props) {
    6305             :         object->InObjectPropertyAtPut(current_offset, value,
    6306       25181 :                                       UPDATE_WRITE_BARRIER);
    6307             :       } else {
    6308      413048 :         int offset = current_offset - inobject_props;
    6309      413048 :         fields->set(offset, value);
    6310             :       }
    6311      438229 :       current_offset += details.field_width_in_words();
    6312             :     }
    6313     2249789 :     descriptors->Set(i, &d);
    6314             :   }
    6315             :   DCHECK(current_offset == number_of_fields);
    6316             : 
    6317      372385 :   descriptors->Sort();
    6318             : 
    6319             :   Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New(
    6320      372385 :       new_map, descriptors, descriptors->number_of_descriptors());
    6321             : 
    6322             :   DisallowHeapAllocation no_gc;
    6323      372385 :   new_map->InitializeDescriptors(*descriptors, *layout_descriptor);
    6324      372385 :   if (number_of_allocated_fields == 0) {
    6325      258601 :     new_map->SetInObjectUnusedPropertyFields(unused_property_fields);
    6326             :   } else {
    6327             :     new_map->SetOutOfObjectUnusedPropertyFields(unused_property_fields);
    6328             :   }
    6329             : 
    6330             :   // Transform the object.
    6331      372385 :   object->synchronized_set_map(*new_map);
    6332             : 
    6333      372385 :   object->SetProperties(*fields);
    6334             :   DCHECK(object->IsJSObject());
    6335             : 
    6336             :   // Check that it really works.
    6337             :   DCHECK(object->HasFastProperties());
    6338             : }
    6339             : 
    6340       86869 : void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) {
    6341      173738 :   if (dictionary->requires_slow_elements()) return;
    6342             :   dictionary->set_requires_slow_elements();
    6343       53001 :   if (map()->is_prototype_map()) {
    6344             :     // If this object is a prototype (the callee will check), invalidate any
    6345             :     // prototype chains involving it.
    6346             :     InvalidatePrototypeChains(map());
    6347             :   }
    6348             : }
    6349             : 
    6350             : 
    6351      304401 : Handle<SeededNumberDictionary> JSObject::NormalizeElements(
    6352             :     Handle<JSObject> object) {
    6353             :   DCHECK(!object->HasFixedTypedArrayElements());
    6354             :   Isolate* isolate = object->GetIsolate();
    6355      304401 :   bool is_sloppy_arguments = object->HasSloppyArgumentsElements();
    6356             :   {
    6357             :     DisallowHeapAllocation no_gc;
    6358             :     FixedArrayBase* elements = object->elements();
    6359             : 
    6360      304401 :     if (is_sloppy_arguments) {
    6361             :       elements = SloppyArgumentsElements::cast(elements)->arguments();
    6362             :     }
    6363             : 
    6364      304401 :     if (elements->IsDictionary()) {
    6365             :       return handle(SeededNumberDictionary::cast(elements), isolate);
    6366             :     }
    6367             :   }
    6368             : 
    6369             :   DCHECK(object->HasSmiOrObjectElements() || object->HasDoubleElements() ||
    6370             :          object->HasFastArgumentsElements() ||
    6371             :          object->HasFastStringWrapperElements());
    6372             : 
    6373             :   Handle<SeededNumberDictionary> dictionary =
    6374      299028 :       object->GetElementsAccessor()->Normalize(object);
    6375             : 
    6376             :   // Switch to using the dictionary as the backing storage for elements.
    6377             :   ElementsKind target_kind = is_sloppy_arguments
    6378             :                                  ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS
    6379      298267 :                                  : object->HasFastStringWrapperElements()
    6380             :                                        ? SLOW_STRING_WRAPPER_ELEMENTS
    6381      597295 :                                        : DICTIONARY_ELEMENTS;
    6382      299028 :   Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind);
    6383             :   // Set the new map first to satify the elements type assert in set_elements().
    6384      299028 :   JSObject::MigrateToMap(object, new_map);
    6385             : 
    6386      299028 :   if (is_sloppy_arguments) {
    6387             :     SloppyArgumentsElements::cast(object->elements())
    6388             :         ->set_arguments(*dictionary);
    6389             :   } else {
    6390      298267 :     object->set_elements(*dictionary);
    6391             :   }
    6392             : 
    6393      299028 :   isolate->counters()->elements_to_dictionary()->Increment();
    6394             : 
    6395             : #ifdef DEBUG
    6396             :   if (FLAG_trace_normalization) {
    6397             :     OFStream os(stdout);
    6398             :     os << "Object elements have been normalized:\n";
    6399             :     object->Print(os);
    6400             :   }
    6401             : #endif
    6402             : 
    6403             :   DCHECK(object->HasDictionaryElements() ||
    6404             :          object->HasSlowArgumentsElements() ||
    6405             :          object->HasSlowStringWrapperElements());
    6406      299028 :   return dictionary;
    6407             : }
    6408             : 
    6409             : namespace {
    6410             : 
    6411       12001 : Object* SetHashAndUpdateProperties(HeapObject* properties, int hash) {
    6412             :   DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
    6413             :   DCHECK(PropertyArray::HashField::is_valid(hash));
    6414             : 
    6415       12199 :   if (properties == properties->GetHeap()->empty_fixed_array() ||
    6416         198 :       properties == properties->GetHeap()->empty_property_dictionary()) {
    6417       11803 :     return Smi::FromInt(hash);
    6418             :   }
    6419             : 
    6420         198 :   if (properties->IsPropertyArray()) {
    6421          85 :     PropertyArray::cast(properties)->SetHash(hash);
    6422          85 :     return properties;
    6423             :   }
    6424             : 
    6425             :   DCHECK(properties->IsDictionary());
    6426             :   NameDictionary::cast(properties)->SetHash(hash);
    6427         113 :   return properties;
    6428             : }
    6429             : 
    6430    23869184 : int GetIdentityHashHelper(Isolate* isolate, JSReceiver* object) {
    6431             :   DisallowHeapAllocation no_gc;
    6432             :   Object* properties = object->raw_properties_or_hash();
    6433    23869184 :   if (properties->IsSmi()) {
    6434             :     return Smi::ToInt(properties);
    6435             :   }
    6436             : 
    6437    23853363 :   if (properties->IsPropertyArray()) {
    6438             :     return PropertyArray::cast(properties)->Hash();
    6439             :   }
    6440             : 
    6441    21875803 :   if (properties->IsDictionary()) {
    6442             :     return NameDictionary::cast(properties)->Hash();
    6443             :   }
    6444             : 
    6445             : #ifdef DEBUG
    6446             :   FixedArray* empty_fixed_array = isolate->heap()->empty_fixed_array();
    6447             :   FixedArray* empty_property_dictionary =
    6448             :       isolate->heap()->empty_property_dictionary();
    6449             :   DCHECK(properties == empty_fixed_array ||
    6450             :          properties == empty_property_dictionary);
    6451             : #endif
    6452             : 
    6453             :   return PropertyArray::kNoHashSentinel;
    6454             : }
    6455             : }  // namespace
    6456             : 
    6457       11853 : void JSReceiver::SetIdentityHash(int hash) {
    6458             :   DisallowHeapAllocation no_gc;
    6459             :   DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
    6460             :   DCHECK(PropertyArray::HashField::is_valid(hash));
    6461             : 
    6462             :   HeapObject* existing_properties = HeapObject::cast(raw_properties_or_hash());
    6463             :   Object* new_properties =
    6464       11853 :       SetHashAndUpdateProperties(existing_properties, hash);
    6465       11853 :   set_raw_properties_or_hash(new_properties);
    6466       11853 : }
    6467             : 
    6468    23838196 : void JSReceiver::SetProperties(HeapObject* properties) {
    6469             :   DisallowHeapAllocation no_gc;
    6470             :   Isolate* isolate = properties->GetIsolate();
    6471    23838196 :   int hash = GetIdentityHashHelper(isolate, this);
    6472             :   Object* new_properties = properties;
    6473             : 
    6474             :   // TODO(cbruni): Make GetIdentityHashHelper return a bool so that we
    6475             :   // don't have to manually compare against kNoHashSentinel.
    6476    23838196 :   if (hash != PropertyArray::kNoHashSentinel) {
    6477         148 :     new_properties = SetHashAndUpdateProperties(properties, hash);
    6478             :   }
    6479             : 
    6480    23838196 :   set_raw_properties_or_hash(new_properties);
    6481    23838196 : }
    6482             : 
    6483             : template <typename ProxyType>
    6484         388 : Smi* GetOrCreateIdentityHashHelper(Isolate* isolate, ProxyType* proxy) {
    6485             :   DisallowHeapAllocation no_gc;
    6486             :   Object* maybe_hash = proxy->hash();
    6487         388 :   if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash);
    6488             : 
    6489         364 :   Smi* hash = Smi::FromInt(isolate->GenerateIdentityHash(Smi::kMaxValue));
    6490         364 :   proxy->set_hash(hash);
    6491         364 :   return hash;
    6492             : }
    6493             : 
    6494       31045 : Object* JSObject::GetIdentityHash(Isolate* isolate) {
    6495             :   DisallowHeapAllocation no_gc;
    6496       31045 :   if (IsJSGlobalProxy()) {
    6497          56 :     return JSGlobalProxy::cast(this)->hash();
    6498             :   }
    6499             : 
    6500       30989 :   int hash = GetIdentityHashHelper(isolate, this);
    6501       30989 :   if (hash == PropertyArray::kNoHashSentinel) {
    6502       15109 :     return isolate->heap()->undefined_value();
    6503             :   }
    6504             : 
    6505       15880 :   return Smi::FromInt(hash);
    6506             : }
    6507             : 
    6508       12457 : Smi* JSObject::GetOrCreateIdentityHash(Isolate* isolate) {
    6509             :   DisallowHeapAllocation no_gc;
    6510       12457 :   if (IsJSGlobalProxy()) {
    6511          46 :     return GetOrCreateIdentityHashHelper(isolate, JSGlobalProxy::cast(this));
    6512             :   }
    6513             : 
    6514       12411 :   Object* hash_obj = GetIdentityHash(isolate);
    6515       12411 :   if (!hash_obj->IsUndefined(isolate)) {
    6516             :     return Smi::cast(hash_obj);
    6517             :   }
    6518             : 
    6519       11823 :   int hash = isolate->GenerateIdentityHash(PropertyArray::HashField::kMax);
    6520             :   DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
    6521             : 
    6522       11823 :   SetIdentityHash(hash);
    6523       11823 :   return Smi::FromInt(hash);
    6524             : }
    6525             : 
    6526           0 : Object* JSProxy::GetIdentityHash() { return hash(); }
    6527             : 
    6528           0 : Smi* JSProxy::GetOrCreateIdentityHash(Isolate* isolate) {
    6529         342 :   return GetOrCreateIdentityHashHelper(isolate, this);
    6530             : }
    6531             : 
    6532             : 
    6533         158 : Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
    6534             :                                                     ShouldThrow should_throw) {
    6535             :   Isolate* isolate = it->isolate();
    6536             :   // Make sure that the top context does not change when doing callbacks or
    6537             :   // interceptor calls.
    6538             :   AssertNoContextChange ncc(isolate);
    6539             : 
    6540             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    6541         100 :   Handle<InterceptorInfo> interceptor(it->GetInterceptor());
    6542         100 :   if (interceptor->deleter()->IsUndefined(isolate)) return Nothing<bool>();
    6543             : 
    6544             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    6545             :   Handle<Object> receiver = it->GetReceiver();
    6546          58 :   if (!receiver->IsJSReceiver()) {
    6547           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    6548             :                                      Object::ConvertReceiver(isolate, receiver),
    6549             :                                      Nothing<bool>());
    6550             :   }
    6551             : 
    6552             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    6553             :                                  *holder, should_throw);
    6554             :   Handle<Object> result;
    6555          58 :   if (it->IsElement()) {
    6556             :     uint32_t index = it->index();
    6557             :     v8::IndexedPropertyDeleterCallback deleter =
    6558             :         v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
    6559          23 :     result = args.Call(deleter, index);
    6560             :   } else {
    6561             :     DCHECK_IMPLIES(it->name()->IsSymbol(),
    6562             :                    interceptor->can_intercept_symbols());
    6563          35 :     Handle<Name> name = it->name();
    6564             :     DCHECK(!name->IsPrivate());
    6565             :     v8::GenericNamedPropertyDeleterCallback deleter =
    6566             :         v8::ToCData<v8::GenericNamedPropertyDeleterCallback>(
    6567             :             interceptor->deleter());
    6568          35 :     result = args.Call(deleter, name);
    6569             :   }
    6570             : 
    6571          58 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    6572          58 :   if (result.is_null()) return Nothing<bool>();
    6573             : 
    6574             :   DCHECK(result->IsBoolean());
    6575             :   // Rebox CustomArguments::kReturnValueOffset before returning.
    6576             :   return Just(result->IsTrue(isolate));
    6577             : }
    6578             : 
    6579       89191 : void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object,
    6580             :                                           int entry) {
    6581             :   DCHECK(!object->HasFastProperties());
    6582             :   Isolate* isolate = object->GetIsolate();
    6583             : 
    6584       89191 :   if (object->IsJSGlobalObject()) {
    6585             :     // If we have a global object, invalidate the cell and swap in a new one.
    6586             :     Handle<GlobalDictionary> dictionary(
    6587             :         JSGlobalObject::cast(*object)->global_dictionary());
    6588             :     DCHECK_NE(GlobalDictionary::kNotFound, entry);
    6589             : 
    6590       10784 :     auto cell = PropertyCell::InvalidateEntry(dictionary, entry);
    6591       21568 :     cell->set_value(isolate->heap()->the_hole_value());
    6592             :     cell->set_property_details(
    6593             :         PropertyDetails::Empty(PropertyCellType::kUninitialized));
    6594             :   } else {
    6595             :     Handle<NameDictionary> dictionary(object->property_dictionary());
    6596             :     DCHECK_NE(NameDictionary::kNotFound, entry);
    6597             : 
    6598       78407 :     dictionary = NameDictionary::DeleteEntry(dictionary, entry);
    6599       78407 :     object->SetProperties(*dictionary);
    6600             :   }
    6601       89191 : }
    6602             : 
    6603             : 
    6604     3017171 : Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it,
    6605             :                                        LanguageMode language_mode) {
    6606     1003500 :   it->UpdateProtector();
    6607             : 
    6608             :   Isolate* isolate = it->isolate();
    6609             : 
    6610     1003500 :   if (it->state() == LookupIterator::JSPROXY) {
    6611             :     return JSProxy::DeletePropertyOrElement(it->GetHolder<JSProxy>(),
    6612        3097 :                                             it->GetName(), language_mode);
    6613             :   }
    6614             : 
    6615     1000403 :   if (it->GetReceiver()->IsJSProxy()) {
    6616          39 :     if (it->state() != LookupIterator::NOT_FOUND) {
    6617             :       DCHECK_EQ(LookupIterator::DATA, it->state());
    6618             :       DCHECK(it->name()->IsPrivate());
    6619           6 :       it->Delete();
    6620             :     }
    6621             :     return Just(true);
    6622             :   }
    6623             :   Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
    6624             : 
    6625     2020264 :   for (; it->IsFound(); it->Next()) {
    6626      213018 :     switch (it->state()) {
    6627             :       case LookupIterator::JSPROXY:
    6628             :       case LookupIterator::NOT_FOUND:
    6629             :       case LookupIterator::TRANSITION:
    6630           0 :         UNREACHABLE();
    6631             :       case LookupIterator::ACCESS_CHECK:
    6632        9728 :         if (it->HasAccess()) break;
    6633          36 :         isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    6634          36 :         RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    6635             :         return Just(false);
    6636             :       case LookupIterator::INTERCEPTOR: {
    6637             :         ShouldThrow should_throw =
    6638         100 :             is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    6639             :         Maybe<bool> result =
    6640         100 :             JSObject::DeletePropertyWithInterceptor(it, should_throw);
    6641             :         // An exception was thrown in the interceptor. Propagate.
    6642         124 :         if (isolate->has_pending_exception()) return Nothing<bool>();
    6643             :         // Delete with interceptor succeeded. Return result.
    6644             :         // TODO(neis): In strict mode, we should probably throw if the
    6645             :         // interceptor returns false.
    6646         100 :         if (result.IsJust()) return result;
    6647          76 :         break;
    6648             :       }
    6649             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    6650             :         return Just(true);
    6651             :       case LookupIterator::DATA:
    6652             :       case LookupIterator::ACCESSOR: {
    6653      203145 :         if (!it->IsConfigurable()) {
    6654             :           // Fail if the property is not configurable.
    6655        2309 :           if (is_strict(language_mode)) {
    6656             :             isolate->Throw(*isolate->factory()->NewTypeError(
    6657             :                 MessageTemplate::kStrictDeleteProperty, it->GetName(),
    6658        1671 :                 receiver));
    6659             :             return Nothing<bool>();
    6660             :           }
    6661             :           return Just(false);
    6662             :         }
    6663             : 
    6664      200836 :         it->Delete();
    6665             : 
    6666             :         return Just(true);
    6667             :       }
    6668             :     }
    6669             :   }
    6670             : 
    6671             :   return Just(true);
    6672             : }
    6673             : 
    6674             : 
    6675          10 : Maybe<bool> JSReceiver::DeleteElement(Handle<JSReceiver> object, uint32_t index,
    6676             :                                       LanguageMode language_mode) {
    6677             :   LookupIterator it(object->GetIsolate(), object, index, object,
    6678             :                     LookupIterator::OWN);
    6679          10 :   return DeleteProperty(&it, language_mode);
    6680             : }
    6681             : 
    6682             : 
    6683         902 : Maybe<bool> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
    6684             :                                        Handle<Name> name,
    6685             :                                        LanguageMode language_mode) {
    6686         902 :   LookupIterator it(object, name, object, LookupIterator::OWN);
    6687         902 :   return DeleteProperty(&it, language_mode);
    6688             : }
    6689             : 
    6690             : 
    6691        3785 : Maybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object,
    6692             :                                                 Handle<Name> name,
    6693             :                                                 LanguageMode language_mode) {
    6694             :   LookupIterator it = LookupIterator::PropertyOrElement(
    6695        3785 :       name->GetIsolate(), object, name, object, LookupIterator::OWN);
    6696        3785 :   return DeleteProperty(&it, language_mode);
    6697             : }
    6698             : 
    6699             : // ES6 19.1.2.4
    6700             : // static
    6701      191234 : Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object,
    6702             :                                    Handle<Object> key,
    6703             :                                    Handle<Object> attributes) {
    6704             :   // 1. If Type(O) is not Object, throw a TypeError exception.
    6705      191234 :   if (!object->IsJSReceiver()) {
    6706             :     Handle<String> fun_name =
    6707          67 :         isolate->factory()->InternalizeUtf8String("Object.defineProperty");
    6708         134 :     THROW_NEW_ERROR_RETURN_FAILURE(
    6709             :         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name));
    6710             :   }
    6711             :   // 2. Let key be ToPropertyKey(P).
    6712             :   // 3. ReturnIfAbrupt(key).
    6713      382334 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, ToPropertyKey(isolate, key));
    6714             :   // 4. Let desc be ToPropertyDescriptor(Attributes).
    6715             :   // 5. ReturnIfAbrupt(desc).
    6716             :   PropertyDescriptor desc;
    6717      191167 :   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
    6718         140 :     return isolate->heap()->exception();
    6719             :   }
    6720             :   // 6. Let success be DefinePropertyOrThrow(O,key, desc).
    6721             :   Maybe<bool> success = DefineOwnProperty(
    6722      191027 :       isolate, Handle<JSReceiver>::cast(object), key, &desc, THROW_ON_ERROR);
    6723             :   // 7. ReturnIfAbrupt(success).
    6724      191027 :   MAYBE_RETURN(success, isolate->heap()->exception());
    6725      189929 :   CHECK(success.FromJust());
    6726             :   // 8. Return O.
    6727      189929 :   return *object;
    6728             : }
    6729             : 
    6730             : 
    6731             : // ES6 19.1.2.3.1
    6732             : // static
    6733       13173 : MaybeHandle<Object> JSReceiver::DefineProperties(Isolate* isolate,
    6734             :                                                  Handle<Object> object,
    6735             :                                                  Handle<Object> properties) {
    6736             :   // 1. If Type(O) is not Object, throw a TypeError exception.
    6737       13173 :   if (!object->IsJSReceiver()) {
    6738             :     Handle<String> fun_name =
    6739          28 :         isolate->factory()->InternalizeUtf8String("Object.defineProperties");
    6740          56 :     THROW_NEW_ERROR(isolate,
    6741             :                     NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name),
    6742             :                     Object);
    6743             :   }
    6744             :   // 2. Let props be ToObject(Properties).
    6745             :   // 3. ReturnIfAbrupt(props).
    6746             :   Handle<JSReceiver> props;
    6747       26290 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, props,
    6748             :                              Object::ToObject(isolate, properties), Object);
    6749             : 
    6750             :   // 4. Let keys be props.[[OwnPropertyKeys]]().
    6751             :   // 5. ReturnIfAbrupt(keys).
    6752             :   Handle<FixedArray> keys;
    6753       26270 :   ASSIGN_RETURN_ON_EXCEPTION(
    6754             :       isolate, keys, KeyAccumulator::GetKeys(props, KeyCollectionMode::kOwnOnly,
    6755             :                                              ALL_PROPERTIES),
    6756             :       Object);
    6757             :   // 6. Let descriptors be an empty List.
    6758             :   int capacity = keys->length();
    6759       13135 :   std::vector<PropertyDescriptor> descriptors(capacity);
    6760             :   size_t descriptors_index = 0;
    6761             :   // 7. Repeat for each element nextKey of keys in List order,
    6762      251706 :   for (int i = 0; i < keys->length(); ++i) {
    6763             :     Handle<Object> next_key(keys->get(i), isolate);
    6764             :     // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey).
    6765             :     // 7b. ReturnIfAbrupt(propDesc).
    6766      112952 :     bool success = false;
    6767             :     LookupIterator it = LookupIterator::PropertyOrElement(
    6768      112952 :         isolate, props, next_key, &success, LookupIterator::OWN);
    6769             :     DCHECK(success);
    6770      112952 :     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
    6771      112952 :     if (!maybe.IsJust()) return MaybeHandle<Object>();
    6772             :     PropertyAttributes attrs = maybe.FromJust();
    6773             :     // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true:
    6774      114098 :     if (attrs == ABSENT) continue;
    6775      112952 :     if (attrs & DONT_ENUM) continue;
    6776             :     // 7c i. Let descObj be Get(props, nextKey).
    6777             :     // 7c ii. ReturnIfAbrupt(descObj).
    6778             :     Handle<Object> desc_obj;
    6779      223612 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, desc_obj, Object::GetProperty(&it),
    6780             :                                Object);
    6781             :     // 7c iii. Let desc be ToPropertyDescriptor(descObj).
    6782             :     success = PropertyDescriptor::ToPropertyDescriptor(
    6783      223612 :         isolate, desc_obj, &descriptors[descriptors_index]);
    6784             :     // 7c iv. ReturnIfAbrupt(desc).
    6785      111806 :     if (!success) return MaybeHandle<Object>();
    6786             :     // 7c v. Append the pair (a two element List) consisting of nextKey and
    6787             :     //       desc to the end of descriptors.
    6788      111572 :     descriptors[descriptors_index].set_name(next_key);
    6789      111572 :     descriptors_index++;
    6790             :   }
    6791             :   // 8. For each pair from descriptors in list order,
    6792      111163 :   for (size_t i = 0; i < descriptors_index; ++i) {
    6793      111163 :     PropertyDescriptor* desc = &descriptors[i];
    6794             :     // 8a. Let P be the first element of pair.
    6795             :     // 8b. Let desc be the second element of pair.
    6796             :     // 8c. Let status be DefinePropertyOrThrow(O, P, desc).
    6797             :     Maybe<bool> status =
    6798             :         DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object),
    6799      111163 :                           desc->name(), desc, THROW_ON_ERROR);
    6800             :     // 8d. ReturnIfAbrupt(status).
    6801      111163 :     if (!status.IsJust()) return MaybeHandle<Object>();
    6802      111163 :     CHECK(status.FromJust());
    6803             :   }
    6804             :   // 9. Return o.
    6805       12901 :   return object;
    6806             : }
    6807             : 
    6808             : 
    6809             : // static
    6810      697020 : Maybe<bool> JSReceiver::DefineOwnProperty(Isolate* isolate,
    6811             :                                           Handle<JSReceiver> object,
    6812             :                                           Handle<Object> key,
    6813             :                                           PropertyDescriptor* desc,
    6814             :                                           ShouldThrow should_throw) {
    6815      697020 :   if (object->IsJSArray()) {
    6816             :     return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object),
    6817       53697 :                                       key, desc, should_throw);
    6818             :   }
    6819      643323 :   if (object->IsJSProxy()) {
    6820             :     return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object),
    6821        4005 :                                       key, desc, should_throw);
    6822             :   }
    6823      639318 :   if (object->IsJSTypedArray()) {
    6824             :     return JSTypedArray::DefineOwnProperty(
    6825        3119 :         isolate, Handle<JSTypedArray>::cast(object), key, desc, should_throw);
    6826             :   }
    6827             :   // TODO(neis): Special case for JSModuleNamespace?
    6828             : 
    6829             :   // OrdinaryDefineOwnProperty, by virtue of calling
    6830             :   // DefineOwnPropertyIgnoreAttributes, can handle arguments
    6831             :   // (ES#sec-arguments-exotic-objects-defineownproperty-p-desc).
    6832             :   return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key,
    6833      636199 :                                    desc, should_throw);
    6834             : }
    6835             : 
    6836             : 
    6837             : // static
    6838      708304 : Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate,
    6839             :                                                   Handle<JSObject> object,
    6840             :                                                   Handle<Object> key,
    6841             :                                                   PropertyDescriptor* desc,
    6842             :                                                   ShouldThrow should_throw) {
    6843      708304 :   bool success = false;
    6844             :   DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey...
    6845             :   LookupIterator it = LookupIterator::PropertyOrElement(
    6846      708304 :       isolate, object, key, &success, LookupIterator::OWN);
    6847             :   DCHECK(success);  // ...so creating a LookupIterator can't fail.
    6848             : 
    6849             :   // Deal with access checks first.
    6850      708304 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    6851        2483 :     if (!it.HasAccess()) {
    6852          30 :       isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
    6853          30 :       RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    6854             :       return Just(true);
    6855             :     }
    6856        2453 :     it.Next();
    6857             :   }
    6858             : 
    6859      708274 :   return OrdinaryDefineOwnProperty(&it, desc, should_throw);
    6860             : }
    6861             : 
    6862             : 
    6863             : // ES6 9.1.6.1
    6864             : // static
    6865     1642146 : Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it,
    6866             :                                                   PropertyDescriptor* desc,
    6867             :                                                   ShouldThrow should_throw) {
    6868             :   Isolate* isolate = it->isolate();
    6869             :   // 1. Let current be O.[[GetOwnProperty]](P).
    6870             :   // 2. ReturnIfAbrupt(current).
    6871             :   PropertyDescriptor current;
    6872      708274 :   MAYBE_RETURN(GetOwnPropertyDescriptor(it, &current), Nothing<bool>());
    6873             : 
    6874      708274 :   it->Restart();
    6875             :   // Handle interceptor
    6876     1867744 :   for (; it->IsFound(); it->Next()) {
    6877      225652 :     if (it->state() == LookupIterator::INTERCEPTOR) {
    6878         178 :       if (it->HolderIsReceiverOrHiddenPrototype()) {
    6879             :         Maybe<bool> result = DefinePropertyWithInterceptorInternal(
    6880         178 :             it, it->GetInterceptor(), should_throw, *desc);
    6881         356 :         if (result.IsNothing() || result.FromJust()) {
    6882          54 :           return result;
    6883             :         }
    6884             :       }
    6885             :     }
    6886             :   }
    6887             : 
    6888             :   // TODO(jkummerow/verwaest): It would be nice if we didn't have to reset
    6889             :   // the iterator every time. Currently, the reasons why we need it are:
    6890             :   // - handle interceptors correctly
    6891             :   // - handle accessors correctly (which might change the holder's map)
    6892      708220 :   it->Restart();
    6893             :   // 3. Let extensible be the value of the [[Extensible]] internal slot of O.
    6894      708220 :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    6895      708220 :   bool extensible = JSObject::IsExtensible(object);
    6896             : 
    6897             :   return ValidateAndApplyPropertyDescriptor(
    6898      708220 :       isolate, it, extensible, desc, &current, should_throw, Handle<Name>());
    6899             : }
    6900             : 
    6901             : 
    6902             : // ES6 9.1.6.2
    6903             : // static
    6904           0 : Maybe<bool> JSReceiver::IsCompatiblePropertyDescriptor(
    6905             :     Isolate* isolate, bool extensible, PropertyDescriptor* desc,
    6906             :     PropertyDescriptor* current, Handle<Name> property_name,
    6907             :     ShouldThrow should_throw) {
    6908             :   // 1. Return ValidateAndApplyPropertyDescriptor(undefined, undefined,
    6909             :   //    Extensible, Desc, Current).
    6910             :   return ValidateAndApplyPropertyDescriptor(
    6911        4522 :       isolate, nullptr, extensible, desc, current, should_throw, property_name);
    6912             : }
    6913             : 
    6914             : 
    6915             : // ES6 9.1.6.3
    6916             : // static
    6917      712742 : Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
    6918             :     Isolate* isolate, LookupIterator* it, bool extensible,
    6919             :     PropertyDescriptor* desc, PropertyDescriptor* current,
    6920             :     ShouldThrow should_throw, Handle<Name> property_name) {
    6921             :   // We either need a LookupIterator, or a property name.
    6922             :   DCHECK((it == nullptr) != property_name.is_null());
    6923             :   Handle<JSObject> object;
    6924             :   if (it != nullptr) object = Handle<JSObject>::cast(it->GetReceiver());
    6925             :   bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc);
    6926             :   bool desc_is_accessor_descriptor =
    6927             :       PropertyDescriptor::IsAccessorDescriptor(desc);
    6928             :   bool desc_is_generic_descriptor =
    6929             :       PropertyDescriptor::IsGenericDescriptor(desc);
    6930             :   // 1. (Assert)
    6931             :   // 2. If current is undefined, then
    6932      712742 :   if (current->is_empty()) {
    6933             :     // 2a. If extensible is false, return false.
    6934      487842 :     if (!extensible) {
    6935         325 :       RETURN_FAILURE(
    6936             :           isolate, should_throw,
    6937             :           NewTypeError(MessageTemplate::kDefineDisallowed,
    6938             :                        it != nullptr ? it->GetName() : property_name));
    6939             :     }
    6940             :     // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then:
    6941             :     // (This is equivalent to !IsAccessorDescriptor(desc).)
    6942             :     DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) ==
    6943             :            !desc_is_accessor_descriptor);
    6944      487724 :     if (!desc_is_accessor_descriptor) {
    6945             :       // 2c i. If O is not undefined, create an own data property named P of
    6946             :       // object O whose [[Value]], [[Writable]], [[Enumerable]] and
    6947             :       // [[Configurable]] attribute values are described by Desc. If the value
    6948             :       // of an attribute field of Desc is absent, the attribute of the newly
    6949             :       // created property is set to its default value.
    6950      419303 :       if (it != nullptr) {
    6951      416801 :         if (!desc->has_writable()) desc->set_writable(false);
    6952      416801 :         if (!desc->has_enumerable()) desc->set_enumerable(false);
    6953      416801 :         if (!desc->has_configurable()) desc->set_configurable(false);
    6954             :         Handle<Object> value(
    6955             :             desc->has_value()
    6956             :                 ? desc->value()
    6957      502522 :                 : Handle<Object>::cast(isolate->factory()->undefined_value()));
    6958             :         MaybeHandle<Object> result =
    6959             :             JSObject::DefineOwnPropertyIgnoreAttributes(it, value,
    6960      416801 :                                                         desc->ToAttributes());
    6961      416801 :         if (result.is_null()) return Nothing<bool>();
    6962             :       }
    6963             :     } else {
    6964             :       // 2d. Else Desc must be an accessor Property Descriptor,
    6965             :       DCHECK(desc_is_accessor_descriptor);
    6966             :       // 2d i. If O is not undefined, create an own accessor property named P
    6967             :       // of object O whose [[Get]], [[Set]], [[Enumerable]] and
    6968             :       // [[Configurable]] attribute values are described by Desc. If the value
    6969             :       // of an attribute field of Desc is absent, the attribute of the newly
    6970             :       // created property is set to its default value.
    6971       68421 :       if (it != nullptr) {
    6972       68277 :         if (!desc->has_enumerable()) desc->set_enumerable(false);
    6973       68277 :         if (!desc->has_configurable()) desc->set_configurable(false);
    6974             :         Handle<Object> getter(
    6975             :             desc->has_get()
    6976             :                 ? desc->get()
    6977       80797 :                 : Handle<Object>::cast(isolate->factory()->null_value()));
    6978             :         Handle<Object> setter(
    6979             :             desc->has_set()
    6980             :                 ? desc->set()
    6981      110229 :                 : Handle<Object>::cast(isolate->factory()->null_value()));
    6982             :         MaybeHandle<Object> result =
    6983       68277 :             JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes());
    6984       68277 :         if (result.is_null()) return Nothing<bool>();
    6985             :       }
    6986             :     }
    6987             :     // 2e. Return true.
    6988             :     return Just(true);
    6989             :   }
    6990             :   // 3. Return true, if every field in Desc is absent.
    6991             :   // 4. Return true, if every field in Desc also occurs in current and the
    6992             :   // value of every field in Desc is the same value as the corresponding field
    6993             :   // in current when compared using the SameValue algorithm.
    6994      394229 :   if ((!desc->has_enumerable() ||
    6995       95891 :        desc->enumerable() == current->enumerable()) &&
    6996       58967 :       (!desc->has_configurable() ||
    6997       93437 :        desc->configurable() == current->configurable()) &&
    6998       76298 :       (!desc->has_value() ||
    6999      142825 :        (current->has_value() && current->value()->SameValue(*desc->value()))) &&
    7000       50461 :       (!desc->has_writable() ||
    7001      104519 :        (current->has_writable() && current->writable() == desc->writable())) &&
    7002        5503 :       (!desc->has_get() ||
    7003      277630 :        (current->has_get() && current->get()->SameValue(*desc->get()))) &&
    7004        7225 :       (!desc->has_set() ||
    7005        7030 :        (current->has_set() && current->set()->SameValue(*desc->set())))) {
    7006             :     return Just(true);
    7007             :   }
    7008             :   // 5. If the [[Configurable]] field of current is false, then
    7009      183258 :   if (!current->configurable()) {
    7010             :     // 5a. Return false, if the [[Configurable]] field of Desc is true.
    7011       19832 :     if (desc->has_configurable() && desc->configurable()) {
    7012         585 :       RETURN_FAILURE(
    7013             :           isolate, should_throw,
    7014             :           NewTypeError(MessageTemplate::kRedefineDisallowed,
    7015             :                        it != nullptr ? it->GetName() : property_name));
    7016             :     }
    7017             :     // 5b. Return false, if the [[Enumerable]] field of Desc is present and the
    7018             :     // [[Enumerable]] fields of current and Desc are the Boolean negation of
    7019             :     // each other.
    7020       19160 :     if (desc->has_enumerable() && desc->enumerable() != current->enumerable()) {
    7021         296 :       RETURN_FAILURE(
    7022             :           isolate, should_throw,
    7023             :           NewTypeError(MessageTemplate::kRedefineDisallowed,
    7024             :                        it != nullptr ? it->GetName() : property_name));
    7025             :     }
    7026             :   }
    7027             : 
    7028             :   bool current_is_data_descriptor =
    7029             :       PropertyDescriptor::IsDataDescriptor(current);
    7030             :   // 6. If IsGenericDescriptor(Desc) is true, no further validation is required.
    7031      182935 :   if (desc_is_generic_descriptor) {
    7032             :     // Nothing to see here.
    7033             : 
    7034             :     // 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) have
    7035             :     // different results, then:
    7036      181997 :   } else if (current_is_data_descriptor != desc_is_data_descriptor) {
    7037             :     // 7a. Return false, if the [[Configurable]] field of current is false.
    7038      130545 :     if (!current->configurable()) {
    7039         448 :       RETURN_FAILURE(
    7040             :           isolate, should_throw,
    7041             :           NewTypeError(MessageTemplate::kRedefineDisallowed,
    7042             :                        it != nullptr ? it->GetName() : property_name));
    7043             :     }
    7044             :     // 7b. If IsDataDescriptor(current) is true, then:
    7045             :     if (current_is_data_descriptor) {
    7046             :       // 7b i. If O is not undefined, convert the property named P of object O
    7047             :       // from a data property to an accessor property. Preserve the existing
    7048             :       // values of the converted property's [[Configurable]] and [[Enumerable]]
    7049             :       // attributes and set the rest of the property's attributes to their
    7050             :       // default values.
    7051             :       // --> Folded into step 10.
    7052             :     } else {
    7053             :       // 7c i. If O is not undefined, convert the property named P of object O
    7054             :       // from an accessor property to a data property. Preserve the existing
    7055             :       // values of the converted property’s [[Configurable]] and [[Enumerable]]
    7056             :       // attributes and set the rest of the property’s attributes to their
    7057             :       // default values.
    7058             :       // --> Folded into step 10.
    7059             :     }
    7060             : 
    7061             :     // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both
    7062             :     // true, then:
    7063       51452 :   } else if (current_is_data_descriptor && desc_is_data_descriptor) {
    7064             :     // 8a. If the [[Configurable]] field of current is false, then:
    7065       40427 :     if (!current->configurable()) {
    7066             :       // 8a i. Return false, if the [[Writable]] field of current is false and
    7067             :       // the [[Writable]] field of Desc is true.
    7068       16159 :       if (!current->writable() && desc->has_writable() && desc->writable()) {
    7069         193 :         RETURN_FAILURE(
    7070             :             isolate, should_throw,
    7071             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    7072             :                          it != nullptr ? it->GetName() : property_name));
    7073             :       }
    7074             :       // 8a ii. If the [[Writable]] field of current is false, then:
    7075       15731 :       if (!current->writable()) {
    7076             :         // 8a ii 1. Return false, if the [[Value]] field of Desc is present and
    7077             :         // SameValue(Desc.[[Value]], current.[[Value]]) is false.
    7078         488 :         if (desc->has_value() && !desc->value()->SameValue(*current->value())) {
    7079         811 :           RETURN_FAILURE(
    7080             :               isolate, should_throw,
    7081             :               NewTypeError(MessageTemplate::kRedefineDisallowed,
    7082             :                            it != nullptr ? it->GetName() : property_name));
    7083             :         }
    7084             :       }
    7085             :     }
    7086             :   } else {
    7087             :     // 9. Else IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc)
    7088             :     // are both true,
    7089             :     DCHECK(PropertyDescriptor::IsAccessorDescriptor(current) &&
    7090             :            desc_is_accessor_descriptor);
    7091             :     // 9a. If the [[Configurable]] field of current is false, then:
    7092       11025 :     if (!current->configurable()) {
    7093             :       // 9a i. Return false, if the [[Set]] field of Desc is present and
    7094             :       // SameValue(Desc.[[Set]], current.[[Set]]) is false.
    7095         147 :       if (desc->has_set() && !desc->set()->SameValue(*current->set())) {
    7096         121 :         RETURN_FAILURE(
    7097             :             isolate, should_throw,
    7098             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    7099             :                          it != nullptr ? it->GetName() : property_name));
    7100             :       }
    7101             :       // 9a ii. Return false, if the [[Get]] field of Desc is present and
    7102             :       // SameValue(Desc.[[Get]], current.[[Get]]) is false.
    7103         108 :       if (desc->has_get() && !desc->get()->SameValue(*current->get())) {
    7104         174 :         RETURN_FAILURE(
    7105             :             isolate, should_throw,
    7106             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    7107             :                          it != nullptr ? it->GetName() : property_name));
    7108             :       }
    7109             :     }
    7110             :   }
    7111             : 
    7112             :   // 10. If O is not undefined, then:
    7113      182412 :   if (it != nullptr) {
    7114             :     // 10a. For each field of Desc that is present, set the corresponding
    7115             :     // attribute of the property named P of object O to the value of the field.
    7116             :     PropertyAttributes attrs = NONE;
    7117             : 
    7118      182178 :     if (desc->has_enumerable()) {
    7119             :       attrs = static_cast<PropertyAttributes>(
    7120      134344 :           attrs | (desc->enumerable() ? NONE : DONT_ENUM));
    7121             :     } else {
    7122             :       attrs = static_cast<PropertyAttributes>(
    7123       47834 :           attrs | (current->enumerable() ? NONE : DONT_ENUM));
    7124             :     }
    7125      182178 :     if (desc->has_configurable()) {
    7126             :       attrs = static_cast<PropertyAttributes>(
    7127      146287 :           attrs | (desc->configurable() ? NONE : DONT_DELETE));
    7128             :     } else {
    7129             :       attrs = static_cast<PropertyAttributes>(
    7130       35891 :           attrs | (current->configurable() ? NONE : DONT_DELETE));
    7131             :     }
    7132      324011 :     if (desc_is_data_descriptor ||
    7133      141833 :         (desc_is_generic_descriptor && current_is_data_descriptor)) {
    7134       41178 :       if (desc->has_writable()) {
    7135             :         attrs = static_cast<PropertyAttributes>(
    7136       38267 :             attrs | (desc->writable() ? NONE : READ_ONLY));
    7137             :       } else {
    7138             :         attrs = static_cast<PropertyAttributes>(
    7139        2911 :             attrs | (current->writable() ? NONE : READ_ONLY));
    7140             :       }
    7141             :       Handle<Object> value(
    7142             :           desc->has_value() ? desc->value()
    7143             :                             : current->has_value()
    7144             :                                   ? current->value()
    7145             :                                   : Handle<Object>::cast(
    7146       43971 :                                         isolate->factory()->undefined_value()));
    7147             :       return JSObject::DefineOwnPropertyIgnoreAttributes(it, value, attrs,
    7148       41178 :                                                          should_throw);
    7149             :     } else {
    7150             :       DCHECK(desc_is_accessor_descriptor ||
    7151             :              (desc_is_generic_descriptor &&
    7152             :               PropertyDescriptor::IsAccessorDescriptor(current)));
    7153             :       Handle<Object> getter(
    7154             :           desc->has_get()
    7155             :               ? desc->get()
    7156             :               : current->has_get()
    7157             :                     ? current->get()
    7158      148554 :                     : Handle<Object>::cast(isolate->factory()->null_value()));
    7159             :       Handle<Object> setter(
    7160             :           desc->has_set()
    7161             :               ? desc->set()
    7162             :               : current->has_set()
    7163             :                     ? current->set()
    7164      403565 :                     : Handle<Object>::cast(isolate->factory()->null_value()));
    7165             :       MaybeHandle<Object> result =
    7166      141000 :           JSObject::DefineAccessor(it, getter, setter, attrs);
    7167      141000 :       if (result.is_null()) return Nothing<bool>();
    7168             :     }
    7169             :   }
    7170             : 
    7171             :   // 11. Return true.
    7172             :   return Just(true);
    7173             : }
    7174             : 
    7175             : 
    7176             : // static
    7177     1110623 : Maybe<bool> JSReceiver::CreateDataProperty(LookupIterator* it,
    7178             :                                            Handle<Object> value,
    7179             :                                            ShouldThrow should_throw) {
    7180             :   DCHECK(!it->check_prototype_chain());
    7181             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    7182             :   Isolate* isolate = receiver->GetIsolate();
    7183             : 
    7184     1110623 :   if (receiver->IsJSObject()) {
    7185     1109722 :     return JSObject::CreateDataProperty(it, value, should_throw);  // Shortcut.
    7186             :   }
    7187             : 
    7188             :   PropertyDescriptor new_desc;
    7189             :   new_desc.set_value(value);
    7190             :   new_desc.set_writable(true);
    7191             :   new_desc.set_enumerable(true);
    7192             :   new_desc.set_configurable(true);
    7193             : 
    7194             :   return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
    7195        1802 :                                        &new_desc, should_throw);
    7196             : }
    7197             : 
    7198     2223907 : Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
    7199             :                                          Handle<Object> value,
    7200             :                                          ShouldThrow should_throw) {
    7201             :   DCHECK(it->GetReceiver()->IsJSObject());
    7202     1111956 :   MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
    7203             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    7204             :   Isolate* isolate = receiver->GetIsolate();
    7205             : 
    7206     1111951 :   if (it->IsFound()) {
    7207         338 :     Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
    7208         376 :     MAYBE_RETURN(attributes, Nothing<bool>());
    7209         338 :     if ((attributes.FromJust() & DONT_DELETE) != 0) {
    7210         122 :       RETURN_FAILURE(
    7211             :           isolate, should_throw,
    7212             :           NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
    7213             :     }
    7214             :   } else {
    7215     1111613 :     if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) {
    7216         229 :       RETURN_FAILURE(
    7217             :           isolate, should_throw,
    7218             :           NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
    7219             :     }
    7220             :   }
    7221             : 
    7222     2223704 :   RETURN_ON_EXCEPTION_VALUE(it->isolate(),
    7223             :                             DefineOwnPropertyIgnoreAttributes(it, value, NONE),
    7224             :                             Nothing<bool>());
    7225             : 
    7226             :   return Just(true);
    7227             : }
    7228             : 
    7229             : 
    7230             : // TODO(jkummerow): Consider unification with FastAsArrayLength() in
    7231             : // accessors.cc.
    7232       43230 : bool PropertyKeyToArrayLength(Handle<Object> value, uint32_t* length) {
    7233             :   DCHECK(value->IsNumber() || value->IsName());
    7234       43230 :   if (value->ToArrayLength(length)) return true;
    7235       58293 :   if (value->IsString()) return String::cast(*value)->AsArrayIndex(length);
    7236             :   return false;
    7237             : }
    7238             : 
    7239           0 : bool PropertyKeyToArrayIndex(Handle<Object> index_obj, uint32_t* output) {
    7240       43230 :   return PropertyKeyToArrayLength(index_obj, output) && *output != kMaxUInt32;
    7241             : }
    7242             : 
    7243             : 
    7244             : // ES6 9.4.2.1
    7245             : // static
    7246       55327 : Maybe<bool> JSArray::DefineOwnProperty(Isolate* isolate, Handle<JSArray> o,
    7247             :                                        Handle<Object> name,
    7248             :                                        PropertyDescriptor* desc,
    7249             :                                        ShouldThrow should_throw) {
    7250             :   // 1. Assert: IsPropertyKey(P) is true. ("P" is |name|.)
    7251             :   // 2. If P is "length", then:
    7252             :   // TODO(jkummerow): Check if we need slow string comparison.
    7253       55327 :   if (*name == isolate->heap()->length_string()) {
    7254             :     // 2a. Return ArraySetLength(A, Desc).
    7255       12097 :     return ArraySetLength(isolate, o, desc, should_throw);
    7256             :   }
    7257             :   // 3. Else if P is an array index, then:
    7258       43230 :   uint32_t index = 0;
    7259       43230 :   if (PropertyKeyToArrayIndex(name, &index)) {
    7260             :     // 3a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    7261             :     PropertyDescriptor old_len_desc;
    7262             :     Maybe<bool> success = GetOwnPropertyDescriptor(
    7263       38968 :         isolate, o, isolate->factory()->length_string(), &old_len_desc);
    7264             :     // 3b. (Assert)
    7265             :     DCHECK(success.FromJust());
    7266             :     USE(success);
    7267             :     // 3c. Let oldLen be oldLenDesc.[[Value]].
    7268       38968 :     uint32_t old_len = 0;
    7269       38968 :     CHECK(old_len_desc.value()->ToArrayLength(&old_len));
    7270             :     // 3d. Let index be ToUint32(P).
    7271             :     // (Already done above.)
    7272             :     // 3e. (Assert)
    7273             :     // 3f. If index >= oldLen and oldLenDesc.[[Writable]] is false,
    7274             :     //     return false.
    7275       66760 :     if (index >= old_len && old_len_desc.has_writable() &&
    7276             :         !old_len_desc.writable()) {
    7277           0 :       RETURN_FAILURE(isolate, should_throw,
    7278             :                      NewTypeError(MessageTemplate::kDefineDisallowed, name));
    7279             :     }
    7280             :     // 3g. Let succeeded be OrdinaryDefineOwnProperty(A, P, Desc).
    7281             :     Maybe<bool> succeeded =
    7282       38968 :         OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
    7283             :     // 3h. Assert: succeeded is not an abrupt completion.
    7284             :     //     In our case, if should_throw == THROW_ON_ERROR, it can be!
    7285             :     // 3i. If succeeded is false, return false.
    7286       77849 :     if (succeeded.IsNothing() || !succeeded.FromJust()) return succeeded;
    7287             :     // 3j. If index >= oldLen, then:
    7288       38872 :     if (index >= old_len) {
    7289             :       // 3j i. Set oldLenDesc.[[Value]] to index + 1.
    7290       13896 :       old_len_desc.set_value(isolate->factory()->NewNumberFromUint(index + 1));
    7291             :       // 3j ii. Let succeeded be
    7292             :       //        OrdinaryDefineOwnProperty(A, "length", oldLenDesc).
    7293             :       succeeded = OrdinaryDefineOwnProperty(isolate, o,
    7294             :                                             isolate->factory()->length_string(),
    7295       13896 :                                             &old_len_desc, should_throw);
    7296             :       // 3j iii. Assert: succeeded is true.
    7297             :       DCHECK(succeeded.FromJust());
    7298             :       USE(succeeded);
    7299             :     }
    7300             :     // 3k. Return true.
    7301             :     return Just(true);
    7302             :   }
    7303             : 
    7304             :   // 4. Return OrdinaryDefineOwnProperty(A, P, Desc).
    7305        4262 :   return OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
    7306             : }
    7307             : 
    7308             : 
    7309             : // Part of ES6 9.4.2.4 ArraySetLength.
    7310             : // static
    7311      538625 : bool JSArray::AnythingToArrayLength(Isolate* isolate,
    7312             :                                     Handle<Object> length_object,
    7313             :                                     uint32_t* output) {
    7314             :   // Fast path: check numbers and strings that can be converted directly
    7315             :   // and unobservably.
    7316      538625 :   if (length_object->ToArrayLength(output)) return true;
    7317      473825 :   if (length_object->IsString() &&
    7318          20 :       Handle<String>::cast(length_object)->AsArrayIndex(output)) {
    7319             :     return true;
    7320             :   }
    7321             :   // Slow path: follow steps in ES6 9.4.2.4 "ArraySetLength".
    7322             :   // 3. Let newLen be ToUint32(Desc.[[Value]]).
    7323             :   Handle<Object> uint32_v;
    7324      947590 :   if (!Object::ToUint32(isolate, length_object).ToHandle(&uint32_v)) {
    7325             :     // 4. ReturnIfAbrupt(newLen).
    7326             :     return false;
    7327             :   }
    7328             :   // 5. Let numberLen be ToNumber(Desc.[[Value]]).
    7329             :   Handle<Object> number_v;
    7330      947570 :   if (!Object::ToNumber(length_object).ToHandle(&number_v)) {
    7331             :     // 6. ReturnIfAbrupt(newLen).
    7332             :     return false;
    7333             :   }
    7334             :   // 7. If newLen != numberLen, throw a RangeError exception.
    7335      473785 :   if (uint32_v->Number() != number_v->Number()) {
    7336             :     Handle<Object> exception =
    7337         256 :         isolate->factory()->NewRangeError(MessageTemplate::kInvalidArrayLength);
    7338         256 :     isolate->Throw(*exception);
    7339             :     return false;
    7340             :   }
    7341      473529 :   CHECK(uint32_v->ToArrayLength(output));
    7342             :   return true;
    7343             : }
    7344             : 
    7345             : 
    7346             : // ES6 9.4.2.4
    7347             : // static
    7348       12097 : Maybe<bool> JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a,
    7349             :                                     PropertyDescriptor* desc,
    7350             :                                     ShouldThrow should_throw) {
    7351             :   // 1. If the [[Value]] field of Desc is absent, then
    7352       12097 :   if (!desc->has_value()) {
    7353             :     // 1a. Return OrdinaryDefineOwnProperty(A, "length", Desc).
    7354             :     return OrdinaryDefineOwnProperty(
    7355         264 :         isolate, a, isolate->factory()->length_string(), desc, should_throw);
    7356             :   }
    7357             :   // 2. Let newLenDesc be a copy of Desc.
    7358             :   // (Actual copying is not necessary.)
    7359             :   PropertyDescriptor* new_len_desc = desc;
    7360             :   // 3. - 7. Convert Desc.[[Value]] to newLen.
    7361       11833 :   uint32_t new_len = 0;
    7362       11833 :   if (!AnythingToArrayLength(isolate, desc->value(), &new_len)) {
    7363             :     DCHECK(isolate->has_pending_exception());
    7364             :     return Nothing<bool>();
    7365             :   }
    7366             :   // 8. Set newLenDesc.[[Value]] to newLen.
    7367             :   // (Done below, if needed.)
    7368             :   // 9. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    7369             :   PropertyDescriptor old_len_desc;
    7370             :   Maybe<bool> success = GetOwnPropertyDescriptor(
    7371       11823 :       isolate, a, isolate->factory()->length_string(), &old_len_desc);
    7372             :   // 10. (Assert)
    7373             :   DCHECK(success.FromJust());
    7374             :   USE(success);
    7375             :   // 11. Let oldLen be oldLenDesc.[[Value]].
    7376       11823 :   uint32_t old_len = 0;
    7377       11823 :   CHECK(old_len_desc.value()->ToArrayLength(&old_len));
    7378             :   // 12. If newLen >= oldLen, then
    7379       11823 :   if (new_len >= old_len) {
    7380             :     // 8. Set newLenDesc.[[Value]] to newLen.
    7381             :     // 12a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc).
    7382       11814 :     new_len_desc->set_value(isolate->factory()->NewNumberFromUint(new_len));
    7383             :     return OrdinaryDefineOwnProperty(isolate, a,
    7384             :                                      isolate->factory()->length_string(),
    7385       11814 :                                      new_len_desc, should_throw);
    7386             :   }
    7387             :   // 13. If oldLenDesc.[[Writable]] is false, return false.
    7388           9 :   if (!old_len_desc.writable()) {
    7389           0 :     RETURN_FAILURE(isolate, should_throw,
    7390             :                    NewTypeError(MessageTemplate::kRedefineDisallowed,
    7391             :                                 isolate->factory()->length_string()));
    7392             :   }
    7393             :   // 14. If newLenDesc.[[Writable]] is absent or has the value true,
    7394             :   // let newWritable be true.
    7395             :   bool new_writable = false;
    7396           9 :   if (!new_len_desc->has_writable() || new_len_desc->writable()) {
    7397             :     new_writable = true;
    7398             :   } else {
    7399             :     // 15. Else,
    7400             :     // 15a. Need to defer setting the [[Writable]] attribute to false in case
    7401             :     //      any elements cannot be deleted.
    7402             :     // 15b. Let newWritable be false. (It's initialized as "false" anyway.)
    7403             :     // 15c. Set newLenDesc.[[Writable]] to true.
    7404             :     // (Not needed.)
    7405             :   }
    7406             :   // Most of steps 16 through 19 is implemented by JSArray::SetLength.
    7407           9 :   JSArray::SetLength(a, new_len);
    7408             :   // Steps 19d-ii, 20.
    7409           9 :   if (!new_writable) {
    7410             :     PropertyDescriptor readonly;
    7411             :     readonly.set_writable(false);
    7412             :     Maybe<bool> success = OrdinaryDefineOwnProperty(
    7413             :         isolate, a, isolate->factory()->length_string(), &readonly,
    7414           0 :         should_throw);
    7415             :     DCHECK(success.FromJust());
    7416             :     USE(success);
    7417             :   }
    7418           9 :   uint32_t actual_new_len = 0;
    7419           9 :   CHECK(a->length()->ToArrayLength(&actual_new_len));
    7420             :   // Steps 19d-v, 21. Return false if there were non-deletable elements.
    7421           9 :   bool result = actual_new_len == new_len;
    7422           9 :   if (!result) {
    7423           9 :     RETURN_FAILURE(
    7424             :         isolate, should_throw,
    7425             :         NewTypeError(MessageTemplate::kStrictDeleteProperty,
    7426             :                      isolate->factory()->NewNumberFromUint(actual_new_len - 1),
    7427             :                      a));
    7428             :   }
    7429             :   return Just(result);
    7430             : }
    7431             : 
    7432             : 
    7433             : // ES6 9.5.6
    7434             : // static
    7435        4005 : Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy,
    7436             :                                        Handle<Object> key,
    7437             :                                        PropertyDescriptor* desc,
    7438             :                                        ShouldThrow should_throw) {
    7439        4005 :   STACK_CHECK(isolate, Nothing<bool>());
    7440        4293 :   if (key->IsSymbol() && Handle<Symbol>::cast(key)->IsPrivate()) {
    7441             :     return SetPrivateProperty(isolate, proxy, Handle<Symbol>::cast(key), desc,
    7442          18 :                               should_throw);
    7443             :   }
    7444             :   Handle<String> trap_name = isolate->factory()->defineProperty_string();
    7445             :   // 1. Assert: IsPropertyKey(P) is true.
    7446             :   DCHECK(key->IsName() || key->IsNumber());
    7447             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    7448             :   Handle<Object> handler(proxy->handler(), isolate);
    7449             :   // 3. If handler is null, throw a TypeError exception.
    7450             :   // 4. Assert: Type(handler) is Object.
    7451        3987 :   if (proxy->IsRevoked()) {
    7452             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7453          18 :         MessageTemplate::kProxyRevoked, trap_name));
    7454             :     return Nothing<bool>();
    7455             :   }
    7456             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    7457             :   Handle<JSReceiver> target(proxy->target(), isolate);
    7458             :   // 6. Let trap be ? GetMethod(handler, "defineProperty").
    7459             :   Handle<Object> trap;
    7460        7956 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7461             :       isolate, trap,
    7462             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    7463             :       Nothing<bool>());
    7464             :   // 7. If trap is undefined, then:
    7465        3888 :   if (trap->IsUndefined(isolate)) {
    7466             :     // 7a. Return target.[[DefineOwnProperty]](P, Desc).
    7467             :     return JSReceiver::DefineOwnProperty(isolate, target, key, desc,
    7468        2035 :                                          should_throw);
    7469             :   }
    7470             :   // 8. Let descObj be FromPropertyDescriptor(Desc).
    7471        1853 :   Handle<Object> desc_obj = desc->ToObject(isolate);
    7472             :   // 9. Let booleanTrapResult be
    7473             :   //    ToBoolean(? Call(trap, handler, «target, P, descObj»)).
    7474             :   Handle<Name> property_name =
    7475             :       key->IsName()
    7476             :           ? Handle<Name>::cast(key)
    7477        1853 :           : Handle<Name>::cast(isolate->factory()->NumberToString(key));
    7478             :   // Do not leak private property names.
    7479             :   DCHECK(!property_name->IsPrivate());
    7480             :   Handle<Object> trap_result_obj;
    7481        1853 :   Handle<Object> args[] = {target, property_name, desc_obj};
    7482        3706 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7483             :       isolate, trap_result_obj,
    7484             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    7485             :       Nothing<bool>());
    7486             :   // 10. If booleanTrapResult is false, return false.
    7487        1327 :   if (!trap_result_obj->BooleanValue()) {
    7488          99 :     RETURN_FAILURE(isolate, should_throw,
    7489             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    7490             :                                 trap_name, property_name));
    7491             :   }
    7492             :   // 11. Let targetDesc be ? target.[[GetOwnProperty]](P).
    7493             :   PropertyDescriptor target_desc;
    7494             :   Maybe<bool> target_found =
    7495        1246 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, key, &target_desc);
    7496        1246 :   MAYBE_RETURN(target_found, Nothing<bool>());
    7497             :   // 12. Let extensibleTarget be ? IsExtensible(target).
    7498        1246 :   Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target);
    7499        1246 :   MAYBE_RETURN(maybe_extensible, Nothing<bool>());
    7500             :   bool extensible_target = maybe_extensible.FromJust();
    7501             :   // 13. If Desc has a [[Configurable]] field and if Desc.[[Configurable]]
    7502             :   //     is false, then:
    7503             :   // 13a. Let settingConfigFalse be true.
    7504             :   // 14. Else let settingConfigFalse be false.
    7505        1941 :   bool setting_config_false = desc->has_configurable() && !desc->configurable();
    7506             :   // 15. If targetDesc is undefined, then
    7507        1246 :   if (!target_found.FromJust()) {
    7508             :     // 15a. If extensibleTarget is false, throw a TypeError exception.
    7509         621 :     if (!extensible_target) {
    7510             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7511          18 :           MessageTemplate::kProxyDefinePropertyNonExtensible, property_name));
    7512             :       return Nothing<bool>();
    7513             :     }
    7514             :     // 15b. If settingConfigFalse is true, throw a TypeError exception.
    7515         612 :     if (setting_config_false) {
    7516             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7517          18 :           MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
    7518             :       return Nothing<bool>();
    7519             :     }
    7520             :   } else {
    7521             :     // 16. Else targetDesc is not undefined,
    7522             :     // 16a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc,
    7523             :     //      targetDesc) is false, throw a TypeError exception.
    7524             :     Maybe<bool> valid =
    7525             :         IsCompatiblePropertyDescriptor(isolate, extensible_target, desc,
    7526             :                                        &target_desc, property_name, DONT_THROW);
    7527         625 :     MAYBE_RETURN(valid, Nothing<bool>());
    7528         625 :     if (!valid.FromJust()) {
    7529             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7530          18 :           MessageTemplate::kProxyDefinePropertyIncompatible, property_name));
    7531             :       return Nothing<bool>();
    7532             :     }
    7533             :     // 16b. If settingConfigFalse is true and targetDesc.[[Configurable]] is
    7534             :     //      true, throw a TypeError exception.
    7535         706 :     if (setting_config_false && target_desc.configurable()) {
    7536             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7537          18 :           MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
    7538             :       return Nothing<bool>();
    7539             :     }
    7540             :   }
    7541             :   // 17. Return true.
    7542             :   return Just(true);
    7543             : }
    7544             : 
    7545             : 
    7546             : // static
    7547          36 : Maybe<bool> JSProxy::SetPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy,
    7548             :                                         Handle<Symbol> private_name,
    7549             :                                         PropertyDescriptor* desc,
    7550             :                                         ShouldThrow should_throw) {
    7551             :   // Despite the generic name, this can only add private data properties.
    7552          54 :   if (!PropertyDescriptor::IsDataDescriptor(desc) ||
    7553          18 :       desc->ToAttributes() != DONT_ENUM) {
    7554          36 :     RETURN_FAILURE(isolate, should_throw,
    7555             :                    NewTypeError(MessageTemplate::kProxyPrivate));
    7556             :   }
    7557             :   DCHECK(proxy->map()->is_dictionary_map());
    7558             :   Handle<Object> value =
    7559             :       desc->has_value()
    7560             :           ? desc->value()
    7561          18 :           : Handle<Object>::cast(isolate->factory()->undefined_value());
    7562             : 
    7563          18 :   LookupIterator it(proxy, private_name, proxy);
    7564             : 
    7565          18 :   if (it.IsFound()) {
    7566             :     DCHECK_EQ(LookupIterator::DATA, it.state());
    7567             :     DCHECK_EQ(DONT_ENUM, it.property_attributes());
    7568           6 :     it.WriteDataValue(value, false);
    7569             :     return Just(true);
    7570             :   }
    7571             : 
    7572             :   Handle<NameDictionary> dict(proxy->property_dictionary());
    7573             :   PropertyDetails details(kData, DONT_ENUM, PropertyCellType::kNoCell);
    7574             :   Handle<NameDictionary> result =
    7575          12 :       NameDictionary::Add(dict, private_name, value, details);
    7576          18 :   if (!dict.is_identical_to(result)) proxy->SetProperties(*result);
    7577             :   return Just(true);
    7578             : }
    7579             : 
    7580             : 
    7581             : // static
    7582     2279114 : Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate,
    7583             :                                                  Handle<JSReceiver> object,
    7584             :                                                  Handle<Object> key,
    7585             :                                                  PropertyDescriptor* desc) {
    7586     2279114 :   bool success = false;
    7587             :   DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey...
    7588             :   LookupIterator it = LookupIterator::PropertyOrElement(
    7589     2279114 :       isolate, object, key, &success, LookupIterator::OWN);
    7590             :   DCHECK(success);  // ...so creating a LookupIterator can't fail.
    7591     2279114 :   return GetOwnPropertyDescriptor(&it, desc);
    7592             : }
    7593             : 
    7594             : namespace {
    7595             : 
    7596     5967247 : Maybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
    7597             :                                                  PropertyDescriptor* desc) {
    7598             :   bool has_access = true;
    7599     2983347 :   if (it->state() == LookupIterator::ACCESS_CHECK) {
    7600     2169299 :     has_access = it->HasAccess() || JSObject::AllCanRead(it);
    7601     2169299 :     it->Next();
    7602             :   }
    7603             : 
    7604     5966649 :   if (has_access && it->state() == LookupIterator::INTERCEPTOR) {
    7605             :     Isolate* isolate = it->isolate();
    7606         548 :     Handle<InterceptorInfo> interceptor = it->GetInterceptor();
    7607         548 :     if (!interceptor->descriptor()->IsUndefined(isolate)) {
    7608             :       Handle<Object> result;
    7609             :       Handle<JSObject> holder = it->GetHolder<JSObject>();
    7610             : 
    7611             :       Handle<Object> receiver = it->GetReceiver();
    7612          38 :       if (!receiver->IsJSReceiver()) {
    7613          12 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7614             :             isolate, receiver, Object::ConvertReceiver(isolate, receiver),
    7615             :             Nothing<bool>());
    7616             :       }
    7617             : 
    7618             :       PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    7619             :                                      *holder, Object::DONT_THROW);
    7620          38 :       if (it->IsElement()) {
    7621             :         uint32_t index = it->index();
    7622             :         v8::IndexedPropertyDescriptorCallback descriptorCallback =
    7623             :             v8::ToCData<v8::IndexedPropertyDescriptorCallback>(
    7624             :                 interceptor->descriptor());
    7625             : 
    7626          10 :         result = args.Call(descriptorCallback, index);
    7627             :       } else {
    7628          28 :         Handle<Name> name = it->name();
    7629             :         DCHECK(!name->IsPrivate());
    7630             :         v8::GenericNamedPropertyDescriptorCallback descriptorCallback =
    7631             :             v8::ToCData<v8::GenericNamedPropertyDescriptorCallback>(
    7632             :                 interceptor->descriptor());
    7633          28 :         result = args.Call(descriptorCallback, name);
    7634             :       }
    7635          38 :       if (!result.is_null()) {
    7636             :         // Request successfully intercepted, try to set the property
    7637             :         // descriptor.
    7638             :         Utils::ApiCheck(
    7639          12 :             PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
    7640             :             it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
    7641             :                             : "v8::NamedPropertyDescriptorCallback",
    7642          12 :             "Invalid property descriptor.");
    7643             : 
    7644             :         return Just(true);
    7645             :       }
    7646             :     }
    7647             :   }
    7648     2983335 :   it->Restart();
    7649             :   return Just(false);
    7650             : }
    7651             : }  // namespace
    7652             : 
    7653             : // ES6 9.1.5.1
    7654             : // Returns true on success, false if the property didn't exist, nothing if
    7655             : // an exception was thrown.
    7656             : // static
    7657     5455613 : Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it,
    7658             :                                                  PropertyDescriptor* desc) {
    7659             :   Isolate* isolate = it->isolate();
    7660             :   // "Virtual" dispatch.
    7661     5462270 :   if (it->IsFound() && it->GetHolder<JSReceiver>()->IsJSProxy()) {
    7662             :     return JSProxy::GetOwnPropertyDescriptor(isolate, it->GetHolder<JSProxy>(),
    7663        6267 :                                              it->GetName(), desc);
    7664             :   }
    7665             : 
    7666     2983347 :   Maybe<bool> intercepted = GetPropertyDescriptorWithInterceptor(it, desc);
    7667     2983347 :   MAYBE_RETURN(intercepted, Nothing<bool>());
    7668     2983347 :   if (intercepted.FromJust()) {
    7669             :     return Just(true);
    7670             :   }
    7671             : 
    7672             :   // Request was not intercepted, continue as normal.
    7673             :   // 1. (Assert)
    7674             :   // 2. If O does not have an own property with key P, return undefined.
    7675     2983335 :   Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it);
    7676     2983335 :   MAYBE_RETURN(maybe, Nothing<bool>());
    7677             :   PropertyAttributes attrs = maybe.FromJust();
    7678     2983290 :   if (attrs == ABSENT) return Just(false);
    7679             :   DCHECK(!isolate->has_pending_exception());
    7680             : 
    7681             :   // 3. Let D be a newly created Property Descriptor with no fields.
    7682             :   DCHECK(desc->is_empty());
    7683             :   // 4. Let X be O's own property whose key is P.
    7684             :   // 5. If X is a data property, then
    7685     2571514 :   bool is_accessor_pair = it->state() == LookupIterator::ACCESSOR &&
    7686     2571514 :                           it->GetAccessors()->IsAccessorPair();
    7687     2465999 :   if (!is_accessor_pair) {
    7688             :     // 5a. Set D.[[Value]] to the value of X's [[Value]] attribute.
    7689             :     Handle<Object> value;
    7690     4904228 :     if (!Object::GetProperty(it).ToHandle(&value)) {
    7691             :       DCHECK(isolate->has_pending_exception());
    7692             :       return Nothing<bool>();
    7693             :     }
    7694             :     desc->set_value(value);
    7695             :     // 5b. Set D.[[Writable]] to the value of X's [[Writable]] attribute
    7696     2452114 :     desc->set_writable((attrs & READ_ONLY) == 0);
    7697             :   } else {
    7698             :     // 6. Else X is an accessor property, so
    7699             :     Handle<AccessorPair> accessors =
    7700       13885 :         Handle<AccessorPair>::cast(it->GetAccessors());
    7701             :     // 6a. Set D.[[Get]] to the value of X's [[Get]] attribute.
    7702       13885 :     desc->set_get(AccessorPair::GetComponent(accessors, ACCESSOR_GETTER));
    7703             :     // 6b. Set D.[[Set]] to the value of X's [[Set]] attribute.
    7704       13885 :     desc->set_set(AccessorPair::GetComponent(accessors, ACCESSOR_SETTER));
    7705             :   }
    7706             : 
    7707             :   // 7. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
    7708     2465999 :   desc->set_enumerable((attrs & DONT_ENUM) == 0);
    7709             :   // 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
    7710     2465999 :   desc->set_configurable((attrs & DONT_DELETE) == 0);
    7711             :   // 9. Return D.
    7712             :   DCHECK(PropertyDescriptor::IsAccessorDescriptor(desc) !=
    7713             :          PropertyDescriptor::IsDataDescriptor(desc));
    7714             :   return Just(true);
    7715             : }
    7716             : 
    7717             : 
    7718             : // ES6 9.5.5
    7719             : // static
    7720        9420 : Maybe<bool> JSProxy::GetOwnPropertyDescriptor(Isolate* isolate,
    7721             :                                               Handle<JSProxy> proxy,
    7722             :                                               Handle<Name> name,
    7723             :                                               PropertyDescriptor* desc) {
    7724             :   DCHECK(!name->IsPrivate());
    7725        9420 :   STACK_CHECK(isolate, Nothing<bool>());
    7726             : 
    7727             :   Handle<String> trap_name =
    7728             :       isolate->factory()->getOwnPropertyDescriptor_string();
    7729             :   // 1. (Assert)
    7730             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    7731             :   Handle<Object> handler(proxy->handler(), isolate);
    7732             :   // 3. If handler is null, throw a TypeError exception.
    7733             :   // 4. Assert: Type(handler) is Object.
    7734        9420 :   if (proxy->IsRevoked()) {
    7735             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7736          36 :         MessageTemplate::kProxyRevoked, trap_name));
    7737             :     return Nothing<bool>();
    7738             :   }
    7739             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    7740             :   Handle<JSReceiver> target(proxy->target(), isolate);
    7741             :   // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor").
    7742             :   Handle<Object> trap;
    7743       18804 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7744             :       isolate, trap,
    7745             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    7746             :       Nothing<bool>());
    7747             :   // 7. If trap is undefined, then
    7748        9348 :   if (trap->IsUndefined(isolate)) {
    7749             :     // 7a. Return target.[[GetOwnProperty]](P).
    7750        3657 :     return JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, desc);
    7751             :   }
    7752             :   // 8. Let trapResultObj be ? Call(trap, handler, «target, P»).
    7753             :   Handle<Object> trap_result_obj;
    7754             :   Handle<Object> args[] = {target, name};
    7755       11382 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7756             :       isolate, trap_result_obj,
    7757             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    7758             :       Nothing<bool>());
    7759             :   // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a
    7760             :   //    TypeError exception.
    7761        5589 :   if (!trap_result_obj->IsJSReceiver() &&
    7762             :       !trap_result_obj->IsUndefined(isolate)) {
    7763             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7764          36 :         MessageTemplate::kProxyGetOwnPropertyDescriptorInvalid, name));
    7765             :     return Nothing<bool>();
    7766             :   }
    7767             :   // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
    7768             :   PropertyDescriptor target_desc;
    7769             :   Maybe<bool> found =
    7770        4761 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    7771        4761 :   MAYBE_RETURN(found, Nothing<bool>());
    7772             :   // 11. If trapResultObj is undefined, then
    7773        4761 :   if (trap_result_obj->IsUndefined(isolate)) {
    7774             :     // 11a. If targetDesc is undefined, return undefined.
    7775         792 :     if (!found.FromJust()) return Just(false);
    7776             :     // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError
    7777             :     //      exception.
    7778          45 :     if (!target_desc.configurable()) {
    7779             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7780          54 :           MessageTemplate::kProxyGetOwnPropertyDescriptorUndefined, name));
    7781             :       return Nothing<bool>();
    7782             :     }
    7783             :     // 11c. Let extensibleTarget be ? IsExtensible(target).
    7784          18 :     Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    7785          18 :     MAYBE_RETURN(extensible_target, Nothing<bool>());
    7786             :     // 11d. (Assert)
    7787             :     // 11e. If extensibleTarget is false, throw a TypeError exception.
    7788          18 :     if (!extensible_target.FromJust()) {
    7789             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7790           0 :           MessageTemplate::kProxyGetOwnPropertyDescriptorNonExtensible, name));
    7791             :       return Nothing<bool>();
    7792             :     }
    7793             :     // 11f. Return undefined.
    7794             :     return Just(false);
    7795             :   }
    7796             :   // 12. Let extensibleTarget be ? IsExtensible(target).
    7797        3969 :   Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    7798        3969 :   MAYBE_RETURN(extensible_target, Nothing<bool>());
    7799             :   // 13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj).
    7800        3969 :   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj,
    7801        3969 :                                                 desc)) {
    7802             :     DCHECK(isolate->has_pending_exception());
    7803             :     return Nothing<bool>();
    7804             :   }
    7805             :   // 14. Call CompletePropertyDescriptor(resultDesc).
    7806        3897 :   PropertyDescriptor::CompletePropertyDescriptor(isolate, desc);
    7807             :   // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget,
    7808             :   //     resultDesc, targetDesc).
    7809             :   Maybe<bool> valid =
    7810             :       IsCompatiblePropertyDescriptor(isolate, extensible_target.FromJust(),
    7811             :                                      desc, &target_desc, name, DONT_THROW);
    7812        3897 :   MAYBE_RETURN(valid, Nothing<bool>());
    7813             :   // 16. If valid is false, throw a TypeError exception.
    7814        3897 :   if (!valid.FromJust()) {
    7815             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7816          36 :         MessageTemplate::kProxyGetOwnPropertyDescriptorIncompatible, name));
    7817             :     return Nothing<bool>();
    7818             :   }
    7819             :   // 17. If resultDesc.[[Configurable]] is false, then
    7820        3879 :   if (!desc->configurable()) {
    7821             :     // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true:
    7822         477 :     if (target_desc.is_empty() || target_desc.configurable()) {
    7823             :       // 17a i. Throw a TypeError exception.
    7824             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7825             :           MessageTemplate::kProxyGetOwnPropertyDescriptorNonConfigurable,
    7826          36 :           name));
    7827             :       return Nothing<bool>();
    7828             :     }
    7829             :   }
    7830             :   // 18. Return resultDesc.
    7831             :   return Just(true);
    7832             : }
    7833             : 
    7834             : 
    7835           0 : bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
    7836             :                                             ElementsKind kind,
    7837             :                                             Object* object) {
    7838             :   Isolate* isolate = elements->GetIsolate();
    7839           0 :   if (IsObjectElementsKind(kind) || kind == FAST_STRING_WRAPPER_ELEMENTS) {
    7840             :     int length = IsJSArray() ? Smi::ToInt(JSArray::cast(this)->length())
    7841           0 :                              : elements->length();
    7842           0 :     for (int i = 0; i < length; ++i) {
    7843             :       Object* element = elements->get(i);
    7844           0 :       if (!element->IsTheHole(isolate) && element == object) return true;
    7845             :     }
    7846             :   } else {
    7847             :     DCHECK(kind == DICTIONARY_ELEMENTS || kind == SLOW_STRING_WRAPPER_ELEMENTS);
    7848             :     Object* key =
    7849           0 :         SeededNumberDictionary::cast(elements)->SlowReverseLookup(object);
    7850           0 :     if (!key->IsUndefined(isolate)) return true;
    7851             :   }
    7852             :   return false;
    7853             : }
    7854             : 
    7855             : 
    7856             : // Check whether this object references another object.
    7857           0 : bool JSObject::ReferencesObject(Object* obj) {
    7858             :   Map* map_of_this = map();
    7859             :   Heap* heap = GetHeap();
    7860             :   DisallowHeapAllocation no_allocation;
    7861             : 
    7862             :   // Is the object the constructor for this object?
    7863           0 :   if (map_of_this->GetConstructor() == obj) {
    7864             :     return true;
    7865             :   }
    7866             : 
    7867             :   // Is the object the prototype for this object?
    7868           0 :   if (map_of_this->prototype() == obj) {
    7869             :     return true;
    7870             :   }
    7871             : 
    7872             :   // Check if the object is among the named properties.
    7873           0 :   Object* key = SlowReverseLookup(obj);
    7874           0 :   if (!key->IsUndefined(heap->isolate())) {
    7875             :     return true;
    7876             :   }
    7877             : 
    7878             :   // Check if the object is among the indexed properties.
    7879             :   ElementsKind kind = GetElementsKind();
    7880           0 :   switch (kind) {
    7881             :     // Raw pixels and external arrays do not reference other
    7882             :     // objects.
    7883             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
    7884             :     case TYPE##_ELEMENTS:                                                      \
    7885             :       break;
    7886             : 
    7887             :     TYPED_ARRAYS(TYPED_ARRAY_CASE)
    7888             : #undef TYPED_ARRAY_CASE
    7889             : 
    7890             :     case PACKED_DOUBLE_ELEMENTS:
    7891             :     case HOLEY_DOUBLE_ELEMENTS:
    7892             :       break;
    7893             :     case PACKED_SMI_ELEMENTS:
    7894             :     case HOLEY_SMI_ELEMENTS:
    7895             :       break;
    7896             :     case PACKED_ELEMENTS:
    7897             :     case HOLEY_ELEMENTS:
    7898             :     case DICTIONARY_ELEMENTS:
    7899             :     case FAST_STRING_WRAPPER_ELEMENTS:
    7900             :     case SLOW_STRING_WRAPPER_ELEMENTS: {
    7901             :       FixedArray* elements = FixedArray::cast(this->elements());
    7902           0 :       if (ReferencesObjectFromElements(elements, kind, obj)) return true;
    7903             :       break;
    7904             :     }
    7905             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    7906             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
    7907             :       SloppyArgumentsElements* elements =
    7908             :           SloppyArgumentsElements::cast(this->elements());
    7909             :       // Check the mapped parameters.
    7910           0 :       for (uint32_t i = 0; i < elements->parameter_map_length(); ++i) {
    7911             :         Object* value = elements->get_mapped_entry(i);
    7912           0 :         if (!value->IsTheHole(heap->isolate()) && value == obj) return true;
    7913             :       }
    7914             :       // Check the arguments.
    7915             :       FixedArray* arguments = elements->arguments();
    7916           0 :       kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : HOLEY_ELEMENTS;
    7917           0 :       if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
    7918             :       break;
    7919             :     }
    7920             :     case NO_ELEMENTS:
    7921             :       break;
    7922             :   }
    7923             : 
    7924             :   // For functions check the context.
    7925           0 :   if (IsJSFunction()) {
    7926             :     // Get the constructor function for arguments array.
    7927             :     Map* arguments_map =
    7928           0 :         heap->isolate()->context()->native_context()->sloppy_arguments_map();
    7929             :     JSFunction* arguments_function =
    7930           0 :         JSFunction::cast(arguments_map->GetConstructor());
    7931             : 
    7932             :     // Get the context and don't check if it is the native context.
    7933             :     JSFunction* f = JSFunction::cast(this);
    7934             :     Context* context = f->context();
    7935           0 :     if (context->IsNativeContext()) {
    7936             :       return false;
    7937             :     }
    7938             : 
    7939             :     // Check the non-special context slots.
    7940           0 :     for (int i = Context::MIN_CONTEXT_SLOTS; i < context->length(); i++) {
    7941             :       // Only check JS objects.
    7942           0 :       if (context->get(i)->IsJSObject()) {
    7943             :         JSObject* ctxobj = JSObject::cast(context->get(i));
    7944             :         // If it is an arguments array check the content.
    7945           0 :         if (ctxobj->map()->GetConstructor() == arguments_function) {
    7946           0 :           if (ctxobj->ReferencesObject(obj)) {
    7947             :             return true;
    7948             :           }
    7949           0 :         } else if (ctxobj == obj) {
    7950             :           return true;
    7951             :         }
    7952             :       }
    7953             :     }
    7954             : 
    7955             :     // Check the context extension (if any) if it can have references.
    7956           0 :     if (context->has_extension() && !context->IsCatchContext() &&
    7957           0 :         !context->IsModuleContext()) {
    7958             :       // With harmony scoping, a JSFunction may have a script context.
    7959             :       // TODO(mvstanton): walk into the ScopeInfo.
    7960           0 :       if (context->IsScriptContext()) {
    7961             :         return false;
    7962             :       }
    7963             : 
    7964           0 :       return context->extension_object()->ReferencesObject(obj);
    7965             :     }
    7966             :   }
    7967             : 
    7968             :   // No references to object.
    7969             :   return false;
    7970             : }
    7971             : 
    7972             : 
    7973      260371 : Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver,
    7974             :                                           IntegrityLevel level,
    7975             :                                           ShouldThrow should_throw) {
    7976             :   DCHECK(level == SEALED || level == FROZEN);
    7977             : 
    7978      260371 :   if (receiver->IsJSObject()) {
    7979             :     Handle<JSObject> object = Handle<JSObject>::cast(receiver);
    7980             : 
    7981      259957 :     if (!object->HasSloppyArgumentsElements()) {  // Fast path.
    7982             :       // prevent memory leaks by not adding unnecessary transitions
    7983      259905 :       Maybe<bool> test = JSObject::TestIntegrityLevel(object, level);
    7984      259905 :       MAYBE_RETURN(test, Nothing<bool>());
    7985      259905 :       if (test.FromJust()) return test;
    7986             : 
    7987      256764 :       if (level == SEALED) {
    7988             :         return JSObject::PreventExtensionsWithTransition<SEALED>(object,
    7989         477 :                                                                  should_throw);
    7990             :       } else {
    7991             :         return JSObject::PreventExtensionsWithTransition<FROZEN>(object,
    7992      256287 :                                                                  should_throw);
    7993             :       }
    7994             :     }
    7995             :   }
    7996             : 
    7997             :   Isolate* isolate = receiver->GetIsolate();
    7998             : 
    7999         466 :   MAYBE_RETURN(JSReceiver::PreventExtensions(receiver, should_throw),
    8000             :                Nothing<bool>());
    8001             : 
    8002             :   Handle<FixedArray> keys;
    8003         466 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8004             :       isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
    8005             : 
    8006             :   PropertyDescriptor no_conf;
    8007             :   no_conf.set_configurable(false);
    8008             : 
    8009             :   PropertyDescriptor no_conf_no_write;
    8010             :   no_conf_no_write.set_configurable(false);
    8011             :   no_conf_no_write.set_writable(false);
    8012             : 
    8013         466 :   if (level == SEALED) {
    8014         294 :     for (int i = 0; i < keys->length(); ++i) {
    8015             :       Handle<Object> key(keys->get(i), isolate);
    8016          96 :       MAYBE_RETURN(
    8017             :           DefineOwnProperty(isolate, receiver, key, &no_conf, THROW_ON_ERROR),
    8018             :           Nothing<bool>());
    8019             :     }
    8020             :     return Just(true);
    8021             :   }
    8022             : 
    8023        2908 :   for (int i = 0; i < keys->length(); ++i) {
    8024             :     Handle<Object> key(keys->get(i), isolate);
    8025             :     PropertyDescriptor current_desc;
    8026             :     Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
    8027        1272 :         isolate, receiver, key, &current_desc);
    8028        1272 :     MAYBE_RETURN(owned, Nothing<bool>());
    8029        1272 :     if (owned.FromJust()) {
    8030             :       PropertyDescriptor desc =
    8031             :           PropertyDescriptor::IsAccessorDescriptor(&current_desc)
    8032             :               ? no_conf
    8033        1272 :               : no_conf_no_write;
    8034        1272 :       MAYBE_RETURN(
    8035             :           DefineOwnProperty(isolate, receiver, key, &desc, THROW_ON_ERROR),
    8036             :           Nothing<bool>());
    8037             :     }
    8038             :   }
    8039             :   return Just(true);
    8040             : }
    8041             : 
    8042             : namespace {
    8043             : 
    8044             : template <typename Dictionary>
    8045        4375 : bool TestDictionaryPropertiesIntegrityLevel(Dictionary* dict, Isolate* isolate,
    8046             :                                             PropertyAttributes level) {
    8047             :   DCHECK(level == SEALED || level == FROZEN);
    8048             : 
    8049        4375 :   uint32_t capacity = dict->Capacity();
    8050       13883 :   for (uint32_t i = 0; i < capacity; i++) {
    8051             :     Object* key;
    8052       16803 :     if (!dict->ToKey(isolate, i, &key)) continue;
    8053        2689 :     if (key->FilterKey(ALL_PROPERTIES)) continue;
    8054             :     PropertyDetails details = dict->DetailsAt(i);
    8055        2900 :     if (details.IsConfigurable()) return false;
    8056        5574 :     if (level == FROZEN && details.kind() == kData && !details.IsReadOnly()) {
    8057             :       return false;
    8058             :     }
    8059             :   }
    8060             :   return true;
    8061             : }
    8062             : 
    8063        3991 : bool TestFastPropertiesIntegrityLevel(Map* map, PropertyAttributes level) {
    8064             :   DCHECK(level == SEALED || level == FROZEN);
    8065             :   DCHECK_LT(LAST_CUSTOM_ELEMENTS_RECEIVER, map->instance_type());
    8066             :   DCHECK(!map->is_dictionary_map());
    8067             : 
    8068             :   DescriptorArray* descriptors = map->instance_descriptors();
    8069             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    8070        5745 :   for (int i = 0; i < number_of_own_descriptors; i++) {
    8071        1911 :     if (descriptors->GetKey(i)->IsPrivate()) continue;
    8072        1893 :     PropertyDetails details = descriptors->GetDetails(i);
    8073        1893 :     if (details.IsConfigurable()) return false;
    8074        4092 :     if (level == FROZEN && details.kind() == kData && !details.IsReadOnly()) {
    8075             :       return false;
    8076             :     }
    8077             :   }
    8078             :   return true;
    8079             : }
    8080             : 
    8081        4085 : bool TestPropertiesIntegrityLevel(JSObject* object, PropertyAttributes level) {
    8082             :   DCHECK_LT(LAST_CUSTOM_ELEMENTS_RECEIVER, object->map()->instance_type());
    8083             : 
    8084        4085 :   if (object->HasFastProperties()) {
    8085        3991 :     return TestFastPropertiesIntegrityLevel(object->map(), level);
    8086             :   }
    8087             : 
    8088             :   return TestDictionaryPropertiesIntegrityLevel(object->property_dictionary(),
    8089          94 :                                                 object->GetIsolate(), level);
    8090             : }
    8091             : 
    8092        4281 : bool TestElementsIntegrityLevel(JSObject* object, PropertyAttributes level) {
    8093             :   DCHECK(!object->HasSloppyArgumentsElements());
    8094             : 
    8095             :   ElementsKind kind = object->GetElementsKind();
    8096             : 
    8097        4281 :   if (IsDictionaryElementsKind(kind)) {
    8098             :     return TestDictionaryPropertiesIntegrityLevel(
    8099             :         SeededNumberDictionary::cast(object->elements()), object->GetIsolate(),
    8100        4281 :         level);
    8101             :   }
    8102             : 
    8103             :   ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
    8104             :   // Only DICTIONARY_ELEMENTS and SLOW_SLOPPY_ARGUMENTS_ELEMENTS have
    8105             :   // PropertyAttributes so just test if empty
    8106           0 :   return accessor->NumberOfElements(object) == 0;
    8107             : }
    8108             : 
    8109      270951 : bool FastTestIntegrityLevel(JSObject* object, PropertyAttributes level) {
    8110             :   DCHECK_LT(LAST_CUSTOM_ELEMENTS_RECEIVER, object->map()->instance_type());
    8111             : 
    8112        4281 :   return !object->map()->is_extensible() &&
    8113      275036 :          TestElementsIntegrityLevel(object, level) &&
    8114      275036 :          TestPropertiesIntegrityLevel(object, level);
    8115             : }
    8116             : 
    8117         246 : Maybe<bool> GenericTestIntegrityLevel(Handle<JSReceiver> receiver,
    8118             :                                       PropertyAttributes level) {
    8119             :   DCHECK(level == SEALED || level == FROZEN);
    8120             : 
    8121         246 :   Maybe<bool> extensible = JSReceiver::IsExtensible(receiver);
    8122         246 :   MAYBE_RETURN(extensible, Nothing<bool>());
    8123         246 :   if (extensible.FromJust()) return Just(false);
    8124             : 
    8125             :   Isolate* isolate = receiver->GetIsolate();
    8126             : 
    8127             :   Handle<FixedArray> keys;
    8128          98 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8129             :       isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
    8130             : 
    8131        4802 :   for (int i = 0; i < keys->length(); ++i) {
    8132             :     Handle<Object> key(keys->get(i), isolate);
    8133             :     PropertyDescriptor current_desc;
    8134             :     Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
    8135        2380 :         isolate, receiver, key, &current_desc);
    8136        2408 :     MAYBE_RETURN(owned, Nothing<bool>());
    8137        2380 :     if (owned.FromJust()) {
    8138        2380 :       if (current_desc.configurable()) return Just(false);
    8139        3568 :       if (level == FROZEN &&
    8140        3559 :           PropertyDescriptor::IsDataDescriptor(&current_desc) &&
    8141             :           current_desc.writable()) {
    8142             :         return Just(false);
    8143             :       }
    8144             :     }
    8145             :   }
    8146             :   return Just(true);
    8147             : }
    8148             : 
    8149             : }  // namespace
    8150             : 
    8151       11292 : Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> receiver,
    8152             :                                            IntegrityLevel level) {
    8153       11292 :   if (receiver->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER) {
    8154             :     return JSObject::TestIntegrityLevel(Handle<JSObject>::cast(receiver),
    8155       11178 :                                         level);
    8156             :   }
    8157         114 :   return GenericTestIntegrityLevel(receiver, level);
    8158             : }
    8159             : 
    8160      271083 : Maybe<bool> JSObject::TestIntegrityLevel(Handle<JSObject> object,
    8161             :                                          IntegrityLevel level) {
    8162      542066 :   if (object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER &&
    8163      270983 :       !object->HasSloppyArgumentsElements()) {
    8164      270951 :     return Just(FastTestIntegrityLevel(*object, level));
    8165             :   }
    8166         132 :   return GenericTestIntegrityLevel(Handle<JSReceiver>::cast(object), level);
    8167             : }
    8168             : 
    8169        4637 : Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object,
    8170             :                                           ShouldThrow should_throw) {
    8171        4637 :   if (object->IsJSProxy()) {
    8172             :     return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object),
    8173         612 :                                       should_throw);
    8174             :   }
    8175             :   DCHECK(object->IsJSObject());
    8176             :   return JSObject::PreventExtensions(Handle<JSObject>::cast(object),
    8177        4025 :                                      should_throw);
    8178             : }
    8179             : 
    8180             : 
    8181         612 : Maybe<bool> JSProxy::PreventExtensions(Handle<JSProxy> proxy,
    8182             :                                        ShouldThrow should_throw) {
    8183             :   Isolate* isolate = proxy->GetIsolate();
    8184         612 :   STACK_CHECK(isolate, Nothing<bool>());
    8185             :   Factory* factory = isolate->factory();
    8186             :   Handle<String> trap_name = factory->preventExtensions_string();
    8187             : 
    8188         612 :   if (proxy->IsRevoked()) {
    8189             :     isolate->Throw(
    8190          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    8191             :     return Nothing<bool>();
    8192             :   }
    8193             :   Handle<JSReceiver> target(proxy->target(), isolate);
    8194             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    8195             : 
    8196             :   Handle<Object> trap;
    8197        1188 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8198             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    8199         576 :   if (trap->IsUndefined(isolate)) {
    8200         522 :     return JSReceiver::PreventExtensions(target, should_throw);
    8201             :   }
    8202             : 
    8203             :   Handle<Object> trap_result;
    8204             :   Handle<Object> args[] = {target};
    8205         108 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8206             :       isolate, trap_result,
    8207             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    8208             :       Nothing<bool>());
    8209          54 :   if (!trap_result->BooleanValue()) {
    8210          18 :     RETURN_FAILURE(
    8211             :         isolate, should_throw,
    8212             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
    8213             :   }
    8214             : 
    8215             :   // Enforce the invariant.
    8216          36 :   Maybe<bool> target_result = JSReceiver::IsExtensible(target);
    8217          36 :   MAYBE_RETURN(target_result, Nothing<bool>());
    8218          36 :   if (target_result.FromJust()) {
    8219             :     isolate->Throw(*factory->NewTypeError(
    8220          18 :         MessageTemplate::kProxyPreventExtensionsExtensible));
    8221             :     return Nothing<bool>();
    8222             :   }
    8223             :   return Just(true);
    8224             : }
    8225             : 
    8226             : 
    8227        4328 : Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
    8228             :                                         ShouldThrow should_throw) {
    8229           0 :   Isolate* isolate = object->GetIsolate();
    8230             : 
    8231        4328 :   if (!object->HasSloppyArgumentsElements()) {
    8232        4266 :     return PreventExtensionsWithTransition<NONE>(object, should_throw);
    8233             :   }
    8234             : 
    8235          62 :   if (object->IsAccessCheckNeeded() &&
    8236           0 :       !isolate->MayAccess(handle(isolate->context()), object)) {
    8237           0 :     isolate->ReportFailedAccessCheck(object);
    8238           0 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    8239           0 :     RETURN_FAILURE(isolate, should_throw,
    8240             :                    NewTypeError(MessageTemplate::kNoAccess));
    8241             :   }
    8242             : 
    8243          62 :   if (!object->map()->is_extensible()) return Just(true);
    8244             : 
    8245          62 :   if (object->IsJSGlobalProxy()) {
    8246           0 :     PrototypeIterator iter(isolate, object);
    8247           0 :     if (iter.IsAtEnd()) return Just(true);
    8248             :     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
    8249             :     return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter),
    8250           0 :                              should_throw);
    8251             :   }
    8252             : 
    8253         124 :   if (object->map()->has_named_interceptor() ||
    8254             :       object->map()->has_indexed_interceptor()) {
    8255           0 :     RETURN_FAILURE(isolate, should_throw,
    8256             :                    NewTypeError(MessageTemplate::kCannotPreventExt));
    8257             :   }
    8258             : 
    8259          62 :   if (!object->HasFixedTypedArrayElements()) {
    8260             :     // If there are fast elements we normalize.
    8261          62 :     Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
    8262             :     DCHECK(object->HasDictionaryElements() ||
    8263             :            object->HasSlowArgumentsElements());
    8264             : 
    8265             :     // Make sure that we never go back to fast case.
    8266          62 :     object->RequireSlowElements(*dictionary);
    8267             :   }
    8268             : 
    8269             :   // Do a map transition, other objects with this map may still
    8270             :   // be extensible.
    8271             :   // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
    8272          62 :   Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions");
    8273             : 
    8274             :   new_map->set_is_extensible(false);
    8275          62 :   JSObject::MigrateToMap(object, new_map);
    8276             :   DCHECK(!object->map()->is_extensible());
    8277             : 
    8278             :   return Just(true);
    8279             : }
    8280             : 
    8281             : 
    8282     1032836 : Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) {
    8283     1032836 :   if (object->IsJSProxy()) {
    8284         585 :     return JSProxy::IsExtensible(Handle<JSProxy>::cast(object));
    8285             :   }
    8286     1032251 :   return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object)));
    8287             : }
    8288             : 
    8289             : 
    8290         585 : Maybe<bool> JSProxy::IsExtensible(Handle<JSProxy> proxy) {
    8291             :   Isolate* isolate = proxy->GetIsolate();
    8292         585 :   STACK_CHECK(isolate, Nothing<bool>());
    8293             :   Factory* factory = isolate->factory();
    8294             :   Handle<String> trap_name = factory->isExtensible_string();
    8295             : 
    8296         585 :   if (proxy->IsRevoked()) {
    8297             :     isolate->Throw(
    8298          36 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    8299             :     return Nothing<bool>();
    8300             :   }
    8301             :   Handle<JSReceiver> target(proxy->target(), isolate);
    8302             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    8303             : 
    8304             :   Handle<Object> trap;
    8305        1134 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8306             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    8307         549 :   if (trap->IsUndefined(isolate)) {
    8308         126 :     return JSReceiver::IsExtensible(target);
    8309             :   }
    8310             : 
    8311             :   Handle<Object> trap_result;
    8312             :   Handle<Object> args[] = {target};
    8313         846 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8314             :       isolate, trap_result,
    8315             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    8316             :       Nothing<bool>());
    8317             : 
    8318             :   // Enforce the invariant.
    8319         423 :   Maybe<bool> target_result = JSReceiver::IsExtensible(target);
    8320         423 :   MAYBE_RETURN(target_result, Nothing<bool>());
    8321         423 :   if (target_result.FromJust() != trap_result->BooleanValue()) {
    8322             :     isolate->Throw(
    8323             :         *factory->NewTypeError(MessageTemplate::kProxyIsExtensibleInconsistent,
    8324          54 :                                factory->ToBoolean(target_result.FromJust())));
    8325             :     return Nothing<bool>();
    8326             :   }
    8327         396 :   return target_result;
    8328             : }
    8329             : 
    8330             : 
    8331     2852264 : bool JSObject::IsExtensible(Handle<JSObject> object) {
    8332          40 :   Isolate* isolate = object->GetIsolate();
    8333     2852304 :   if (object->IsAccessCheckNeeded() &&
    8334          40 :       !isolate->MayAccess(handle(isolate->context()), object)) {
    8335             :     return true;
    8336             :   }
    8337     2852234 :   if (object->IsJSGlobalProxy()) {
    8338             :     PrototypeIterator iter(isolate, *object);
    8339        2817 :     if (iter.IsAtEnd()) return false;
    8340             :     DCHECK(iter.GetCurrent()->IsJSGlobalObject());
    8341        5634 :     return iter.GetCurrent<JSObject>()->map()->is_extensible();
    8342             :   }
    8343     2849417 :   return object->map()->is_extensible();
    8344             : }
    8345             : 
    8346             : namespace {
    8347             : 
    8348             : template <typename Dictionary>
    8349        4035 : void ApplyAttributesToDictionary(Isolate* isolate,
    8350             :                                  Handle<Dictionary> dictionary,
    8351             :                                  const PropertyAttributes attributes) {
    8352             :   int capacity = dictionary->Capacity();
    8353       47491 :   for (int i = 0; i < capacity; i++) {
    8354             :     Object* k;
    8355       68556 :     if (!dictionary->ToKey(isolate, i, &k)) continue;
    8356       18374 :     if (k->FilterKey(ALL_PROPERTIES)) continue;
    8357             :     PropertyDetails details = dictionary->DetailsAt(i);
    8358       18356 :     int attrs = attributes;
    8359             :     // READ_ONLY is an invalid attribute for JS setters/getters.
    8360       34702 :     if ((attributes & READ_ONLY) && details.kind() == kAccessor) {
    8361          29 :       Object* v = dictionary->ValueAt(i);
    8362          39 :       if (v->IsAccessorPair()) attrs &= ~READ_ONLY;
    8363             :     }
    8364             :     details = details.CopyAddAttributes(static_cast<PropertyAttributes>(attrs));
    8365             :     dictionary->DetailsAtPut(i, details);
    8366             :   }
    8367        4035 : }
    8368             : 
    8369             : }  // namespace
    8370             : 
    8371             : template <PropertyAttributes attrs>
    8372      261128 : Maybe<bool> JSObject::PreventExtensionsWithTransition(
    8373             :     Handle<JSObject> object, ShouldThrow should_throw) {
    8374             :   STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN);
    8375             : 
    8376             :   // Sealing/freezing sloppy arguments should be handled elsewhere.
    8377             :   DCHECK(!object->HasSloppyArgumentsElements());
    8378             : 
    8379          25 :   Isolate* isolate = object->GetIsolate();
    8380      261153 :   if (object->IsAccessCheckNeeded() &&
    8381          25 :       !isolate->MayAccess(handle(isolate->context()), object)) {
    8382          20 :     isolate->ReportFailedAccessCheck(object);
    8383          20 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    8384           0 :     RETURN_FAILURE(isolate, should_throw,
    8385             :                    NewTypeError(MessageTemplate::kNoAccess));
    8386             :   }
    8387             : 
    8388        4265 :   if (attrs == NONE && !object->map()->is_extensible()) return Just(true);
    8389             : 
    8390      261098 :   if (object->IsJSGlobalProxy()) {
    8391          98 :     PrototypeIterator iter(isolate, object);
    8392          98 :     if (iter.IsAtEnd()) return Just(true);
    8393             :     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
    8394             :     return PreventExtensionsWithTransition<attrs>(
    8395          98 :         PrototypeIterator::GetCurrent<JSObject>(iter), should_throw);
    8396             :   }
    8397             : 
    8398      521999 :   if (object->map()->has_named_interceptor() ||
    8399             :       object->map()->has_indexed_interceptor()) {
    8400             :     MessageTemplate::Template message = MessageTemplate::kNone;
    8401             :     switch (attrs) {
    8402             :       case NONE:
    8403             :         message = MessageTemplate::kCannotPreventExt;
    8404             :         break;
    8405             : 
    8406             :       case SEALED:
    8407             :         message = MessageTemplate::kCannotSeal;
    8408             :         break;
    8409             : 
    8410             :       case FROZEN:
    8411             :         message = MessageTemplate::kCannotFreeze;
    8412             :         break;
    8413             :     }
    8414           3 :     RETURN_FAILURE(isolate, should_throw, NewTypeError(message));
    8415             :   }
    8416             : 
    8417             :   Handle<SeededNumberDictionary> new_element_dictionary;
    8418      782695 :   if (!object->HasFixedTypedArrayElements() &&
    8419      260940 :       !object->HasDictionaryElements() &&
    8420      260756 :       !object->HasSlowStringWrapperElements()) {
    8421             :     int length = object->IsJSArray()
    8422             :                      ? Smi::ToInt(Handle<JSArray>::cast(object)->length())
    8423      260756 :                      : object->elements()->length();
    8424      264941 :     new_element_dictionary =
    8425             :         length == 0 ? isolate->factory()->empty_slow_element_dictionary()
    8426        4185 :                     : object->GetElementsAccessor()->Normalize(object);
    8427             :   }
    8428             : 
    8429             :   Handle<Symbol> transition_marker;
    8430             :   if (attrs == NONE) {
    8431             :     transition_marker = isolate->factory()->nonextensible_symbol();
    8432             :   } else if (attrs == SEALED) {
    8433             :     transition_marker = isolate->factory()->sealed_symbol();
    8434             :   } else {
    8435             :     DCHECK(attrs == FROZEN);
    8436             :     transition_marker = isolate->factory()->frozen_symbol();
    8437             :   }
    8438             : 
    8439             :   Handle<Map> old_map(object->map(), isolate);
    8440             :   TransitionsAccessor transitions(old_map);
    8441      260999 :   Map* transition = transitions.SearchSpecial(*transition_marker);
    8442      260999 :   if (transition != nullptr) {
    8443             :     Handle<Map> transition_map(transition, isolate);
    8444             :     DCHECK(transition_map->has_dictionary_elements() ||
    8445             :            transition_map->has_fixed_typed_array_elements() ||
    8446             :            transition_map->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
    8447             :     DCHECK(!transition_map->is_extensible());
    8448      106794 :     JSObject::MigrateToMap(object, transition_map);
    8449      154205 :   } else if (transitions.CanHaveMoreTransitions()) {
    8450             :     // Create a new descriptor array with the appropriate property attributes
    8451             :     Handle<Map> new_map = Map::CopyForPreventExtensions(
    8452      153533 :         old_map, attrs, transition_marker, "CopyForPreventExtensions");
    8453      153533 :     JSObject::MigrateToMap(object, new_map);
    8454             :   } else {
    8455             :     DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map());
    8456             :     // Slow path: need to normalize properties for safety
    8457         672 :     NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0,
    8458             :                         "SlowPreventExtensions");
    8459             : 
    8460             :     // Create a new map, since other objects with this map may be extensible.
    8461             :     // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
    8462             :     Handle<Map> new_map =
    8463         672 :         Map::Copy(handle(object->map()), "SlowCopyForPreventExtensions");
    8464             :     new_map->set_is_extensible(false);
    8465         672 :     if (!new_element_dictionary.is_null()) {
    8466             :       ElementsKind new_kind =
    8467             :           IsStringWrapperElementsKind(old_map->elements_kind())
    8468             :               ? SLOW_STRING_WRAPPER_ELEMENTS
    8469         672 :               : DICTIONARY_ELEMENTS;
    8470             :       new_map->set_elements_kind(new_kind);
    8471             :     }
    8472         672 :     JSObject::MigrateToMap(object, new_map);
    8473             : 
    8474             :     if (attrs != NONE) {
    8475         170 :       if (object->IsJSGlobalObject()) {
    8476             :         Handle<GlobalDictionary> dictionary(
    8477             :             JSGlobalObject::cast(*object)->global_dictionary(), isolate);
    8478          89 :         ApplyAttributesToDictionary(isolate, dictionary, attrs);
    8479             :       } else {
    8480             :         Handle<NameDictionary> dictionary(object->property_dictionary(),
    8481             :                                           isolate);
    8482          81 :         ApplyAttributesToDictionary(isolate, dictionary, attrs);
    8483             :       }
    8484             :     }
    8485             :   }
    8486             : 
    8487             :   // Both seal and preventExtensions always go through without modifications to
    8488             :   // typed array elements. Freeze works only if there are no actual elements.
    8489      260999 :   if (object->HasFixedTypedArrayElements()) {
    8490          39 :     if (attrs == FROZEN &&
    8491             :         JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) {
    8492          29 :       isolate->Throw(*isolate->factory()->NewTypeError(
    8493          58 :           MessageTemplate::kCannotFreezeArrayBufferView));
    8494             :       return Nothing<bool>();
    8495             :     }
    8496             :     return Just(true);
    8497             :   }
    8498             : 
    8499             :   DCHECK(object->map()->has_dictionary_elements() ||
    8500             :          object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
    8501      260940 :   if (!new_element_dictionary.is_null()) {
    8502      260756 :     object->set_elements(*new_element_dictionary);
    8503             :   }
    8504             : 
    8505      260940 :   if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
    8506             :     Handle<SeededNumberDictionary> dictionary(object->element_dictionary(),
    8507             :                                               isolate);
    8508             :     // Make sure we never go back to the fast case
    8509        4351 :     object->RequireSlowElements(*dictionary);
    8510             :     if (attrs != NONE) {
    8511        3865 :       ApplyAttributesToDictionary(isolate, dictionary, attrs);
    8512             :     }
    8513             :   }
    8514             : 
    8515             :   return Just(true);
    8516             : }
    8517             : 
    8518             : 
    8519    35106458 : Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
    8520             :                                         Representation representation,
    8521             :                                         FieldIndex index) {
    8522             :   Isolate* isolate = object->GetIsolate();
    8523    35106458 :   if (object->IsUnboxedDoubleField(index)) {
    8524             :     double value = object->RawFastDoublePropertyAt(index);
    8525       33752 :     return isolate->factory()->NewHeapNumber(value);
    8526             :   }
    8527    35072708 :   Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
    8528    35072708 :   return Object::WrapForRead(isolate, raw_value, representation);
    8529             : }
    8530             : 
    8531             : // static
    8532     6785896 : MaybeHandle<Object> JSReceiver::ToPrimitive(Handle<JSReceiver> receiver,
    8533             :                                             ToPrimitiveHint hint) {
    8534             :   Isolate* const isolate = receiver->GetIsolate();
    8535             :   Handle<Object> exotic_to_prim;
    8536    13571792 :   ASSIGN_RETURN_ON_EXCEPTION(
    8537             :       isolate, exotic_to_prim,
    8538             :       GetMethod(receiver, isolate->factory()->to_primitive_symbol()), Object);
    8539     6785891 :   if (!exotic_to_prim->IsUndefined(isolate)) {
    8540             :     Handle<Object> hint_string =
    8541        3823 :         isolate->factory()->ToPrimitiveHintString(hint);
    8542             :     Handle<Object> result;
    8543        7646 :     ASSIGN_RETURN_ON_EXCEPTION(
    8544             :         isolate, result,
    8545             :         Execution::Call(isolate, exotic_to_prim, receiver, 1, &hint_string),
    8546             :         Object);
    8547        3692 :     if (result->IsPrimitive()) return result;
    8548           0 :     THROW_NEW_ERROR(isolate,
    8549             :                     NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
    8550             :                     Object);
    8551             :   }
    8552             :   return OrdinaryToPrimitive(receiver, (hint == ToPrimitiveHint::kString)
    8553             :                                            ? OrdinaryToPrimitiveHint::kString
    8554     6782068 :                                            : OrdinaryToPrimitiveHint::kNumber);
    8555             : }
    8556             : 
    8557             : 
    8558             : // static
    8559     6782068 : MaybeHandle<Object> JSReceiver::OrdinaryToPrimitive(
    8560             :     Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint) {
    8561             :   Isolate* const isolate = receiver->GetIsolate();
    8562    20346204 :   Handle<String> method_names[2];
    8563     6782068 :   switch (hint) {
    8564             :     case OrdinaryToPrimitiveHint::kNumber:
    8565        4499 :       method_names[0] = isolate->factory()->valueOf_string();
    8566        4499 :       method_names[1] = isolate->factory()->toString_string();
    8567        4499 :       break;
    8568             :     case OrdinaryToPrimitiveHint::kString:
    8569     6777569 :       method_names[0] = isolate->factory()->toString_string();
    8570     6777569 :       method_names[1] = isolate->factory()->valueOf_string();
    8571     6777569 :       break;
    8572             :   }
    8573     6785196 :   for (Handle<String> name : method_names) {
    8574             :     Handle<Object> method;
    8575    13567130 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, method,
    8576             :                                JSReceiver::GetProperty(receiver, name), Object);
    8577     6783547 :     if (method->IsCallable()) {
    8578             :       Handle<Object> result;
    8579    13566104 :       ASSIGN_RETURN_ON_EXCEPTION(
    8580             :           isolate, result,
    8581             :           Execution::Call(isolate, method, receiver, 0, nullptr), Object);
    8582     6769323 :       if (result->IsPrimitive()) return result;
    8583             :     }
    8584             :   }
    8585         268 :   THROW_NEW_ERROR(isolate,
    8586             :                   NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
    8587             :                   Object);
    8588             : }
    8589             : 
    8590             : 
    8591             : // TODO(cbruni/jkummerow): Consider moving this into elements.cc.
    8592      152253 : bool JSObject::HasEnumerableElements() {
    8593             :   // TODO(cbruni): cleanup
    8594             :   JSObject* object = this;
    8595      152253 :   switch (object->GetElementsKind()) {
    8596             :     case PACKED_SMI_ELEMENTS:
    8597             :     case PACKED_ELEMENTS:
    8598             :     case PACKED_DOUBLE_ELEMENTS: {
    8599             :       int length = object->IsJSArray()
    8600             :                        ? Smi::ToInt(JSArray::cast(object)->length())
    8601       62531 :                        : object->elements()->length();
    8602       62531 :       return length > 0;
    8603             :     }
    8604             :     case HOLEY_SMI_ELEMENTS:
    8605             :     case HOLEY_ELEMENTS: {
    8606             :       FixedArray* elements = FixedArray::cast(object->elements());
    8607             :       int length = object->IsJSArray()
    8608             :                        ? Smi::ToInt(JSArray::cast(object)->length())
    8609       89437 :                        : elements->length();
    8610             :       Isolate* isolate = GetIsolate();
    8611     2622242 :       for (int i = 0; i < length; i++) {
    8612     2558433 :         if (!elements->is_the_hole(isolate, i)) return true;
    8613             :       }
    8614             :       return false;
    8615             :     }
    8616             :     case HOLEY_DOUBLE_ELEMENTS: {
    8617             :       int length = object->IsJSArray()
    8618             :                        ? Smi::ToInt(JSArray::cast(object)->length())
    8619          50 :                        : object->elements()->length();
    8620             :       // Zero-length arrays would use the empty FixedArray...
    8621          50 :       if (length == 0) return false;
    8622             :       // ...so only cast to FixedDoubleArray otherwise.
    8623             :       FixedDoubleArray* elements = FixedDoubleArray::cast(object->elements());
    8624          50 :       for (int i = 0; i < length; i++) {
    8625          50 :         if (!elements->is_the_hole(i)) return true;
    8626             :       }
    8627             :       return false;
    8628             :     }
    8629             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
    8630             :     case TYPE##_ELEMENTS:
    8631             : 
    8632             :       TYPED_ARRAYS(TYPED_ARRAY_CASE)
    8633             : #undef TYPED_ARRAY_CASE
    8634             :       {
    8635             :         int length = object->elements()->length();
    8636           0 :         return length > 0;
    8637             :       }
    8638             :     case DICTIONARY_ELEMENTS: {
    8639             :       SeededNumberDictionary* elements =
    8640             :           SeededNumberDictionary::cast(object->elements());
    8641         175 :       return elements->NumberOfEnumerableProperties() > 0;
    8642             :     }
    8643             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    8644             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    8645             :       // We're approximating non-empty arguments objects here.
    8646             :       return true;
    8647             :     case FAST_STRING_WRAPPER_ELEMENTS:
    8648             :     case SLOW_STRING_WRAPPER_ELEMENTS:
    8649           0 :       if (String::cast(JSValue::cast(object)->value())->length() > 0) {
    8650             :         return true;
    8651             :       }
    8652           0 :       return object->elements()->length() > 0;
    8653             :     case NO_ELEMENTS:
    8654           0 :       return false;
    8655             :   }
    8656           0 :   UNREACHABLE();
    8657             : }
    8658             : 
    8659      228779 : int Map::NumberOfEnumerableProperties() const {
    8660             :   int result = 0;
    8661             :   DescriptorArray* descs = instance_descriptors();
    8662             :   int limit = NumberOfOwnDescriptors();
    8663     1211740 :   for (int i = 0; i < limit; i++) {
    8664     2801838 :     if ((descs->GetDetails(i).attributes() & ONLY_ENUMERABLE) == 0 &&
    8665      835916 :         !descs->GetKey(i)->FilterKey(ENUMERABLE_STRINGS)) {
    8666      834147 :       result++;
    8667             :     }
    8668             :   }
    8669      228779 :   return result;
    8670             : }
    8671             : 
    8672     6747542 : int Map::NextFreePropertyIndex() const {
    8673             :   int free_index = 0;
    8674             :   int number_of_own_descriptors = NumberOfOwnDescriptors();
    8675             :   DescriptorArray* descs = instance_descriptors();
    8676   211917722 :   for (int i = 0; i < number_of_own_descriptors; i++) {
    8677   205170176 :     PropertyDetails details = descs->GetDetails(i);
    8678   205170180 :     if (details.location() == kField) {
    8679   195403536 :       int candidate = details.field_index() + details.field_width_in_words();
    8680   195403536 :       if (candidate > free_index) free_index = candidate;
    8681             :     }
    8682             :   }
    8683     6747546 :   return free_index;
    8684             : }
    8685             : 
    8686      228832 : bool Map::OnlyHasSimpleProperties() const {
    8687             :   // Wrapped string elements aren't explicitly stored in the elements backing
    8688             :   // store, but are loaded indirectly from the underlying string.
    8689      225389 :   return !IsStringWrapperElementsKind(elements_kind()) &&
    8690      641848 :          !IsSpecialReceiverMap() && !has_hidden_prototype() &&
    8691      228832 :          !is_dictionary_map();
    8692             : }
    8693             : 
    8694        1054 : MUST_USE_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
    8695             :     Isolate* isolate, Handle<JSReceiver> receiver, bool get_entries,
    8696             :     Handle<FixedArray>* result) {
    8697             :   Handle<Map> map(JSReceiver::cast(*receiver)->map(), isolate);
    8698             : 
    8699        1054 :   if (!map->IsJSObjectMap()) return Just(false);
    8700         766 :   if (!map->OnlyHasSimpleProperties()) return Just(false);
    8701             : 
    8702             :   Handle<JSObject> object(JSObject::cast(*receiver));
    8703             : 
    8704             :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    8705             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    8706             :   int number_of_own_elements =
    8707        1172 :       object->GetElementsAccessor()->GetCapacity(*object, object->elements());
    8708             :   Handle<FixedArray> values_or_entries = isolate->factory()->NewFixedArray(
    8709         586 :       number_of_own_descriptors + number_of_own_elements);
    8710         586 :   int count = 0;
    8711             : 
    8712         586 :   if (object->elements() != isolate->heap()->empty_fixed_array()) {
    8713         496 :     MAYBE_RETURN(object->GetElementsAccessor()->CollectValuesOrEntries(
    8714             :                      isolate, object, values_or_entries, get_entries, &count,
    8715             :                      ENUMERABLE_STRINGS),
    8716             :                  Nothing<bool>());
    8717             :   }
    8718             : 
    8719         586 :   bool stable = object->map() == *map;
    8720             : 
    8721        1592 :   for (int index = 0; index < number_of_own_descriptors; index++) {
    8722             :     Handle<Name> next_key(descriptors->GetKey(index), isolate);
    8723        1006 :     if (!next_key->IsString()) continue;
    8724             :     Handle<Object> prop_value;
    8725             : 
    8726             :     // Directly decode from the descriptor array if |from| did not change shape.
    8727         916 :     if (stable) {
    8728         898 :       PropertyDetails details = descriptors->GetDetails(index);
    8729         898 :       if (!details.IsEnumerable()) continue;
    8730         664 :       if (details.kind() == kData) {
    8731         628 :         if (details.location() == kDescriptor) {
    8732             :           prop_value = handle(descriptors->GetValue(index), isolate);
    8733             :         } else {
    8734         628 :           Representation representation = details.representation();
    8735         628 :           FieldIndex field_index = FieldIndex::ForDescriptor(*map, index);
    8736             :           prop_value =
    8737         628 :               JSObject::FastPropertyAt(object, representation, field_index);
    8738             :         }
    8739             :       } else {
    8740          72 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8741             :             isolate, prop_value, JSReceiver::GetProperty(object, next_key),
    8742             :             Nothing<bool>());
    8743          36 :         stable = object->map() == *map;
    8744             :       }
    8745             :     } else {
    8746             :       // If the map did change, do a slower lookup. We are still guaranteed that
    8747             :       // the object has a simple shape, and that the key is a name.
    8748          18 :       LookupIterator it(object, next_key, LookupIterator::OWN_SKIP_INTERCEPTOR);
    8749          18 :       if (!it.IsFound()) continue;
    8750             :       DCHECK(it.state() == LookupIterator::DATA ||
    8751             :              it.state() == LookupIterator::ACCESSOR);
    8752          18 :       if (!it.IsEnumerable()) continue;
    8753          36 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8754             :           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
    8755             :     }
    8756             : 
    8757         682 :     if (get_entries) {
    8758         360 :       prop_value = MakeEntryPair(isolate, next_key, prop_value);
    8759             :     }
    8760             : 
    8761        1364 :     values_or_entries->set(count, *prop_value);
    8762         682 :     count++;
    8763             :   }
    8764             : 
    8765         586 :   if (count < values_or_entries->length()) values_or_entries->Shrink(count);
    8766         586 :   *result = values_or_entries;
    8767             :   return Just(true);
    8768             : }
    8769             : 
    8770        1054 : MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
    8771             :                                               Handle<JSReceiver> object,
    8772             :                                               PropertyFilter filter,
    8773             :                                               bool get_entries) {
    8774             :   Handle<FixedArray> values_or_entries;
    8775        1054 :   if (filter == ENUMERABLE_STRINGS) {
    8776             :     Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries(
    8777        1054 :         isolate, object, get_entries, &values_or_entries);
    8778        1054 :     if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>();
    8779        1054 :     if (fast_values_or_entries.FromJust()) return values_or_entries;
    8780             :   }
    8781             : 
    8782             :   PropertyFilter key_filter =
    8783         468 :       static_cast<PropertyFilter>(filter & ~ONLY_ENUMERABLE);
    8784             : 
    8785             :   Handle<FixedArray> keys;
    8786         936 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8787             :       isolate, keys,
    8788             :       KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, key_filter,
    8789             :                               GetKeysConversion::kConvertToString),
    8790             :       MaybeHandle<FixedArray>());
    8791             : 
    8792         468 :   values_or_entries = isolate->factory()->NewFixedArray(keys->length());
    8793             :   int length = 0;
    8794             : 
    8795        4092 :   for (int i = 0; i < keys->length(); ++i) {
    8796             :     Handle<Name> key = Handle<Name>::cast(handle(keys->get(i), isolate));
    8797             : 
    8798        1578 :     if (filter & ONLY_ENUMERABLE) {
    8799             :       PropertyDescriptor descriptor;
    8800             :       Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
    8801        1578 :           isolate, object, key, &descriptor);
    8802        1578 :       MAYBE_RETURN(did_get_descriptor, MaybeHandle<FixedArray>());
    8803        3108 :       if (!did_get_descriptor.FromJust() || !descriptor.enumerable()) continue;
    8804             :     }
    8805             : 
    8806             :     Handle<Object> value;
    8807        1944 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8808             :         isolate, value, JSReceiver::GetPropertyOrElement(object, key),
    8809             :         MaybeHandle<FixedArray>());
    8810             : 
    8811         972 :     if (get_entries) {
    8812             :       Handle<FixedArray> entry_storage =
    8813         495 :           isolate->factory()->NewUninitializedFixedArray(2);
    8814         495 :       entry_storage->set(0, *key);
    8815         495 :       entry_storage->set(1, *value);
    8816             :       value = isolate->factory()->NewJSArrayWithElements(entry_storage,
    8817         495 :                                                          PACKED_ELEMENTS, 2);
    8818             :     }
    8819             : 
    8820         972 :     values_or_entries->set(length, *value);
    8821         972 :     length++;
    8822             :   }
    8823         468 :   if (length < values_or_entries->length()) values_or_entries->Shrink(length);
    8824         468 :   return values_or_entries;
    8825             : }
    8826             : 
    8827         649 : MaybeHandle<FixedArray> JSReceiver::GetOwnValues(Handle<JSReceiver> object,
    8828             :                                                  PropertyFilter filter) {
    8829         649 :   return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, false);
    8830             : }
    8831             : 
    8832         405 : MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object,
    8833             :                                                   PropertyFilter filter) {
    8834         405 :   return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, true);
    8835             : }
    8836             : 
    8837      174321 : bool Map::DictionaryElementsInPrototypeChainOnly() {
    8838      174321 :   if (IsDictionaryElementsKind(elements_kind())) {
    8839             :     return false;
    8840             :   }
    8841             : 
    8842      506629 :   for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) {
    8843             :     // Be conservative, don't walk into proxies.
    8844      685236 :     if (iter.GetCurrent()->IsJSProxy()) return true;
    8845             :     // String wrappers have non-configurable, non-writable elements.
    8846      685236 :     if (iter.GetCurrent()->IsStringWrapper()) return true;
    8847      342598 :     JSObject* current = iter.GetCurrent<JSObject>();
    8848             : 
    8849      350835 :     if (current->HasDictionaryElements() &&
    8850        8237 :         current->element_dictionary()->requires_slow_elements()) {
    8851             :       return true;
    8852             :     }
    8853             : 
    8854      334561 :     if (current->HasSlowArgumentsElements()) {
    8855             :       FixedArray* parameter_map = FixedArray::cast(current->elements());
    8856             :       Object* arguments = parameter_map->get(1);
    8857           0 :       if (SeededNumberDictionary::cast(arguments)->requires_slow_elements()) {
    8858             :         return true;
    8859             :       }
    8860             :     }
    8861             :   }
    8862             : 
    8863      164011 :   return false;
    8864             : }
    8865             : 
    8866             : 
    8867      444764 : MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
    8868             :                                              Handle<Name> name,
    8869             :                                              Handle<Object> getter,
    8870             :                                              Handle<Object> setter,
    8871             :                                              PropertyAttributes attributes) {
    8872             :   Isolate* isolate = object->GetIsolate();
    8873             : 
    8874             :   LookupIterator it = LookupIterator::PropertyOrElement(
    8875      444764 :       isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    8876      444764 :   return DefineAccessor(&it, getter, setter, attributes);
    8877             : }
    8878             : 
    8879             : 
    8880     1962118 : MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
    8881             :                                              Handle<Object> getter,
    8882             :                                              Handle<Object> setter,
    8883             :                                              PropertyAttributes attributes) {
    8884             :   Isolate* isolate = it->isolate();
    8885             : 
    8886      654041 :   it->UpdateProtector();
    8887             : 
    8888      654041 :   if (it->state() == LookupIterator::ACCESS_CHECK) {
    8889        1759 :     if (!it->HasAccess()) {
    8890           5 :       isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    8891           5 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    8892           0 :       return isolate->factory()->undefined_value();
    8893             :     }
    8894        1754 :     it->Next();
    8895             :   }
    8896             : 
    8897             :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    8898             :   // Ignore accessors on typed arrays.
    8899      680197 :   if (it->IsElement() && object->HasFixedTypedArrayElements()) {
    8900           0 :     return it->factory()->undefined_value();
    8901             :   }
    8902             : 
    8903             :   DCHECK(getter->IsCallable() || getter->IsUndefined(isolate) ||
    8904             :          getter->IsNull(isolate) || getter->IsFunctionTemplateInfo());
    8905             :   DCHECK(setter->IsCallable() || setter->IsUndefined(isolate) ||
    8906             :          setter->IsNull(isolate) || setter->IsFunctionTemplateInfo());
    8907      654036 :   it->TransitionToAccessorProperty(getter, setter, attributes);
    8908             : 
    8909      654036 :   return isolate->factory()->undefined_value();
    8910             : }
    8911             : 
    8912             : 
    8913      124136 : MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
    8914             :                                           Handle<AccessorInfo> info) {
    8915             :   Isolate* isolate = object->GetIsolate();
    8916             :   Handle<Name> name(Name::cast(info->name()), isolate);
    8917             : 
    8918             :   LookupIterator it = LookupIterator::PropertyOrElement(
    8919      124136 :       isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    8920             : 
    8921             :   // Duplicate ACCESS_CHECK outside of GetPropertyAttributes for the case that
    8922             :   // the FailedAccessCheckCallbackFunction doesn't throw an exception.
    8923             :   //
    8924             :   // TODO(verwaest): Force throw an exception if the callback doesn't, so we can
    8925             :   // remove reliance on default return values.
    8926      124136 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    8927        7356 :     if (!it.HasAccess()) {
    8928           5 :       isolate->ReportFailedAccessCheck(object);
    8929           5 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    8930           0 :       return it.factory()->undefined_value();
    8931             :     }
    8932        7351 :     it.Next();
    8933             :   }
    8934             : 
    8935             :   // Ignore accessors on typed arrays.
    8936      124143 :   if (it.IsElement() && object->HasFixedTypedArrayElements()) {
    8937           0 :     return it.factory()->undefined_value();
    8938             :   }
    8939             : 
    8940      124131 :   CHECK(GetPropertyAttributes(&it).IsJust());
    8941             : 
    8942             :   // ES5 forbids turning a property into an accessor if it's not
    8943             :   // configurable. See 8.6.1 (Table 5).
    8944      124178 :   if (it.IsFound() && !it.IsConfigurable()) {
    8945          50 :     return it.factory()->undefined_value();
    8946             :   }
    8947             : 
    8948      124106 :   it.TransitionToAccessorPair(info, info->property_attributes());
    8949             : 
    8950      124106 :   return object;
    8951             : }
    8952             : 
    8953          50 : Object* JSObject::SlowReverseLookup(Object* value) {
    8954          50 :   if (HasFastProperties()) {
    8955             :     int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
    8956             :     DescriptorArray* descs = map()->instance_descriptors();
    8957             :     bool value_is_number = value->IsNumber();
    8958         250 :     for (int i = 0; i < number_of_own_descriptors; i++) {
    8959         220 :       PropertyDetails details = descs->GetDetails(i);
    8960         220 :       if (details.location() == kField) {
    8961             :         DCHECK_EQ(kData, details.kind());
    8962           0 :         FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
    8963           0 :         if (IsUnboxedDoubleField(field_index)) {
    8964           0 :           if (value_is_number) {
    8965             :             double property = RawFastDoublePropertyAt(field_index);
    8966           0 :             if (property == value->Number()) {
    8967           0 :               return descs->GetKey(i);
    8968             :             }
    8969             :           }
    8970             :         } else {
    8971           0 :           Object* property = RawFastPropertyAt(field_index);
    8972           0 :           if (field_index.is_double()) {
    8973             :             DCHECK(property->IsMutableHeapNumber());
    8974           0 :             if (value_is_number && property->Number() == value->Number()) {
    8975           0 :               return descs->GetKey(i);
    8976             :             }
    8977           0 :           } else if (property == value) {
    8978           0 :             return descs->GetKey(i);
    8979             :           }
    8980             :         }
    8981             :       } else {
    8982             :         DCHECK_EQ(kDescriptor, details.location());
    8983         220 :         if (details.kind() == kData) {
    8984         210 :           if (descs->GetValue(i) == value) {
    8985          10 :             return descs->GetKey(i);
    8986             :           }
    8987             :         }
    8988             :       }
    8989             :     }
    8990          30 :     return GetHeap()->undefined_value();
    8991          10 :   } else if (IsJSGlobalObject()) {
    8992             :     return JSGlobalObject::cast(this)->global_dictionary()->SlowReverseLookup(
    8993          10 :         value);
    8994             :   } else {
    8995           0 :     return property_dictionary()->SlowReverseLookup(value);
    8996             :   }
    8997             : }
    8998             : 
    8999    21708450 : Handle<Map> Map::RawCopy(Handle<Map> map, int instance_size,
    9000             :                          int inobject_properties) {
    9001             :   Isolate* isolate = map->GetIsolate();
    9002             :   Handle<Map> result = isolate->factory()->NewMap(
    9003             :       map->instance_type(), instance_size, TERMINAL_FAST_ELEMENTS_KIND,
    9004    21708450 :       inobject_properties);
    9005             :   Handle<Object> prototype(map->prototype(), isolate);
    9006    21708450 :   Map::SetPrototype(result, prototype);
    9007    43416901 :   result->set_constructor_or_backpointer(map->GetConstructor());
    9008             :   result->set_bit_field(map->bit_field());
    9009             :   result->set_bit_field2(map->bit_field2());
    9010             :   int new_bit_field3 = map->bit_field3();
    9011             :   new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
    9012             :   new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
    9013             :   new_bit_field3 = EnumLengthBits::update(new_bit_field3,
    9014             :                                           kInvalidEnumCacheSentinel);
    9015    21708449 :   new_bit_field3 = Deprecated::update(new_bit_field3, false);
    9016    21708449 :   if (!map->is_dictionary_map()) {
    9017    20595001 :     new_bit_field3 = IsUnstable::update(new_bit_field3, false);
    9018             :   }
    9019    21708449 :   result->set_bit_field3(new_bit_field3);
    9020    21708449 :   return result;
    9021             : }
    9022             : 
    9023             : 
    9024      918333 : Handle<Map> Map::Normalize(Handle<Map> fast_map, PropertyNormalizationMode mode,
    9025             :                            const char* reason) {
    9026             :   DCHECK(!fast_map->is_dictionary_map());
    9027             : 
    9028             :   Isolate* isolate = fast_map->GetIsolate();
    9029             :   Handle<Object> maybe_cache(isolate->native_context()->normalized_map_cache(),
    9030     1836666 :                              isolate);
    9031             :   bool use_cache =
    9032     1673643 :       !fast_map->is_prototype_map() && !maybe_cache->IsUndefined(isolate);
    9033             :   Handle<NormalizedMapCache> cache;
    9034      918333 :   if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache);
    9035             : 
    9036             :   Handle<Map> new_map;
    9037     2428831 :   if (use_cache && cache->Get(fast_map, mode).ToHandle(&new_map)) {
    9038             : #ifdef VERIFY_HEAP
    9039             :     if (FLAG_verify_heap) new_map->DictionaryMapVerify();
    9040             : #endif
    9041             : #ifdef ENABLE_SLOW_DCHECKS
    9042             :     if (FLAG_enable_slow_asserts) {
    9043             :       // The cached map should match newly created normalized map bit-by-bit,
    9044             :       // except for the code cache, which can contain some ics which can be
    9045             :       // applied to the shared map, dependent code and weak cell cache.
    9046             :       Handle<Map> fresh = Map::CopyNormalized(fast_map, mode);
    9047             : 
    9048             :       if (new_map->is_prototype_map()) {
    9049             :         // For prototype maps, the PrototypeInfo is not copied.
    9050             :         DCHECK_EQ(0, memcmp(fresh->address(), new_map->address(),
    9051             :                             kTransitionsOrPrototypeInfoOffset));
    9052             :         DCHECK_EQ(fresh->raw_transitions(), Smi::kZero);
    9053             :         STATIC_ASSERT(kDescriptorsOffset ==
    9054             :                       kTransitionsOrPrototypeInfoOffset + kPointerSize);
    9055             :         DCHECK_EQ(0, memcmp(HeapObject::RawField(*fresh, kDescriptorsOffset),
    9056             :                             HeapObject::RawField(*new_map, kDescriptorsOffset),
    9057             :                             kDependentCodeOffset - kDescriptorsOffset));
    9058             :       } else {
    9059             :         DCHECK_EQ(0, memcmp(fresh->address(), new_map->address(),
    9060             :                             Map::kDependentCodeOffset));
    9061             :       }
    9062             :       STATIC_ASSERT(Map::kWeakCellCacheOffset ==
    9063             :                     Map::kDependentCodeOffset + kPointerSize);
    9064             :       int offset = Map::kWeakCellCacheOffset + kPointerSize;
    9065             :       DCHECK_EQ(0, memcmp(fresh->address() + offset,
    9066             :                           new_map->address() + offset, Map::kSize - offset));
    9067             :     }
    9068             : #endif
    9069             :   } else {
    9070      365336 :     new_map = Map::CopyNormalized(fast_map, mode);
    9071      365336 :     if (use_cache) {
    9072      202252 :       Handle<WeakCell> cell = Map::WeakCellForMap(new_map);
    9073      202252 :       cache->Set(fast_map, new_map, cell);
    9074      202252 :       isolate->counters()->maps_normalized()->Increment();
    9075             :     }
    9076             : #if V8_TRACE_MAPS
    9077             :     if (FLAG_trace_maps) {
    9078             :       PrintF("[TraceMaps: Normalize from= %p to= %p reason= %s ]\n",
    9079             :              reinterpret_cast<void*>(*fast_map),
    9080             :              reinterpret_cast<void*>(*new_map), reason);
    9081             :     }
    9082             : #endif
    9083             :   }
    9084      918333 :   fast_map->NotifyLeafMapLayoutChange();
    9085      918333 :   return new_map;
    9086             : }
    9087             : 
    9088             : 
    9089      365397 : Handle<Map> Map::CopyNormalized(Handle<Map> map,
    9090             :                                 PropertyNormalizationMode mode) {
    9091             :   int new_instance_size = map->instance_size();
    9092      365397 :   if (mode == CLEAR_INOBJECT_PROPERTIES) {
    9093      102307 :     new_instance_size -= map->GetInObjectProperties() * kPointerSize;
    9094             :   }
    9095             : 
    9096             :   Handle<Map> result = RawCopy(
    9097             :       map, new_instance_size,
    9098      730794 :       mode == CLEAR_INOBJECT_PROPERTIES ? 0 : map->GetInObjectProperties());
    9099             :   // Clear the unused_property_fields explicitly as this field should not
    9100             :   // be accessed for normalized maps.
    9101      365397 :   result->SetInObjectUnusedPropertyFields(0);
    9102             :   result->set_dictionary_map(true);
    9103             :   result->set_migration_target(false);
    9104             :   result->set_may_have_interesting_symbols(true);
    9105             :   result->set_construction_counter(kNoSlackTracking);
    9106             : 
    9107             : #ifdef VERIFY_HEAP
    9108             :   if (FLAG_verify_heap) result->DictionaryMapVerify();
    9109             : #endif
    9110             : 
    9111      365397 :   return result;
    9112             : }
    9113             : 
    9114             : // Return an immutable prototype exotic object version of the input map.
    9115             : // Never even try to cache it in the transition tree, as it is intended
    9116             : // for the global object and its prototype chain, and excluding it saves
    9117             : // memory on the map transition tree.
    9118             : 
    9119             : // static
    9120           6 : Handle<Map> Map::TransitionToImmutableProto(Handle<Map> map) {
    9121           6 :   Handle<Map> new_map = Map::Copy(map, "ImmutablePrototype");
    9122             :   new_map->set_immutable_proto(true);
    9123           6 :   return new_map;
    9124             : }
    9125             : 
    9126             : namespace {
    9127             : void EnsureInitialMap(Handle<Map> map) {
    9128             : #ifdef DEBUG
    9129             :   Isolate* isolate = map->GetIsolate();
    9130             :   // Strict function maps have Function as a constructor but the
    9131             :   // Function's initial map is a sloppy function map. Same holds for
    9132             :   // GeneratorFunction / AsyncFunction and its initial map.
    9133             :   Object* constructor = map->GetConstructor();
    9134             :   DCHECK(constructor->IsJSFunction());
    9135             :   DCHECK(*map == JSFunction::cast(constructor)->initial_map() ||
    9136             :          *map == *isolate->strict_function_map() ||
    9137             :          *map == *isolate->strict_function_with_name_map() ||
    9138             :          *map == *isolate->generator_function_map() ||
    9139             :          *map == *isolate->generator_function_with_name_map() ||
    9140             :          *map == *isolate->generator_function_with_home_object_map() ||
    9141             :          *map == *isolate->generator_function_with_name_and_home_object_map() ||
    9142             :          *map == *isolate->async_function_map() ||
    9143             :          *map == *isolate->async_function_with_name_map() ||
    9144             :          *map == *isolate->async_function_with_home_object_map() ||
    9145             :          *map == *isolate->async_function_with_name_and_home_object_map());
    9146             : #endif
    9147             :   // Initial maps must always own their descriptors and it's descriptor array
    9148             :   // does not contain descriptors that do not belong to the map.
    9149             :   DCHECK(map->owns_descriptors());
    9150             :   DCHECK_EQ(map->NumberOfOwnDescriptors(),
    9151             :             map->instance_descriptors()->number_of_descriptors());
    9152             : }
    9153             : }  // namespace
    9154             : 
    9155             : // static
    9156          61 : Handle<Map> Map::CopyInitialMapNormalized(Handle<Map> map,
    9157             :                                           PropertyNormalizationMode mode) {
    9158             :   EnsureInitialMap(map);
    9159          61 :   return CopyNormalized(map, mode);
    9160             : }
    9161             : 
    9162             : // static
    9163      132881 : Handle<Map> Map::CopyInitialMap(Handle<Map> map, int instance_size,
    9164             :                                 int inobject_properties,
    9165             :                                 int unused_property_fields) {
    9166             :   EnsureInitialMap(map);
    9167      132881 :   Handle<Map> result = RawCopy(map, instance_size, inobject_properties);
    9168             : 
    9169             :   // Please note instance_type and instance_size are set when allocated.
    9170      132881 :   result->SetInObjectUnusedPropertyFields(unused_property_fields);
    9171             : 
    9172             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9173      132881 :   if (number_of_own_descriptors > 0) {
    9174             :     // The copy will use the same descriptors array.
    9175             :     result->UpdateDescriptors(map->instance_descriptors(),
    9176        3034 :                               map->GetLayoutDescriptor());
    9177             :     result->SetNumberOfOwnDescriptors(number_of_own_descriptors);
    9178             : 
    9179             :     DCHECK_EQ(result->NumberOfFields(),
    9180             :               result->GetInObjectProperties() - result->UnusedPropertyFields());
    9181             :   }
    9182             : 
    9183      132881 :   return result;
    9184             : }
    9185             : 
    9186             : 
    9187    21210169 : Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) {
    9188             :   Handle<Map> result =
    9189             :       RawCopy(map, map->instance_size(),
    9190    42420338 :               map->IsJSObjectMap() ? map->GetInObjectProperties() : 0);
    9191             : 
    9192             :   // Please note instance_type and instance_size are set when allocated.
    9193    21210172 :   if (map->IsJSObjectMap()) {
    9194             :     result->CopyUnusedPropertyFields(*map);
    9195             :   }
    9196    21210172 :   map->NotifyLeafMapLayoutChange();
    9197    21210172 :   return result;
    9198             : }
    9199             : 
    9200             : 
    9201     4824044 : Handle<Map> Map::ShareDescriptor(Handle<Map> map,
    9202             :                                  Handle<DescriptorArray> descriptors,
    9203             :                                  Descriptor* descriptor) {
    9204             :   // Sanity check. This path is only to be taken if the map owns its descriptor
    9205             :   // array, implying that its NumberOfOwnDescriptors equals the number of
    9206             :   // descriptors in the descriptor array.
    9207             :   DCHECK_EQ(map->NumberOfOwnDescriptors(),
    9208             :             map->instance_descriptors()->number_of_descriptors());
    9209             : 
    9210     4824044 :   Handle<Map> result = CopyDropDescriptors(map);
    9211             :   Handle<Name> name = descriptor->GetKey();
    9212             : 
    9213             :   // Properly mark the {result} if the {name} is an "interesting symbol".
    9214     4824044 :   if (name->IsInterestingSymbol()) {
    9215             :     result->set_may_have_interesting_symbols(true);
    9216             :   }
    9217             : 
    9218             :   // Ensure there's space for the new descriptor in the shared descriptor array.
    9219     4824044 :   if (descriptors->NumberOfSlackDescriptors() == 0) {
    9220             :     int old_size = descriptors->number_of_descriptors();
    9221     2414661 :     if (old_size == 0) {
    9222         382 :       descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1);
    9223             :     } else {
    9224     2414279 :       int slack = SlackForArraySize(old_size, kMaxNumberOfDescriptors);
    9225     2414279 :       EnsureDescriptorSlack(map, slack);
    9226             :       descriptors = handle(map->instance_descriptors());
    9227             :     }
    9228             :   }
    9229             : 
    9230             :   Handle<LayoutDescriptor> layout_descriptor =
    9231             :       FLAG_unbox_double_fields
    9232             :           ? LayoutDescriptor::ShareAppend(map, descriptor->GetDetails())
    9233     4824044 :           : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate());
    9234             : 
    9235             :   {
    9236             :     DisallowHeapAllocation no_gc;
    9237     4824044 :     descriptors->Append(descriptor);
    9238     4824043 :     result->InitializeDescriptors(*descriptors, *layout_descriptor);
    9239             :   }
    9240             : 
    9241             :   DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
    9242     4824043 :   ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION);
    9243             : 
    9244     4824044 :   return result;
    9245             : }
    9246             : 
    9247             : #if V8_TRACE_MAPS
    9248             : 
    9249             : // static
    9250             : void Map::TraceTransition(const char* what, Map* from, Map* to, Name* name) {
    9251             :   if (FLAG_trace_maps) {
    9252             :     PrintF("[TraceMaps: %s from= %p to= %p name= ", what,
    9253             :            reinterpret_cast<void*>(from), reinterpret_cast<void*>(to));
    9254             :     name->NameShortPrint();
    9255             :     PrintF(" ]\n");
    9256             :   }
    9257             : }
    9258             : 
    9259             : 
    9260             : // static
    9261             : void Map::TraceAllTransitions(Map* map) {
    9262             :   DisallowHeapAllocation no_gc;
    9263             :   TransitionsAccessor transitions(map, &no_gc);
    9264             :   int num_transitions = transitions.NumberOfTransitions();
    9265             :   for (int i = -0; i < num_transitions; ++i) {
    9266             :     Map* target = transitions.GetTarget(i);
    9267             :     Name* key = transitions.GetKey(i);
    9268             :     Map::TraceTransition("Transition", map, target, key);
    9269             :     Map::TraceAllTransitions(target);
    9270             :   }
    9271             : }
    9272             : 
    9273             : #endif  // V8_TRACE_MAPS
    9274             : 
    9275    12459974 : void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child,
    9276             :                             Handle<Name> name, SimpleTransitionFlag flag) {
    9277    12459974 :   Isolate* isolate = parent->GetIsolate();
    9278             :   DCHECK_IMPLIES(name->IsInterestingSymbol(),
    9279             :                  child->may_have_interesting_symbols());
    9280             :   DCHECK_IMPLIES(parent->may_have_interesting_symbols(),
    9281             :                  child->may_have_interesting_symbols());
    9282             :   // Do not track transitions during bootstrap except for element transitions.
    9283    18774906 :   if (isolate->bootstrapper()->IsActive() &&
    9284             :       !name.is_identical_to(isolate->factory()->elements_transition_symbol())) {
    9285    12459975 :     return;
    9286             :   }
    9287    12291426 :   if (!parent->GetBackPointer()->IsUndefined(isolate)) {
    9288             :     parent->set_owns_descriptors(false);
    9289             :   } else {
    9290             :     // |parent| is initial map and it must keep the ownership, there must be no
    9291             :     // descriptors in the descriptors array that do not belong to the map.
    9292             :     DCHECK(parent->owns_descriptors());
    9293             :     DCHECK_EQ(parent->NumberOfOwnDescriptors(),
    9294             :               parent->instance_descriptors()->number_of_descriptors());
    9295             :   }
    9296     6145713 :   if (parent->is_prototype_map()) {
    9297             :     DCHECK(child->is_prototype_map());
    9298             : #if V8_TRACE_MAPS
    9299             :     Map::TraceTransition("NoTransition", *parent, *child, *name);
    9300             : #endif
    9301             :   } else {
    9302     6145713 :     TransitionsAccessor(parent).Insert(name, child, flag);
    9303             : #if V8_TRACE_MAPS
    9304             :     Map::TraceTransition("Transition", *parent, *child, *name);
    9305             : #endif
    9306             :   }
    9307             : }
    9308             : 
    9309             : 
    9310    15704120 : Handle<Map> Map::CopyReplaceDescriptors(
    9311             :     Handle<Map> map, Handle<DescriptorArray> descriptors,
    9312             :     Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
    9313             :     MaybeHandle<Name> maybe_name, const char* reason,
    9314             :     SimpleTransitionFlag simple_flag) {
    9315             :   DCHECK(descriptors->IsSortedNoDuplicates());
    9316             : 
    9317    15704120 :   Handle<Map> result = CopyDropDescriptors(map);
    9318             : 
    9319             :   // Properly mark the {result} if the {name} is an "interesting symbol".
    9320             :   Handle<Name> name;
    9321    26530773 :   if (maybe_name.ToHandle(&name) && name->IsInterestingSymbol()) {
    9322             :     result->set_may_have_interesting_symbols(true);
    9323             :   }
    9324             : 
    9325    15704122 :   if (!map->is_prototype_map()) {
    9326    36875724 :     if (flag == INSERT_TRANSITION &&
    9327    27256008 :         TransitionsAccessor(map).CanHaveMoreTransitions()) {
    9328     7482050 :       result->InitializeDescriptors(*descriptors, *layout_descriptor);
    9329             : 
    9330             :       DCHECK(!maybe_name.is_null());
    9331     7482049 :       ConnectTransition(map, result, name, simple_flag);
    9332             :     } else {
    9333     4809858 :       descriptors->GeneralizeAllFields();
    9334             :       result->InitializeDescriptors(*descriptors,
    9335     4809859 :                                     LayoutDescriptor::FastPointerLayout());
    9336             :     }
    9337             :   } else {
    9338     3412214 :     result->InitializeDescriptors(*descriptors, *layout_descriptor);
    9339             :   }
    9340             : #if V8_TRACE_MAPS
    9341             :   if (FLAG_trace_maps &&
    9342             :       // Mirror conditions above that did not call ConnectTransition().
    9343             :       (map->is_prototype_map() ||
    9344             :        !(flag == INSERT_TRANSITION &&
    9345             :          TransitionsAccessor(map).CanHaveMoreTransitions()))) {
    9346             :     PrintF("[TraceMaps: ReplaceDescriptors from= %p to= %p reason= %s ]\n",
    9347             :            reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*result),
    9348             :            reason);
    9349             :   }
    9350             : #endif
    9351             : 
    9352    15704122 :   return result;
    9353             : }
    9354             : 
    9355             : 
    9356             : // Creates transition tree starting from |split_map| and adding all descriptors
    9357             : // starting from descriptor with index |split_map|.NumberOfOwnDescriptors().
    9358             : // The way how it is done is tricky because of GC and special descriptors
    9359             : // marking logic.
    9360       24903 : Handle<Map> Map::AddMissingTransitions(
    9361             :     Handle<Map> split_map, Handle<DescriptorArray> descriptors,
    9362             :     Handle<LayoutDescriptor> full_layout_descriptor) {
    9363             :   DCHECK(descriptors->IsSortedNoDuplicates());
    9364             :   int split_nof = split_map->NumberOfOwnDescriptors();
    9365             :   int nof_descriptors = descriptors->number_of_descriptors();
    9366             :   DCHECK_LT(split_nof, nof_descriptors);
    9367             : 
    9368             :   // Start with creating last map which will own full descriptors array.
    9369             :   // This is necessary to guarantee that GC will mark the whole descriptor
    9370             :   // array if any of the allocations happening below fail.
    9371             :   // Number of unused properties is temporarily incorrect and the layout
    9372             :   // descriptor could unnecessarily be in slow mode but we will fix after
    9373             :   // all the other intermediate maps are created.
    9374       24903 :   Handle<Map> last_map = CopyDropDescriptors(split_map);
    9375       24903 :   last_map->InitializeDescriptors(*descriptors, *full_layout_descriptor);
    9376       24903 :   last_map->SetInObjectUnusedPropertyFields(0);
    9377             : 
    9378             :   // During creation of intermediate maps we violate descriptors sharing
    9379             :   // invariant since the last map is not yet connected to the transition tree
    9380             :   // we create here. But it is safe because GC never trims map's descriptors
    9381             :   // if there are no dead transitions from that map and this is exactly the
    9382             :   // case for all the intermediate maps we create here.
    9383             :   Handle<Map> map = split_map;
    9384       62585 :   for (int i = split_nof; i < nof_descriptors - 1; ++i) {
    9385       37682 :     Handle<Map> new_map = CopyDropDescriptors(map);
    9386       37682 :     InstallDescriptors(map, new_map, i, descriptors, full_layout_descriptor);
    9387       37682 :     map = new_map;
    9388             :   }
    9389       24903 :   map->NotifyLeafMapLayoutChange();
    9390             :   InstallDescriptors(map, last_map, nof_descriptors - 1, descriptors,
    9391       24903 :                      full_layout_descriptor);
    9392       24903 :   return last_map;
    9393             : }
    9394             : 
    9395             : 
    9396             : // Since this method is used to rewrite an existing transition tree, it can
    9397             : // always insert transitions without checking.
    9398       62585 : void Map::InstallDescriptors(Handle<Map> parent, Handle<Map> child,
    9399             :                              int new_descriptor,
    9400             :                              Handle<DescriptorArray> descriptors,
    9401             :                              Handle<LayoutDescriptor> full_layout_descriptor) {
    9402             :   DCHECK(descriptors->IsSortedNoDuplicates());
    9403             : 
    9404       62585 :   child->set_instance_descriptors(*descriptors);
    9405       62585 :   child->SetNumberOfOwnDescriptors(new_descriptor + 1);
    9406             :   child->CopyUnusedPropertyFields(*parent);
    9407       62585 :   PropertyDetails details = descriptors->GetDetails(new_descriptor);
    9408       62585 :   if (details.location() == kField) {
    9409       60450 :     child->AccountAddedPropertyField();
    9410             :   }
    9411             : 
    9412             :   if (FLAG_unbox_double_fields) {
    9413             :     Handle<LayoutDescriptor> layout_descriptor =
    9414             :         LayoutDescriptor::AppendIfFastOrUseFull(parent, details,
    9415       62585 :                                                 full_layout_descriptor);
    9416       62585 :     child->set_layout_descriptor(*layout_descriptor);
    9417             : #ifdef VERIFY_HEAP
    9418             :     // TODO(ishell): remove these checks from VERIFY_HEAP mode.
    9419             :     if (FLAG_verify_heap) {
    9420             :       CHECK(child->layout_descriptor()->IsConsistentWithMap(*child));
    9421             :     }
    9422             : #else
    9423             :     SLOW_DCHECK(child->layout_descriptor()->IsConsistentWithMap(*child));
    9424             : #endif
    9425       62585 :     child->set_visitor_id(Map::GetVisitorId(*child));
    9426             :   }
    9427             : 
    9428             :   Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
    9429      125099 :   if (parent->may_have_interesting_symbols() || name->IsInterestingSymbol()) {
    9430             :     child->set_may_have_interesting_symbols(true);
    9431             :   }
    9432       62585 :   ConnectTransition(parent, child, name, SIMPLE_PROPERTY_TRANSITION);
    9433       62585 : }
    9434             : 
    9435             : 
    9436      174775 : Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
    9437             :                                     TransitionFlag flag) {
    9438             :   Map* maybe_elements_transition_map = nullptr;
    9439      174775 :   if (flag == INSERT_TRANSITION) {
    9440             :     // Ensure we are requested to add elements kind transition "near the root".
    9441             :     DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(),
    9442             :               map->NumberOfOwnDescriptors());
    9443             : 
    9444      172261 :     maybe_elements_transition_map = map->ElementsTransitionMap();
    9445             :     DCHECK(maybe_elements_transition_map == nullptr ||
    9446             :            (maybe_elements_transition_map->elements_kind() ==
    9447             :                 DICTIONARY_ELEMENTS &&
    9448             :             kind == DICTIONARY_ELEMENTS));
    9449             :     DCHECK(!IsFastElementsKind(kind) ||
    9450             :            IsMoreGeneralElementsKindTransition(map->elements_kind(), kind));
    9451             :     DCHECK(kind != map->elements_kind());
    9452             :   }
    9453             : 
    9454      172261 :   bool insert_transition = flag == INSERT_TRANSITION &&
    9455      610474 :                            TransitionsAccessor(map).CanHaveMoreTransitions() &&
    9456        2514 :                            maybe_elements_transition_map == nullptr;
    9457             : 
    9458      174775 :   if (insert_transition) {
    9459       91177 :     Handle<Map> new_map = CopyForTransition(map, "CopyAsElementsKind");
    9460             :     new_map->set_elements_kind(kind);
    9461             : 
    9462             :     Isolate* isolate = map->GetIsolate();
    9463             :     Handle<Name> name = isolate->factory()->elements_transition_symbol();
    9464       91177 :     ConnectTransition(map, new_map, name, SPECIAL_TRANSITION);
    9465       91177 :     return new_map;
    9466             :   }
    9467             : 
    9468             :   // Create a new free-floating map only if we are not allowed to store it.
    9469       83598 :   Handle<Map> new_map = Copy(map, "CopyAsElementsKind");
    9470             :   new_map->set_elements_kind(kind);
    9471       83598 :   return new_map;
    9472             : }
    9473             : 
    9474         687 : Handle<Map> Map::AsLanguageMode(Handle<Map> initial_map,
    9475             :                                 Handle<SharedFunctionInfo> shared_info) {
    9476             :   DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
    9477             :   // Initial map for sloppy mode function is stored in the function
    9478             :   // constructor. Initial maps for strict mode are cached as special transitions
    9479             :   // using |strict_function_transition_symbol| as a key.
    9480         687 :   if (is_sloppy(shared_info->language_mode())) return initial_map;
    9481             :   Isolate* isolate = initial_map->GetIsolate();
    9482             : 
    9483             :   Handle<Map> function_map(Map::cast(
    9484         312 :       isolate->native_context()->get(shared_info->function_map_index())));
    9485             : 
    9486             :   STATIC_ASSERT(LanguageModeSize == 2);
    9487             :   DCHECK_EQ(LanguageMode::kStrict, shared_info->language_mode());
    9488             :   Handle<Symbol> transition_symbol =
    9489             :       isolate->factory()->strict_function_transition_symbol();
    9490             :   Map* maybe_transition =
    9491         156 :       TransitionsAccessor(initial_map).SearchSpecial(*transition_symbol);
    9492         156 :   if (maybe_transition != nullptr) {
    9493             :     return handle(maybe_transition, isolate);
    9494             :   }
    9495         120 :   initial_map->NotifyLeafMapLayoutChange();
    9496             : 
    9497             :   // Create new map taking descriptors from the |function_map| and all
    9498             :   // the other details from the |initial_map|.
    9499             :   Handle<Map> map =
    9500             :       Map::CopyInitialMap(function_map, initial_map->instance_size(),
    9501             :                           initial_map->GetInObjectProperties(),
    9502         120 :                           initial_map->UnusedPropertyFields());
    9503         120 :   map->SetConstructor(initial_map->GetConstructor());
    9504         120 :   map->set_prototype(initial_map->prototype());
    9505             :   map->set_construction_counter(initial_map->construction_counter());
    9506             : 
    9507         120 :   if (TransitionsAccessor(initial_map).CanHaveMoreTransitions()) {
    9508             :     Map::ConnectTransition(initial_map, map, transition_symbol,
    9509         120 :                            SPECIAL_TRANSITION);
    9510             :   }
    9511         120 :   return map;
    9512             : }
    9513             : 
    9514             : 
    9515       91177 : Handle<Map> Map::CopyForTransition(Handle<Map> map, const char* reason) {
    9516             :   DCHECK(!map->is_prototype_map());
    9517       91177 :   Handle<Map> new_map = CopyDropDescriptors(map);
    9518             : 
    9519       91177 :   if (map->owns_descriptors()) {
    9520             :     // In case the map owned its own descriptors, share the descriptors and
    9521             :     // transfer ownership to the new map.
    9522             :     // The properties did not change, so reuse descriptors.
    9523             :     new_map->InitializeDescriptors(map->instance_descriptors(),
    9524       91175 :                                    map->GetLayoutDescriptor());
    9525             :   } else {
    9526             :     // In case the map did not own its own descriptors, a split is forced by
    9527             :     // copying the map; creating a new descriptor array cell.
    9528             :     Handle<DescriptorArray> descriptors(map->instance_descriptors());
    9529             :     int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9530             :     Handle<DescriptorArray> new_descriptors =
    9531             :         DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
    9532             :     Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9533             :                                                    map->GetIsolate());
    9534           2 :     new_map->InitializeDescriptors(*new_descriptors, *new_layout_descriptor);
    9535             :   }
    9536             : 
    9537             : #if V8_TRACE_MAPS
    9538             :   if (FLAG_trace_maps) {
    9539             :     PrintF("[TraceMaps: CopyForTransition from= %p to= %p reason= %s ]\n",
    9540             :            reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*new_map),
    9541             :            reason);
    9542             :   }
    9543             : #endif
    9544             : 
    9545       91177 :   return new_map;
    9546             : }
    9547             : 
    9548             : 
    9549     4859341 : Handle<Map> Map::Copy(Handle<Map> map, const char* reason) {
    9550             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    9551             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9552             :   Handle<DescriptorArray> new_descriptors =
    9553     4859343 :       DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
    9554             :   Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9555             :                                                  map->GetIsolate());
    9556             :   return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
    9557             :                                 OMIT_TRANSITION, MaybeHandle<Name>(), reason,
    9558     4859341 :                                 SPECIAL_TRANSITION);
    9559             : }
    9560             : 
    9561             : 
    9562      149919 : Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
    9563             :   Handle<Map> copy =
    9564      299838 :       Copy(handle(isolate->object_function()->initial_map()), "MapCreate");
    9565             : 
    9566             :   // Check that we do not overflow the instance size when adding the extra
    9567             :   // inobject properties. If the instance size overflows, we allocate as many
    9568             :   // properties as we can as inobject properties.
    9569      149919 :   if (inobject_properties > JSObject::kMaxInObjectProperties) {
    9570             :     inobject_properties = JSObject::kMaxInObjectProperties;
    9571             :   }
    9572             : 
    9573             :   int new_instance_size =
    9574      149919 :       JSObject::kHeaderSize + kPointerSize * inobject_properties;
    9575             : 
    9576             :   // Adjust the map with the extra inobject properties.
    9577             :   copy->set_instance_size(new_instance_size);
    9578             :   copy->SetInObjectProperties(inobject_properties);
    9579      149919 :   copy->SetInObjectUnusedPropertyFields(inobject_properties);
    9580      149919 :   copy->set_visitor_id(Map::GetVisitorId(*copy));
    9581      149919 :   return copy;
    9582             : }
    9583             : 
    9584             : 
    9585      153543 : Handle<Map> Map::CopyForPreventExtensions(Handle<Map> map,
    9586             :                                           PropertyAttributes attrs_to_add,
    9587             :                                           Handle<Symbol> transition_marker,
    9588             :                                           const char* reason) {
    9589             :   int num_descriptors = map->NumberOfOwnDescriptors();
    9590             :   Isolate* isolate = map->GetIsolate();
    9591             :   Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
    9592             :       handle(map->instance_descriptors(), isolate), num_descriptors,
    9593      153543 :       attrs_to_add);
    9594             :   Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9595             :                                                  isolate);
    9596             :   Handle<Map> new_map = CopyReplaceDescriptors(
    9597             :       map, new_desc, new_layout_descriptor, INSERT_TRANSITION,
    9598      153543 :       transition_marker, reason, SPECIAL_TRANSITION);
    9599             :   new_map->set_is_extensible(false);
    9600      153543 :   if (!IsFixedTypedArrayElementsKind(map->elements_kind())) {
    9601             :     ElementsKind new_kind = IsStringWrapperElementsKind(map->elements_kind())
    9602             :                                 ? SLOW_STRING_WRAPPER_ELEMENTS
    9603      153494 :                                 : DICTIONARY_ELEMENTS;
    9604             :     new_map->set_elements_kind(new_kind);
    9605             :   }
    9606      153543 :   return new_map;
    9607             : }
    9608             : 
    9609             : namespace {
    9610             : 
    9611    11226062 : bool CanHoldValue(DescriptorArray* descriptors, int descriptor,
    9612             :                   PropertyConstness constness, Object* value) {
    9613    11226062 :   PropertyDetails details = descriptors->GetDetails(descriptor);
    9614    11226062 :   if (details.location() == kField) {
    9615    11209715 :     if (details.kind() == kData) {
    9616    11209715 :       return IsGeneralizableTo(constness, details.constness()) &&
    9617    33318983 :              value->FitsRepresentation(details.representation()) &&
    9618    22109268 :              descriptors->GetFieldType(descriptor)->NowContains(value);
    9619             :     } else {
    9620             :       DCHECK_EQ(kAccessor, details.kind());
    9621             :       return false;
    9622             :     }
    9623             : 
    9624             :   } else {
    9625             :     DCHECK_EQ(kDescriptor, details.location());
    9626             :     DCHECK_EQ(kConst, details.constness());
    9627       16347 :     if (details.kind() == kData) {
    9628             :       DCHECK(!FLAG_track_constant_fields);
    9629             :       DCHECK(descriptors->GetValue(descriptor) != value ||
    9630             :              value->FitsRepresentation(details.representation()));
    9631       16347 :       return descriptors->GetValue(descriptor) == value;
    9632             :     } else {
    9633             :       DCHECK_EQ(kAccessor, details.kind());
    9634             :       return false;
    9635             :     }
    9636             :   }
    9637             :   UNREACHABLE();
    9638             : }
    9639             : 
    9640    11226062 : Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor,
    9641             :                                      PropertyConstness constness,
    9642             :                                      Handle<Object> value) {
    9643    11226062 :   if (CanHoldValue(map->instance_descriptors(), descriptor, constness,
    9644             :                    *value)) {
    9645    10879951 :     return map;
    9646             :   }
    9647             : 
    9648             :   Isolate* isolate = map->GetIsolate();
    9649             :   PropertyAttributes attributes =
    9650      692222 :       map->instance_descriptors()->GetDetails(descriptor).attributes();
    9651      346111 :   Representation representation = value->OptimalRepresentation();
    9652      346111 :   Handle<FieldType> type = value->OptimalType(isolate, representation);
    9653             : 
    9654      346111 :   MapUpdater mu(isolate, map);
    9655             :   return mu.ReconfigureToDataField(descriptor, attributes, constness,
    9656      346111 :                                    representation, type);
    9657             : }
    9658             : 
    9659             : }  // namespace
    9660             : 
    9661             : // static
    9662     5669476 : Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor,
    9663             :                                         PropertyConstness constness,
    9664             :                                         Handle<Object> value) {
    9665             :   // Dictionaries can store any property value.
    9666             :   DCHECK(!map->is_dictionary_map());
    9667             :   // Update to the newest map before storing the property.
    9668     5669476 :   return UpdateDescriptorForValue(Update(map), descriptor, constness, value);
    9669             : }
    9670             : 
    9671    20702316 : Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
    9672             :                                           Handle<Object> value,
    9673             :                                           PropertyAttributes attributes,
    9674             :                                           PropertyConstness constness,
    9675             :                                           StoreFromKeyed store_mode,
    9676             :                                           bool* created_new_map) {
    9677             :   RuntimeCallTimerScope stats_scope(
    9678             :       *map, map->is_prototype_map()
    9679             :                 ? &RuntimeCallStats::PrototypeMap_TransitionToDataProperty
    9680    20702316 :                 : &RuntimeCallStats::Map_TransitionToDataProperty);
    9681             : 
    9682             :   DCHECK(name->IsUniqueName());
    9683             :   DCHECK(!map->is_dictionary_map());
    9684             : 
    9685             :   // Migrate to the newest map before storing the property.
    9686    20702319 :   map = Update(map);
    9687             : 
    9688             :   Map* maybe_transition =
    9689    20702318 :       TransitionsAccessor(map).SearchTransition(*name, kData, attributes);
    9690    20702316 :   if (maybe_transition != nullptr) {
    9691     5556586 :     *created_new_map = false;
    9692             :     Handle<Map> transition(maybe_transition);
    9693             :     int descriptor = transition->LastAdded();
    9694             : 
    9695             :     DCHECK_EQ(attributes, transition->instance_descriptors()
    9696             :                               ->GetDetails(descriptor)
    9697             :                               .attributes());
    9698             : 
    9699     5556586 :     return UpdateDescriptorForValue(transition, descriptor, constness, value);
    9700             :   }
    9701             : 
    9702    15145730 :   *created_new_map = true;
    9703             :   TransitionFlag flag = INSERT_TRANSITION;
    9704             :   MaybeHandle<Map> maybe_map;
    9705    15145733 :   if (!FLAG_track_constant_fields && value->IsJSFunction()) {
    9706     8384952 :     maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag);
    9707     6760781 :   } else if (!map->TooManyFastProperties(store_mode)) {
    9708             :     Isolate* isolate = name->GetIsolate();
    9709     6734774 :     Representation representation = value->OptimalRepresentation();
    9710     6734774 :     Handle<FieldType> type = value->OptimalType(isolate, representation);
    9711             :     maybe_map = Map::CopyWithField(map, name, type, attributes, constness,
    9712     6734773 :                                    representation, flag);
    9713             :   }
    9714             : 
    9715             :   Handle<Map> result;
    9716    15145731 :   if (!maybe_map.ToHandle(&result)) {
    9717             :     Isolate* isolate = name->GetIsolate();
    9718             :     const char* reason = "TooManyFastProperties";
    9719             : #if V8_TRACE_MAPS
    9720             :     std::unique_ptr<ScopedVector<char>> buffer;
    9721             :     if (FLAG_trace_maps) {
    9722             :       ScopedVector<char> name_buffer(100);
    9723             :       name->NameShortPrint(name_buffer);
    9724             :       buffer.reset(new ScopedVector<char>(128));
    9725             :       SNPrintF(*buffer, "TooManyFastProperties %s", name_buffer.start());
    9726             :       reason = buffer->start();
    9727             :     }
    9728             : #endif
    9729       26085 :     Handle<Object> maybe_constructor(map->GetConstructor(), isolate);
    9730       26085 :     if (FLAG_feedback_normalization && map->new_target_is_base() &&
    9731       26085 :         maybe_constructor->IsJSFunction() &&
    9732             :         !JSFunction::cast(*maybe_constructor)->shared()->native()) {
    9733             :       Handle<JSFunction> constructor =
    9734             :           Handle<JSFunction>::cast(maybe_constructor);
    9735             :       DCHECK_NE(*constructor,
    9736             :                 constructor->context()->native_context()->object_function());
    9737             :       Handle<Map> initial_map(constructor->initial_map(), isolate);
    9738           0 :       result = Map::Normalize(initial_map, CLEAR_INOBJECT_PROPERTIES, reason);
    9739           0 :       initial_map->DeprecateTransitionTree();
    9740             :       Handle<Object> prototype(result->prototype(), isolate);
    9741           0 :       JSFunction::SetInitialMap(constructor, result, prototype);
    9742             : 
    9743             :       // Deoptimize all code that embeds the previous initial map.
    9744             :       initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
    9745           0 :           isolate, DependentCode::kInitialMapChangedGroup);
    9746           0 :       if (!result->EquivalentToForNormalization(*map,
    9747           0 :                                                 CLEAR_INOBJECT_PROPERTIES)) {
    9748           0 :         result = Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, reason);
    9749             :       }
    9750             :     } else {
    9751       26085 :       result = Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, reason);
    9752             :     }
    9753             :   }
    9754             : 
    9755    15145731 :   return result;
    9756             : }
    9757             : 
    9758             : 
    9759       13660 : Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor,
    9760             :                                              PropertyKind kind,
    9761             :                                              PropertyAttributes attributes) {
    9762             :   // Dictionaries have to be reconfigured in-place.
    9763             :   DCHECK(!map->is_dictionary_map());
    9764             : 
    9765       27320 :   if (!map->GetBackPointer()->IsMap()) {
    9766             :     // There is no benefit from reconstructing transition tree for maps without
    9767             :     // back pointers.
    9768             :     return CopyGeneralizeAllFields(map, map->elements_kind(), descriptor, kind,
    9769             :                                    attributes,
    9770        1060 :                                    "GenAll_AttributesMismatchProtoMap");
    9771             :   }
    9772             : 
    9773       12600 :   if (FLAG_trace_generalization) {
    9774           0 :     map->PrintReconfiguration(stdout, descriptor, kind, attributes);
    9775             :   }
    9776             : 
    9777             :   Isolate* isolate = map->GetIsolate();
    9778             : 
    9779       12600 :   MapUpdater mu(isolate, map);
    9780             :   DCHECK_EQ(kData, kind);  // Only kData case is supported so far.
    9781             :   Handle<Map> new_map = mu.ReconfigureToDataField(
    9782             :       descriptor, attributes, kDefaultFieldConstness, Representation::None(),
    9783       12600 :       FieldType::None(isolate));
    9784       12600 :   return new_map;
    9785             : }
    9786             : 
    9787      606699 : Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
    9788             :                                               Handle<Name> name, int descriptor,
    9789             :                                               Handle<Object> getter,
    9790             :                                               Handle<Object> setter,
    9791             :                                               PropertyAttributes attributes) {
    9792             :   RuntimeCallTimerScope stats_scope(
    9793             :       isolate,
    9794             :       map->is_prototype_map()
    9795             :           ? &RuntimeCallStats::PrototypeMap_TransitionToAccessorProperty
    9796      606699 :           : &RuntimeCallStats::Map_TransitionToAccessorProperty);
    9797             : 
    9798             :   // At least one of the accessors needs to be a new value.
    9799             :   DCHECK(!getter->IsNull(isolate) || !setter->IsNull(isolate));
    9800             :   DCHECK(name->IsUniqueName());
    9801             : 
    9802             :   // Dictionary maps can always have additional data properties.
    9803      606699 :   if (map->is_dictionary_map()) return map;
    9804             : 
    9805             :   // Migrate to the newest map before transitioning to the new property.
    9806      606699 :   map = Update(map);
    9807             : 
    9808             :   PropertyNormalizationMode mode = map->is_prototype_map()
    9809             :                                        ? KEEP_INOBJECT_PROPERTIES
    9810      606699 :                                        : CLEAR_INOBJECT_PROPERTIES;
    9811             : 
    9812             :   Map* maybe_transition =
    9813      606699 :       TransitionsAccessor(map).SearchTransition(*name, kAccessor, attributes);
    9814      606699 :   if (maybe_transition != nullptr) {
    9815             :     Handle<Map> transition(maybe_transition, isolate);
    9816             :     DescriptorArray* descriptors = transition->instance_descriptors();
    9817             :     int descriptor = transition->LastAdded();
    9818             :     DCHECK(descriptors->GetKey(descriptor)->Equals(*name));
    9819             : 
    9820             :     DCHECK_EQ(kAccessor, descriptors->GetDetails(descriptor).kind());
    9821             :     DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes());
    9822             : 
    9823             :     Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
    9824       11881 :     if (!maybe_pair->IsAccessorPair()) {
    9825           0 :       return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair");
    9826             :     }
    9827             : 
    9828             :     Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair);
    9829       11881 :     if (!pair->Equals(*getter, *setter)) {
    9830       11328 :       return Map::Normalize(map, mode, "TransitionToDifferentAccessor");
    9831             :     }
    9832             : 
    9833         553 :     return transition;
    9834             :   }
    9835             : 
    9836             :   Handle<AccessorPair> pair;
    9837             :   DescriptorArray* old_descriptors = map->instance_descriptors();
    9838      594818 :   if (descriptor != DescriptorArray::kNotFound) {
    9839      230195 :     if (descriptor != map->LastAdded()) {
    9840      129915 :       return Map::Normalize(map, mode, "AccessorsOverwritingNonLast");
    9841             :     }
    9842      100280 :     PropertyDetails old_details = old_descriptors->GetDetails(descriptor);
    9843      100280 :     if (old_details.kind() != kAccessor) {
    9844       98602 :       return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors");
    9845             :     }
    9846             : 
    9847        1678 :     if (old_details.attributes() != attributes) {
    9848          86 :       return Map::Normalize(map, mode, "AccessorsWithAttributes");
    9849             :     }
    9850             : 
    9851             :     Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate);
    9852        1592 :     if (!maybe_pair->IsAccessorPair()) {
    9853          24 :       return Map::Normalize(map, mode, "AccessorsOverwritingNonPair");
    9854             :     }
    9855             : 
    9856             :     Handle<AccessorPair> current_pair = Handle<AccessorPair>::cast(maybe_pair);
    9857        1568 :     if (current_pair->Equals(*getter, *setter)) return map;
    9858             : 
    9859             :     bool overwriting_accessor = false;
    9860        3130 :     if (!getter->IsNull(isolate) &&
    9861        3036 :         !current_pair->get(ACCESSOR_GETTER)->IsNull(isolate) &&
    9862             :         current_pair->get(ACCESSOR_GETTER) != *getter) {
    9863             :       overwriting_accessor = true;
    9864             :     }
    9865        3127 :     if (!setter->IsNull(isolate) &&
    9866        2740 :         !current_pair->get(ACCESSOR_SETTER)->IsNull(isolate) &&
    9867             :         current_pair->get(ACCESSOR_SETTER) != *setter) {
    9868             :       overwriting_accessor = true;
    9869             :     }
    9870        1568 :     if (overwriting_accessor) {
    9871        1378 :       return Map::Normalize(map, mode, "AccessorsOverwritingAccessors");
    9872             :     }
    9873             : 
    9874         190 :     pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair));
    9875      729246 :   } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors ||
    9876      364623 :              map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) {
    9877           0 :     return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors");
    9878             :   } else {
    9879      364623 :     pair = isolate->factory()->NewAccessorPair();
    9880             :   }
    9881             : 
    9882      364813 :   pair->SetComponents(*getter, *setter);
    9883             : 
    9884             :   TransitionFlag flag = INSERT_TRANSITION;
    9885             :   Descriptor d = Descriptor::AccessorConstant(name, pair, attributes);
    9886      364813 :   return Map::CopyInsertDescriptor(map, &d, flag);
    9887             : }
    9888             : 
    9889             : 
    9890    15496960 : Handle<Map> Map::CopyAddDescriptor(Handle<Map> map,
    9891             :                                    Descriptor* descriptor,
    9892             :                                    TransitionFlag flag) {
    9893             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    9894             : 
    9895             :   // Share descriptors only if map owns descriptors and it not an initial map.
    9896    57108460 :   if (flag == INSERT_TRANSITION && map->owns_descriptors() &&
    9897    35762870 :       !map->GetBackPointer()->IsUndefined(map->GetIsolate()) &&
    9898    25145050 :       TransitionsAccessor(map).CanHaveMoreTransitions()) {
    9899     4824044 :     return ShareDescriptor(map, descriptors, descriptor);
    9900             :   }
    9901             : 
    9902             :   int nof = map->NumberOfOwnDescriptors();
    9903             :   Handle<DescriptorArray> new_descriptors =
    9904             :       DescriptorArray::CopyUpTo(descriptors, nof, 1);
    9905    10672919 :   new_descriptors->Append(descriptor);
    9906             : 
    9907             :   Handle<LayoutDescriptor> new_layout_descriptor =
    9908             :       FLAG_unbox_double_fields
    9909    10672918 :           ? LayoutDescriptor::New(map, new_descriptors, nof + 1)
    9910    10672918 :           : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate());
    9911             : 
    9912             :   return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
    9913             :                                 flag, descriptor->GetKey(), "CopyAddDescriptor",
    9914    10672918 :                                 SIMPLE_PROPERTY_TRANSITION);
    9915             : }
    9916             : 
    9917             : 
    9918      364853 : Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map,
    9919             :                                       Descriptor* descriptor,
    9920             :                                       TransitionFlag flag) {
    9921             :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors());
    9922             : 
    9923             :   // We replace the key if it is already present.
    9924             :   int index = old_descriptors->SearchWithCache(map->GetIsolate(),
    9925             :                                                *descriptor->GetKey(), *map);
    9926      364853 :   if (index != DescriptorArray::kNotFound) {
    9927         190 :     return CopyReplaceDescriptor(map, old_descriptors, descriptor, index, flag);
    9928             :   }
    9929      364663 :   return CopyAddDescriptor(map, descriptor, flag);
    9930             : }
    9931             : 
    9932             : 
    9933           0 : Handle<DescriptorArray> DescriptorArray::CopyUpTo(
    9934             :     Handle<DescriptorArray> desc,
    9935             :     int enumeration_index,
    9936             :     int slack) {
    9937             :   return DescriptorArray::CopyUpToAddAttributes(
    9938    17967490 :       desc, enumeration_index, NONE, slack);
    9939             : }
    9940             : 
    9941             : 
    9942    18121034 : Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
    9943             :     Handle<DescriptorArray> desc,
    9944             :     int enumeration_index,
    9945             :     PropertyAttributes attributes,
    9946             :     int slack) {
    9947    18121034 :   if (enumeration_index + slack == 0) {
    9948             :     return desc->GetIsolate()->factory()->empty_descriptor_array();
    9949             :   }
    9950             : 
    9951             :   int size = enumeration_index;
    9952             : 
    9953             :   Handle<DescriptorArray> descriptors =
    9954    16535188 :       DescriptorArray::Allocate(desc->GetIsolate(), size, slack);
    9955             : 
    9956    16535188 :   if (attributes != NONE) {
    9957      188391 :     for (int i = 0; i < size; ++i) {
    9958             :       Object* value = desc->GetValue(i);
    9959             :       Name* key = desc->GetKey(i);
    9960      188391 :       PropertyDetails details = desc->GetDetails(i);
    9961             :       // Bulk attribute changes never affect private properties.
    9962      188391 :       if (!key->IsPrivate()) {
    9963             :         int mask = DONT_DELETE | DONT_ENUM;
    9964             :         // READ_ONLY is an invalid attribute for JS setters/getters.
    9965      189326 :         if (details.kind() != kAccessor || !value->IsAccessorPair()) {
    9966             :           mask |= READ_ONLY;
    9967             :         }
    9968             :         details = details.CopyAddAttributes(
    9969      188373 :             static_cast<PropertyAttributes>(attributes & mask));
    9970             :       }
    9971      188391 :       descriptors->Set(i, key, value, details);
    9972             :     }
    9973             :   } else {
    9974   104562671 :     for (int i = 0; i < size; ++i) {
    9975   104562672 :       descriptors->CopyFrom(i, *desc);
    9976             :     }
    9977             :   }
    9978             : 
    9979    16594799 :   if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort();
    9980             : 
    9981    16535189 :   return descriptors;
    9982             : }
    9983             : 
    9984             : 
    9985        2303 : bool DescriptorArray::IsEqualUpTo(DescriptorArray* desc, int nof_descriptors) {
    9986       27751 :   for (int i = 0; i < nof_descriptors; i++) {
    9987       50896 :     if (GetKey(i) != desc->GetKey(i) || GetValue(i) != desc->GetValue(i)) {
    9988             :       return false;
    9989             :     }
    9990       25448 :     PropertyDetails details = GetDetails(i);
    9991       25448 :     PropertyDetails other_details = desc->GetDetails(i);
    9992       50896 :     if (details.kind() != other_details.kind() ||
    9993       50896 :         details.location() != other_details.location() ||
    9994             :         !details.representation().Equals(other_details.representation())) {
    9995             :       return false;
    9996             :     }
    9997             :   }
    9998             :   return true;
    9999             : }
   10000             : 
   10001             : 
   10002         190 : Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map,
   10003             :                                        Handle<DescriptorArray> descriptors,
   10004             :                                        Descriptor* descriptor,
   10005             :                                        int insertion_index,
   10006             :                                        TransitionFlag flag) {
   10007             :   Handle<Name> key = descriptor->GetKey();
   10008             :   DCHECK_EQ(*key, descriptors->GetKey(insertion_index));
   10009             :   // This function does not support replacing property fields as
   10010             :   // that would break property field counters.
   10011             :   DCHECK_NE(kField, descriptor->GetDetails().location());
   10012             :   DCHECK_NE(kField, descriptors->GetDetails(insertion_index).location());
   10013             : 
   10014             :   Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
   10015             :       descriptors, map->NumberOfOwnDescriptors());
   10016             : 
   10017         190 :   new_descriptors->Replace(insertion_index, descriptor);
   10018             :   Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New(
   10019         190 :       map, new_descriptors, new_descriptors->number_of_descriptors());
   10020             : 
   10021             :   SimpleTransitionFlag simple_flag =
   10022         190 :       (insertion_index == descriptors->number_of_descriptors() - 1)
   10023             :           ? SIMPLE_PROPERTY_TRANSITION
   10024         190 :           : PROPERTY_TRANSITION;
   10025             :   return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
   10026             :                                 flag, key, "CopyReplaceDescriptor",
   10027         190 :                                 simple_flag);
   10028             : }
   10029             : 
   10030     8437134 : Handle<FixedArray> FixedArray::SetAndGrow(Handle<FixedArray> array, int index,
   10031             :                                           Handle<Object> value) {
   10032     8437134 :   if (index < array->length()) {
   10033     7973284 :     array->set(index, *value);
   10034     7973284 :     return array;
   10035             :   }
   10036             :   int capacity = array->length();
   10037      463850 :   do {
   10038      927700 :     capacity = JSObject::NewElementsCapacity(capacity);
   10039             :   } while (capacity <= index);
   10040             :   Handle<FixedArray> new_array =
   10041      463850 :       array->GetIsolate()->factory()->NewUninitializedFixedArray(capacity);
   10042      463850 :   array->CopyTo(0, *new_array, 0, array->length());
   10043      463850 :   new_array->FillWithHoles(array->length(), new_array->length());
   10044      463850 :   new_array->set(index, *value);
   10045      463850 :   return new_array;
   10046             : }
   10047             : 
   10048     8033883 : void FixedArray::Shrink(int new_length) {
   10049             :   DCHECK(0 <= new_length && new_length <= length());
   10050     8033883 :   if (new_length < length()) {
   10051    12601610 :     GetHeap()->RightTrimFixedArray(this, length() - new_length);
   10052             :   }
   10053     8033883 : }
   10054             : 
   10055      525339 : void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos,
   10056             :                         int len) const {
   10057             :   DisallowHeapAllocation no_gc;
   10058      525339 :   WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
   10059    20999450 :   for (int index = 0; index < len; index++) {
   10060    40948222 :     dest->set(dest_pos+index, get(pos+index), mode);
   10061             :   }
   10062      525339 : }
   10063             : 
   10064             : #ifdef DEBUG
   10065             : bool FixedArray::IsEqualTo(FixedArray* other) {
   10066             :   if (length() != other->length()) return false;
   10067             :   for (int i = 0 ; i < length(); ++i) {
   10068             :     if (get(i) != other->get(i)) return false;
   10069             :   }
   10070             :   return true;
   10071             : }
   10072             : #endif
   10073             : 
   10074             : 
   10075             : // static
   10076    11560960 : void WeakFixedArray::Set(Handle<WeakFixedArray> array, int index,
   10077             :                          Handle<HeapObject> value) {
   10078             :   DCHECK(array->IsEmptySlot(index));  // Don't overwrite anything.
   10079             :   Handle<WeakCell> cell =
   10080             :       value->IsMap() ? Map::WeakCellForMap(Handle<Map>::cast(value))
   10081    22747214 :                      : array->GetIsolate()->factory()->NewWeakCell(value);
   10082    23121922 :   Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell);
   10083    11560961 :   if (FLAG_trace_weak_arrays) {
   10084           0 :     PrintF("[WeakFixedArray: storing at index %d ]\n", index);
   10085             :   }
   10086             :   array->set_last_used_index(index);
   10087    11560961 : }
   10088             : 
   10089             : 
   10090             : // static
   10091    11560959 : Handle<WeakFixedArray> WeakFixedArray::Add(Handle<Object> maybe_array,
   10092             :                                            Handle<HeapObject> value,
   10093             :                                            int* assigned_index) {
   10094             :   Handle<WeakFixedArray> array =
   10095    11545918 :       (maybe_array.is_null() || !maybe_array->IsWeakFixedArray())
   10096             :           ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null())
   10097    11632247 :           : Handle<WeakFixedArray>::cast(maybe_array);
   10098             :   // Try to store the new entry if there's room. Optimize for consecutive
   10099             :   // accesses.
   10100             :   int first_index = array->last_used_index();
   10101             :   int length = array->Length();
   10102    11560961 :   if (length > 0) {
   10103             :     for (int i = first_index;;) {
   10104    54377260 :       if (array->IsEmptySlot((i))) {
   10105    11407519 :         WeakFixedArray::Set(array, i, value);
   10106    11407519 :         if (assigned_index != nullptr) *assigned_index = i;
   10107    11407519 :         return array;
   10108             :       }
   10109    42969741 :       if (FLAG_trace_weak_arrays) {
   10110           0 :         PrintF("[WeakFixedArray: searching for free slot]\n");
   10111             :       }
   10112    42969741 :       i = (i + 1) % length;
   10113    42969741 :       if (i == first_index) break;
   10114             :     }
   10115             :   }
   10116             : 
   10117             :   // No usable slot found, grow the array.
   10118      153442 :   int new_length = length == 0 ? 1 : length + (length >> 1) + 4;
   10119             :   Handle<WeakFixedArray> new_array =
   10120      153442 :       Allocate(array->GetIsolate(), new_length, array);
   10121      153442 :   if (FLAG_trace_weak_arrays) {
   10122           0 :     PrintF("[WeakFixedArray: growing to size %d ]\n", new_length);
   10123             :   }
   10124      153442 :   WeakFixedArray::Set(new_array, length, value);
   10125      153442 :   if (assigned_index != nullptr) *assigned_index = length;
   10126      153442 :   return new_array;
   10127             : }
   10128             : 
   10129             : 
   10130             : template <class CompactionCallback>
   10131         398 : void WeakFixedArray::Compact() {
   10132             :   FixedArray* array = FixedArray::cast(this);
   10133             :   int new_length = kFirstIndex;
   10134      198084 :   for (int i = kFirstIndex; i < array->length(); i++) {
   10135             :     Object* element = array->get(i);
   10136       98644 :     if (element->IsSmi()) continue;
   10137       65881 :     if (WeakCell::cast(element)->cleared()) continue;
   10138             :     Object* value = WeakCell::cast(element)->value();
   10139             :     CompactionCallback::Callback(value, i - kFirstIndex,
   10140         171 :                                  new_length - kFirstIndex);
   10141       65639 :     array->set(new_length++, element);
   10142             :   }
   10143         398 :   array->Shrink(new_length);
   10144             :   set_last_used_index(0);
   10145         398 : }
   10146             : 
   10147             : 
   10148      916247 : void WeakFixedArray::Iterator::Reset(Object* maybe_array) {
   10149      916247 :   if (maybe_array->IsWeakFixedArray()) {
   10150      244196 :     list_ = WeakFixedArray::cast(maybe_array);
   10151      244196 :     index_ = 0;
   10152             : #ifdef DEBUG
   10153             :     last_used_index_ = list_->last_used_index();
   10154             : #endif  // DEBUG
   10155             :   }
   10156      916247 : }
   10157             : 
   10158             : 
   10159           0 : void JSObject::PrototypeRegistryCompactionCallback::Callback(Object* value,
   10160             :                                                              int old_index,
   10161             :                                                              int new_index) {
   10162             :   DCHECK(value->IsMap() && Map::cast(value)->is_prototype_map());
   10163             :   Map* map = Map::cast(value);
   10164             :   DCHECK(map->prototype_info()->IsPrototypeInfo());
   10165             :   PrototypeInfo* proto_info = PrototypeInfo::cast(map->prototype_info());
   10166             :   DCHECK_EQ(old_index, proto_info->registry_slot());
   10167             :   proto_info->set_registry_slot(new_index);
   10168           0 : }
   10169             : 
   10170             : 
   10171             : template void WeakFixedArray::Compact<WeakFixedArray::NullCallback>();
   10172             : template void
   10173             : WeakFixedArray::Compact<JSObject::PrototypeRegistryCompactionCallback>();
   10174             : 
   10175             : 
   10176     5172755 : bool WeakFixedArray::Remove(Handle<HeapObject> value) {
   10177     5172755 :   if (Length() == 0) return false;
   10178             :   // Optimize for the most recently added element to be removed again.
   10179             :   int first_index = last_used_index();
   10180             :   for (int i = first_index;;) {
   10181    11591232 :     if (Get(i) == *value) {
   10182             :       Clear(i);
   10183             :       // Users of WeakFixedArray should make sure that there are no duplicates.
   10184     5172755 :       return true;
   10185             :     }
   10186     1245722 :     i = (i + 1) % Length();
   10187      622861 :     if (i == first_index) return false;
   10188             :   }
   10189             :   UNREACHABLE();
   10190             : }
   10191             : 
   10192             : 
   10193             : // static
   10194      224732 : Handle<WeakFixedArray> WeakFixedArray::Allocate(
   10195             :     Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from) {
   10196             :   DCHECK_LE(0, size);
   10197             :   Handle<FixedArray> result =
   10198      224732 :       isolate->factory()->NewUninitializedFixedArray(size + kFirstIndex);
   10199             :   int index = 0;
   10200      224731 :   if (!initialize_from.is_null()) {
   10201             :     DCHECK(initialize_from->Length() <= size);
   10202             :     Handle<FixedArray> raw_source = Handle<FixedArray>::cast(initialize_from);
   10203             :     // Copy the entries without compacting, since the PrototypeInfo relies on
   10204             :     // the index of the entries not to change.
   10205    36725965 :     while (index < raw_source->length()) {
   10206    36572522 :       result->set(index, raw_source->get(index));
   10207    36572523 :       index++;
   10208             :     }
   10209             :   }
   10210    19167259 :   while (index < result->length()) {
   10211             :     result->set(index, Smi::kZero);
   10212    18942527 :     index++;
   10213             :   }
   10214      224732 :   return Handle<WeakFixedArray>::cast(result);
   10215             : }
   10216             : 
   10217             : // static
   10218        2199 : Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj,
   10219             :                                  AddMode mode) {
   10220        2199 :   int length = array->Length();
   10221        2199 :   array = EnsureSpace(array, length + 1);
   10222        2199 :   if (mode == kReloadLengthAfterAllocation) {
   10223             :     DCHECK(array->Length() <= length);
   10224           0 :     length = array->Length();
   10225             :   }
   10226             :   array->Set(length, *obj);
   10227             :   array->SetLength(length + 1);
   10228        2199 :   return array;
   10229             : }
   10230             : 
   10231             : // static
   10232      391567 : Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj1,
   10233             :                                  Handle<Object> obj2, AddMode mode) {
   10234      391567 :   int length = array->Length();
   10235      391567 :   array = EnsureSpace(array, length + 2);
   10236      391567 :   if (mode == kReloadLengthAfterAllocation) {
   10237       34675 :     length = array->Length();
   10238             :   }
   10239             :   array->Set(length, *obj1);
   10240             :   array->Set(length + 1, *obj2);
   10241             :   array->SetLength(length + 2);
   10242      391567 :   return array;
   10243             : }
   10244             : 
   10245             : // static
   10246         419 : Handle<ArrayList> ArrayList::New(Isolate* isolate, int size) {
   10247             :   Handle<ArrayList> result = Handle<ArrayList>::cast(
   10248         419 :       isolate->factory()->NewFixedArray(size + kFirstIndex));
   10249             :   result->SetLength(0);
   10250         419 :   return result;
   10251             : }
   10252             : 
   10253           0 : Handle<FixedArray> ArrayList::Elements(Handle<ArrayList> array) {
   10254           0 :   int length = array->Length();
   10255             :   Handle<FixedArray> result =
   10256           0 :       array->GetIsolate()->factory()->NewFixedArray(length);
   10257             :   // Do not copy the first entry, i.e., the length.
   10258           0 :   array->CopyTo(kFirstIndex, *result, 0, length);
   10259           0 :   return result;
   10260             : }
   10261             : 
   10262       34675 : bool ArrayList::IsFull() {
   10263             :   int capacity = length();
   10264       34675 :   return kFirstIndex + Length() == capacity;
   10265             : }
   10266             : 
   10267             : namespace {
   10268             : 
   10269     5116809 : Handle<FixedArray> EnsureSpaceInFixedArray(Handle<FixedArray> array,
   10270             :                                            int length) {
   10271             :   int capacity = array->length();
   10272     5116809 :   if (capacity < length) {
   10273             :     Isolate* isolate = array->GetIsolate();
   10274             :     int new_capacity = length;
   10275       66374 :     new_capacity = new_capacity + Max(new_capacity / 2, 2);
   10276       33187 :     int grow_by = new_capacity - capacity;
   10277       33187 :     array = isolate->factory()->CopyFixedArrayAndGrow(array, grow_by);
   10278             :   }
   10279     5116809 :   return array;
   10280             : }
   10281             : 
   10282             : }  // namespace
   10283             : 
   10284             : // static
   10285      393766 : Handle<ArrayList> ArrayList::EnsureSpace(Handle<ArrayList> array, int length) {
   10286             :   const bool empty = (array->length() == 0);
   10287             :   auto ret = Handle<ArrayList>::cast(
   10288      787532 :       EnsureSpaceInFixedArray(array, kFirstIndex + length));
   10289      393766 :   if (empty) ret->SetLength(0);
   10290      393766 :   return ret;
   10291             : }
   10292             : 
   10293      309058 : Handle<RegExpMatchInfo> RegExpMatchInfo::ReserveCaptures(
   10294             :     Handle<RegExpMatchInfo> match_info, int capture_count) {
   10295             :   DCHECK_GE(match_info->length(), kLastMatchOverhead);
   10296      309058 :   const int required_length = kFirstCaptureIndex + capture_count;
   10297             :   Handle<FixedArray> result =
   10298      309058 :       EnsureSpaceInFixedArray(match_info, required_length);
   10299      309058 :   return Handle<RegExpMatchInfo>::cast(result);
   10300             : }
   10301             : 
   10302             : // static
   10303     4368901 : Handle<FrameArray> FrameArray::AppendJSFrame(Handle<FrameArray> in,
   10304             :                                              Handle<Object> receiver,
   10305             :                                              Handle<JSFunction> function,
   10306             :                                              Handle<AbstractCode> code,
   10307             :                                              int offset, int flags) {
   10308             :   const int frame_count = in->FrameCount();
   10309     4368901 :   const int new_length = LengthFor(frame_count + 1);
   10310             :   Handle<FrameArray> array = EnsureSpace(in, new_length);
   10311             :   array->SetReceiver(frame_count, *receiver);
   10312             :   array->SetFunction(frame_count, *function);
   10313             :   array->SetCode(frame_count, *code);
   10314             :   array->SetOffset(frame_count, Smi::FromInt(offset));
   10315     4368901 :   array->SetFlags(frame_count, Smi::FromInt(flags));
   10316             :   array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1));
   10317     4368901 :   return array;
   10318             : }
   10319             : 
   10320             : // static
   10321       45084 : Handle<FrameArray> FrameArray::AppendWasmFrame(
   10322             :     Handle<FrameArray> in, Handle<WasmInstanceObject> wasm_instance,
   10323             :     int wasm_function_index, Handle<AbstractCode> code, int offset, int flags) {
   10324             :   const int frame_count = in->FrameCount();
   10325       45084 :   const int new_length = LengthFor(frame_count + 1);
   10326             :   Handle<FrameArray> array = EnsureSpace(in, new_length);
   10327             :   array->SetWasmInstance(frame_count, *wasm_instance);
   10328             :   array->SetWasmFunctionIndex(frame_count, Smi::FromInt(wasm_function_index));
   10329             :   // code will be a null handle for interpreted wasm frames.
   10330       45084 :   if (!code.is_null()) array->SetCode(frame_count, *code);
   10331             :   array->SetOffset(frame_count, Smi::FromInt(offset));
   10332       45084 :   array->SetFlags(frame_count, Smi::FromInt(flags));
   10333             :   array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1));
   10334       45084 :   return array;
   10335             : }
   10336             : 
   10337     2119966 : void FrameArray::ShrinkToFit() { Shrink(LengthFor(FrameCount())); }
   10338             : 
   10339             : // static
   10340           0 : Handle<FrameArray> FrameArray::EnsureSpace(Handle<FrameArray> array,
   10341             :                                            int length) {
   10342     4413985 :   return Handle<FrameArray>::cast(EnsureSpaceInFixedArray(array, length));
   10343             : }
   10344             : 
   10345    16932923 : Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
   10346             :                                                   int number_of_descriptors,
   10347             :                                                   int slack,
   10348             :                                                   PretenureFlag pretenure) {
   10349             :   DCHECK_LE(0, number_of_descriptors);
   10350             :   Factory* factory = isolate->factory();
   10351             :   // Do not use DescriptorArray::cast on incomplete object.
   10352    16932923 :   int size = number_of_descriptors + slack;
   10353    16932923 :   if (size == 0) return factory->empty_descriptor_array();
   10354             :   // Allocate the array of keys.
   10355             :   Handle<FixedArray> result =
   10356    16932923 :       factory->NewFixedArray(LengthFor(size), pretenure);
   10357             : 
   10358             :   result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
   10359    33865842 :   result->set(kEnumCacheIndex, isolate->heap()->empty_enum_cache());
   10360             :   return Handle<DescriptorArray>::cast(result);
   10361             : }
   10362             : 
   10363          90 : void DescriptorArray::ClearEnumCache() {
   10364          90 :   set(kEnumCacheIndex, GetHeap()->empty_enum_cache());
   10365          90 : }
   10366             : 
   10367      329604 : void DescriptorArray::Replace(int index, Descriptor* descriptor) {
   10368             :   descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index));
   10369      329604 :   Set(index, descriptor);
   10370      329604 : }
   10371             : 
   10372             : // static
   10373      189119 : void DescriptorArray::SetEnumCache(Handle<DescriptorArray> descriptors,
   10374             :                                    Isolate* isolate, Handle<FixedArray> keys,
   10375             :                                    Handle<FixedArray> indices) {
   10376             :   EnumCache* enum_cache = descriptors->GetEnumCache();
   10377      189119 :   if (enum_cache == isolate->heap()->empty_enum_cache()) {
   10378      365540 :     enum_cache = *isolate->factory()->NewEnumCache(keys, indices);
   10379      182770 :     descriptors->set(kEnumCacheIndex, enum_cache);
   10380             :   } else {
   10381        6349 :     enum_cache->set_keys(*keys);
   10382        6349 :     enum_cache->set_indices(*indices);
   10383             :   }
   10384      189119 : }
   10385             : 
   10386   104562670 : void DescriptorArray::CopyFrom(int index, DescriptorArray* src) {
   10387   104562670 :   PropertyDetails details = src->GetDetails(index);
   10388   104562674 :   Set(index, src->GetKey(index), src->GetValue(index), details);
   10389   104562670 : }
   10390             : 
   10391    13234543 : void DescriptorArray::Sort() {
   10392             :   // In-place heap sort.
   10393             :   int len = number_of_descriptors();
   10394             :   // Reset sorting since the descriptor array might contain invalid pointers.
   10395    13234543 :   for (int i = 0; i < len; ++i) SetSortedKey(i, i);
   10396             :   // Bottom-up max-heap construction.
   10397             :   // Index of the last node with children
   10398    13234545 :   const int max_parent_index = (len / 2) - 1;
   10399    53043814 :   for (int i = max_parent_index; i >= 0; --i) {
   10400             :     int parent_index = i;
   10401    39809271 :     const uint32_t parent_hash = GetSortedKey(i)->Hash();
   10402   117652352 :     while (parent_index <= max_parent_index) {
   10403    57774525 :       int child_index = 2 * parent_index + 1;
   10404    57774525 :       uint32_t child_hash = GetSortedKey(child_index)->Hash();
   10405    57774518 :       if (child_index + 1 < len) {
   10406    46521631 :         uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
   10407    46521640 :         if (right_child_hash > child_hash) {
   10408             :           child_index++;
   10409             :           child_hash = right_child_hash;
   10410             :         }
   10411             :       }
   10412    57774527 :       if (child_hash <= parent_hash) break;
   10413    38033815 :       SwapSortedKeys(parent_index, child_index);
   10414             :       // Now element at child_index could be < its children.
   10415             :       parent_index = child_index;  // parent_hash remains correct.
   10416             :     }
   10417             :   }
   10418             : 
   10419             :   // Extract elements and create sorted array.
   10420    85134509 :   for (int i = len - 1; i > 0; --i) {
   10421             :     // Put max element at the back of the array.
   10422    71899972 :     SwapSortedKeys(0, i);
   10423             :     // Shift down the new top element.
   10424             :     int parent_index = 0;
   10425    71899981 :     const uint32_t parent_hash = GetSortedKey(parent_index)->Hash();
   10426    71899973 :     const int max_parent_index = (i / 2) - 1;
   10427   260037727 :     while (parent_index <= max_parent_index) {
   10428   127164883 :       int child_index = parent_index * 2 + 1;
   10429   127164883 :       uint32_t child_hash = GetSortedKey(child_index)->Hash();
   10430   127164806 :       if (child_index + 1 < i) {
   10431   108706567 :         uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
   10432   108706570 :         if (right_child_hash > child_hash) {
   10433             :           child_index++;
   10434             :           child_hash = right_child_hash;
   10435             :         }
   10436             :       }
   10437   127164809 :       if (child_hash <= parent_hash) break;
   10438   116237714 :       SwapSortedKeys(parent_index, child_index);
   10439             :       parent_index = child_index;
   10440             :     }
   10441             :   }
   10442             :   DCHECK(IsSortedNoDuplicates());
   10443    13234537 : }
   10444             : 
   10445             : 
   10446       11311 : Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) {
   10447       11311 :   Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair();
   10448       11311 :   copy->set_getter(pair->getter());
   10449       11311 :   copy->set_setter(pair->setter());
   10450       11311 :   return copy;
   10451             : }
   10452             : 
   10453       27992 : Handle<Object> AccessorPair::GetComponent(Handle<AccessorPair> accessor_pair,
   10454             :                                           AccessorComponent component) {
   10455             :   Object* accessor = accessor_pair->get(component);
   10456       27992 :   if (accessor->IsFunctionTemplateInfo()) {
   10457             :     return ApiNatives::InstantiateFunction(
   10458          79 :                handle(FunctionTemplateInfo::cast(accessor)))
   10459         158 :         .ToHandleChecked();
   10460             :   }
   10461             :   Isolate* isolate = accessor_pair->GetIsolate();
   10462       27913 :   if (accessor->IsNull(isolate)) {
   10463        3909 :     return isolate->factory()->undefined_value();
   10464             :   }
   10465             :   return handle(accessor, isolate);
   10466             : }
   10467             : 
   10468      442526 : Handle<DeoptimizationData> DeoptimizationData::New(Isolate* isolate,
   10469             :                                                    int deopt_entry_count,
   10470             :                                                    PretenureFlag pretenure) {
   10471             :   return Handle<DeoptimizationData>::cast(isolate->factory()->NewFixedArray(
   10472      442526 :       LengthFor(deopt_entry_count), pretenure));
   10473             : }
   10474             : 
   10475     1226823 : Handle<DeoptimizationData> DeoptimizationData::Empty(Isolate* isolate) {
   10476             :   return Handle<DeoptimizationData>::cast(
   10477     1226823 :       isolate->factory()->empty_fixed_array());
   10478             : }
   10479             : 
   10480          36 : SharedFunctionInfo* DeoptimizationData::GetInlinedFunction(int index) {
   10481          36 :   if (index == -1) {
   10482           0 :     return SharedFunctionInfo::cast(SharedFunctionInfo());
   10483             :   } else {
   10484          36 :     return SharedFunctionInfo::cast(LiteralArray()->get(index));
   10485             :   }
   10486             : }
   10487             : 
   10488    22097306 : int HandlerTable::LookupRange(int pc_offset, int* data_out,
   10489             :                               CatchPrediction* prediction_out) {
   10490             :   int innermost_handler = -1;
   10491             : #ifdef DEBUG
   10492             :   // Assuming that ranges are well nested, we don't need to track the innermost
   10493             :   // offsets. This is just to verify that the table is actually well nested.
   10494             :   int innermost_start = std::numeric_limits<int>::min();
   10495             :   int innermost_end = std::numeric_limits<int>::max();
   10496             : #endif
   10497    64283428 :   for (int i = 0; i < length(); i += kRangeEntrySize) {
   10498             :     int start_offset = Smi::ToInt(get(i + kRangeStartIndex));
   10499    10044408 :     int end_offset = Smi::ToInt(get(i + kRangeEndIndex));
   10500    10044408 :     int handler_field = Smi::ToInt(get(i + kRangeHandlerIndex));
   10501    10044408 :     int handler_offset = HandlerOffsetField::decode(handler_field);
   10502             :     CatchPrediction prediction = HandlerPredictionField::decode(handler_field);
   10503    10044408 :     int handler_data = Smi::ToInt(get(i + kRangeDataIndex));
   10504    10044408 :     if (pc_offset >= start_offset && pc_offset < end_offset) {
   10505             :       DCHECK_GE(start_offset, innermost_start);
   10506             :       DCHECK_LT(end_offset, innermost_end);
   10507             :       innermost_handler = handler_offset;
   10508             : #ifdef DEBUG
   10509             :       innermost_start = start_offset;
   10510             :       innermost_end = end_offset;
   10511             : #endif
   10512     1601161 :       if (data_out) *data_out = handler_data;
   10513     1601161 :       if (prediction_out) *prediction_out = prediction;
   10514             :     }
   10515             :   }
   10516    22097306 :   return innermost_handler;
   10517             : }
   10518             : 
   10519             : 
   10520             : // TODO(turbofan): Make sure table is sorted and use binary search.
   10521     2906054 : int HandlerTable::LookupReturn(int pc_offset) {
   10522     6870130 :   for (int i = 0; i < length(); i += kReturnEntrySize) {
   10523             :     int return_offset = Smi::ToInt(get(i + kReturnOffsetIndex));
   10524      761777 :     int handler_field = Smi::ToInt(get(i + kReturnHandlerIndex));
   10525      761777 :     if (pc_offset == return_offset) {
   10526      465532 :       return HandlerOffsetField::decode(handler_field);
   10527             :     }
   10528             :   }
   10529             :   return -1;
   10530             : }
   10531             : 
   10532     1669287 : Handle<HandlerTable> HandlerTable::Empty(Isolate* isolate) {
   10533     1669287 :   return Handle<HandlerTable>::cast(isolate->factory()->empty_fixed_array());
   10534             : }
   10535             : 
   10536             : #ifdef DEBUG
   10537             : bool DescriptorArray::IsEqualTo(DescriptorArray* other) {
   10538             :   if (length() != other->length()) return false;
   10539             :   for (int i = 0; i < length(); ++i) {
   10540             :     if (get(i) != other->get(i)) return false;
   10541             :   }
   10542             :   return true;
   10543             : }
   10544             : #endif
   10545             : 
   10546             : // static
   10547          36 : Handle<String> String::Trim(Handle<String> string, TrimMode mode) {
   10548          36 :   Isolate* const isolate = string->GetIsolate();
   10549          36 :   string = String::Flatten(string);
   10550             :   int const length = string->length();
   10551             : 
   10552             :   // Perform left trimming if requested.
   10553             :   int left = 0;
   10554             :   UnicodeCache* unicode_cache = isolate->unicode_cache();
   10555          36 :   if (mode == kTrim || mode == kTrimLeft) {
   10556        1206 :     while (left < length &&
   10557         603 :            unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
   10558         567 :       left++;
   10559             :     }
   10560             :   }
   10561             : 
   10562             :   // Perform right trimming if requested.
   10563             :   int right = length;
   10564          36 :   if (mode == kTrim || mode == kTrimRight) {
   10565          36 :     while (
   10566          72 :         right > left &&
   10567          72 :         unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(right - 1))) {
   10568           0 :       right--;
   10569             :     }
   10570             :   }
   10571             : 
   10572          36 :   return isolate->factory()->NewSubString(string, left, right);
   10573             : }
   10574             : 
   10575     2728329 : bool String::LooksValid() { return GetIsolate()->heap()->Contains(this); }
   10576             : 
   10577             : // static
   10578      291767 : MaybeHandle<String> Name::ToFunctionName(Handle<Name> name) {
   10579      291767 :   if (name->IsString()) return Handle<String>::cast(name);
   10580             :   // ES6 section 9.2.11 SetFunctionName, step 4.
   10581             :   Isolate* const isolate = name->GetIsolate();
   10582             :   Handle<Object> description(Handle<Symbol>::cast(name)->name(), isolate);
   10583        9959 :   if (description->IsUndefined(isolate)) {
   10584          81 :     return isolate->factory()->empty_string();
   10585             :   }
   10586        9878 :   IncrementalStringBuilder builder(isolate);
   10587             :   builder.AppendCharacter('[');
   10588        9878 :   builder.AppendString(Handle<String>::cast(description));
   10589             :   builder.AppendCharacter(']');
   10590        9878 :   return builder.Finish();
   10591             : }
   10592             : 
   10593             : // static
   10594       87483 : MaybeHandle<String> Name::ToFunctionName(Handle<Name> name,
   10595             :                                          Handle<String> prefix) {
   10596             :   Handle<String> name_string;
   10597             :   Isolate* const isolate = name->GetIsolate();
   10598      174966 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, name_string, ToFunctionName(name),
   10599             :                              String);
   10600       87483 :   IncrementalStringBuilder builder(isolate);
   10601       87483 :   builder.AppendString(prefix);
   10602             :   builder.AppendCharacter(' ');
   10603       87483 :   builder.AppendString(name_string);
   10604       87483 :   return builder.Finish();
   10605             : }
   10606             : 
   10607             : namespace {
   10608             : 
   10609             : bool AreDigits(const uint8_t* s, int from, int to) {
   10610       30918 :   for (int i = from; i < to; i++) {
   10611       50936 :     if (s[i] < '0' || s[i] > '9') return false;
   10612             :   }
   10613             : 
   10614             :   return true;
   10615             : }
   10616             : 
   10617             : 
   10618             : int ParseDecimalInteger(const uint8_t* s, int from, int to) {
   10619             :   DCHECK_LT(to - from, 10);  // Overflow is not possible.
   10620             :   DCHECK(from < to);
   10621        1659 :   int d = s[from] - '0';
   10622             : 
   10623        2043 :   for (int i = from + 1; i < to; i++) {
   10624         384 :     d = 10 * d + (s[i] - '0');
   10625             :   }
   10626             : 
   10627             :   return d;
   10628             : }
   10629             : 
   10630             : }  // namespace
   10631             : 
   10632             : // static
   10633     4539635 : Handle<Object> String::ToNumber(Handle<String> subject) {
   10634     1821993 :   Isolate* const isolate = subject->GetIsolate();
   10635             : 
   10636             :   // Flatten {subject} string first.
   10637     4539635 :   subject = String::Flatten(subject);
   10638             : 
   10639             :   // Fast array index case.
   10640             :   uint32_t index;
   10641     4539635 :   if (subject->AsArrayIndex(&index)) {
   10642       46689 :     return isolate->factory()->NewNumberFromUint(index);
   10643             :   }
   10644             : 
   10645             :   // Fast case: short integer or some sorts of junk values.
   10646     4492946 :   if (subject->IsSeqOneByteString()) {
   10647             :     int len = subject->length();
   10648     2826581 :     if (len == 0) return handle(Smi::kZero, isolate);
   10649             : 
   10650             :     DisallowHeapAllocation no_gc;
   10651     2782575 :     uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
   10652     2782575 :     bool minus = (data[0] == '-');
   10653     2782575 :     int start_pos = (minus ? 1 : 0);
   10654             : 
   10655     2782575 :     if (start_pos == len) {
   10656           0 :       return isolate->factory()->nan_value();
   10657     2782575 :     } else if (data[start_pos] > '9') {
   10658             :       // Fast check for a junk value. A valid string may start from a
   10659             :       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
   10660             :       // or the 'I' character ('Infinity'). All of that have codes not greater
   10661             :       // than '9' except 'I' and &nbsp;.
   10662     2652969 :       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
   10663     2647291 :         return isolate->factory()->nan_value();
   10664             :       }
   10665      151283 :     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
   10666             :       // The maximal/minimal smi has 10 digits. If the string has less digits
   10667             :       // we know it will fit into the smi-data type.
   10668             :       int d = ParseDecimalInteger(data, start_pos, len);
   10669        1659 :       if (minus) {
   10670        1864 :         if (d == 0) return isolate->factory()->minus_zero_value();
   10671        1334 :         d = -d;
   10672         120 :       } else if (!subject->HasHashCode() && len <= String::kMaxArrayIndexSize &&
   10673           0 :                  (len == 1 || data[0] != '0')) {
   10674             :         // String hash is not calculated yet but all the data are present.
   10675             :         // Update the hash field to speed up sequential convertions.
   10676           0 :         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
   10677             : #ifdef DEBUG
   10678             :         subject->Hash();  // Force hash calculation.
   10679             :         DCHECK_EQ(static_cast<int>(subject->hash_field()),
   10680             :                   static_cast<int>(hash));
   10681             : #endif
   10682             :         subject->set_hash_field(hash);
   10683             :       }
   10684        1394 :       return handle(Smi::FromInt(d), isolate);
   10685             :     }
   10686             :   }
   10687             : 
   10688             :   // Slower case.
   10689             :   int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
   10690             :   return isolate->factory()->NewNumber(
   10691     1821993 :       StringToDouble(isolate->unicode_cache(), subject, flags));
   10692             : }
   10693             : 
   10694             : 
   10695   114207095 : String::FlatContent String::GetFlatContent() {
   10696             :   DCHECK(!AllowHeapAllocation::IsAllowed());
   10697             :   int length = this->length();
   10698             :   StringShape shape(this);
   10699             :   String* string = this;
   10700             :   int offset = 0;
   10701   114207095 :   if (shape.representation_tag() == kConsStringTag) {
   10702             :     ConsString* cons = ConsString::cast(string);
   10703           0 :     if (cons->second()->length() != 0) {
   10704           0 :       return FlatContent();
   10705             :     }
   10706             :     string = cons->first();
   10707             :     shape = StringShape(string);
   10708   114207095 :   } else if (shape.representation_tag() == kSlicedStringTag) {
   10709             :     SlicedString* slice = SlicedString::cast(string);
   10710             :     offset = slice->offset();
   10711             :     string = slice->parent();
   10712             :     shape = StringShape(string);
   10713             :     DCHECK(shape.representation_tag() != kConsStringTag &&
   10714             :            shape.representation_tag() != kSlicedStringTag);
   10715             :   }
   10716   114207095 :   if (shape.representation_tag() == kThinStringTag) {
   10717             :     ThinString* thin = ThinString::cast(string);
   10718             :     string = thin->actual();
   10719             :     shape = StringShape(string);
   10720             :     DCHECK(!shape.IsCons());
   10721             :     DCHECK(!shape.IsSliced());
   10722             :   }
   10723   114207095 :   if (shape.encoding_tag() == kOneByteStringTag) {
   10724             :     const uint8_t* start;
   10725   106165841 :     if (shape.representation_tag() == kSeqStringTag) {
   10726   106163830 :       start = SeqOneByteString::cast(string)->GetChars();
   10727             :     } else {
   10728             :       start = ExternalOneByteString::cast(string)->GetChars();
   10729             :     }
   10730   106165845 :     return FlatContent(start + offset, length);
   10731             :   } else {
   10732             :     DCHECK_EQ(shape.encoding_tag(), kTwoByteStringTag);
   10733             :     const uc16* start;
   10734     8041254 :     if (shape.representation_tag() == kSeqStringTag) {
   10735     8039606 :       start = SeqTwoByteString::cast(string)->GetChars();
   10736             :     } else {
   10737             :       start = ExternalTwoByteString::cast(string)->GetChars();
   10738             :     }
   10739     8041254 :     return FlatContent(start + offset, length);
   10740             :   }
   10741             : }
   10742             : 
   10743     3194585 : std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls,
   10744             :                                           RobustnessFlag robust_flag,
   10745             :                                           int offset, int length,
   10746             :                                           int* length_return) {
   10747     5922850 :   if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
   10748             :     return std::unique_ptr<char[]>();
   10749             :   }
   10750             :   // Negative length means the to the end of the string.
   10751     3194585 :   if (length < 0) length = kMaxInt - offset;
   10752             : 
   10753             :   // Compute the size of the UTF-8 string. Start at the specified offset.
   10754             :   StringCharacterStream stream(this, offset);
   10755             :   int character_position = offset;
   10756             :   int utf8_bytes = 0;
   10757             :   int last = unibrow::Utf16::kNoPreviousCharacter;
   10758    33720284 :   while (stream.HasMore() && character_position++ < offset + length) {
   10759    27331116 :     uint16_t character = stream.GetNext();
   10760    27331116 :     utf8_bytes += unibrow::Utf8::Length(character, last);
   10761    27331116 :     last = character;
   10762             :   }
   10763             : 
   10764     3194584 :   if (length_return) {
   10765     2685533 :     *length_return = utf8_bytes;
   10766             :   }
   10767             : 
   10768     3194584 :   char* result = NewArray<char>(utf8_bytes + 1);
   10769             : 
   10770             :   // Convert the UTF-16 string to a UTF-8 buffer. Start at the specified offset.
   10771     3194585 :   stream.Reset(this, offset);
   10772             :   character_position = offset;
   10773             :   int utf8_byte_position = 0;
   10774             :   last = unibrow::Utf16::kNoPreviousCharacter;
   10775    33720284 :   while (stream.HasMore() && character_position++ < offset + length) {
   10776    27331116 :     uint16_t character = stream.GetNext();
   10777    27331116 :     if (allow_nulls == DISALLOW_NULLS && character == 0) {
   10778             :       character = ' ';
   10779             :     }
   10780             :     utf8_byte_position +=
   10781    27331116 :         unibrow::Utf8::Encode(result + utf8_byte_position, character, last);
   10782    27331114 :     last = character;
   10783             :   }
   10784     3194585 :   result[utf8_byte_position] = 0;
   10785             :   return std::unique_ptr<char[]>(result);
   10786             : }
   10787             : 
   10788      509052 : std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls,
   10789             :                                           RobustnessFlag robust_flag,
   10790             :                                           int* length_return) {
   10791      509052 :   return ToCString(allow_nulls, robust_flag, 0, -1, length_return);
   10792             : }
   10793             : 
   10794             : 
   10795          62 : const uc16* String::GetTwoByteData(unsigned start) {
   10796             :   DCHECK(!IsOneByteRepresentationUnderneath());
   10797          62 :   switch (StringShape(this).representation_tag()) {
   10798             :     case kSeqStringTag:
   10799           0 :       return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start);
   10800             :     case kExternalStringTag:
   10801             :       return ExternalTwoByteString::cast(this)->
   10802          62 :         ExternalTwoByteStringGetData(start);
   10803             :     case kSlicedStringTag: {
   10804             :       SlicedString* slice = SlicedString::cast(this);
   10805           0 :       return slice->parent()->GetTwoByteData(start + slice->offset());
   10806             :     }
   10807             :     case kConsStringTag:
   10808             :     case kThinStringTag:
   10809           0 :       UNREACHABLE();
   10810             :   }
   10811           0 :   UNREACHABLE();
   10812             : }
   10813             : 
   10814             : 
   10815           0 : const uc16* SeqTwoByteString::SeqTwoByteStringGetData(unsigned start) {
   10816             :   return reinterpret_cast<uc16*>(
   10817           0 :       reinterpret_cast<char*>(this) - kHeapObjectTag + kHeaderSize) + start;
   10818             : }
   10819             : 
   10820             : 
   10821       86451 : void Relocatable::PostGarbageCollectionProcessing(Isolate* isolate) {
   10822             :   Relocatable* current = isolate->relocatable_top();
   10823      194561 :   while (current != nullptr) {
   10824       21659 :     current->PostGarbageCollection();
   10825       21659 :     current = current->prev_;
   10826             :   }
   10827       86451 : }
   10828             : 
   10829             : 
   10830             : // Reserve space for statics needing saving and restoring.
   10831        1118 : int Relocatable::ArchiveSpacePerThread() {
   10832        1118 :   return sizeof(Relocatable*);  // NOLINT
   10833             : }
   10834             : 
   10835             : 
   10836             : // Archive statics that are thread-local.
   10837       24163 : char* Relocatable::ArchiveState(Isolate* isolate, char* to) {
   10838       24163 :   *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top();
   10839             :   isolate->set_relocatable_top(nullptr);
   10840       24163 :   return to + ArchiveSpacePerThread();
   10841             : }
   10842             : 
   10843             : 
   10844             : // Restore statics that are thread-local.
   10845       24163 : char* Relocatable::RestoreState(Isolate* isolate, char* from) {
   10846       24163 :   isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from));
   10847       24163 :   return from + ArchiveSpacePerThread();
   10848             : }
   10849             : 
   10850        5994 : char* Relocatable::Iterate(RootVisitor* v, char* thread_storage) {
   10851        5994 :   Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage);
   10852             :   Iterate(v, top);
   10853        5994 :   return thread_storage + ArchiveSpacePerThread();
   10854             : }
   10855             : 
   10856      232423 : void Relocatable::Iterate(Isolate* isolate, RootVisitor* v) {
   10857             :   Iterate(v, isolate->relocatable_top());
   10858      232423 : }
   10859             : 
   10860           0 : void Relocatable::Iterate(RootVisitor* v, Relocatable* top) {
   10861             :   Relocatable* current = top;
   10862      286736 :   while (current != nullptr) {
   10863       48319 :     current->IterateInstance(v);
   10864       48319 :     current = current->prev_;
   10865             :   }
   10866           0 : }
   10867             : 
   10868             : 
   10869     1524155 : FlatStringReader::FlatStringReader(Isolate* isolate, Handle<String> str)
   10870             :     : Relocatable(isolate),
   10871             :       str_(str.location()),
   10872     4572465 :       length_(str->length()) {
   10873     1524155 :   PostGarbageCollection();
   10874     1524155 : }
   10875             : 
   10876             : 
   10877        3072 : FlatStringReader::FlatStringReader(Isolate* isolate, Vector<const char> input)
   10878             :     : Relocatable(isolate),
   10879             :       str_(0),
   10880             :       is_one_byte_(true),
   10881        3072 :       length_(input.length()),
   10882        9216 :       start_(input.start()) {}
   10883             : 
   10884             : 
   10885     1524585 : void FlatStringReader::PostGarbageCollection() {
   10886     1524585 :   if (str_ == nullptr) return;
   10887             :   Handle<String> str(str_);
   10888             :   DCHECK(str->IsFlat());
   10889             :   DisallowHeapAllocation no_gc;
   10890             :   // This does not actually prevent the vector from being relocated later.
   10891     1524585 :   String::FlatContent content = str->GetFlatContent();
   10892             :   DCHECK(content.IsFlat());
   10893     3049170 :   is_one_byte_ = content.IsOneByte();
   10894     1524585 :   if (is_one_byte_) {
   10895     1385341 :     start_ = content.ToOneByteVector().start();
   10896             :   } else {
   10897      139244 :     start_ = content.ToUC16Vector().start();
   10898             :   }
   10899             : }
   10900             : 
   10901             : 
   10902       47184 : void ConsStringIterator::Initialize(ConsString* cons_string, int offset) {
   10903             :   DCHECK_NOT_NULL(cons_string);
   10904     3660153 :   root_ = cons_string;
   10905     3660153 :   consumed_ = offset;
   10906             :   // Force stack blown condition to trigger restart.
   10907     3660153 :   depth_ = 1;
   10908     3660153 :   maximum_depth_ = kStackSize + depth_;
   10909             :   DCHECK(StackBlown());
   10910       47184 : }
   10911             : 
   10912             : 
   10913    43511997 : String* ConsStringIterator::Continue(int* offset_out) {
   10914             :   DCHECK_NE(depth_, 0);
   10915             :   DCHECK_EQ(0, *offset_out);
   10916    43511997 :   bool blew_stack = StackBlown();
   10917             :   String* string = nullptr;
   10918             :   // Get the next leaf if there is one.
   10919    43511997 :   if (!blew_stack) string = NextLeaf(&blew_stack);
   10920             :   // Restart search from root.
   10921    43511997 :   if (blew_stack) {
   10922             :     DCHECK_NULL(string);
   10923     4053378 :     string = Search(offset_out);
   10924             :   }
   10925             :   // Ensure future calls return null immediately.
   10926    43511997 :   if (string == nullptr) Reset(nullptr);
   10927    43511997 :   return string;
   10928             : }
   10929             : 
   10930             : 
   10931     8106611 : String* ConsStringIterator::Search(int* offset_out) {
   10932     4053378 :   ConsString* cons_string = root_;
   10933             :   // Reset the stack, pushing the root string.
   10934     4053378 :   depth_ = 1;
   10935     4053378 :   maximum_depth_ = 1;
   10936     4053378 :   frames_[0] = cons_string;
   10937     4053378 :   const int consumed = consumed_;
   10938             :   int offset = 0;
   10939             :   while (true) {
   10940             :     // Loop until the string is found which contains the target offset.
   10941             :     String* string = cons_string->first();
   10942             :     int length = string->length();
   10943             :     int32_t type;
   10944  9838866271 :     if (consumed < offset + length) {
   10945             :       // Target offset is in the left branch.
   10946             :       // Keep going if we're still in a ConString.
   10947             :       type = string->map()->instance_type();
   10948  9837169956 :       if ((type & kStringRepresentationMask) == kConsStringTag) {
   10949             :         cons_string = ConsString::cast(string);
   10950             :         PushLeft(cons_string);
   10951             :         continue;
   10952             :       }
   10953             :       // Tell the stack we're done descending.
   10954             :       AdjustMaximumDepth();
   10955             :     } else {
   10956             :       // Descend right.
   10957             :       // Update progress through the string.
   10958             :       offset += length;
   10959             :       // Keep going if we're still in a ConString.
   10960             :       string = cons_string->second();
   10961             :       type = string->map()->instance_type();
   10962     1696315 :       if ((type & kStringRepresentationMask) == kConsStringTag) {
   10963             :         cons_string = ConsString::cast(string);
   10964             :         PushRight(cons_string);
   10965             :         continue;
   10966             :       }
   10967             :       // Need this to be updated for the current string.
   10968             :       length = string->length();
   10969             :       // Account for the possibility of an empty right leaf.
   10970             :       // This happens only if we have asked for an offset outside the string.
   10971      398240 :       if (length == 0) {
   10972             :         // Reset so future operations will return null immediately.
   10973             :         Reset(nullptr);
   10974         145 :         return nullptr;
   10975             :       }
   10976             :       // Tell the stack we're done descending.
   10977             :       AdjustMaximumDepth();
   10978             :       // Pop stack so next iteration is in correct place.
   10979             :       Pop();
   10980             :     }
   10981             :     DCHECK_NE(length, 0);
   10982             :     // Adjust return values and exit.
   10983     4053233 :     consumed_ = offset + length;
   10984     4053233 :     *offset_out = consumed - offset;
   10985     4053233 :     return string;
   10986             :   }
   10987             :   UNREACHABLE();
   10988             : }
   10989             : 
   10990             : 
   10991    88559491 : String* ConsStringIterator::NextLeaf(bool* blew_stack) {
   10992             :   while (true) {
   10993             :     // Tree traversal complete.
   10994    39922496 :     if (depth_ == 0) {
   10995        6787 :       *blew_stack = false;
   10996        6787 :       return nullptr;
   10997             :     }
   10998             :     // We've lost track of higher nodes.
   10999    39915709 :     if (StackBlown()) {
   11000         695 :       *blew_stack = true;
   11001         695 :       return nullptr;
   11002             :     }
   11003             :     // Go right.
   11004    79830028 :     ConsString* cons_string = frames_[OffsetForDepth(depth_ - 1)];
   11005             :     String* string = cons_string->second();
   11006             :     int32_t type = string->map()->instance_type();
   11007    39915014 :     if ((type & kStringRepresentationMask) != kConsStringTag) {
   11008             :       // Pop stack so next iteration is in correct place.
   11009             :       Pop();
   11010             :       int length = string->length();
   11011             :       // Could be a flattened ConsString.
   11012    30730546 :       if (length == 0) continue;
   11013    30267364 :       consumed_ += length;
   11014    30267364 :       return string;
   11015             :     }
   11016             :     cons_string = ConsString::cast(string);
   11017             :     PushRight(cons_string);
   11018             :     // Need to traverse all the way left.
   11019             :     while (true) {
   11020             :       // Continue left.
   11021             :       string = cons_string->first();
   11022             :       type = string->map()->instance_type();
   11023    15414030 :       if ((type & kStringRepresentationMask) != kConsStringTag) {
   11024             :         AdjustMaximumDepth();
   11025             :         int length = string->length();
   11026     9184468 :         if (length == 0) break;  // Skip empty left-hand sides of ConsStrings.
   11027     9184468 :         consumed_ += length;
   11028     9184468 :         return string;
   11029             :       }
   11030             :       cons_string = ConsString::cast(string);
   11031             :       PushLeft(cons_string);
   11032             :     }
   11033             :   }
   11034             :   UNREACHABLE();
   11035             : }
   11036             : 
   11037             : 
   11038     2576397 : uint16_t ConsString::ConsStringGet(int index) {
   11039             :   DCHECK(index >= 0 && index < this->length());
   11040             : 
   11041             :   // Check for a flattened cons string
   11042     2576397 :   if (second()->length() == 0) {
   11043             :     String* left = first();
   11044      300474 :     return left->Get(index);
   11045             :   }
   11046             : 
   11047             :   String* string = String::cast(this);
   11048             : 
   11049             :   while (true) {
   11050    22223504 :     if (StringShape(string).IsCons()) {
   11051             :       ConsString* cons_string = ConsString::cast(string);
   11052             :       String* left = cons_string->first();
   11053    19947581 :       if (left->length() > index) {
   11054             :         string = left;
   11055             :       } else {
   11056      407486 :         index -= left->length();
   11057             :         string = cons_string->second();
   11058             :       }
   11059             :     } else {
   11060     2275923 :       return string->Get(index);
   11061             :     }
   11062             :   }
   11063             : 
   11064             :   UNREACHABLE();
   11065             : }
   11066             : 
   11067        4316 : uint16_t ThinString::ThinStringGet(int index) { return actual()->Get(index); }
   11068             : 
   11069     1237991 : uint16_t SlicedString::SlicedStringGet(int index) {
   11070     2475982 :   return parent()->Get(offset() + index);
   11071             : }
   11072             : 
   11073             : 
   11074             : template <typename sinkchar>
   11075   223877430 : void String::WriteToFlat(String* src,
   11076             :                          sinkchar* sink,
   11077             :                          int f,
   11078             :                          int t) {
   11079             :   String* source = src;
   11080             :   int from = f;
   11081             :   int to = t;
   11082             :   while (true) {
   11083             :     DCHECK(0 <= from && from <= to && to <= source->length());
   11084   296605740 :     switch (StringShape(source).full_representation_tag()) {
   11085             :       case kOneByteStringTag | kExternalStringTag: {
   11086             :         CopyChars(sink, ExternalOneByteString::cast(source)->GetChars() + from,
   11087      810978 :                   to - from);
   11088             :         return;
   11089             :       }
   11090             :       case kTwoByteStringTag | kExternalStringTag: {
   11091             :         const uc16* data =
   11092             :             ExternalTwoByteString::cast(source)->GetChars();
   11093             :         CopyChars(sink,
   11094             :                   data + from,
   11095      283084 :                   to - from);
   11096             :         return;
   11097             :       }
   11098             :       case kOneByteStringTag | kSeqStringTag: {
   11099             :         CopyChars(sink,
   11100   172714349 :                   SeqOneByteString::cast(source)->GetChars() + from,
   11101   345428698 :                   to - from);
   11102             :         return;
   11103             :       }
   11104             :       case kTwoByteStringTag | kSeqStringTag: {
   11105             :         CopyChars(sink,
   11106     7901734 :                   SeqTwoByteString::cast(source)->GetChars() + from,
   11107    15803468 :                   to - from);
   11108             :         return;
   11109             :       }
   11110             :       case kOneByteStringTag | kConsStringTag:
   11111             :       case kTwoByteStringTag | kConsStringTag: {
   11112             :         ConsString* cons_string = ConsString::cast(source);
   11113             :         String* first = cons_string->first();
   11114             :         int boundary = first->length();
   11115   113696206 :         if (to - boundary >= boundary - from) {
   11116             :           // Right hand side is longer.  Recurse over left.
   11117    49990012 :           if (from < boundary) {
   11118    49990012 :             WriteToFlat(first, sink, from, boundary);
   11119    99980024 :             if (from == 0 && cons_string->second() == first) {
   11120    41003981 :               CopyChars(sink + boundary, sink, boundary);
   11121             :               return;
   11122             :             }
   11123     8986031 :             sink += boundary - from;
   11124             :             from = 0;
   11125             :           } else {
   11126           0 :             from -= boundary;
   11127             :           }
   11128             :           to -= boundary;
   11129             :           source = cons_string->second();
   11130             :         } else {
   11131             :           // Left hand side is longer.  Recurse over right.
   11132    63706194 :           if (to > boundary) {
   11133             :             String* second = cons_string->second();
   11134             :             // When repeatedly appending to a string, we get a cons string that
   11135             :             // is unbalanced to the left, a list, essentially.  We inline the
   11136             :             // common case of sequential one-byte right child.
   11137    63443212 :             if (to - boundary == 1) {
   11138    49233914 :               sink[boundary - from] = static_cast<sinkchar>(second->Get(0));
   11139    38826255 :             } else if (second->IsSeqOneByteString()) {
   11140    26980495 :               CopyChars(sink + boundary - from,
   11141    26980495 :                         SeqOneByteString::cast(second)->GetChars(),
   11142    53960990 :                         to - boundary);
   11143             :             } else {
   11144    11845760 :               WriteToFlat(second,
   11145    11845760 :                           sink + boundary - from,
   11146             :                           0,
   11147    11845760 :                           to - boundary);
   11148             :             }
   11149             :             to = boundary;
   11150             :           }
   11151             :           source = first;
   11152             :         }
   11153             :         break;
   11154             :       }
   11155             :       case kOneByteStringTag | kSlicedStringTag:
   11156             :       case kTwoByteStringTag | kSlicedStringTag: {
   11157             :         SlicedString* slice = SlicedString::cast(source);
   11158     1568792 :         unsigned offset = slice->offset();
   11159     3137584 :         WriteToFlat(slice->parent(), sink, from + offset, to + offset);
   11160     1568792 :         return;
   11161             :       }
   11162             :       case kOneByteStringTag | kThinStringTag:
   11163             :       case kTwoByteStringTag | kThinStringTag:
   11164             :         source = ThinString::cast(source)->actual();
   11165       36086 :         break;
   11166             :     }
   11167             :   }
   11168             : }
   11169             : 
   11170             : template <typename SourceChar>
   11171       45720 : static void CalculateLineEndsImpl(Isolate* isolate, std::vector<int>* line_ends,
   11172             :                                   Vector<const SourceChar> src,
   11173             :                                   bool include_ending_line) {
   11174       91440 :   const int src_len = src.length();
   11175             :   UnicodeCache* cache = isolate->unicode_cache();
   11176   213205794 :   for (int i = 0; i < src_len - 1; i++) {
   11177   426320148 :     SourceChar current = src[i];
   11178   426320148 :     SourceChar next = src[i + 1];
   11179   426320148 :     if (cache->IsLineTerminatorSequence(current, next)) line_ends->push_back(i);
   11180             :   }
   11181             : 
   11182      136512 :   if (src_len > 0 && cache->IsLineTerminatorSequence(src[src_len - 1], 0)) {
   11183       34094 :     line_ends->push_back(src_len - 1);
   11184             :   }
   11185       45720 :   if (include_ending_line) {
   11186             :     // Include one character beyond the end of script. The rewriter uses that
   11187             :     // position for the implicit return statement.
   11188       44456 :     line_ends->push_back(src_len);
   11189             :   }
   11190       45720 : }
   11191             : 
   11192             : 
   11193       45720 : Handle<FixedArray> String::CalculateLineEnds(Handle<String> src,
   11194             :                                              bool include_ending_line) {
   11195       45720 :   src = Flatten(src);
   11196             :   // Rough estimate of line count based on a roughly estimated average
   11197             :   // length of (unpacked) code.
   11198       45720 :   int line_count_estimate = src->length() >> 4;
   11199             :   std::vector<int> line_ends;
   11200       45720 :   line_ends.reserve(line_count_estimate);
   11201             :   Isolate* isolate = src->GetIsolate();
   11202             :   { DisallowHeapAllocation no_allocation;  // ensure vectors stay valid.
   11203             :     // Dispatch on type of strings.
   11204       45720 :     String::FlatContent content = src->GetFlatContent();
   11205             :     DCHECK(content.IsFlat());
   11206       45720 :     if (content.IsOneByte()) {
   11207             :       CalculateLineEndsImpl(isolate,
   11208             :                             &line_ends,
   11209             :                             content.ToOneByteVector(),
   11210       91404 :                             include_ending_line);
   11211             :     } else {
   11212             :       CalculateLineEndsImpl(isolate,
   11213             :                             &line_ends,
   11214             :                             content.ToUC16Vector(),
   11215          36 :                             include_ending_line);
   11216             :     }
   11217             :   }
   11218       91440 :   int line_count = static_cast<int>(line_ends.size());
   11219       45720 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
   11220    11528329 :   for (int i = 0; i < line_count; i++) {
   11221    22965218 :     array->set(i, Smi::FromInt(line_ends[i]));
   11222             :   }
   11223       91440 :   return array;
   11224             : }
   11225             : 
   11226             : 
   11227             : // Compares the contents of two strings by reading and comparing
   11228             : // int-sized blocks of characters.
   11229             : template <typename Char>
   11230             : static inline bool CompareRawStringContents(const Char* const a,
   11231             :                                             const Char* const b,
   11232             :                                             int length) {
   11233    51511944 :   return CompareChars(a, b, length) == 0;
   11234             : }
   11235             : 
   11236             : 
   11237             : template<typename Chars1, typename Chars2>
   11238             : class RawStringComparator : public AllStatic {
   11239             :  public:
   11240             :   static inline bool compare(const Chars1* a, const Chars2* b, int len) {
   11241             :     DCHECK(sizeof(Chars1) != sizeof(Chars2));
   11242     2947468 :     for (int i = 0; i < len; i++) {
   11243     2947483 :       if (a[i] != b[i]) {
   11244             :         return false;
   11245             :       }
   11246             :     }
   11247             :     return true;
   11248             :   }
   11249             : };
   11250             : 
   11251             : 
   11252             : template<>
   11253             : class RawStringComparator<uint16_t, uint16_t> {
   11254             :  public:
   11255             :   static inline bool compare(const uint16_t* a, const uint16_t* b, int len) {
   11256             :     return CompareRawStringContents(a, b, len);
   11257             :   }
   11258             : };
   11259             : 
   11260             : 
   11261             : template<>
   11262             : class RawStringComparator<uint8_t, uint8_t> {
   11263             :  public:
   11264             :   static inline bool compare(const uint8_t* a, const uint8_t* b, int len) {
   11265             :     return CompareRawStringContents(a, b, len);
   11266             :   }
   11267             : };
   11268             : 
   11269             : 
   11270             : class StringComparator {
   11271             :   class State {
   11272             :    public:
   11273     2119394 :     State() : is_one_byte_(true), length_(0), buffer8_(nullptr) {}
   11274             : 
   11275     4238788 :     void Init(String* string) {
   11276     4238788 :       ConsString* cons_string = String::VisitFlat(this, string);
   11277             :       iter_.Reset(cons_string);
   11278     4238788 :       if (cons_string != nullptr) {
   11279             :         int offset;
   11280     2130716 :         string = iter_.Next(&offset);
   11281     2130716 :         String::VisitFlat(this, string, offset);
   11282             :       }
   11283     4238788 :     }
   11284             : 
   11285             :     inline void VisitOneByteString(const uint8_t* chars, int length) {
   11286    24958339 :       is_one_byte_ = true;
   11287    24958339 :       buffer8_ = chars;
   11288    24958339 :       length_ = length;
   11289             :     }
   11290             : 
   11291             :     inline void VisitTwoByteString(const uint16_t* chars, int length) {
   11292     1623878 :       is_one_byte_ = false;
   11293     1623878 :       buffer16_ = chars;
   11294     1623878 :       length_ = length;
   11295             :     }
   11296             : 
   11297    27824344 :     void Advance(int consumed) {
   11298             :       DCHECK(consumed <= length_);
   11299             :       // Still in buffer.
   11300    27824344 :       if (length_ != consumed) {
   11301     5480915 :         if (is_one_byte_) {
   11302     4757504 :           buffer8_ += consumed;
   11303             :         } else {
   11304      723411 :           buffer16_ += consumed;
   11305             :         }
   11306     5480915 :         length_ -= consumed;
   11307    33305259 :         return;
   11308             :       }
   11309             :       // Advance state.
   11310             :       int offset;
   11311    22343429 :       String* next = iter_.Next(&offset);
   11312             :       DCHECK_EQ(0, offset);
   11313             :       DCHECK_NOT_NULL(next);
   11314    22343429 :       String::VisitFlat(this, next);
   11315             :     }
   11316             : 
   11317             :     ConsStringIterator iter_;
   11318             :     bool is_one_byte_;
   11319             :     int length_;
   11320             :     union {
   11321             :       const uint8_t* buffer8_;
   11322             :       const uint16_t* buffer16_;
   11323             :     };
   11324             : 
   11325             :    private:
   11326             :     DISALLOW_COPY_AND_ASSIGN(State);
   11327             :   };
   11328             : 
   11329             :  public:
   11330             :   inline StringComparator() {}
   11331             : 
   11332             :   template<typename Chars1, typename Chars2>
   11333             :   static inline bool Equals(State* state_1, State* state_2, int to_check) {
   11334             :     const Chars1* a = reinterpret_cast<const Chars1*>(state_1->buffer8_);
   11335             :     const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_);
   11336             :     return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check);
   11337             :   }
   11338             : 
   11339     2119394 :   bool Equals(String* string_1, String* string_2) {
   11340             :     int length = string_1->length();
   11341    18150960 :     state_1_.Init(string_1);
   11342    18150960 :     state_2_.Init(string_2);
   11343             :     while (true) {
   11344    16031566 :       int to_check = Min(state_1_.length_, state_2_.length_);
   11345             :       DCHECK(to_check > 0 && to_check <= length);
   11346             :       bool is_equal;
   11347    16031566 :       if (state_1_.is_one_byte_) {
   11348    14496921 :         if (state_2_.is_one_byte_) {
   11349             :           is_equal = Equals<uint8_t, uint8_t>(&state_1_, &state_2_, to_check);
   11350             :         } else {
   11351             :           is_equal = Equals<uint8_t, uint16_t>(&state_1_, &state_2_, to_check);
   11352             :         }
   11353             :       } else {
   11354     1534645 :         if (state_2_.is_one_byte_) {
   11355             :           is_equal = Equals<uint16_t, uint8_t>(&state_1_, &state_2_, to_check);
   11356             :         } else {
   11357             :           is_equal = Equals<uint16_t, uint16_t>(&state_1_, &state_2_, to_check);
   11358             :         }
   11359             :       }
   11360             :       // Looping done.
   11361    16031566 :       if (!is_equal) return false;
   11362    16024823 :       length -= to_check;
   11363             :       // Exit condition. Strings are equal.
   11364    16024823 :       if (length == 0) return true;
   11365    13912172 :       state_1_.Advance(to_check);
   11366    13912172 :       state_2_.Advance(to_check);
   11367    13912172 :     }
   11368             :   }
   11369             : 
   11370             :  private:
   11371             :   State state_1_;
   11372             :   State state_2_;
   11373             : 
   11374             :   DISALLOW_COPY_AND_ASSIGN(StringComparator);
   11375             : };
   11376             : 
   11377             : 
   11378    16636501 : bool String::SlowEquals(String* other) {
   11379             :   DisallowHeapAllocation no_gc;
   11380             :   // Fast check: negative check with lengths.
   11381             :   int len = length();
   11382    16636501 :   if (len != other->length()) return false;
   11383    12711256 :   if (len == 0) return true;
   11384             : 
   11385             :   // Fast check: if at least one ThinString is involved, dereference it/them
   11386             :   // and restart.
   11387    25420255 :   if (this->IsThinString() || other->IsThinString()) {
   11388        4543 :     if (other->IsThinString()) other = ThinString::cast(other)->actual();
   11389        4543 :     if (this->IsThinString()) {
   11390        2257 :       return ThinString::cast(this)->actual()->Equals(other);
   11391             :     } else {
   11392        2286 :       return this->Equals(other);
   11393             :     }
   11394             :   }
   11395             : 
   11396             :   // Fast check: if hash code is computed for both strings
   11397             :   // a fast negative check can be performed.
   11398    25208082 :   if (HasHashCode() && other->HasHashCode()) {
   11399             : #ifdef ENABLE_SLOW_DCHECKS
   11400             :     if (FLAG_enable_slow_asserts) {
   11401             :       if (Hash() != other->Hash()) {
   11402             :         bool found_difference = false;
   11403             :         for (int i = 0; i < len; i++) {
   11404             :           if (Get(i) != other->Get(i)) {
   11405             :             found_difference = true;
   11406             :             break;
   11407             :           }
   11408             :         }
   11409             :         DCHECK(found_difference);
   11410             :       }
   11411             :     }
   11412             : #endif
   11413    12500146 :     if (Hash() != other->Hash()) return false;
   11414             :   }
   11415             : 
   11416             :   // We know the strings are both non-empty. Compare the first chars
   11417             :   // before we try to flatten the strings.
   11418    11627037 :   if (this->Get(0) != other->Get(0)) return false;
   11419             : 
   11420    21519932 :   if (IsSeqOneByteString() && other->IsSeqOneByteString()) {
   11421     9506760 :     const uint8_t* str1 = SeqOneByteString::cast(this)->GetChars();
   11422     9506760 :     const uint8_t* str2 = SeqOneByteString::cast(other)->GetChars();
   11423     9506760 :     return CompareRawStringContents(str1, str2, len);
   11424             :   }
   11425             : 
   11426             :   StringComparator comparator;
   11427     2119394 :   return comparator.Equals(this, other);
   11428             : }
   11429             : 
   11430             : 
   11431     4313902 : bool String::SlowEquals(Handle<String> one, Handle<String> two) {
   11432             :   // Fast check: negative check with lengths.
   11433             :   int one_length = one->length();
   11434     4313902 :   if (one_length != two->length()) return false;
   11435     4303375 :   if (one_length == 0) return true;
   11436             : 
   11437             :   // Fast check: if at least one ThinString is involved, dereference it/them
   11438             :   // and restart.
   11439     8606750 :   if (one->IsThinString() || two->IsThinString()) {
   11440          23 :     if (one->IsThinString()) one = handle(ThinString::cast(*one)->actual());
   11441          23 :     if (two->IsThinString()) two = handle(ThinString::cast(*two)->actual());
   11442          23 :     return String::Equals(one, two);
   11443             :   }
   11444             : 
   11445             :   // Fast check: if hash code is computed for both strings
   11446             :   // a fast negative check can be performed.
   11447     4319579 :   if (one->HasHashCode() && two->HasHashCode()) {
   11448             : #ifdef ENABLE_SLOW_DCHECKS
   11449             :     if (FLAG_enable_slow_asserts) {
   11450             :       if (one->Hash() != two->Hash()) {
   11451             :         bool found_difference = false;
   11452             :         for (int i = 0; i < one_length; i++) {
   11453             :           if (one->Get(i) != two->Get(i)) {
   11454             :             found_difference = true;
   11455             :             break;
   11456             :           }
   11457             :         }
   11458             :         DCHECK(found_difference);
   11459             :       }
   11460             :     }
   11461             : #endif
   11462        5635 :     if (one->Hash() != two->Hash()) return false;
   11463             :   }
   11464             : 
   11465             :   // We know the strings are both non-empty. Compare the first chars
   11466             :   // before we try to flatten the strings.
   11467     4303207 :   if (one->Get(0) != two->Get(0)) return false;
   11468             : 
   11469     2936423 :   one = String::Flatten(one);
   11470     2936423 :   two = String::Flatten(two);
   11471             : 
   11472             :   DisallowHeapAllocation no_gc;
   11473     2936423 :   String::FlatContent flat1 = one->GetFlatContent();
   11474     2936423 :   String::FlatContent flat2 = two->GetFlatContent();
   11475             : 
   11476     2936423 :   if (flat1.IsOneByte() && flat2.IsOneByte()) {
   11477             :       return CompareRawStringContents(flat1.ToOneByteVector().start(),
   11478             :                                       flat2.ToOneByteVector().start(),
   11479             :                                       one_length);
   11480             :   } else {
   11481    13652567 :     for (int i = 0; i < one_length; i++) {
   11482    13652567 :       if (flat1.Get(i) != flat2.Get(i)) return false;
   11483             :     }
   11484             :     return true;
   11485             :   }
   11486             : }
   11487             : 
   11488             : 
   11489             : // static
   11490     5120741 : ComparisonResult String::Compare(Handle<String> x, Handle<String> y) {
   11491             :   // A few fast case tests before we flatten.
   11492     5120741 :   if (x.is_identical_to(y)) {
   11493             :     return ComparisonResult::kEqual;
   11494     5120735 :   } else if (y->length() == 0) {
   11495             :     return x->length() == 0 ? ComparisonResult::kEqual
   11496           0 :                             : ComparisonResult::kGreaterThan;
   11497     5120735 :   } else if (x->length() == 0) {
   11498             :     return ComparisonResult::kLessThan;
   11499             :   }
   11500             : 
   11501    10241470 :   int const d = x->Get(0) - y->Get(0);
   11502     5120735 :   if (d < 0) {
   11503             :     return ComparisonResult::kLessThan;
   11504     3353726 :   } else if (d > 0) {
   11505             :     return ComparisonResult::kGreaterThan;
   11506             :   }
   11507             : 
   11508             :   // Slow case.
   11509      410957 :   x = String::Flatten(x);
   11510      410957 :   y = String::Flatten(y);
   11511             : 
   11512             :   DisallowHeapAllocation no_gc;
   11513             :   ComparisonResult result = ComparisonResult::kEqual;
   11514             :   int prefix_length = x->length();
   11515      410957 :   if (y->length() < prefix_length) {
   11516             :     prefix_length = y->length();
   11517             :     result = ComparisonResult::kGreaterThan;
   11518      370717 :   } else if (y->length() > prefix_length) {
   11519             :     result = ComparisonResult::kLessThan;
   11520             :   }
   11521             :   int r;
   11522      410957 :   String::FlatContent x_content = x->GetFlatContent();
   11523      410957 :   String::FlatContent y_content = y->GetFlatContent();
   11524      410957 :   if (x_content.IsOneByte()) {
   11525             :     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
   11526      393577 :     if (y_content.IsOneByte()) {
   11527             :       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   11528      391489 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11529             :     } else {
   11530             :       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   11531        2088 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11532             :     }
   11533             :   } else {
   11534             :     Vector<const uc16> x_chars = x_content.ToUC16Vector();
   11535       17380 :     if (y_content.IsOneByte()) {
   11536             :       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   11537        1044 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11538             :     } else {
   11539             :       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   11540       16336 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11541             :     }
   11542             :   }
   11543      410957 :   if (r < 0) {
   11544             :     result = ComparisonResult::kLessThan;
   11545      162295 :   } else if (r > 0) {
   11546             :     result = ComparisonResult::kGreaterThan;
   11547             :   }
   11548      410957 :   return result;
   11549             : }
   11550             : 
   11551        2439 : Object* String::IndexOf(Isolate* isolate, Handle<Object> receiver,
   11552             :                         Handle<Object> search, Handle<Object> position) {
   11553        2439 :   if (receiver->IsNullOrUndefined(isolate)) {
   11554         600 :     THROW_NEW_ERROR_RETURN_FAILURE(
   11555             :         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
   11556             :                               isolate->factory()->NewStringFromAsciiChecked(
   11557             :                                   "String.prototype.indexOf")));
   11558             :   }
   11559             :   Handle<String> receiver_string;
   11560        4478 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_string,
   11561             :                                      Object::ToString(isolate, receiver));
   11562             : 
   11563             :   Handle<String> search_string;
   11564        4478 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, search_string,
   11565             :                                      Object::ToString(isolate, search));
   11566             : 
   11567        2239 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   11568             :                                      Object::ToInteger(isolate, position));
   11569             : 
   11570             :   uint32_t index = receiver_string->ToValidIndex(*position);
   11571             :   return Smi::FromInt(
   11572        4458 :       String::IndexOf(isolate, receiver_string, search_string, index));
   11573             : }
   11574             : 
   11575             : namespace {
   11576             : 
   11577             : template <typename T>
   11578      117734 : int SearchString(Isolate* isolate, String::FlatContent receiver_content,
   11579             :                  Vector<T> pat_vector, int start_index) {
   11580      117734 :   if (receiver_content.IsOneByte()) {
   11581             :     return SearchString(isolate, receiver_content.ToOneByteVector(), pat_vector,
   11582      117508 :                         start_index);
   11583             :   }
   11584             :   return SearchString(isolate, receiver_content.ToUC16Vector(), pat_vector,
   11585         226 :                       start_index);
   11586             : }
   11587             : 
   11588             : }  // namespace
   11589             : 
   11590      120555 : int String::IndexOf(Isolate* isolate, Handle<String> receiver,
   11591             :                     Handle<String> search, int start_index) {
   11592             :   DCHECK_LE(0, start_index);
   11593             :   DCHECK(start_index <= receiver->length());
   11594             : 
   11595      120555 :   uint32_t search_length = search->length();
   11596      120555 :   if (search_length == 0) return start_index;
   11597             : 
   11598      120508 :   uint32_t receiver_length = receiver->length();
   11599      120508 :   if (start_index + search_length > receiver_length) return -1;
   11600             : 
   11601      117734 :   receiver = String::Flatten(receiver);
   11602      117734 :   search = String::Flatten(search);
   11603             : 
   11604             :   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   11605             :   // Extract flattened substrings of cons strings before getting encoding.
   11606      117734 :   String::FlatContent receiver_content = receiver->GetFlatContent();
   11607      117734 :   String::FlatContent search_content = search->GetFlatContent();
   11608             : 
   11609             :   // dispatch on type of strings
   11610      117734 :   if (search_content.IsOneByte()) {
   11611      115747 :     Vector<const uint8_t> pat_vector = search_content.ToOneByteVector();
   11612             :     return SearchString<const uint8_t>(isolate, receiver_content, pat_vector,
   11613      115747 :                                        start_index);
   11614             :   }
   11615        1987 :   Vector<const uc16> pat_vector = search_content.ToUC16Vector();
   11616             :   return SearchString<const uc16>(isolate, receiver_content, pat_vector,
   11617        1987 :                                   start_index);
   11618             : }
   11619             : 
   11620        3976 : MaybeHandle<String> String::GetSubstitution(Isolate* isolate, Match* match,
   11621             :                                             Handle<String> replacement,
   11622             :                                             int start_index) {
   11623             :   DCHECK_IMPLIES(match->HasNamedCaptures(), FLAG_harmony_regexp_named_captures);
   11624             :   DCHECK_GE(start_index, 0);
   11625             : 
   11626             :   Factory* factory = isolate->factory();
   11627             : 
   11628             :   const int replacement_length = replacement->length();
   11629        3976 :   const int captures_length = match->CaptureCount();
   11630             : 
   11631        3976 :   replacement = String::Flatten(replacement);
   11632             : 
   11633             :   Handle<String> dollar_string =
   11634        3976 :       factory->LookupSingleCharacterStringFromCode('$');
   11635             :   int next_dollar_ix =
   11636        3976 :       String::IndexOf(isolate, replacement, dollar_string, start_index);
   11637        3976 :   if (next_dollar_ix < 0) {
   11638          50 :     return replacement;
   11639             :   }
   11640             : 
   11641        3926 :   IncrementalStringBuilder builder(isolate);
   11642             : 
   11643        3926 :   if (next_dollar_ix > 0) {
   11644         310 :     builder.AppendString(factory->NewSubString(replacement, 0, next_dollar_ix));
   11645             :   }
   11646             : 
   11647             :   while (true) {
   11648        8599 :     const int peek_ix = next_dollar_ix + 1;
   11649        8599 :     if (peek_ix >= replacement_length) {
   11650             :       builder.AppendCharacter('$');
   11651          20 :       return builder.Finish();
   11652             :     }
   11653             : 
   11654             :     int continue_from_ix = -1;
   11655             :     const uint16_t peek = replacement->Get(peek_ix);
   11656        8579 :     switch (peek) {
   11657             :       case '$':  // $$
   11658             :         builder.AppendCharacter('$');
   11659          60 :         continue_from_ix = peek_ix + 1;
   11660          60 :         break;
   11661             :       case '&':  // $& - match
   11662          60 :         builder.AppendString(match->GetMatch());
   11663          60 :         continue_from_ix = peek_ix + 1;
   11664          60 :         break;
   11665             :       case '`':  // $` - prefix
   11666          40 :         builder.AppendString(match->GetPrefix());
   11667          40 :         continue_from_ix = peek_ix + 1;
   11668          40 :         break;
   11669             :       case '\'':  // $' - suffix
   11670          40 :         builder.AppendString(match->GetSuffix());
   11671          40 :         continue_from_ix = peek_ix + 1;
   11672          40 :         break;
   11673             :       case '0':
   11674             :       case '1':
   11675             :       case '2':
   11676             :       case '3':
   11677             :       case '4':
   11678             :       case '5':
   11679             :       case '6':
   11680             :       case '7':
   11681             :       case '8':
   11682             :       case '9': {
   11683             :         // Valid indices are $1 .. $9, $01 .. $09 and $10 .. $99
   11684        7998 :         int scaled_index = (peek - '0');
   11685             :         int advance = 1;
   11686             : 
   11687        7998 :         if (peek_ix + 1 < replacement_length) {
   11688             :           const uint16_t next_peek = replacement->Get(peek_ix + 1);
   11689        6661 :           if (next_peek >= '0' && next_peek <= '9') {
   11690        1490 :             const int new_scaled_index = scaled_index * 10 + (next_peek - '0');
   11691        1490 :             if (new_scaled_index < captures_length) {
   11692             :               scaled_index = new_scaled_index;
   11693             :               advance = 2;
   11694             :             }
   11695             :           }
   11696             :         }
   11697             : 
   11698        7998 :         if (scaled_index == 0 || scaled_index >= captures_length) {
   11699             :           builder.AppendCharacter('$');
   11700             :           continue_from_ix = peek_ix;
   11701        8098 :           break;
   11702             :         }
   11703             : 
   11704             :         bool capture_exists;
   11705             :         Handle<String> capture;
   11706       15796 :         ASSIGN_RETURN_ON_EXCEPTION(
   11707             :             isolate, capture, match->GetCapture(scaled_index, &capture_exists),
   11708             :             String);
   11709        7898 :         if (capture_exists) builder.AppendString(capture);
   11710        7898 :         continue_from_ix = peek_ix + advance;
   11711        7898 :         break;
   11712             :       }
   11713             :       case '<': {  // $<name> - named capture
   11714             :         typedef String::Match::CaptureState CaptureState;
   11715             : 
   11716         351 :         if (!match->HasNamedCaptures()) {
   11717             :           builder.AppendCharacter('$');
   11718             :           continue_from_ix = peek_ix;
   11719         414 :           break;
   11720             :         }
   11721             : 
   11722             :         Handle<String> bracket_string =
   11723         288 :             factory->LookupSingleCharacterStringFromCode('>');
   11724             :         const int closing_bracket_ix =
   11725         288 :             String::IndexOf(isolate, replacement, bracket_string, peek_ix + 1);
   11726             : 
   11727         288 :         if (closing_bracket_ix == -1) {
   11728             :           // No closing bracket was found, treat '$<' as a string literal.
   11729             :           builder.AppendCharacter('$');
   11730             :           continue_from_ix = peek_ix;
   11731          72 :           break;
   11732             :         }
   11733             : 
   11734             :         Handle<String> capture_name =
   11735         216 :             factory->NewSubString(replacement, peek_ix + 1, closing_bracket_ix);
   11736             :         Handle<String> capture;
   11737             :         CaptureState capture_state;
   11738         432 :         ASSIGN_RETURN_ON_EXCEPTION(
   11739             :             isolate, capture,
   11740             :             match->GetNamedCapture(capture_name, &capture_state), String);
   11741             : 
   11742         216 :         switch (capture_state) {
   11743             :           case CaptureState::INVALID:
   11744             :           case CaptureState::UNMATCHED:
   11745             :             break;
   11746             :           case CaptureState::MATCHED:
   11747          72 :             builder.AppendString(capture);
   11748          72 :             break;
   11749             :         }
   11750             : 
   11751         216 :         continue_from_ix = closing_bracket_ix + 1;
   11752         216 :         break;
   11753             :       }
   11754             :       default:
   11755             :         builder.AppendCharacter('$');
   11756             :         continue_from_ix = peek_ix;
   11757          30 :         break;
   11758             :     }
   11759             : 
   11760             :     // Go the the next $ in the replacement.
   11761             :     // TODO(jgruber): Single-char lookups could be much more efficient.
   11762             :     DCHECK_NE(continue_from_ix, -1);
   11763             :     next_dollar_ix =
   11764        8579 :         String::IndexOf(isolate, replacement, dollar_string, continue_from_ix);
   11765             : 
   11766             :     // Return if there are no more $ characters in the replacement. If we
   11767             :     // haven't reached the end, we need to append the suffix.
   11768        8579 :     if (next_dollar_ix < 0) {
   11769        3906 :       if (continue_from_ix < replacement_length) {
   11770             :         builder.AppendString(factory->NewSubString(
   11771        1369 :             replacement, continue_from_ix, replacement_length));
   11772             :       }
   11773        3906 :       return builder.Finish();
   11774             :     }
   11775             : 
   11776             :     // Append substring between the previous and the next $ character.
   11777        4673 :     if (next_dollar_ix > continue_from_ix) {
   11778             :       builder.AppendString(
   11779          72 :           factory->NewSubString(replacement, continue_from_ix, next_dollar_ix));
   11780             :     }
   11781             :   }
   11782             : 
   11783             :   UNREACHABLE();
   11784             : }
   11785             : 
   11786             : namespace {  // for String.Prototype.lastIndexOf
   11787             : 
   11788             : template <typename schar, typename pchar>
   11789        1579 : int StringMatchBackwards(Vector<const schar> subject,
   11790             :                          Vector<const pchar> pattern, int idx) {
   11791        1579 :   int pattern_length = pattern.length();
   11792             :   DCHECK_GE(pattern_length, 1);
   11793             :   DCHECK(idx + pattern_length <= subject.length());
   11794             : 
   11795             :   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
   11796           0 :     for (int i = 0; i < pattern_length; i++) {
   11797           0 :       uc16 c = pattern[i];
   11798           0 :       if (c > String::kMaxOneByteCharCode) {
   11799             :         return -1;
   11800             :       }
   11801             :     }
   11802             :   }
   11803             : 
   11804        1579 :   pchar pattern_first_char = pattern[0];
   11805        5704 :   for (int i = idx; i >= 0; i--) {
   11806       14198 :     if (subject[i] != pattern_first_char) continue;
   11807             :     int j = 1;
   11808        2159 :     while (j < pattern_length) {
   11809        2292 :       if (pattern[j] != subject[i + j]) {
   11810             :         break;
   11811             :       }
   11812         744 :       j++;
   11813             :     }
   11814        1415 :     if (j == pattern_length) {
   11815             :       return i;
   11816             :     }
   11817             :   }
   11818             :   return -1;
   11819             : }
   11820             : 
   11821             : }  // namespace
   11822             : 
   11823        2039 : Object* String::LastIndexOf(Isolate* isolate, Handle<Object> receiver,
   11824             :                             Handle<Object> search, Handle<Object> position) {
   11825        2039 :   if (receiver->IsNullOrUndefined(isolate)) {
   11826         540 :     THROW_NEW_ERROR_RETURN_FAILURE(
   11827             :         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
   11828             :                               isolate->factory()->NewStringFromAsciiChecked(
   11829             :                                   "String.prototype.lastIndexOf")));
   11830             :   }
   11831             :   Handle<String> receiver_string;
   11832        3718 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_string,
   11833             :                                      Object::ToString(isolate, receiver));
   11834             : 
   11835             :   Handle<String> search_string;
   11836        3718 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, search_string,
   11837             :                                      Object::ToString(isolate, search));
   11838             : 
   11839        3718 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   11840             :                                      Object::ToNumber(position));
   11841             : 
   11842             :   uint32_t start_index;
   11843             : 
   11844        1859 :   if (position->IsNaN()) {
   11845        1329 :     start_index = receiver_string->length();
   11846             :   } else {
   11847         530 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   11848             :                                        Object::ToInteger(isolate, position));
   11849             :     start_index = receiver_string->ToValidIndex(*position);
   11850             :   }
   11851             : 
   11852        1859 :   uint32_t pattern_length = search_string->length();
   11853        1859 :   uint32_t receiver_length = receiver_string->length();
   11854             : 
   11855        1859 :   if (start_index + pattern_length > receiver_length) {
   11856        1409 :     start_index = receiver_length - pattern_length;
   11857             :   }
   11858             : 
   11859        1859 :   if (pattern_length == 0) {
   11860         560 :     return Smi::FromInt(start_index);
   11861             :   }
   11862             : 
   11863        1579 :   receiver_string = String::Flatten(receiver_string);
   11864        1579 :   search_string = String::Flatten(search_string);
   11865             : 
   11866             :   int last_index = -1;
   11867             :   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   11868             : 
   11869        1579 :   String::FlatContent receiver_content = receiver_string->GetFlatContent();
   11870        1579 :   String::FlatContent search_content = search_string->GetFlatContent();
   11871             : 
   11872        1579 :   if (search_content.IsOneByte()) {
   11873        1579 :     Vector<const uint8_t> pat_vector = search_content.ToOneByteVector();
   11874        1579 :     if (receiver_content.IsOneByte()) {
   11875             :       last_index = StringMatchBackwards(receiver_content.ToOneByteVector(),
   11876        1573 :                                         pat_vector, start_index);
   11877             :     } else {
   11878             :       last_index = StringMatchBackwards(receiver_content.ToUC16Vector(),
   11879           6 :                                         pat_vector, start_index);
   11880             :     }
   11881             :   } else {
   11882           0 :     Vector<const uc16> pat_vector = search_content.ToUC16Vector();
   11883           0 :     if (receiver_content.IsOneByte()) {
   11884             :       last_index = StringMatchBackwards(receiver_content.ToOneByteVector(),
   11885           0 :                                         pat_vector, start_index);
   11886             :     } else {
   11887             :       last_index = StringMatchBackwards(receiver_content.ToUC16Vector(),
   11888           0 :                                         pat_vector, start_index);
   11889             :     }
   11890             :   }
   11891        1579 :   return Smi::FromInt(last_index);
   11892             : }
   11893             : 
   11894    25823454 : bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) {
   11895             :   int slen = length();
   11896             :   // Can't check exact length equality, but we can check bounds.
   11897    25823454 :   int str_len = str.length();
   11898    25823454 :   if (!allow_prefix_match &&
   11899    25020651 :       (str_len < slen ||
   11900    25020651 :           str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) {
   11901             :     return false;
   11902             :   }
   11903             :   int i;
   11904    24963901 :   size_t remaining_in_str = static_cast<size_t>(str_len);
   11905    24963901 :   const uint8_t* utf8_data = reinterpret_cast<const uint8_t*>(str.start());
   11906   697222780 :   for (i = 0; i < slen && remaining_in_str > 0; i++) {
   11907   332003234 :     size_t cursor = 0;
   11908   332003234 :     uint32_t r = unibrow::Utf8::ValueOf(utf8_data, remaining_in_str, &cursor);
   11909             :     DCHECK(cursor > 0 && cursor <= remaining_in_str);
   11910   332003234 :     if (r > unibrow::Utf16::kMaxNonSurrogateCharCode) {
   11911     8355757 :       if (i > slen - 1) return false;
   11912          24 :       if (Get(i++) != unibrow::Utf16::LeadSurrogate(r)) return false;
   11913          12 :       if (Get(i) != unibrow::Utf16::TrailSurrogate(r)) return false;
   11914             :     } else {
   11915   332003222 :       if (Get(i) != r) return false;
   11916             :     }
   11917   323647489 :     utf8_data += cursor;
   11918   323647489 :     remaining_in_str -= cursor;
   11919             :   }
   11920    16608156 :   return (allow_prefix_match || i == slen) && remaining_in_str == 0;
   11921             : }
   11922             : 
   11923             : template <>
   11924         135 : bool String::IsEqualTo(Vector<const uint8_t> str) {
   11925         135 :   return IsOneByteEqualTo(str);
   11926             : }
   11927             : 
   11928             : template <>
   11929           0 : bool String::IsEqualTo(Vector<const uc16> str) {
   11930           0 :   return IsTwoByteEqualTo(str);
   11931             : }
   11932             : 
   11933    90244315 : bool String::IsOneByteEqualTo(Vector<const uint8_t> str) {
   11934             :   int slen = length();
   11935   180488630 :   if (str.length() != slen) return false;
   11936             :   DisallowHeapAllocation no_gc;
   11937    75655719 :   FlatContent content = GetFlatContent();
   11938    75655722 :   if (content.IsOneByte()) {
   11939    75655663 :     return CompareChars(content.ToOneByteVector().start(),
   11940   151311326 :                         str.start(), slen) == 0;
   11941             :   }
   11942          82 :   for (int i = 0; i < slen; i++) {
   11943         258 :     if (Get(i) != static_cast<uint16_t>(str[i])) return false;
   11944             :   }
   11945             :   return true;
   11946             : }
   11947             : 
   11948             : 
   11949       25494 : bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
   11950             :   int slen = length();
   11951       50988 :   if (str.length() != slen) return false;
   11952             :   DisallowHeapAllocation no_gc;
   11953        8193 :   FlatContent content = GetFlatContent();
   11954        8193 :   if (content.IsTwoByte()) {
   11955       14744 :     return CompareChars(content.ToUC16Vector().start(), str.start(), slen) == 0;
   11956             :   }
   11957           0 :   for (int i = 0; i < slen; i++) {
   11958        1642 :     if (Get(i) != str[i]) return false;
   11959             :   }
   11960             :   return true;
   11961             : }
   11962             : 
   11963             : 
   11964    63848349 : uint32_t String::ComputeAndSetHash() {
   11965             :   // Should only be called if hash code has not yet been computed.
   11966             :   DCHECK(!HasHashCode());
   11967             : 
   11968             :   // Store the hash code in the object.
   11969    63848349 :   uint32_t field = IteratingStringHasher::Hash(this, GetHeap()->HashSeed());
   11970             :   set_hash_field(field);
   11971             : 
   11972             :   // Check the hash code is there.
   11973             :   DCHECK(HasHashCode());
   11974    63848510 :   uint32_t result = field >> kHashShift;
   11975             :   DCHECK_NE(result, 0);  // Ensure that the hash value of 0 is never computed.
   11976    63848510 :   return result;
   11977             : }
   11978             : 
   11979             : 
   11980     3429979 : bool String::ComputeArrayIndex(uint32_t* index) {
   11981             :   int length = this->length();
   11982     3429979 :   if (length == 0 || length > kMaxArrayIndexSize) return false;
   11983             :   StringCharacterStream stream(this);
   11984     1760817 :   return StringToArrayIndex(&stream, index);
   11985             : }
   11986             : 
   11987             : 
   11988    12573935 : bool String::SlowAsArrayIndex(uint32_t* index) {
   11989    12573935 :   if (length() <= kMaxCachedArrayIndexLength) {
   11990     9143956 :     Hash();  // force computation of hash code
   11991             :     uint32_t field = hash_field();
   11992     9143956 :     if ((field & kIsNotArrayIndexMask) != 0) return false;
   11993             :     // Isolate the array index form the full hash field.
   11994      509908 :     *index = ArrayIndexValueBits::decode(field);
   11995      509908 :     return true;
   11996             :   } else {
   11997     3429979 :     return ComputeArrayIndex(index);
   11998             :   }
   11999             : }
   12000             : 
   12001             : 
   12002    25817815 : Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) {
   12003             :   Heap* heap = string->GetHeap();
   12004    25817815 :   if (new_length == 0) return heap->isolate()->factory()->empty_string();
   12005             : 
   12006             :   int new_size, old_size;
   12007             :   int old_length = string->length();
   12008    19250877 :   if (old_length <= new_length) return string;
   12009             : 
   12010    18214886 :   if (string->IsSeqOneByteString()) {
   12011             :     old_size = SeqOneByteString::SizeFor(old_length);
   12012             :     new_size = SeqOneByteString::SizeFor(new_length);
   12013             :   } else {
   12014             :     DCHECK(string->IsSeqTwoByteString());
   12015             :     old_size = SeqTwoByteString::SizeFor(old_length);
   12016             :     new_size = SeqTwoByteString::SizeFor(new_length);
   12017             :   }
   12018             : 
   12019    18214886 :   int delta = old_size - new_size;
   12020             : 
   12021    18214886 :   Address start_of_string = string->address();
   12022             :   DCHECK_OBJECT_ALIGNED(start_of_string);
   12023             :   DCHECK_OBJECT_ALIGNED(start_of_string + new_size);
   12024             : 
   12025             :   // Sizes are pointer size aligned, so that we can use filler objects
   12026             :   // that are a multiple of pointer size.
   12027             :   heap->CreateFillerObjectAt(start_of_string + new_size, delta,
   12028    18214886 :                              ClearRecordedSlots::kNo);
   12029             :   // We are storing the new length using release store after creating a filler
   12030             :   // for the left-over space to avoid races with the sweeper thread.
   12031             :   string->synchronized_set_length(new_length);
   12032             : 
   12033    18214886 :   return string;
   12034             : }
   12035             : 
   12036      177406 : void SeqOneByteString::clear_padding() {
   12037      177406 :   int data_size = SeqString::kHeaderSize + length() * kOneByteSize;
   12038      177406 :   memset(address() + data_size, 0, SizeFor(length()) - data_size);
   12039      177406 : }
   12040             : 
   12041           0 : void SeqTwoByteString::clear_padding() {
   12042           0 :   int data_size = SeqString::kHeaderSize + length() * kUC16Size;
   12043           0 :   memset(address() + data_size, 0, SizeFor(length()) - data_size);
   12044           0 : }
   12045             : 
   12046     1513200 : uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
   12047             :   // For array indexes mix the length into the hash as an array index could
   12048             :   // be zero.
   12049             :   DCHECK_GT(length, 0);
   12050             :   DCHECK_LE(length, String::kMaxArrayIndexSize);
   12051             :   DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) <
   12052             :          (1 << String::kArrayIndexValueBits));
   12053             : 
   12054     5901124 :   value <<= String::ArrayIndexValueBits::kShift;
   12055     5901124 :   value |= length << String::ArrayIndexLengthBits::kShift;
   12056             : 
   12057             :   DCHECK_EQ(value & String::kIsNotArrayIndexMask, 0);
   12058             :   DCHECK_EQ(length <= String::kMaxCachedArrayIndexLength,
   12059             :             Name::ContainsCachedArrayIndex(value));
   12060     1513200 :   return value;
   12061             : }
   12062             : 
   12063             : 
   12064   210939162 : uint32_t StringHasher::GetHashField() {
   12065   210939162 :   if (length_ <= String::kMaxHashCalcLength) {
   12066   210894699 :     if (is_array_index_) {
   12067     8020144 :       return MakeArrayIndexHash(array_index_, length_);
   12068             :     }
   12069   413769254 :     return (GetHashCore(raw_running_hash_) << String::kHashShift) |
   12070   206884627 :            String::kIsNotArrayIndexMask;
   12071             :   } else {
   12072       44463 :     return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask;
   12073             :   }
   12074             : }
   12075             : 
   12076             : 
   12077    16790285 : uint32_t StringHasher::ComputeUtf8Hash(Vector<const char> chars,
   12078             :                                        uint32_t seed,
   12079             :                                        int* utf16_length_out) {
   12080    16790285 :   int vector_length = chars.length();
   12081             :   // Handle some edge cases
   12082    16790285 :   if (vector_length <= 1) {
   12083             :     DCHECK(vector_length == 0 ||
   12084             :            static_cast<uint8_t>(chars.start()[0]) <=
   12085             :                unibrow::Utf8::kMaxOneByteChar);
   12086        2370 :     *utf16_length_out = vector_length;
   12087        2370 :     return HashSequentialString(chars.start(), vector_length, seed);
   12088             :   }
   12089             :   // Start with a fake length which won't affect computation.
   12090             :   // It will be updated later.
   12091             :   StringHasher hasher(String::kMaxArrayIndexSize, seed);
   12092    16787915 :   size_t remaining = static_cast<size_t>(vector_length);
   12093             :   const uint8_t* stream = reinterpret_cast<const uint8_t*>(chars.start());
   12094             :   int utf16_length = 0;
   12095             :   bool is_index = true;
   12096             :   DCHECK(hasher.is_array_index_);
   12097   358512549 :   while (remaining > 0) {
   12098   324936719 :     size_t consumed = 0;
   12099   324936719 :     uint32_t c = unibrow::Utf8::ValueOf(stream, remaining, &consumed);
   12100             :     DCHECK(consumed > 0 && consumed <= remaining);
   12101   324936719 :     stream += consumed;
   12102   324936719 :     remaining -= consumed;
   12103   324936719 :     bool is_two_characters = c > unibrow::Utf16::kMaxNonSurrogateCharCode;
   12104   324936719 :     utf16_length += is_two_characters ? 2 : 1;
   12105             :     // No need to keep hashing. But we do need to calculate utf16_length.
   12106   324936719 :     if (utf16_length > String::kMaxHashCalcLength) continue;
   12107   324936719 :     if (is_two_characters) {
   12108             :       uint16_t c1 = unibrow::Utf16::LeadSurrogate(c);
   12109             :       uint16_t c2 = unibrow::Utf16::TrailSurrogate(c);
   12110             :       hasher.AddCharacter(c1);
   12111             :       hasher.AddCharacter(c2);
   12112          12 :       if (is_index) is_index = hasher.UpdateIndex(c1);
   12113          12 :       if (is_index) is_index = hasher.UpdateIndex(c2);
   12114             :     } else {
   12115             :       hasher.AddCharacter(c);
   12116   324936707 :       if (is_index) is_index = hasher.UpdateIndex(c);
   12117             :     }
   12118             :   }
   12119    16787915 :   *utf16_length_out = static_cast<int>(utf16_length);
   12120             :   // Must set length here so that hash computation is correct.
   12121    16787915 :   hasher.length_ = utf16_length;
   12122    16787915 :   return hasher.GetHashField();
   12123             : }
   12124             : 
   12125             : 
   12126     1664856 : void IteratingStringHasher::VisitConsString(ConsString* cons_string) {
   12127             :   // Run small ConsStrings through ConsStringIterator.
   12128     1664856 :   if (cons_string->length() < 64) {
   12129             :     ConsStringIterator iter(cons_string);
   12130             :     int offset;
   12131             :     String* string;
   12132     9977429 :     while (nullptr != (string = iter.Next(&offset))) {
   12133             :       DCHECK_EQ(0, offset);
   12134     8516550 :       String::VisitFlat(this, string, 0);
   12135             :     }
   12136     1664856 :     return;
   12137             :   }
   12138             :   // Slow case.
   12139      203977 :   const int max_length = String::kMaxHashCalcLength;
   12140      407954 :   int length = std::min(cons_string->length(), max_length);
   12141      203977 :   if (cons_string->HasOnlyOneByteChars()) {
   12142      183180 :     uint8_t* buffer = new uint8_t[length];
   12143      183180 :     String::WriteToFlat(cons_string, buffer, 0, length);
   12144      183180 :     AddCharacters(buffer, length);
   12145      183180 :     delete[] buffer;
   12146             :   } else {
   12147       20797 :     uint16_t* buffer = new uint16_t[length];
   12148       20797 :     String::WriteToFlat(cons_string, buffer, 0, length);
   12149       20797 :     AddCharacters(buffer, length);
   12150       20797 :     delete[] buffer;
   12151             :   }
   12152             : }
   12153             : 
   12154             : 
   12155       35009 : void String::PrintOn(FILE* file) {
   12156             :   int length = this->length();
   12157     3217188 :   for (int i = 0; i < length; i++) {
   12158     3182179 :     PrintF(file, "%c", Get(i));
   12159             :   }
   12160       35009 : }
   12161             : 
   12162             : 
   12163      957501 : int Map::Hash() {
   12164             :   // For performance reasons we only hash the 3 most variable fields of a map:
   12165             :   // constructor, prototype and bit_field2. For predictability reasons we
   12166             :   // use objects' offsets in respective pages for hashing instead of raw
   12167             :   // addresses.
   12168             : 
   12169             :   // Shift away the tag.
   12170     1915002 :   int hash = ObjectAddressForHashing(GetConstructor()) >> 2;
   12171             : 
   12172             :   // XOR-ing the prototype and constructor directly yields too many zero bits
   12173             :   // when the two pointers are close (which is fairly common).
   12174             :   // To avoid this we shift the prototype bits relatively to the constructor.
   12175      957501 :   hash ^= ObjectAddressForHashing(prototype()) << (32 - kPageSizeBits);
   12176             : 
   12177     1915002 :   return hash ^ (hash >> 16) ^ bit_field2();
   12178             : }
   12179             : 
   12180             : 
   12181             : namespace {
   12182             : 
   12183     1193673 : bool CheckEquivalent(const Map* first, const Map* second) {
   12184     2349987 :   return first->GetConstructor() == second->GetConstructor() &&
   12185     1146419 :          first->prototype() == second->prototype() &&
   12186     1146410 :          first->instance_type() == second->instance_type() &&
   12187     1146400 :          first->bit_field() == second->bit_field() &&
   12188     1146245 :          first->is_extensible() == second->is_extensible() &&
   12189     2339898 :          first->new_target_is_base() == second->new_target_is_base() &&
   12190     1193673 :          first->has_hidden_prototype() == second->has_hidden_prototype();
   12191             : }
   12192             : 
   12193             : }  // namespace
   12194             : 
   12195      550684 : bool Map::EquivalentToForTransition(const Map* other) const {
   12196      550684 :   if (!CheckEquivalent(this, other)) return false;
   12197      550519 :   if (instance_type() == JS_FUNCTION_TYPE) {
   12198             :     // JSFunctions require more checks to ensure that sloppy function is
   12199             :     // not equivalent to strict function.
   12200             :     int nof = Min(NumberOfOwnDescriptors(), other->NumberOfOwnDescriptors());
   12201             :     return instance_descriptors()->IsEqualUpTo(other->instance_descriptors(),
   12202        2303 :                                                nof);
   12203             :   }
   12204             :   return true;
   12205             : }
   12206             : 
   12207           0 : bool Map::EquivalentToForElementsKindTransition(const Map* other) const {
   12208       31825 :   if (!EquivalentToForTransition(other)) return false;
   12209             : #ifdef DEBUG
   12210             :   // Ensure that we don't try to generate elements kind transitions from maps
   12211             :   // with fields that may be generalized in-place. This must already be handled
   12212             :   // during addition of a new field.
   12213             :   DescriptorArray* descriptors = instance_descriptors();
   12214             :   int nof = NumberOfOwnDescriptors();
   12215             :   for (int i = 0; i < nof; i++) {
   12216             :     PropertyDetails details = descriptors->GetDetails(i);
   12217             :     if (details.location() == kField) {
   12218             :       DCHECK(!IsInplaceGeneralizableField(details.constness(),
   12219             :                                           details.representation(),
   12220             :                                           descriptors->GetFieldType(i)));
   12221             :     }
   12222             :   }
   12223             : #endif
   12224           0 :   return true;
   12225             : }
   12226             : 
   12227      642989 : bool Map::EquivalentToForNormalization(const Map* other,
   12228             :                                        PropertyNormalizationMode mode) const {
   12229             :   int properties =
   12230      642989 :       mode == CLEAR_INOBJECT_PROPERTIES ? 0 : other->GetInObjectProperties();
   12231     1834401 :   return CheckEquivalent(this, other) && bit_field2() == other->bit_field2() &&
   12232     1195986 :          GetInObjectProperties() == properties &&
   12233      552997 :          JSObject::GetEmbedderFieldCount(this) ==
   12234     1195986 :              JSObject::GetEmbedderFieldCount(other);
   12235             : }
   12236             : 
   12237             : 
   12238      352024 : void JSFunction::MarkForOptimization(ConcurrencyMode mode) {
   12239      703596 :   Isolate* isolate = GetIsolate();
   12240      703596 :   if (!isolate->concurrent_recompilation_enabled() ||
   12241      351572 :       isolate->bootstrapper()->IsActive()) {
   12242             :     mode = ConcurrencyMode::kNotConcurrent;
   12243             :   }
   12244             : 
   12245             :   DCHECK(!IsOptimized());
   12246             :   DCHECK(!HasOptimizedCode());
   12247             :   DCHECK(shared()->allows_lazy_compilation() ||
   12248             :          !shared()->optimization_disabled());
   12249             : 
   12250      352024 :   if (mode == ConcurrencyMode::kConcurrent) {
   12251       13102 :     if (IsInOptimizationQueue()) {
   12252           0 :       if (FLAG_trace_concurrent_recompilation) {
   12253           0 :         PrintF("  ** Not marking ");
   12254           0 :         ShortPrint();
   12255           0 :         PrintF(" -- already in optimization queue.\n");
   12256             :       }
   12257      352024 :       return;
   12258             :     }
   12259       13102 :     if (FLAG_trace_concurrent_recompilation) {
   12260           0 :       PrintF("  ** Marking ");
   12261           0 :       ShortPrint();
   12262           0 :       PrintF(" for concurrent recompilation.\n");
   12263             :     }
   12264             :   }
   12265             : 
   12266      352024 :   if (!IsInterpreted()) {
   12267             :     // For non I+TF path, install a shim which checks the optimization marker.
   12268             :     // No write barrier required, since the builtin is part of the root set.
   12269             :     set_code_no_write_barrier(
   12270             :         isolate->builtins()->builtin(Builtins::kCheckOptimizationMarker));
   12271             :   }
   12272             :   SetOptimizationMarker(mode == ConcurrencyMode::kConcurrent
   12273             :                             ? OptimizationMarker::kCompileOptimizedConcurrent
   12274      352024 :                             : OptimizationMarker::kCompileOptimized);
   12275             : }
   12276             : 
   12277             : // static
   12278    12159295 : void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
   12279             :   Handle<SharedFunctionInfo> shared(function->shared());
   12280             :   Isolate* isolate = shared->GetIsolate();
   12281             : 
   12282    12159296 :   FeedbackVectorState state = function->GetFeedbackVectorState(isolate);
   12283    12159298 :   switch (state) {
   12284             :     case TOP_LEVEL_SCRIPT_NEEDS_VECTOR: {
   12285             :       // A top level script didn't get it's literals installed.
   12286             :       Handle<FeedbackVector> feedback_vector =
   12287     4601565 :           FeedbackVector::New(isolate, shared);
   12288             :       Handle<Cell> new_cell =
   12289     4601566 :           isolate->factory()->NewOneClosureCell(feedback_vector);
   12290     4601566 :       function->set_feedback_vector_cell(*new_cell);
   12291             :       break;
   12292             :     }
   12293             :     case NEEDS_VECTOR: {
   12294             :       Handle<FeedbackVector> feedback_vector =
   12295     1587642 :           FeedbackVector::New(isolate, shared);
   12296     1587640 :       function->feedback_vector_cell()->set_value(*feedback_vector);
   12297             :       break;
   12298             :     }
   12299             :     case HAS_VECTOR:
   12300             :     case NO_VECTOR_NEEDED:
   12301             :       // Nothing to do.
   12302             :       break;
   12303             :   }
   12304    12159299 : }
   12305             : 
   12306      160969 : static void GetMinInobjectSlack(Map* map, void* data) {
   12307             :   int slack = map->UnusedPropertyFields();
   12308      160969 :   if (*reinterpret_cast<int*>(data) > slack) {
   12309       41723 :     *reinterpret_cast<int*>(data) = slack;
   12310             :   }
   12311      160969 : }
   12312             : 
   12313             : 
   12314      154706 : static void ShrinkInstanceSize(Map* map, void* data) {
   12315             : #ifdef DEBUG
   12316             :   int old_visitor_id = Map::GetVisitorId(map);
   12317             : #endif
   12318      154706 :   int slack = *reinterpret_cast<int*>(data);
   12319             :   DCHECK_GE(slack, 0);
   12320      154706 :   map->SetInObjectProperties(map->GetInObjectProperties() - slack);
   12321      154706 :   map->set_unused_property_fields(map->unused_property_fields() - slack);
   12322      154706 :   map->set_instance_size(map->instance_size() - slack * kPointerSize);
   12323             :   map->set_construction_counter(Map::kNoSlackTracking);
   12324             :   DCHECK_EQ(old_visitor_id, Map::GetVisitorId(map));
   12325      154706 : }
   12326             : 
   12327        6263 : static void StopSlackTracking(Map* map, void* data) {
   12328             :   map->set_construction_counter(Map::kNoSlackTracking);
   12329        6263 : }
   12330             : 
   12331       45806 : void Map::CompleteInobjectSlackTracking() {
   12332             :   // Has to be an initial map.
   12333             :   DCHECK(GetBackPointer()->IsUndefined(GetIsolate()));
   12334             : 
   12335       45806 :   int slack = UnusedPropertyFields();
   12336             :   DisallowHeapAllocation no_gc;
   12337             :   TransitionsAccessor transitions(this, &no_gc);
   12338             :   transitions.TraverseTransitionTree(&GetMinInobjectSlack, &slack);
   12339       45806 :   if (slack != 0) {
   12340             :     // Resize the initial map and all maps in its transition tree.
   12341             :     transitions.TraverseTransitionTree(&ShrinkInstanceSize, &slack);
   12342             :   } else {
   12343             :     transitions.TraverseTransitionTree(&StopSlackTracking, nullptr);
   12344             :   }
   12345       45806 : }
   12346             : 
   12347             : 
   12348    23211418 : static bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) {
   12349             :   DisallowHeapAllocation no_gc;
   12350    23211418 :   if (!object->HasFastProperties()) return false;
   12351    22063489 :   if (object->IsJSGlobalProxy()) return false;
   12352    22042374 :   if (object->GetIsolate()->bootstrapper()->IsActive()) return false;
   12353     8803438 :   return !object->map()->is_prototype_map() ||
   12354     8803438 :          !object->map()->should_be_fast_prototype_map();
   12355             : }
   12356             : 
   12357             : // static
   12358     2786137 : void JSObject::MakePrototypesFast(Handle<Object> receiver,
   12359             :                                   WhereToStart where_to_start,
   12360             :                                   Isolate* isolate) {
   12361     2786137 :   if (!receiver->IsJSReceiver()) return;
   12362     7371988 :   for (PrototypeIterator iter(isolate, Handle<JSReceiver>::cast(receiver),
   12363     2739286 :                               where_to_start);
   12364     6526120 :        !iter.IsAtEnd(); iter.Advance()) {
   12365             :     Handle<Object> current = PrototypeIterator::GetCurrent(iter);
   12366     4526605 :     if (!current->IsJSObject()) return;
   12367             :     Handle<JSObject> current_obj = Handle<JSObject>::cast(current);
   12368             :     Map* current_map = current_obj->map();
   12369     4521256 :     if (current_map->is_prototype_map()) {
   12370             :       // If the map is already marked as should be fast, we're done. Its
   12371             :       // prototypes will have been marked already as well.
   12372     5586509 :       if (current_map->should_be_fast_prototype_map()) return;
   12373             :       Handle<Map> map(current_map);
   12374      330830 :       Map::SetShouldBeFastPrototypeMap(map, true, isolate);
   12375      330830 :       JSObject::OptimizeAsPrototype(current_obj);
   12376             :     }
   12377             :   }
   12378             : }
   12379             : 
   12380             : // static
   12381    23301469 : void JSObject::OptimizeAsPrototype(Handle<JSObject> object) {
   12382    46602926 :   if (object->IsJSGlobalObject()) return;
   12383    23211417 :   if (PrototypeBenefitsFromNormalization(object)) {
   12384             :     // First normalize to ensure all JSFunctions are DATA_CONSTANT.
   12385             :     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0,
   12386      424963 :                                   "NormalizeAsPrototype");
   12387             :   }
   12388             :   Handle<Map> previous_map(object->map());
   12389    23211416 :   if (object->map()->is_prototype_map()) {
   12390    35665668 :     if (object->map()->should_be_fast_prototype_map() &&
   12391    16189351 :         !object->HasFastProperties()) {
   12392      313483 :       JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype");
   12393             :     }
   12394             :   } else {
   12395     3735099 :     if (object->map() == *previous_map) {
   12396     3735099 :       Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype");
   12397     3735099 :       JSObject::MigrateToMap(object, new_map);
   12398             :     }
   12399             :     object->map()->set_is_prototype_map(true);
   12400             : 
   12401             :     // Replace the pointer to the exact constructor with the Object function
   12402             :     // from the same context if undetectable from JS. This is to avoid keeping
   12403             :     // memory alive unnecessarily.
   12404     3735099 :     Object* maybe_constructor = object->map()->GetConstructor();
   12405     3735099 :     if (maybe_constructor->IsJSFunction()) {
   12406             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
   12407             :       Isolate* isolate = object->GetIsolate();
   12408     7420620 :       if (!constructor->shared()->IsApiFunction() &&
   12409     3686061 :           object->class_name() == isolate->heap()->Object_string()) {
   12410             :         Context* context = constructor->context()->native_context();
   12411             :         JSFunction* object_function = context->object_function();
   12412             :         object->map()->SetConstructor(object_function);
   12413             :       }
   12414             :     }
   12415             :   }
   12416             : }
   12417             : 
   12418             : 
   12419             : // static
   12420      571358 : void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) {
   12421      571358 :   if (!object->map()->is_prototype_map()) return;
   12422       63228 :   if (!object->map()->should_be_fast_prototype_map()) return;
   12423       39146 :   OptimizeAsPrototype(object);
   12424             : }
   12425             : 
   12426             : 
   12427             : // static
   12428     1229283 : void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
   12429             :   // Contract: In line with InvalidatePrototypeChains()'s requirements,
   12430             :   // leaf maps don't need to register as users, only prototypes do.
   12431             :   DCHECK(user->is_prototype_map());
   12432             : 
   12433     1229283 :   Handle<Map> current_user = user;
   12434             :   Handle<PrototypeInfo> current_user_info =
   12435     1229283 :       Map::GetOrCreatePrototypeInfo(user, isolate);
   12436     3207976 :   for (PrototypeIterator iter(user); !iter.IsAtEnd(); iter.Advance()) {
   12437             :     // Walk up the prototype chain as far as links haven't been registered yet.
   12438     1166997 :     if (current_user_info->registry_slot() != PrototypeInfo::UNREGISTERED) {
   12439             :       break;
   12440             :     }
   12441             :     Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter);
   12442             :     // Proxies on the prototype chain are not supported. They make it
   12443             :     // impossible to make any assumptions about the prototype chain anyway.
   12444     1604318 :     if (maybe_proto->IsJSProxy()) return;
   12445             :     Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto);
   12446             :     Handle<PrototypeInfo> proto_info =
   12447      374706 :         Map::GetOrCreatePrototypeInfo(proto, isolate);
   12448             :     Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
   12449      374706 :     int slot = 0;
   12450             :     Handle<WeakFixedArray> new_array =
   12451      374706 :         WeakFixedArray::Add(maybe_registry, current_user, &slot);
   12452      374706 :     current_user_info->set_registry_slot(slot);
   12453      374706 :     if (!maybe_registry.is_identical_to(new_array)) {
   12454       90165 :       proto_info->set_prototype_users(*new_array);
   12455             :     }
   12456      374706 :     if (FLAG_trace_prototype_users) {
   12457             :       PrintF("Registering %p as a user of prototype %p (map=%p).\n",
   12458             :              reinterpret_cast<void*>(*current_user),
   12459             :              reinterpret_cast<void*>(*proto),
   12460           0 :              reinterpret_cast<void*>(proto->map()));
   12461             :     }
   12462             : 
   12463             :     current_user = handle(proto->map(), isolate);
   12464             :     current_user_info = proto_info;
   12465             :   }
   12466             : }
   12467             : 
   12468             : 
   12469             : // Can be called regardless of whether |user| was actually registered with
   12470             : // |prototype|. Returns true when there was a registration.
   12471             : // static
   12472     3888596 : bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
   12473             :   DCHECK(user->is_prototype_map());
   12474             :   // If it doesn't have a PrototypeInfo, it was never registered.
   12475     3888596 :   if (!user->prototype_info()->IsPrototypeInfo()) return false;
   12476             :   // If it had no prototype before, see if it had users that might expect
   12477             :   // registration.
   12478      642464 :   if (!user->prototype()->IsJSObject()) {
   12479             :     Object* users =
   12480             :         PrototypeInfo::cast(user->prototype_info())->prototype_users();
   12481       76680 :     return users->IsWeakFixedArray();
   12482             :   }
   12483             :   Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate);
   12484             :   Handle<PrototypeInfo> user_info =
   12485      565784 :       Map::GetOrCreatePrototypeInfo(user, isolate);
   12486             :   int slot = user_info->registry_slot();
   12487      565784 :   if (slot == PrototypeInfo::UNREGISTERED) return false;
   12488             :   DCHECK(prototype->map()->is_prototype_map());
   12489             :   Object* maybe_proto_info = prototype->map()->prototype_info();
   12490             :   // User knows its registry slot, prototype info and user registry must exist.
   12491             :   DCHECK(maybe_proto_info->IsPrototypeInfo());
   12492             :   Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info),
   12493             :                                    isolate);
   12494             :   Object* maybe_registry = proto_info->prototype_users();
   12495             :   DCHECK(maybe_registry->IsWeakFixedArray());
   12496             :   DCHECK(WeakFixedArray::cast(maybe_registry)->Get(slot) == *user);
   12497             :   WeakFixedArray::cast(maybe_registry)->Clear(slot);
   12498       81624 :   if (FLAG_trace_prototype_users) {
   12499             :     PrintF("Unregistering %p as a user of prototype %p.\n",
   12500           0 :            reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
   12501             :   }
   12502             :   return true;
   12503             : }
   12504             : 
   12505             : 
   12506     3972722 : static void InvalidatePrototypeChainsInternal(Map* map) {
   12507             :   DCHECK(map->is_prototype_map());
   12508     3972722 :   if (FLAG_trace_prototype_users) {
   12509             :     PrintF("Invalidating prototype map %p 's cell\n",
   12510           0 :            reinterpret_cast<void*>(map));
   12511             :   }
   12512             :   Object* maybe_proto_info = map->prototype_info();
   12513     7219221 :   if (!maybe_proto_info->IsPrototypeInfo()) return;
   12514             :   PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_proto_info);
   12515             :   Object* maybe_cell = proto_info->validity_cell();
   12516      726223 :   if (maybe_cell->IsCell()) {
   12517             :     // Just set the value; the cell will be replaced lazily.
   12518             :     Cell* cell = Cell::cast(maybe_cell);
   12519      151839 :     cell->set_value(Smi::FromInt(Map::kPrototypeChainInvalid));
   12520             :   }
   12521             : 
   12522             :   WeakFixedArray::Iterator iterator(proto_info->prototype_users());
   12523             :   // For now, only maps register themselves as users.
   12524             :   Map* user;
   12525      808985 :   while ((user = iterator.Next<Map>()) != nullptr) {
   12526             :     // Walk the prototype chain (backwards, towards leaf objects) if necessary.
   12527       82762 :     InvalidatePrototypeChainsInternal(user);
   12528             :   }
   12529             : }
   12530             : 
   12531             : 
   12532             : // static
   12533           0 : void JSObject::InvalidatePrototypeChains(Map* map) {
   12534             :   DisallowHeapAllocation no_gc;
   12535     3889960 :   InvalidatePrototypeChainsInternal(map);
   12536           0 : }
   12537             : 
   12538             : 
   12539             : // static
   12540     2088105 : Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<JSObject> prototype,
   12541             :                                                     Isolate* isolate) {
   12542             :   Object* maybe_proto_info = prototype->map()->prototype_info();
   12543     2088105 :   if (maybe_proto_info->IsPrototypeInfo()) {
   12544             :     return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
   12545             :   }
   12546      128319 :   Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
   12547      128319 :   prototype->map()->set_prototype_info(*proto_info);
   12548      128319 :   return proto_info;
   12549             : }
   12550             : 
   12551             : 
   12552             : // static
   12553     2292811 : Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> prototype_map,
   12554             :                                                     Isolate* isolate) {
   12555             :   Object* maybe_proto_info = prototype_map->prototype_info();
   12556     2292811 :   if (maybe_proto_info->IsPrototypeInfo()) {
   12557             :     return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
   12558             :   }
   12559      313577 :   Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
   12560      313577 :   prototype_map->set_prototype_info(*proto_info);
   12561      313577 :   return proto_info;
   12562             : }
   12563             : 
   12564             : // static
   12565      497744 : void Map::SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
   12566             :                                       Isolate* isolate) {
   12567      497744 :   if (value == false && !map->prototype_info()->IsPrototypeInfo()) {
   12568             :     // "False" is the implicit default value, so there's nothing to do.
   12569      497744 :     return;
   12570             :   }
   12571      995488 :   GetOrCreatePrototypeInfo(map, isolate)->set_should_be_fast_map(value);
   12572             : }
   12573             : 
   12574             : // static
   12575     1094435 : Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
   12576             :                                                         Isolate* isolate) {
   12577             :   Handle<Object> maybe_prototype;
   12578     1094435 :   if (map->IsJSGlobalObjectMap()) {
   12579             :     DCHECK(map->is_prototype_map());
   12580             :     // Global object is prototype of a global proxy and therefore we can
   12581             :     // use its validity cell for guarding global object's prototype change.
   12582        2068 :     maybe_prototype = isolate->global_object();
   12583             :   } else {
   12584             :     maybe_prototype =
   12585     1092367 :         handle(map->GetPrototypeChainRootMap(isolate)->prototype(), isolate);
   12586     1092367 :     if (!maybe_prototype->IsJSReceiver()) return Handle<Cell>::null();
   12587             :   }
   12588     1075735 :   if (maybe_prototype->IsJSProxy()) {
   12589             :     Handle<Cell> cell = isolate->factory()->NewCell(
   12590        1251 :         handle(Smi::FromInt(Map::kPrototypeChainValid), isolate));
   12591        1251 :     return cell;
   12592             :   }
   12593             :   Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
   12594             :   // Ensure the prototype is registered with its own prototypes so its cell
   12595             :   // will be invalidated when necessary.
   12596             :   JSObject::LazyRegisterPrototypeUser(handle(prototype->map(), isolate),
   12597     1074484 :                                       isolate);
   12598             :   Handle<PrototypeInfo> proto_info =
   12599     1074483 :       GetOrCreatePrototypeInfo(prototype, isolate);
   12600             :   Object* maybe_cell = proto_info->validity_cell();
   12601             :   // Return existing cell if it's still valid.
   12602     1074483 :   if (maybe_cell->IsCell()) {
   12603             :     Handle<Cell> cell(Cell::cast(maybe_cell), isolate);
   12604      811922 :     if (cell->value() == Smi::FromInt(Map::kPrototypeChainValid)) {
   12605      795028 :       return cell;
   12606             :     }
   12607             :   }
   12608             :   // Otherwise create a new cell.
   12609             :   Handle<Cell> cell = isolate->factory()->NewCell(
   12610      279456 :       handle(Smi::FromInt(Map::kPrototypeChainValid), isolate));
   12611      279456 :   proto_info->set_validity_cell(*cell);
   12612      279456 :   return cell;
   12613             : }
   12614             : 
   12615             : // static
   12616      518483 : Handle<WeakCell> Map::GetOrCreatePrototypeWeakCell(Handle<JSReceiver> prototype,
   12617             :                                                    Isolate* isolate) {
   12618             :   DCHECK(!prototype.is_null());
   12619      518483 :   if (prototype->IsJSProxy()) {
   12620        1170 :     Handle<WeakCell> cell = isolate->factory()->NewWeakCell(prototype);
   12621        1170 :     return cell;
   12622             :   }
   12623             : 
   12624             :   Handle<PrototypeInfo> proto_info =
   12625      517313 :       GetOrCreatePrototypeInfo(Handle<JSObject>::cast(prototype), isolate);
   12626             :   Object* maybe_cell = proto_info->weak_cell();
   12627             :   // Return existing cell if it's already created.
   12628      517313 :   if (maybe_cell->IsWeakCell()) {
   12629             :     Handle<WeakCell> cell(WeakCell::cast(maybe_cell), isolate);
   12630             :     DCHECK(!cell->cleared());
   12631      441592 :     return cell;
   12632             :   }
   12633             :   // Otherwise create a new cell.
   12634       75721 :   Handle<WeakCell> cell = isolate->factory()->NewWeakCell(prototype);
   12635       75721 :   proto_info->set_weak_cell(*cell);
   12636       75721 :   return cell;
   12637             : }
   12638             : 
   12639             : // static
   12640    26621864 : void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype) {
   12641             :   RuntimeCallTimerScope stats_scope(*map, &RuntimeCallStats::Map_SetPrototype);
   12642             : 
   12643             :   bool is_hidden = false;
   12644    26621867 :   if (prototype->IsJSObject()) {
   12645             :     Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype);
   12646    22156873 :     JSObject::OptimizeAsPrototype(prototype_jsobj);
   12647             : 
   12648    22156867 :     Object* maybe_constructor = prototype_jsobj->map()->GetConstructor();
   12649    22156865 :     if (maybe_constructor->IsJSFunction()) {
   12650             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
   12651             :       Object* data = constructor->shared()->function_data();
   12652      204764 :       is_hidden = (data->IsFunctionTemplateInfo() &&
   12653    42808539 :                    FunctionTemplateInfo::cast(data)->hidden_prototype()) ||
   12654             :                   prototype->IsJSGlobalObject();
   12655      752456 :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
   12656             :       is_hidden =
   12657          42 :           FunctionTemplateInfo::cast(maybe_constructor)->hidden_prototype() ||
   12658             :           prototype->IsJSGlobalObject();
   12659             :     }
   12660             :   }
   12661             :   map->set_has_hidden_prototype(is_hidden);
   12662             : 
   12663             :   WriteBarrierMode wb_mode = prototype->IsNull(map->GetIsolate())
   12664             :                                  ? SKIP_WRITE_BARRIER
   12665    26621860 :                                  : UPDATE_WRITE_BARRIER;
   12666    26621860 :   map->set_prototype(*prototype, wb_mode);
   12667    26621864 : }
   12668             : 
   12669             : 
   12670         122 : Handle<Object> CacheInitialJSArrayMaps(
   12671             :     Handle<Context> native_context, Handle<Map> initial_map) {
   12672             :   // Replace all of the cached initial array maps in the native context with
   12673             :   // the appropriate transitioned elements kind maps.
   12674         122 :   Handle<Map> current_map = initial_map;
   12675             :   ElementsKind kind = current_map->elements_kind();
   12676             :   DCHECK_EQ(GetInitialFastElementsKind(), kind);
   12677         122 :   native_context->set(Context::ArrayMapIndex(kind), *current_map);
   12678         732 :   for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
   12679             :        i < kFastElementsKindCount; ++i) {
   12680             :     Handle<Map> new_map;
   12681         610 :     ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
   12682         610 :     if (Map* maybe_elements_transition = current_map->ElementsTransitionMap()) {
   12683             :       new_map = handle(maybe_elements_transition);
   12684             :     } else {
   12685             :       new_map = Map::CopyAsElementsKind(
   12686         610 :           current_map, next_kind, INSERT_TRANSITION);
   12687             :     }
   12688             :     DCHECK_EQ(next_kind, new_map->elements_kind());
   12689         610 :     native_context->set(Context::ArrayMapIndex(next_kind), *new_map);
   12690             :     current_map = new_map;
   12691             :   }
   12692         122 :   return initial_map;
   12693             : }
   12694             : 
   12695             : namespace {
   12696             : 
   12697      589666 : void SetInstancePrototype(Isolate* isolate, Handle<JSFunction> function,
   12698             :                           Handle<JSReceiver> value) {
   12699             :   // Now some logic for the maps of the objects that are created by using this
   12700             :   // function as a constructor.
   12701      589666 :   if (function->has_initial_map()) {
   12702             :     // If the function has allocated the initial map replace it with a
   12703             :     // copy containing the new prototype.  Also complete any in-object
   12704             :     // slack tracking that is in progress at this point because it is
   12705             :     // still tracking the old copy.
   12706       28069 :     function->CompleteInobjectSlackTrackingIfActive();
   12707             : 
   12708             :     Handle<Map> initial_map(function->initial_map(), isolate);
   12709             : 
   12710       55205 :     if (!initial_map->GetIsolate()->bootstrapper()->IsActive() &&
   12711             :         initial_map->instance_type() == JS_OBJECT_TYPE) {
   12712             :       // Put the value in the initial map field until an initial map is needed.
   12713             :       // At that point, a new initial map is created and the prototype is put
   12714             :       // into the initial map where it belongs.
   12715       26902 :       function->set_prototype_or_initial_map(*value);
   12716             :     } else {
   12717        1167 :       Handle<Map> new_map = Map::Copy(initial_map, "SetInstancePrototype");
   12718        1167 :       JSFunction::SetInitialMap(function, new_map, value);
   12719             : 
   12720             :       // If the function is used as the global Array function, cache the
   12721             :       // updated initial maps (and transitioned versions) in the native context.
   12722             :       Handle<Context> native_context(function->context()->native_context(),
   12723             :                                      isolate);
   12724             :       Handle<Object> array_function(
   12725             :           native_context->get(Context::ARRAY_FUNCTION_INDEX), isolate);
   12726        2273 :       if (array_function->IsJSFunction() &&
   12727             :           *function == JSFunction::cast(*array_function)) {
   12728          61 :         CacheInitialJSArrayMaps(native_context, new_map);
   12729             :       }
   12730             :     }
   12731             : 
   12732             :     // Deoptimize all code that embeds the previous initial map.
   12733             :     initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
   12734       28069 :         isolate, DependentCode::kInitialMapChangedGroup);
   12735             :   } else {
   12736             :     // Put the value in the initial map field until an initial map is
   12737             :     // needed.  At that point, a new initial map is created and the
   12738             :     // prototype is put into the initial map where it belongs.
   12739      561597 :     function->set_prototype_or_initial_map(*value);
   12740      561597 :     if (value->IsJSObject()) {
   12741             :       // Optimize as prototype to detach it from its transition tree.
   12742      561534 :       JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
   12743             :     }
   12744             :   }
   12745      589666 : }
   12746             : 
   12747             : }  // anonymous namespace
   12748             : 
   12749      589666 : void JSFunction::SetPrototype(Handle<JSFunction> function,
   12750             :                               Handle<Object> value) {
   12751             :   DCHECK(function->IsConstructor() ||
   12752             :          IsGeneratorFunction(function->shared()->kind()));
   12753             :   Isolate* isolate = function->GetIsolate();
   12754             :   Handle<JSReceiver> construct_prototype;
   12755             : 
   12756             :   // If the value is not a JSReceiver, store the value in the map's
   12757             :   // constructor field so it can be accessed.  Also, set the prototype
   12758             :   // used for constructing objects to the original object prototype.
   12759             :   // See ECMA-262 13.2.2.
   12760      589666 :   if (!value->IsJSReceiver()) {
   12761             :     // Copy the map so this does not affect unrelated functions.
   12762             :     // Remove map transitions because they point to maps with a
   12763             :     // different prototype.
   12764        4324 :     Handle<Map> new_map = Map::Copy(handle(function->map()), "SetPrototype");
   12765             : 
   12766        4324 :     JSObject::MigrateToMap(function, new_map);
   12767             :     new_map->SetConstructor(*value);
   12768             :     new_map->set_non_instance_prototype(true);
   12769             : 
   12770             :     FunctionKind kind = function->shared()->kind();
   12771             :     Handle<Context> native_context(function->context()->native_context());
   12772             : 
   12773             :     construct_prototype = Handle<JSReceiver>(
   12774             :         IsGeneratorFunction(kind)
   12775             :             ? IsAsyncFunction(kind)
   12776             :                   ? native_context->initial_async_generator_prototype()
   12777             :                   : native_context->initial_generator_prototype()
   12778             :             : native_context->initial_object_prototype(),
   12779        8666 :         isolate);
   12780             :   } else {
   12781      585342 :     construct_prototype = Handle<JSReceiver>::cast(value);
   12782             :     function->map()->set_non_instance_prototype(false);
   12783             :   }
   12784             : 
   12785      589666 :   SetInstancePrototype(isolate, function, construct_prototype);
   12786      589666 : }
   12787             : 
   12788             : 
   12789     3823516 : void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
   12790             :                                Handle<Object> prototype) {
   12791     3823516 :   if (map->prototype() != *prototype) Map::SetPrototype(map, prototype);
   12792     3823515 :   function->set_prototype_or_initial_map(*map);
   12793             :   map->SetConstructor(*function);
   12794             : #if V8_TRACE_MAPS
   12795             :   if (FLAG_trace_maps) {
   12796             :     PrintF("[TraceMaps: InitialMap map= %p SFI= %d_%s ]\n",
   12797             :            reinterpret_cast<void*>(*map), function->shared()->unique_id(),
   12798             :            function->shared()->DebugName()->ToCString().get());
   12799             :   }
   12800             : #endif
   12801     3823515 : }
   12802             : 
   12803             : 
   12804             : #ifdef DEBUG
   12805             : namespace {
   12806             : 
   12807             : bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
   12808             :   switch (instance_type) {
   12809             :     case JS_API_OBJECT_TYPE:
   12810             :     case JS_ARRAY_BUFFER_TYPE:
   12811             :     case JS_ARRAY_TYPE:
   12812             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
   12813             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
   12814             :     case JS_DATA_VIEW_TYPE:
   12815             :     case JS_DATE_TYPE:
   12816             :     case JS_FUNCTION_TYPE:
   12817             :     case JS_GENERATOR_OBJECT_TYPE:
   12818             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
   12819             :     case JS_MAP_TYPE:
   12820             :     case JS_MESSAGE_OBJECT_TYPE:
   12821             :     case JS_OBJECT_TYPE:
   12822             :     case JS_ERROR_TYPE:
   12823             :     case JS_ARGUMENTS_TYPE:
   12824             :     case JS_PROMISE_TYPE:
   12825             :     case JS_REGEXP_TYPE:
   12826             :     case JS_SET_TYPE:
   12827             :     case JS_SPECIAL_API_OBJECT_TYPE:
   12828             :     case JS_TYPED_ARRAY_TYPE:
   12829             :     case JS_VALUE_TYPE:
   12830             :     case JS_WEAK_MAP_TYPE:
   12831             :     case JS_WEAK_SET_TYPE:
   12832             :       return true;
   12833             : 
   12834             :     case BIGINT_TYPE:
   12835             :     case BYTECODE_ARRAY_TYPE:
   12836             :     case BYTE_ARRAY_TYPE:
   12837             :     case CELL_TYPE:
   12838             :     case CODE_TYPE:
   12839             :     case FILLER_TYPE:
   12840             :     case FIXED_ARRAY_TYPE:
   12841             :     case FIXED_DOUBLE_ARRAY_TYPE:
   12842             :     case FOREIGN_TYPE:
   12843             :     case FREE_SPACE_TYPE:
   12844             :     case HASH_TABLE_TYPE:
   12845             :     case HEAP_NUMBER_TYPE:
   12846             :     case JS_BOUND_FUNCTION_TYPE:
   12847             :     case JS_GLOBAL_OBJECT_TYPE:
   12848             :     case JS_GLOBAL_PROXY_TYPE:
   12849             :     case JS_PROXY_TYPE:
   12850             :     case MAP_TYPE:
   12851             :     case MUTABLE_HEAP_NUMBER_TYPE:
   12852             :     case ODDBALL_TYPE:
   12853             :     case PROPERTY_CELL_TYPE:
   12854             :     case SHARED_FUNCTION_INFO_TYPE:
   12855             :     case SYMBOL_TYPE:
   12856             :     case WEAK_CELL_TYPE:
   12857             : 
   12858             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
   12859             :   case FIXED_##TYPE##_ARRAY_TYPE:
   12860             : #undef TYPED_ARRAY_CASE
   12861             : 
   12862             : #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
   12863             :       STRUCT_LIST(MAKE_STRUCT_CASE)
   12864             : #undef MAKE_STRUCT_CASE
   12865             :       // We must not end up here for these instance types at all.
   12866             :       UNREACHABLE();
   12867             :     // Fall through.
   12868             :     default:
   12869             :       return false;
   12870             :   }
   12871             : }
   12872             : 
   12873             : }  // namespace
   12874             : #endif
   12875             : 
   12876             : 
   12877    14596365 : void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
   12878             :   DCHECK(function->has_prototype_slot());
   12879             :   DCHECK(function->IsConstructor() ||
   12880             :          IsResumableFunction(function->shared()->kind()));
   12881    28867807 :   if (function->has_initial_map()) return;
   12882             :   Isolate* isolate = function->GetIsolate();
   12883             : 
   12884             :   // First create a new map with the size and number of in-object properties
   12885             :   // suggested by the function.
   12886             :   InstanceType instance_type;
   12887      324925 :   if (IsResumableFunction(function->shared()->kind())) {
   12888             :     instance_type = IsAsyncGeneratorFunction(function->shared()->kind())
   12889             :                         ? JS_ASYNC_GENERATOR_OBJECT_TYPE
   12890       12374 :                         : JS_GENERATOR_OBJECT_TYPE;
   12891             :   } else {
   12892             :     instance_type = JS_OBJECT_TYPE;
   12893             :   }
   12894             : 
   12895             :   // The constructor should be compiled for the optimization hints to be
   12896             :   // available.
   12897             :   int expected_nof_properties = 0;
   12898      365703 :   if (function->shared()->is_compiled() ||
   12899       40778 :       Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) {
   12900             :     DCHECK(function->shared()->is_compiled());
   12901             :     expected_nof_properties = function->shared()->expected_nof_properties();
   12902             :   }
   12903             : 
   12904             :   int instance_size;
   12905             :   int inobject_properties;
   12906             :   CalculateInstanceSizeHelper(instance_type, false, 0, expected_nof_properties,
   12907      324925 :                               &instance_size, &inobject_properties);
   12908             : 
   12909             :   Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size,
   12910             :                                                TERMINAL_FAST_ELEMENTS_KIND,
   12911      324925 :                                                inobject_properties);
   12912             : 
   12913             :   // Fetch or allocate prototype.
   12914             :   Handle<Object> prototype;
   12915      324925 :   if (function->has_instance_prototype()) {
   12916      259799 :     prototype = handle(function->instance_prototype(), isolate);
   12917             :   } else {
   12918       65126 :     prototype = isolate->factory()->NewFunctionPrototype(function);
   12919             :   }
   12920             :   DCHECK(map->has_fast_object_elements());
   12921             : 
   12922             :   // Finally link initial map and constructor function.
   12923             :   DCHECK(prototype->IsJSReceiver());
   12924      324925 :   JSFunction::SetInitialMap(function, map, prototype);
   12925             :   map->StartInobjectSlackTracking();
   12926             : }
   12927             : 
   12928             : 
   12929             : // static
   12930     2639599 : MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
   12931             :                                            Handle<JSFunction> constructor,
   12932             :                                            Handle<JSReceiver> new_target) {
   12933     2639599 :   EnsureHasInitialMap(constructor);
   12934             : 
   12935             :   Handle<Map> constructor_initial_map(constructor->initial_map(), isolate);
   12936     2639599 :   if (*new_target == *constructor) return constructor_initial_map;
   12937             : 
   12938             :   // Fast case, new.target is a subclass of constructor. The map is cacheable
   12939             :   // (and may already have been cached). new.target.prototype is guaranteed to
   12940             :   // be a JSReceiver.
   12941       99787 :   if (new_target->IsJSFunction()) {
   12942             :     Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
   12943             : 
   12944             :     // Check that |function|'s initial map still in sync with the |constructor|,
   12945             :     // otherwise we must create a new initial map for |function|.
   12946      185858 :     if (function->has_initial_map() &&
   12947       88667 :         function->initial_map()->GetConstructor() == *constructor) {
   12948       88538 :       return handle(function->initial_map(), isolate);
   12949             :     }
   12950             : 
   12951             :     // Create a new map with the size and number of in-object properties
   12952             :     // suggested by |function|.
   12953             : 
   12954             :     // Link initial map and constructor function if the new.target is actually a
   12955             :     // subclass constructor.
   12956        8653 :     if (IsDerivedConstructor(function->shared()->kind())) {
   12957             :       Handle<Object> prototype(function->instance_prototype(), isolate);
   12958             :       InstanceType instance_type = constructor_initial_map->instance_type();
   12959             :       DCHECK(CanSubclassHaveInobjectProperties(instance_type));
   12960             :       int embedder_fields =
   12961        7160 :           JSObject::GetEmbedderFieldCount(*constructor_initial_map);
   12962             :       int pre_allocated = constructor_initial_map->GetInObjectProperties() -
   12963        7160 :                           constructor_initial_map->UnusedPropertyFields();
   12964             :       int instance_size;
   12965             :       int in_object_properties;
   12966             :       CalculateInstanceSizeForDerivedClass(function, instance_type,
   12967             :                                            embedder_fields, &instance_size,
   12968        7160 :                                            &in_object_properties);
   12969             : 
   12970        7160 :       int unused_property_fields = in_object_properties - pre_allocated;
   12971             :       Handle<Map> map =
   12972             :           Map::CopyInitialMap(constructor_initial_map, instance_size,
   12973        7160 :                               in_object_properties, unused_property_fields);
   12974             :       map->set_new_target_is_base(false);
   12975             : 
   12976        7160 :       JSFunction::SetInitialMap(function, map, prototype);
   12977             :       map->SetConstructor(*constructor);
   12978             :       map->set_construction_counter(Map::kNoSlackTracking);
   12979             :       map->StartInobjectSlackTracking();
   12980        7160 :       return map;
   12981             :     }
   12982             :   }
   12983             : 
   12984             :   // Slow path, new.target is either a proxy or can't cache the map.
   12985             :   // new.target.prototype is not guaranteed to be a JSReceiver, and may need to
   12986             :   // fall back to the intrinsicDefaultProto.
   12987             :   Handle<Object> prototype;
   12988        4089 :   if (new_target->IsJSFunction()) {
   12989             :     Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
   12990             :     // Make sure the new.target.prototype is cached.
   12991        1493 :     EnsureHasInitialMap(function);
   12992        1493 :     prototype = handle(function->prototype(), isolate);
   12993             :   } else {
   12994             :     Handle<String> prototype_string = isolate->factory()->prototype_string();
   12995        5192 :     ASSIGN_RETURN_ON_EXCEPTION(
   12996             :         isolate, prototype,
   12997             :         JSReceiver::GetProperty(new_target, prototype_string), Map);
   12998             :     // The above prototype lookup might change the constructor and its
   12999             :     // prototype, hence we have to reload the initial map.
   13000        2536 :     EnsureHasInitialMap(constructor);
   13001             :     constructor_initial_map = handle(constructor->initial_map(), isolate);
   13002             :   }
   13003             : 
   13004             :   // If prototype is not a JSReceiver, fetch the intrinsicDefaultProto from the
   13005             :   // correct realm. Rather than directly fetching the .prototype, we fetch the
   13006             :   // constructor that points to the .prototype. This relies on
   13007             :   // constructor.prototype being FROZEN for those constructors.
   13008        4029 :   if (!prototype->IsJSReceiver()) {
   13009             :     Handle<Context> context;
   13010        2558 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, context,
   13011             :                                JSReceiver::GetFunctionRealm(new_target), Map);
   13012             :     DCHECK(context->IsNativeContext());
   13013             :     Handle<Object> maybe_index = JSReceiver::GetDataProperty(
   13014        1279 :         constructor, isolate->factory()->native_context_index_symbol());
   13015             :     int index = maybe_index->IsSmi() ? Smi::ToInt(*maybe_index)
   13016        1279 :                                      : Context::OBJECT_FUNCTION_INDEX;
   13017             :     Handle<JSFunction> realm_constructor(JSFunction::cast(context->get(index)));
   13018        1279 :     prototype = handle(realm_constructor->prototype(), isolate);
   13019             :   }
   13020             : 
   13021        4029 :   Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
   13022             :   map->set_new_target_is_base(false);
   13023             :   DCHECK(prototype->IsJSReceiver());
   13024        4029 :   if (map->prototype() != *prototype) Map::SetPrototype(map, prototype);
   13025             :   map->SetConstructor(*constructor);
   13026        4029 :   return map;
   13027             : }
   13028             : 
   13029             : 
   13030           0 : void JSFunction::PrintName(FILE* out) {
   13031           0 :   std::unique_ptr<char[]> name = shared()->DebugName()->ToCString();
   13032           0 :   PrintF(out, "%s", name.get());
   13033           0 : }
   13034             : 
   13035             : 
   13036      453615 : Handle<String> JSFunction::GetName(Handle<JSFunction> function) {
   13037             :   Isolate* isolate = function->GetIsolate();
   13038             :   Handle<Object> name =
   13039      453615 :       JSReceiver::GetDataProperty(function, isolate->factory()->name_string());
   13040      453615 :   if (name->IsString()) return Handle<String>::cast(name);
   13041      452894 :   return handle(function->shared()->DebugName(), isolate);
   13042             : }
   13043             : 
   13044             : 
   13045      352788 : Handle<String> JSFunction::GetDebugName(Handle<JSFunction> function) {
   13046             :   Isolate* isolate = function->GetIsolate();
   13047             :   Handle<Object> name = JSReceiver::GetDataProperty(
   13048      352788 :       function, isolate->factory()->display_name_string());
   13049      352788 :   if (name->IsString()) return Handle<String>::cast(name);
   13050      352749 :   return JSFunction::GetName(function);
   13051             : }
   13052             : 
   13053       10755 : bool JSFunction::SetName(Handle<JSFunction> function, Handle<Name> name,
   13054             :                          Handle<String> prefix) {
   13055             :   Isolate* isolate = function->GetIsolate();
   13056             :   Handle<String> function_name;
   13057       21510 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, function_name,
   13058             :                                    Name::ToFunctionName(name), false);
   13059       10745 :   if (prefix->length() > 0) {
   13060        2461 :     IncrementalStringBuilder builder(isolate);
   13061        2461 :     builder.AppendString(prefix);
   13062             :     builder.AppendCharacter(' ');
   13063        2461 :     builder.AppendString(function_name);
   13064        4922 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, function_name, builder.Finish(),
   13065             :                                      false);
   13066             :   }
   13067       21450 :   RETURN_ON_EXCEPTION_VALUE(
   13068             :       isolate,
   13069             :       JSObject::DefinePropertyOrElementIgnoreAttributes(
   13070             :           function, isolate->factory()->name_string(), function_name,
   13071             :           static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)),
   13072             :       false);
   13073       10725 :   return true;
   13074             : }
   13075             : 
   13076             : namespace {
   13077             : 
   13078             : char const kNativeCodeSource[] = "function () { [native code] }";
   13079             : 
   13080             : 
   13081     1023200 : Handle<String> NativeCodeFunctionSourceString(
   13082             :     Handle<SharedFunctionInfo> shared_info) {
   13083             :   Isolate* const isolate = shared_info->GetIsolate();
   13084     1023200 :   IncrementalStringBuilder builder(isolate);
   13085             :   builder.AppendCString("function ");
   13086     1023200 :   builder.AppendString(handle(shared_info->name(), isolate));
   13087             :   builder.AppendCString("() { [native code] }");
   13088     2046400 :   return builder.Finish().ToHandleChecked();
   13089             : }
   13090             : 
   13091             : }  // namespace
   13092             : 
   13093             : 
   13094             : // static
   13095          55 : Handle<String> JSBoundFunction::ToString(Handle<JSBoundFunction> function) {
   13096             :   Isolate* const isolate = function->GetIsolate();
   13097          55 :   return isolate->factory()->NewStringFromAsciiChecked(kNativeCodeSource);
   13098             : }
   13099             : 
   13100             : 
   13101             : // static
   13102     1767950 : Handle<String> JSFunction::ToString(Handle<JSFunction> function) {
   13103             :   Isolate* const isolate = function->GetIsolate();
   13104             :   Handle<SharedFunctionInfo> shared_info(function->shared(), isolate);
   13105             : 
   13106             :   // Check if {function} should hide its source code.
   13107     1767950 :   if (!shared_info->IsUserJavaScript()) {
   13108     1023200 :     return NativeCodeFunctionSourceString(shared_info);
   13109             :   }
   13110             : 
   13111             :   // Check if we should print {function} as a class.
   13112             :   Handle<Object> class_start_position = JSReceiver::GetDataProperty(
   13113      744750 :       function, isolate->factory()->class_start_position_symbol());
   13114      744750 :   if (class_start_position->IsSmi()) {
   13115             :     Handle<Object> class_end_position = JSReceiver::GetDataProperty(
   13116       21565 :         function, isolate->factory()->class_end_position_symbol());
   13117             :     Handle<String> script_source(
   13118             :         String::cast(Script::cast(shared_info->script())->source()), isolate);
   13119             :     return isolate->factory()->NewSubString(
   13120             :         script_source, Handle<Smi>::cast(class_start_position)->value(),
   13121       21565 :         Handle<Smi>::cast(class_end_position)->value());
   13122             :   }
   13123             : 
   13124             :   // Check if we have source code for the {function}.
   13125      723185 :   if (!shared_info->HasSourceCode()) {
   13126           0 :     return NativeCodeFunctionSourceString(shared_info);
   13127             :   }
   13128             : 
   13129      723185 :   if (FLAG_harmony_function_tostring) {
   13130         813 :     return Handle<String>::cast(shared_info->GetSourceCodeHarmony());
   13131             :   }
   13132             : 
   13133      722372 :   IncrementalStringBuilder builder(isolate);
   13134             :   FunctionKind kind = shared_info->kind();
   13135      722372 :   if (!IsArrowFunction(kind)) {
   13136      683271 :     if (IsConciseMethod(kind)) {
   13137          63 :       if (IsAsyncGeneratorFunction(kind)) {
   13138             :         builder.AppendCString("async *");
   13139          36 :       } else if (IsGeneratorFunction(kind)) {
   13140             :         builder.AppendCharacter('*');
   13141          27 :       } else if (IsAsyncFunction(kind)) {
   13142             :         builder.AppendCString("async ");
   13143             :       }
   13144             :     } else {
   13145      683208 :       if (IsAsyncGeneratorFunction(kind)) {
   13146             :         builder.AppendCString("async function* ");
   13147      683163 :       } else if (IsGeneratorFunction(kind)) {
   13148             :         builder.AppendCString("function* ");
   13149      683028 :       } else if (IsAsyncFunction(kind)) {
   13150             :         builder.AppendCString("async function ");
   13151             :       } else {
   13152             :         builder.AppendCString("function ");
   13153             :       }
   13154             :     }
   13155      683271 :     if (shared_info->name_should_print_as_anonymous()) {
   13156             :       builder.AppendCString("anonymous");
   13157      682909 :     } else if (!shared_info->is_anonymous_expression()) {
   13158      616810 :       builder.AppendString(handle(shared_info->name(), isolate));
   13159             :     }
   13160             :   }
   13161      722372 :   builder.AppendString(Handle<String>::cast(shared_info->GetSourceCode()));
   13162     1444744 :   return builder.Finish().ToHandleChecked();
   13163             : }
   13164             : 
   13165         341 : void Oddball::Initialize(Isolate* isolate, Handle<Oddball> oddball,
   13166             :                          const char* to_string, Handle<Object> to_number,
   13167             :                          const char* type_of, byte kind) {
   13168             :   Handle<String> internalized_to_string =
   13169         341 :       isolate->factory()->InternalizeUtf8String(to_string);
   13170             :   Handle<String> internalized_type_of =
   13171         341 :       isolate->factory()->InternalizeUtf8String(type_of);
   13172         341 :   if (to_number->IsHeapNumber()) {
   13173             :     oddball->set_to_number_raw_as_bits(
   13174             :         Handle<HeapNumber>::cast(to_number)->value_as_bits());
   13175             :   } else {
   13176             :     oddball->set_to_number_raw(to_number->Number());
   13177             :   }
   13178         341 :   oddball->set_to_number(*to_number);
   13179         341 :   oddball->set_to_string(*internalized_to_string);
   13180         341 :   oddball->set_type_of(*internalized_type_of);
   13181             :   oddball->set_kind(kind);
   13182         341 : }
   13183             : 
   13184        2168 : int Script::GetEvalPosition() {
   13185             :   DisallowHeapAllocation no_gc;
   13186             :   DCHECK(compilation_type() == Script::COMPILATION_TYPE_EVAL);
   13187             :   int position = eval_from_position();
   13188        2168 :   if (position < 0) {
   13189             :     // Due to laziness, the position may not have been translated from code
   13190             :     // offset yet, which would be encoded as negative integer. In that case,
   13191             :     // translate and set the position.
   13192         791 :     if (eval_from_shared()->IsUndefined(GetIsolate())) {
   13193             :       position = 0;
   13194             :     } else {
   13195             :       SharedFunctionInfo* shared = SharedFunctionInfo::cast(eval_from_shared());
   13196        1582 :       position = shared->abstract_code()->SourcePosition(-position);
   13197             :     }
   13198             :     DCHECK_GE(position, 0);
   13199             :     set_eval_from_position(position);
   13200             :   }
   13201        2168 :   return position;
   13202             : }
   13203             : 
   13204     1142656 : void Script::InitLineEnds(Handle<Script> script) {
   13205             :   Isolate* isolate = script->GetIsolate();
   13206     2285312 :   if (!script->line_ends()->IsUndefined(isolate)) return;
   13207             :   DCHECK_NE(Script::TYPE_WASM, script->type());
   13208             : 
   13209             :   Object* src_obj = script->source();
   13210       44462 :   if (!src_obj->IsString()) {
   13211             :     DCHECK(src_obj->IsUndefined(isolate));
   13212          12 :     script->set_line_ends(isolate->heap()->empty_fixed_array());
   13213             :   } else {
   13214             :     DCHECK(src_obj->IsString());
   13215             :     Handle<String> src(String::cast(src_obj), isolate);
   13216       44456 :     Handle<FixedArray> array = String::CalculateLineEnds(src, true);
   13217       44456 :     script->set_line_ends(*array);
   13218             :   }
   13219             : 
   13220             :   DCHECK(script->line_ends()->IsFixedArray());
   13221             : }
   13222             : 
   13223      957936 : bool Script::GetPositionInfo(Handle<Script> script, int position,
   13224             :                              PositionInfo* info, OffsetFlag offset_flag) {
   13225             :   // For wasm, we do not create an artificial line_ends array, but do the
   13226             :   // translation directly.
   13227      957936 :   if (script->type() != Script::TYPE_WASM) InitLineEnds(script);
   13228      957936 :   return script->GetPositionInfo(position, info, offset_flag);
   13229             : }
   13230             : 
   13231    17924358 : bool Script::IsUserJavaScript() { return type() == Script::TYPE_NORMAL; }
   13232             : 
   13233             : namespace {
   13234        1184 : bool GetPositionInfoSlow(const Script* script, int position,
   13235             :                          Script::PositionInfo* info) {
   13236        1184 :   if (!script->source()->IsString()) return false;
   13237        1184 :   if (position < 0) position = 0;
   13238             : 
   13239             :   String* source_string = String::cast(script->source());
   13240             :   int line = 0;
   13241             :   int line_start = 0;
   13242             :   int len = source_string->length();
   13243      363503 :   for (int pos = 0; pos <= len; ++pos) {
   13244      726946 :     if (pos == len || source_string->Get(pos) == '\n') {
   13245       14912 :       if (position <= pos) {
   13246        1174 :         info->line = line;
   13247        1174 :         info->column = position - line_start;
   13248        1174 :         info->line_start = line_start;
   13249        1174 :         info->line_end = pos;
   13250        1174 :         return true;
   13251             :       }
   13252       13738 :       line++;
   13253       13738 :       line_start = pos + 1;
   13254             :     }
   13255             :   }
   13256             :   return false;
   13257             : }
   13258             : }  // namespace
   13259             : 
   13260             : #define SMI_VALUE(x) (Smi::ToInt(x))
   13261      973603 : bool Script::GetPositionInfo(int position, PositionInfo* info,
   13262             :                              OffsetFlag offset_flag) const {
   13263             :   DisallowHeapAllocation no_allocation;
   13264             : 
   13265             :   // For wasm, we do not rely on the line_ends array, but do the translation
   13266             :   // directly.
   13267      973603 :   if (type() == Script::TYPE_WASM) {
   13268             :     Handle<WasmCompiledModule> compiled_module(
   13269             :         WasmCompiledModule::cast(wasm_compiled_module()));
   13270             :     DCHECK_LE(0, position);
   13271             :     return compiled_module->GetPositionInfo(static_cast<uint32_t>(position),
   13272         976 :                                             info);
   13273             :   }
   13274             : 
   13275      973115 :   if (line_ends()->IsUndefined(GetIsolate())) {
   13276             :     // Slow mode: we do not have line_ends. We have to iterate through source.
   13277        1184 :     if (!GetPositionInfoSlow(this, position, info)) return false;
   13278             :   } else {
   13279             :     DCHECK(line_ends()->IsFixedArray());
   13280             :     FixedArray* ends = FixedArray::cast(line_ends());
   13281             : 
   13282             :     const int ends_len = ends->length();
   13283      971931 :     if (ends_len == 0) return false;
   13284             : 
   13285             :     // Return early on invalid positions. Negative positions behave as if 0 was
   13286             :     // passed, and positions beyond the end of the script return as failure.
   13287      971913 :     if (position < 0) {
   13288             :       position = 0;
   13289     1942776 :     } else if (position > SMI_VALUE(ends->get(ends_len - 1))) {
   13290             :       return false;
   13291             :     }
   13292             : 
   13293             :     // Determine line number by doing a binary search on the line ends array.
   13294      971894 :     if (SMI_VALUE(ends->get(0)) >= position) {
   13295      187945 :       info->line = 0;
   13296      187945 :       info->line_start = 0;
   13297      187945 :       info->column = position;
   13298             :     } else {
   13299             :       int left = 0;
   13300      783949 :       int right = ends_len - 1;
   13301             : 
   13302     5378515 :       while (right > 0) {
   13303             :         DCHECK_LE(left, right);
   13304     4594566 :         const int mid = (left + right) / 2;
   13305     4594566 :         if (position > SMI_VALUE(ends->get(mid))) {
   13306     2331369 :           left = mid + 1;
   13307     4526394 :         } else if (position <= SMI_VALUE(ends->get(mid - 1))) {
   13308             :           right = mid - 1;
   13309             :         } else {
   13310      783949 :           info->line = mid;
   13311      783949 :           break;
   13312             :         }
   13313             :       }
   13314             :       DCHECK(SMI_VALUE(ends->get(info->line)) >= position &&
   13315             :              SMI_VALUE(ends->get(info->line - 1)) < position);
   13316     1567898 :       info->line_start = SMI_VALUE(ends->get(info->line - 1)) + 1;
   13317      783949 :       info->column = position - info->line_start;
   13318             :     }
   13319             : 
   13320             :     // Line end is position of the linebreak character.
   13321     1943788 :     info->line_end = SMI_VALUE(ends->get(info->line));
   13322      971894 :     if (info->line_end > 0) {
   13323             :       DCHECK(source()->IsString());
   13324             :       String* src = String::cast(source());
   13325     1942510 :       if (src->length() >= info->line_end &&
   13326      971255 :           src->Get(info->line_end - 1) == '\r') {
   13327           0 :         info->line_end--;
   13328             :       }
   13329             :     }
   13330             :   }
   13331             : 
   13332             :   // Add offsets if requested.
   13333      973068 :   if (offset_flag == WITH_OFFSET) {
   13334      838900 :     if (info->line == 0) {
   13335      165363 :       info->column += column_offset();
   13336             :     }
   13337      838900 :     info->line += line_offset();
   13338             :   }
   13339             : 
   13340             :   return true;
   13341             : }
   13342             : #undef SMI_VALUE
   13343             : 
   13344      219212 : int Script::GetColumnNumber(Handle<Script> script, int code_pos) {
   13345             :   PositionInfo info;
   13346      219212 :   GetPositionInfo(script, code_pos, &info, WITH_OFFSET);
   13347      219212 :   return info.column;
   13348             : }
   13349             : 
   13350           0 : int Script::GetColumnNumber(int code_pos) const {
   13351             :   PositionInfo info;
   13352           0 :   GetPositionInfo(code_pos, &info, WITH_OFFSET);
   13353           0 :   return info.column;
   13354             : }
   13355             : 
   13356      225395 : int Script::GetLineNumber(Handle<Script> script, int code_pos) {
   13357             :   PositionInfo info;
   13358      225395 :   GetPositionInfo(script, code_pos, &info, WITH_OFFSET);
   13359      225395 :   return info.line;
   13360             : }
   13361             : 
   13362       15567 : int Script::GetLineNumber(int code_pos) const {
   13363             :   PositionInfo info;
   13364       15567 :   GetPositionInfo(code_pos, &info, WITH_OFFSET);
   13365       15567 :   return info.line;
   13366             : }
   13367             : 
   13368       29652 : Object* Script::GetNameOrSourceURL() {
   13369             :   Isolate* isolate = GetIsolate();
   13370             :   // Keep in sync with ScriptNameOrSourceURL in messages.js.
   13371       31740 :   if (!source_url()->IsUndefined(isolate)) return source_url();
   13372       27564 :   return name();
   13373             : }
   13374             : 
   13375             : 
   13376     1224204 : Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
   13377             :   Isolate* isolate = script->GetIsolate();
   13378     1224204 :   if (!script->wrapper()->IsUndefined(isolate)) {
   13379             :     DCHECK(script->wrapper()->IsWeakCell());
   13380             :     Handle<WeakCell> cell(WeakCell::cast(script->wrapper()));
   13381      844390 :     if (!cell->cleared()) {
   13382             :       // Return a handle for the existing script wrapper from the cache.
   13383             :       return handle(JSObject::cast(cell->value()));
   13384             :     }
   13385             :     // If we found an empty WeakCell, that means the script wrapper was
   13386             :     // GCed.  We are not notified directly of that, so we decrement here
   13387             :     // so that we at least don't count double for any given script.
   13388        6928 :     isolate->counters()->script_wrappers()->Decrement();
   13389             :   }
   13390             :   // Construct a new script wrapper.
   13391      386742 :   isolate->counters()->script_wrappers()->Increment();
   13392      386742 :   Handle<JSFunction> constructor = isolate->script_function();
   13393             :   Handle<JSValue> result =
   13394      386742 :       Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
   13395      386742 :   result->set_value(*script);
   13396      386742 :   Handle<WeakCell> cell = isolate->factory()->NewWeakCell(result);
   13397      386742 :   script->set_wrapper(*cell);
   13398      386742 :   return result;
   13399             : }
   13400             : 
   13401     4708095 : MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
   13402     4708095 :     Isolate* isolate, const FunctionLiteral* fun) {
   13403             :   DCHECK_NE(fun->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
   13404             :   DCHECK_LT(fun->function_literal_id(), shared_function_infos()->length());
   13405             :   Object* shared = shared_function_infos()->get(fun->function_literal_id());
   13406     5260430 :   if (shared->IsUndefined(isolate) || WeakCell::cast(shared)->cleared()) {
   13407     4155760 :     return MaybeHandle<SharedFunctionInfo>();
   13408             :   }
   13409      552335 :   return handle(SharedFunctionInfo::cast(WeakCell::cast(shared)->value()));
   13410             : }
   13411             : 
   13412      133214 : Script::Iterator::Iterator(Isolate* isolate)
   13413      266433 :     : iterator_(isolate->heap()->script_list()) {}
   13414             : 
   13415             : 
   13416     2764834 : Script* Script::Iterator::Next() { return iterator_.Next<Script>(); }
   13417             : 
   13418             : 
   13419       60106 : SharedFunctionInfo::ScriptIterator::ScriptIterator(Handle<Script> script)
   13420             :     : ScriptIterator(script->GetIsolate(),
   13421       60106 :                      handle(script->shared_function_infos())) {}
   13422             : 
   13423         460 : SharedFunctionInfo::ScriptIterator::ScriptIterator(
   13424             :     Isolate* isolate, Handle<FixedArray> shared_function_infos)
   13425             :     : isolate_(isolate),
   13426             :       shared_function_infos_(shared_function_infos),
   13427       60566 :       index_(0) {}
   13428             : 
   13429      863188 : SharedFunctionInfo* SharedFunctionInfo::ScriptIterator::Next() {
   13430     3266976 :   while (index_ < shared_function_infos_->length()) {
   13431     1141283 :     Object* raw = shared_function_infos_->get(index_++);
   13432     3104314 :     if (raw->IsUndefined(isolate_) || WeakCell::cast(raw)->cleared()) continue;
   13433      802577 :     return SharedFunctionInfo::cast(WeakCell::cast(raw)->value());
   13434             :   }
   13435             :   return nullptr;
   13436             : }
   13437             : 
   13438          55 : void SharedFunctionInfo::ScriptIterator::Reset(Handle<Script> script) {
   13439          55 :   shared_function_infos_ = handle(script->shared_function_infos());
   13440          55 :   index_ = 0;
   13441          55 : }
   13442             : 
   13443           5 : SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate)
   13444             :     : script_iterator_(isolate),
   13445             :       noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()),
   13446          10 :       sfi_iterator_(handle(script_iterator_.Next(), isolate)) {}
   13447             : 
   13448        4070 : SharedFunctionInfo* SharedFunctionInfo::GlobalIterator::Next() {
   13449        4070 :   SharedFunctionInfo* next = noscript_sfi_iterator_.Next<SharedFunctionInfo>();
   13450        4070 :   if (next != nullptr) return next;
   13451             :   for (;;) {
   13452        1235 :     next = sfi_iterator_.Next();
   13453        1235 :     if (next != nullptr) return next;
   13454             :     Script* next_script = script_iterator_.Next();
   13455          60 :     if (next_script == nullptr) return nullptr;
   13456          55 :     sfi_iterator_.Reset(handle(next_script));
   13457          55 :   }
   13458             : }
   13459             : 
   13460     5174202 : void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
   13461             :                                    Handle<Object> script_object,
   13462             :                                    bool reset_preparsed_scope_data) {
   13463             :   DCHECK_NE(shared->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
   13464    10348404 :   if (shared->script() == *script_object) return;
   13465             :   Isolate* isolate = shared->GetIsolate();
   13466             : 
   13467     5174202 :   if (reset_preparsed_scope_data) {
   13468        7211 :     shared->set_preparsed_scope_data(isolate->heap()->null_value());
   13469             :   }
   13470             : 
   13471             :   // Add shared function info to new script's list. If a collection occurs,
   13472             :   // the shared function info may be temporarily in two lists.
   13473             :   // This is okay because the gc-time processing of these lists can tolerate
   13474             :   // duplicates.
   13475     5174202 :   if (script_object->IsScript()) {
   13476             :     Handle<Script> script = Handle<Script>::cast(script_object);
   13477             :     Handle<FixedArray> list = handle(script->shared_function_infos(), isolate);
   13478             : #ifdef DEBUG
   13479             :     DCHECK_LT(shared->function_literal_id(), list->length());
   13480             :     if (list->get(shared->function_literal_id())->IsWeakCell() &&
   13481             :         !WeakCell::cast(list->get(shared->function_literal_id()))->cleared()) {
   13482             :       DCHECK(
   13483             :           WeakCell::cast(list->get(shared->function_literal_id()))->value() ==
   13484             :           *shared);
   13485             :     }
   13486             : #endif
   13487     5169631 :     Handle<WeakCell> cell = isolate->factory()->NewWeakCell(shared);
   13488     5169631 :     list->set(shared->function_literal_id(), *cell);
   13489             :   } else {
   13490             :     Handle<Object> list = isolate->factory()->noscript_shared_function_infos();
   13491             : 
   13492             : #ifdef DEBUG
   13493             :     if (FLAG_enable_slow_asserts) {
   13494             :       WeakFixedArray::Iterator iterator(*list);
   13495             :       SharedFunctionInfo* next;
   13496             :       while ((next = iterator.Next<SharedFunctionInfo>()) != nullptr) {
   13497             :         DCHECK_NE(next, *shared);
   13498             :       }
   13499             :     }
   13500             : #endif  // DEBUG
   13501             : 
   13502        4571 :     list = WeakFixedArray::Add(list, shared);
   13503             : 
   13504             :     isolate->heap()->SetRootNoScriptSharedFunctionInfos(*list);
   13505             :   }
   13506             : 
   13507     5174202 :   if (shared->script()->IsScript()) {
   13508             :     // Remove shared function info from old script's list.
   13509             :     Script* old_script = Script::cast(shared->script());
   13510             : 
   13511             :     // Due to liveedit, it might happen that the old_script doesn't know
   13512             :     // about the SharedFunctionInfo, so we have to guard against that.
   13513             :     Handle<FixedArray> infos(old_script->shared_function_infos(), isolate);
   13514        4595 :     if (shared->function_literal_id() < infos->length()) {
   13515             :       Object* raw = old_script->shared_function_infos()->get(
   13516             :           shared->function_literal_id());
   13517        9149 :       if (!raw->IsWeakCell() || WeakCell::cast(raw)->value() == *shared) {
   13518             :         old_script->shared_function_infos()->set(
   13519        2168 :             shared->function_literal_id(), isolate->heap()->undefined_value());
   13520             :       }
   13521             :     }
   13522             :   } else {
   13523             :     // Remove shared function info from root array.
   13524     5169607 :     Object* list = isolate->heap()->noscript_shared_function_infos();
   13525     5169607 :     CHECK(WeakFixedArray::cast(list)->Remove(shared));
   13526             :   }
   13527             : 
   13528             :   // Finally set new script.
   13529     5174202 :   shared->set_script(*script_object);
   13530             : }
   13531             : 
   13532     1161758 : bool SharedFunctionInfo::HasBreakInfo() const {
   13533     1161758 :   if (!HasDebugInfo()) return false;
   13534             :   DebugInfo* info = DebugInfo::cast(debug_info());
   13535      308513 :   bool has_break_info = info->HasBreakInfo();
   13536             :   DCHECK_IMPLIES(has_break_info, HasBytecodeArray());
   13537      308513 :   return has_break_info;
   13538             : }
   13539             : 
   13540      244286 : bool SharedFunctionInfo::HasCoverageInfo() const {
   13541      244286 :   if (!HasDebugInfo()) return false;
   13542             :   DebugInfo* info = DebugInfo::cast(debug_info());
   13543      232585 :   bool has_coverage_info = info->HasCoverageInfo();
   13544      232585 :   return has_coverage_info;
   13545             : }
   13546             : 
   13547      224645 : CoverageInfo* SharedFunctionInfo::GetCoverageInfo() const {
   13548             :   DCHECK(HasCoverageInfo());
   13549      224645 :   return CoverageInfo::cast(GetDebugInfo()->coverage_info());
   13550             : }
   13551             : 
   13552      395533 : DebugInfo* SharedFunctionInfo::GetDebugInfo() const {
   13553             :   DCHECK(HasDebugInfo());
   13554      395533 :   return DebugInfo::cast(debug_info());
   13555             : }
   13556             : 
   13557     2483201 : int SharedFunctionInfo::debugger_hints() const {
   13558     9294185 :   if (HasDebugInfo()) return GetDebugInfo()->debugger_hints();
   13559     2329219 :   return Smi::ToInt(debug_info());
   13560             : }
   13561             : 
   13562     7339701 : void SharedFunctionInfo::set_debugger_hints(int value) {
   13563     7339701 :   if (HasDebugInfo()) {
   13564             :     GetDebugInfo()->set_debugger_hints(value);
   13565             :   } else {
   13566     7338271 :     set_debug_info(Smi::FromInt(value));
   13567             :   }
   13568     7339702 : }
   13569             : 
   13570     1428497 : String* SharedFunctionInfo::DebugName() {
   13571             :   String* n = name();
   13572     1428497 :   if (String::cast(n)->length() == 0) return inferred_name();
   13573             :   return String::cast(n);
   13574             : }
   13575             : 
   13576        9732 : bool SharedFunctionInfo::HasNoSideEffect() {
   13577        9732 :   if (!computed_has_no_side_effect()) {
   13578             :     DisallowHeapAllocation not_handlified;
   13579             :     Handle<SharedFunctionInfo> info(this);
   13580        8181 :     set_has_no_side_effect(DebugEvaluate::FunctionHasNoSideEffect(info));
   13581        8181 :     set_computed_has_no_side_effect(true);
   13582             :   }
   13583        9732 :   return has_no_side_effect();
   13584             : }
   13585             : 
   13586             : // The filter is a pattern that matches function names in this way:
   13587             : //   "*"      all; the default
   13588             : //   "-"      all but the top-level function
   13589             : //   "-name"  all but the function "name"
   13590             : //   ""       only the top-level function
   13591             : //   "name"   only the function "name"
   13592             : //   "name*"  only functions starting with "name"
   13593             : //   "~"      none; the tilde is not an identifier
   13594      439182 : bool SharedFunctionInfo::PassesFilter(const char* raw_filter) {
   13595      439182 :   if (*raw_filter == '*') return true;
   13596         207 :   String* name = DebugName();
   13597             :   Vector<const char> filter = CStrVector(raw_filter);
   13598         207 :   if (filter.length() == 0) return name->length() == 0;
   13599         207 :   if (filter[0] == '-') {
   13600             :     // Negative filter.
   13601           0 :     if (filter.length() == 1) {
   13602           0 :       return (name->length() != 0);
   13603           0 :     } else if (name->IsUtf8EqualTo(filter.SubVector(1, filter.length()))) {
   13604             :       return false;
   13605             :     }
   13606           0 :     if (filter[filter.length() - 1] == '*' &&
   13607           0 :         name->IsUtf8EqualTo(filter.SubVector(1, filter.length() - 1), true)) {
   13608             :       return false;
   13609             :     }
   13610           0 :     return true;
   13611             : 
   13612         207 :   } else if (name->IsUtf8EqualTo(filter)) {
   13613             :     return true;
   13614             :   }
   13615         284 :   if (filter[filter.length() - 1] == '*' &&
   13616          28 :       name->IsUtf8EqualTo(filter.SubVector(0, filter.length() - 1), true)) {
   13617             :     return true;
   13618             :   }
   13619         110 :   return false;
   13620             : }
   13621             : 
   13622     6726046 : bool SharedFunctionInfo::HasSourceCode() const {
   13623             :   Isolate* isolate = GetIsolate();
   13624    13452092 :   return !script()->IsUndefined(isolate) &&
   13625     6726046 :          !reinterpret_cast<Script*>(script())->source()->IsUndefined(isolate);
   13626             : }
   13627             : 
   13628             : 
   13629      722624 : Handle<Object> SharedFunctionInfo::GetSourceCode() {
   13630      722624 :   if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value();
   13631             :   Handle<String> source(String::cast(Script::cast(script())->source()));
   13632             :   return GetIsolate()->factory()->NewSubString(
   13633      722624 :       source, start_position(), end_position());
   13634             : }
   13635             : 
   13636         813 : Handle<Object> SharedFunctionInfo::GetSourceCodeHarmony() {
   13637             :   Isolate* isolate = GetIsolate();
   13638         813 :   if (!HasSourceCode()) return isolate->factory()->undefined_value();
   13639             :   Handle<String> script_source(String::cast(Script::cast(script())->source()));
   13640             :   int start_pos = function_token_position();
   13641         813 :   if (start_pos == kNoSourcePosition) start_pos = start_position();
   13642             :   return isolate->factory()->NewSubString(script_source, start_pos,
   13643         813 :                                           end_position());
   13644             : }
   13645             : 
   13646       62272 : bool SharedFunctionInfo::IsInlineable() {
   13647             :   // Check that the function has a script associated with it.
   13648       62272 :   if (!script()->IsScript()) return false;
   13649       62272 :   if (GetIsolate()->is_precise_binary_code_coverage() &&
   13650             :       !has_reported_binary_coverage()) {
   13651             :     // We may miss invocations if this function is inlined.
   13652             :     return false;
   13653             :   }
   13654       62272 :   return !optimization_disabled();
   13655             : }
   13656             : 
   13657           0 : int SharedFunctionInfo::SourceSize() {
   13658           0 :   return end_position() - start_position();
   13659             : }
   13660             : 
   13661      332085 : void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type,
   13662             :                                              bool has_prototype_slot,
   13663             :                                              int requested_embedder_fields,
   13664             :                                              int requested_in_object_properties,
   13665             :                                              int* instance_size,
   13666             :                                              int* in_object_properties) {
   13667      332085 :   int header_size = JSObject::GetHeaderSize(instance_type, has_prototype_slot);
   13668             :   DCHECK_LE(requested_embedder_fields,
   13669             :             (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2);
   13670             :   *instance_size =
   13671             :       Min(header_size +
   13672      332085 :               ((requested_embedder_fields + requested_in_object_properties)
   13673      332085 :                << kPointerSizeLog2),
   13674      664170 :           JSObject::kMaxInstanceSize);
   13675      332085 :   *in_object_properties = ((*instance_size - header_size) >> kPointerSizeLog2) -
   13676      332085 :                           requested_embedder_fields;
   13677      332085 : }
   13678             : 
   13679        7160 : void JSFunction::CalculateInstanceSizeForDerivedClass(
   13680             :     Handle<JSFunction> function, InstanceType instance_type,
   13681             :     int requested_embedder_fields, int* instance_size,
   13682             :     int* in_object_properties) {
   13683             :   Isolate* isolate = function->GetIsolate();
   13684             :   int expected_nof_properties = 0;
   13685       30342 :   for (PrototypeIterator iter(isolate, function, kStartAtReceiver);
   13686       16022 :        !iter.IsAtEnd(); iter.Advance()) {
   13687             :     Handle<JSReceiver> current =
   13688             :         PrototypeIterator::GetCurrent<JSReceiver>(iter);
   13689       23182 :     if (!current->IsJSFunction()) break;
   13690             :     Handle<JSFunction> func(Handle<JSFunction>::cast(current));
   13691             :     // The super constructor should be compiled for the number of expected
   13692             :     // properties to be available.
   13693             :     Handle<SharedFunctionInfo> shared(func->shared());
   13694       23398 :     if (shared->is_compiled() ||
   13695         226 :         Compiler::Compile(func, Compiler::CLEAR_EXCEPTION)) {
   13696             :       DCHECK(shared->is_compiled());
   13697       23172 :       expected_nof_properties += shared->expected_nof_properties();
   13698             :     }
   13699       23172 :     if (!IsDerivedConstructor(shared->kind())) {
   13700             :       break;
   13701             :     }
   13702             :   }
   13703             :   CalculateInstanceSizeHelper(instance_type, true, requested_embedder_fields,
   13704             :                               expected_nof_properties, instance_size,
   13705        7160 :                               in_object_properties);
   13706        7160 : }
   13707             : 
   13708             : 
   13709             : // Output the source code without any allocation in the heap.
   13710           0 : std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) {
   13711           0 :   const SharedFunctionInfo* s = v.value;
   13712             :   // For some native functions there is no source.
   13713           0 :   if (!s->HasSourceCode()) return os << "<No Source>";
   13714             : 
   13715             :   // Get the source for the script which this function came from.
   13716             :   // Don't use String::cast because we don't want more assertion errors while
   13717             :   // we are already creating a stack dump.
   13718             :   String* script_source =
   13719             :       reinterpret_cast<String*>(Script::cast(s->script())->source());
   13720             : 
   13721           0 :   if (!script_source->LooksValid()) return os << "<Invalid Source>";
   13722             : 
   13723           0 :   if (!s->is_toplevel()) {
   13724           0 :     os << "function ";
   13725             :     String* name = s->name();
   13726           0 :     if (name->length() > 0) {
   13727           0 :       name->PrintUC16(os);
   13728             :     }
   13729             :   }
   13730             : 
   13731           0 :   int len = s->end_position() - s->start_position();
   13732           0 :   if (len <= v.max_length || v.max_length < 0) {
   13733           0 :     script_source->PrintUC16(os, s->start_position(), s->end_position());
   13734           0 :     return os;
   13735             :   } else {
   13736             :     script_source->PrintUC16(os, s->start_position(),
   13737           0 :                              s->start_position() + v.max_length);
   13738           0 :     return os << "...\n";
   13739             :   }
   13740             : }
   13741             : 
   13742             : 
   13743       24667 : void SharedFunctionInfo::DisableOptimization(BailoutReason reason) {
   13744             :   DCHECK_NE(reason, kNoReason);
   13745             : 
   13746             :   set_compiler_hints(
   13747       49334 :       DisabledOptimizationReasonBits::update(compiler_hints(), reason));
   13748             :   // Code should be the lazy compilation stub or else interpreted.
   13749             :   DCHECK(abstract_code()->kind() == AbstractCode::INTERPRETED_FUNCTION ||
   13750             :          abstract_code()->kind() == AbstractCode::BUILTIN);
   13751       24667 :   PROFILE(GetIsolate(), CodeDisableOptEvent(abstract_code(), this));
   13752       24667 :   if (FLAG_trace_opt) {
   13753           0 :     PrintF("[disabled optimization for ");
   13754           0 :     ShortPrint();
   13755           0 :     PrintF(", reason: %s]\n", GetBailoutReason(reason));
   13756             :   }
   13757       24667 : }
   13758             : 
   13759     5166991 : void SharedFunctionInfo::InitFromFunctionLiteral(
   13760    34313286 :     Handle<SharedFunctionInfo> shared_info, FunctionLiteral* lit) {
   13761             :   // When adding fields here, make sure DeclarationScope::AnalyzePartially is
   13762             :   // updated accordingly.
   13763             :   shared_info->set_internal_formal_parameter_count(lit->parameter_count());
   13764             :   shared_info->set_function_token_position(lit->function_token_position());
   13765     5166991 :   shared_info->set_start_position(lit->start_position());
   13766     5166991 :   shared_info->set_end_position(lit->end_position());
   13767             :   shared_info->set_is_declaration(lit->is_declaration());
   13768             :   shared_info->set_is_named_expression(lit->is_named_expression());
   13769    10333982 :   shared_info->set_is_anonymous_expression(lit->is_anonymous_expression());
   13770    10333981 :   shared_info->set_inferred_name(*lit->inferred_name());
   13771     5166990 :   shared_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
   13772     5166990 :   shared_info->set_language_mode(lit->language_mode());
   13773             :   //  shared_info->set_kind(lit->kind());
   13774             :   // FunctionKind must have already been set.
   13775             :   DCHECK(lit->kind() == shared_info->kind());
   13776     5166990 :   if (!IsConstructable(lit->kind())) {
   13777             :     shared_info->SetConstructStub(
   13778     1335268 :         *BUILTIN_CODE(shared_info->GetIsolate(), ConstructedNonConstructable));
   13779             :   }
   13780     5166990 :   shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject());
   13781             :   shared_info->set_function_literal_id(lit->function_literal_id());
   13782             : 
   13783             :   // For lazy parsed functions, the following flags will be inaccurate since we
   13784             :   // don't have the information yet. They're set later in
   13785             :   // SetSharedFunctionFlagsFromLiteral (compiler.cc), when the function is
   13786             :   // really parsed and compiled.
   13787     5166991 :   if (lit->body() != nullptr) {
   13788             :     shared_info->set_length(lit->function_length());
   13789             :     shared_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
   13790             :     shared_info->SetExpectedNofPropertiesFromEstimate(lit);
   13791             :     DCHECK_NULL(lit->produced_preparsed_scope_data());
   13792             :   } else {
   13793             :     // Set an invalid length for lazy functions. This way we can set the correct
   13794             :     // value after compiling, but avoid overwriting values set manually by the
   13795             :     // bootstrapper.
   13796             :     shared_info->set_length(SharedFunctionInfo::kInvalidLength);
   13797     1855650 :     if (FLAG_preparser_scope_analysis) {
   13798             :       ProducedPreParsedScopeData* scope_data =
   13799             :           lit->produced_preparsed_scope_data();
   13800     1855650 :       if (scope_data != nullptr) {
   13801             :         MaybeHandle<PreParsedScopeData> maybe_data =
   13802     1818337 :             scope_data->Serialize(shared_info->GetIsolate());
   13803     1818337 :         if (!maybe_data.is_null()) {
   13804             :           Handle<PreParsedScopeData> data = maybe_data.ToHandleChecked();
   13805       52950 :           shared_info->set_preparsed_scope_data(*data);
   13806             :         }
   13807             :       }
   13808             :     }
   13809             :   }
   13810     5166991 : }
   13811             : 
   13812     2134855 : void SharedFunctionInfo::SetExpectedNofPropertiesFromEstimate(
   13813     5446196 :     FunctionLiteral* literal) {
   13814             :   int estimate = literal->expected_property_count();
   13815             : 
   13816             :   // If no properties are added in the constructor, they are more likely
   13817             :   // to be added later.
   13818     5446196 :   if (estimate == 0) estimate = 2;
   13819             : 
   13820             :   // Inobject slack tracking will reclaim redundant inobject space later,
   13821             :   // so we can afford to adjust the estimate generously.
   13822     5446196 :   estimate += 8;
   13823             : 
   13824             :   set_expected_nof_properties(estimate);
   13825     2134855 : }
   13826             : 
   13827    13034551 : void SharedFunctionInfo::SetConstructStub(Code* code) {
   13828    13034551 :   if (code->kind() == Code::BUILTIN) code->set_is_construct_stub(true);
   13829             : #ifdef DEBUG
   13830             :   if (code->is_builtin()) {
   13831             :     // See https://crbug.com/v8/6787. Lazy deserialization currently cannot
   13832             :     // handle lazy construct stubs that differ from the code object.
   13833             :     int builtin_id = code->builtin_index();
   13834             :     DCHECK_NE(Builtins::kDeserializeLazy, builtin_id);
   13835             :     DCHECK(builtin_id == Builtins::kJSBuiltinsConstructStub ||
   13836             :            this->code() == code || !Builtins::IsLazy(builtin_id));
   13837             :   }
   13838             : #endif
   13839    13034551 :   set_construct_stub(code);
   13840    13034552 : }
   13841             : 
   13842           0 : void Map::StartInobjectSlackTracking() {
   13843             :   DCHECK(!IsInobjectSlackTrackingInProgress());
   13844      332085 :   if (UnusedPropertyFields() == 0) return;
   13845             :   set_construction_counter(Map::kSlackTrackingCounterStart);
   13846             : }
   13847             : 
   13848     5795310 : void ObjectVisitor::VisitCodeTarget(Code* host, RelocInfo* rinfo) {
   13849             :   DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
   13850     5795310 :   Object* old_pointer = Code::GetCodeFromTargetAddress(rinfo->target_address());
   13851     5795310 :   Object* new_pointer = old_pointer;
   13852     5795310 :   VisitPointer(host, &new_pointer);
   13853             :   DCHECK_EQ(old_pointer, new_pointer);
   13854     5795310 : }
   13855             : 
   13856      313031 : void ObjectVisitor::VisitEmbeddedPointer(Code* host, RelocInfo* rinfo) {
   13857             :   DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
   13858             :   Object* old_pointer = rinfo->target_object();
   13859      313031 :   Object* new_pointer = old_pointer;
   13860      313031 :   VisitPointer(host, &new_pointer);
   13861             :   DCHECK_EQ(old_pointer, new_pointer);
   13862      313031 : }
   13863             : 
   13864             : 
   13865           0 : void Code::InvalidateRelocation() {
   13866           0 :   InvalidateEmbeddedObjects();
   13867           0 :   set_relocation_info(GetHeap()->empty_byte_array());
   13868           0 : }
   13869             : 
   13870             : 
   13871      255503 : void Code::InvalidateEmbeddedObjects() {
   13872      255503 :   HeapObject* undefined = GetHeap()->undefined_value();
   13873             :   int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
   13874     3432520 :   for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
   13875     3177017 :     RelocInfo::Mode mode = it.rinfo()->rmode();
   13876     3177017 :     if (mode == RelocInfo::EMBEDDED_OBJECT) {
   13877             :       it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER);
   13878             :     }
   13879             :   }
   13880      255503 : }
   13881             : 
   13882             : 
   13883       90109 : void Code::Relocate(intptr_t delta) {
   13884       96839 :   if (trap_handler::UseTrapHandler() && is_wasm_code()) {
   13885             :     const int index = trap_handler_index()->value();
   13886         679 :     if (index >= 0) {
   13887           7 :       trap_handler::UpdateHandlerDataCodePointer(index, instruction_start());
   13888             :     }
   13889             :   }
   13890      265260 :   for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
   13891      175151 :     it.rinfo()->apply(delta);
   13892             :   }
   13893      180218 :   Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size());
   13894       90109 : }
   13895             : 
   13896             : 
   13897     1669351 : void Code::CopyFrom(const CodeDesc& desc) {
   13898             :   // copy code
   13899             :   CopyBytes(instruction_start(), desc.buffer,
   13900     1669351 :             static_cast<size_t>(desc.instr_size));
   13901             : 
   13902             :   // copy unwinding info, if any
   13903     1669351 :   if (desc.unwinding_info) {
   13904             :     DCHECK_GT(desc.unwinding_info_size, 0);
   13905          27 :     set_unwinding_info_size(desc.unwinding_info_size);
   13906             :     CopyBytes(unwinding_info_start(), desc.unwinding_info,
   13907          54 :               static_cast<size_t>(desc.unwinding_info_size));
   13908             :   }
   13909             : 
   13910             :   // copy reloc info
   13911             :   CopyBytes(relocation_start(),
   13912     1669351 :             desc.buffer + desc.buffer_size - desc.reloc_size,
   13913     5008053 :             static_cast<size_t>(desc.reloc_size));
   13914             : 
   13915             :   // unbox handles and relocate
   13916             :   int mode_mask = RelocInfo::kCodeTargetMask |
   13917             :                   RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
   13918     1669351 :                   RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
   13919     1669351 :                   RelocInfo::kApplyMask;
   13920             :   // Needed to find target_object and runtime_entry on X64
   13921     1669351 :   Assembler* origin = desc.origin;
   13922             :   AllowDeferredHandleDereference embedding_raw_address;
   13923    16087600 :   for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
   13924    14418249 :     RelocInfo::Mode mode = it.rinfo()->rmode();
   13925    14418249 :     if (mode == RelocInfo::EMBEDDED_OBJECT) {
   13926     4989532 :       Handle<HeapObject> p = it.rinfo()->target_object_handle(origin);
   13927             :       it.rinfo()->set_target_object(*p, UPDATE_WRITE_BARRIER,
   13928             :                                     SKIP_ICACHE_FLUSH);
   13929     9428717 :     } else if (RelocInfo::IsCodeTarget(mode)) {
   13930             :       // rewrite code handles to direct pointers to the first instruction in the
   13931             :       // code object
   13932     6025821 :       Handle<Object> p = it.rinfo()->target_object_handle(origin);
   13933             :       Code* code = Code::cast(*p);
   13934             :       it.rinfo()->set_target_address(GetIsolate(), code->instruction_start(),
   13935    12051642 :                                      UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
   13936     3402896 :     } else if (RelocInfo::IsRuntimeEntry(mode)) {
   13937     3077632 :       Address p = it.rinfo()->target_runtime_entry(origin);
   13938             :       it.rinfo()->set_target_runtime_entry(
   13939             :           GetIsolate(), p, UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
   13940             :     } else {
   13941      325264 :       intptr_t delta = instruction_start() - desc.buffer;
   13942      325264 :       it.rinfo()->apply(delta);
   13943             :     }
   13944             :   }
   13945     3338702 :   Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size());
   13946     1669351 : }
   13947             : 
   13948             : 
   13949     2758981 : SafepointEntry Code::GetSafepointEntry(Address pc) {
   13950     2758981 :   SafepointTable table(this);
   13951     2758981 :   return table.FindEntry(pc);
   13952             : }
   13953             : 
   13954             : 
   13955             : namespace {
   13956             : template <typename Code>
   13957        7432 : void SetStackFrameCacheCommon(Handle<Code> code,
   13958             :                               Handle<UnseededNumberDictionary> cache) {
   13959             :   Handle<Object> maybe_table(code->source_position_table(), code->GetIsolate());
   13960        7432 :   if (maybe_table->IsSourcePositionTableWithFrameCache()) {
   13961         561 :     Handle<SourcePositionTableWithFrameCache>::cast(maybe_table)
   13962             :         ->set_stack_frame_cache(*cache);
   13963        7993 :     return;
   13964             :   }
   13965             :   DCHECK(maybe_table->IsByteArray());
   13966        6871 :   Handle<ByteArray> table(Handle<ByteArray>::cast(maybe_table));
   13967             :   Handle<SourcePositionTableWithFrameCache> table_with_cache =
   13968             :       code->GetIsolate()->factory()->NewSourcePositionTableWithFrameCache(
   13969        6871 :           table, cache);
   13970        6871 :   code->set_source_position_table(*table_with_cache);
   13971             : }
   13972             : }  // namespace
   13973             : 
   13974             : // static
   13975        7432 : void AbstractCode::SetStackFrameCache(Handle<AbstractCode> abstract_code,
   13976             :                                       Handle<UnseededNumberDictionary> cache) {
   13977        7432 :   if (abstract_code->IsCode()) {
   13978           0 :     SetStackFrameCacheCommon(handle(abstract_code->GetCode()), cache);
   13979             :   } else {
   13980        7432 :     SetStackFrameCacheCommon(handle(abstract_code->GetBytecodeArray()), cache);
   13981             :   }
   13982        7432 : }
   13983             : 
   13984             : namespace {
   13985             : template <typename Code>
   13986     5765601 : void DropStackFrameCacheCommon(Code* code) {
   13987             :   i::Object* maybe_table = code->source_position_table();
   13988    11531202 :   if (maybe_table->IsByteArray()) return;
   13989             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
   13990          20 :   code->set_source_position_table(
   13991             :       i::SourcePositionTableWithFrameCache::cast(maybe_table)
   13992             :           ->source_position_table());
   13993             : }
   13994             : }  // namespace
   13995             : 
   13996     5765601 : void AbstractCode::DropStackFrameCache() {
   13997     5765601 :   if (IsCode()) {
   13998     5754701 :     DropStackFrameCacheCommon(GetCode());
   13999             :   } else {
   14000       10900 :     DropStackFrameCacheCommon(GetBytecodeArray());
   14001             :   }
   14002     5765600 : }
   14003             : 
   14004     1396566 : int AbstractCode::SourcePosition(int offset) {
   14005             :   int position = 0;
   14006             :   // Subtract one because the current PC is one instruction after the call site.
   14007     1396566 :   if (IsCode()) offset--;
   14008    32602042 :   for (SourcePositionTableIterator iterator(source_position_table());
   14009    31205476 :        !iterator.done() && iterator.code_offset() <= offset;
   14010    29808910 :        iterator.Advance()) {
   14011    29808910 :     position = iterator.source_position().ScriptOffset();
   14012             :   }
   14013     1396566 :   return position;
   14014             : }
   14015             : 
   14016       98825 : int AbstractCode::SourceStatementPosition(int offset) {
   14017             :   // First find the closest position.
   14018       98825 :   int position = SourcePosition(offset);
   14019             :   // Now find the closest statement position before the position.
   14020             :   int statement_position = 0;
   14021    11043366 :   for (SourcePositionTableIterator it(source_position_table()); !it.done();
   14022    10845716 :        it.Advance()) {
   14023    10845716 :     if (it.is_statement()) {
   14024     6905911 :       int p = it.source_position().ScriptOffset();
   14025     6905911 :       if (statement_position < p && p <= position) {
   14026             :         statement_position = p;
   14027             :       }
   14028             :     }
   14029             :   }
   14030       98825 :   return statement_position;
   14031             : }
   14032             : 
   14033       57790 : void JSFunction::ClearTypeFeedbackInfo() {
   14034       57790 :   if (feedback_vector_cell()->value()->IsFeedbackVector()) {
   14035             :     FeedbackVector* vector = feedback_vector();
   14036             :     Isolate* isolate = GetIsolate();
   14037       57761 :     if (vector->ClearSlots(isolate)) {
   14038       31961 :       IC::OnFeedbackChanged(isolate, vector, this);
   14039             :     }
   14040             :   }
   14041       57790 : }
   14042             : 
   14043           0 : void Code::PrintDeoptLocation(FILE* out, Address pc) {
   14044           0 :   Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(this, pc);
   14045           0 :   class SourcePosition pos = info.position;
   14046           0 :   if (info.deopt_reason != DeoptimizeReason::kNoReason || pos.IsKnown()) {
   14047           0 :     PrintF(out, "            ;;; deoptimize at ");
   14048           0 :     OFStream outstr(out);
   14049           0 :     pos.Print(outstr, this);
   14050           0 :     PrintF(out, ", %s\n", DeoptimizeReasonToString(info.deopt_reason));
   14051             :   }
   14052           0 : }
   14053             : 
   14054             : 
   14055        2543 : bool Code::CanDeoptAt(Address pc) {
   14056             :   DeoptimizationData* deopt_data =
   14057             :       DeoptimizationData::cast(deoptimization_data());
   14058        2543 :   Address code_start_address = instruction_start();
   14059       60248 :   for (int i = 0; i < deopt_data->DeoptCount(); i++) {
   14060       59474 :     if (deopt_data->Pc(i)->value() == -1) continue;
   14061       52080 :     Address address = code_start_address + deopt_data->Pc(i)->value();
   14062       28196 :     if (address == pc && deopt_data->BytecodeOffset(i) != BailoutId::None()) {
   14063             :       return true;
   14064             :     }
   14065             :   }
   14066             :   return false;
   14067             : }
   14068             : 
   14069             : 
   14070             : // Identify kind of code.
   14071       22729 : const char* Code::Kind2String(Kind kind) {
   14072       22729 :   switch (kind) {
   14073             : #define CASE(name) case name: return #name;
   14074           0 :     CODE_KIND_LIST(CASE)
   14075             : #undef CASE
   14076             :     case NUMBER_OF_KINDS: break;
   14077             :   }
   14078           0 :   UNREACHABLE();
   14079             : }
   14080             : 
   14081             : // Identify kind of code.
   14082           0 : const char* AbstractCode::Kind2String(Kind kind) {
   14083           0 :   if (kind < AbstractCode::INTERPRETED_FUNCTION)
   14084           0 :     return Code::Kind2String((Code::Kind)kind);
   14085           0 :   if (kind == AbstractCode::INTERPRETED_FUNCTION) return "INTERPRETED_FUNCTION";
   14086           0 :   UNREACHABLE();
   14087             : }
   14088             : 
   14089     1154451 : Handle<WeakCell> Code::WeakCellFor(Handle<Code> code) {
   14090             :   DCHECK(code->kind() == OPTIMIZED_FUNCTION);
   14091     1154451 :   WeakCell* raw_cell = code->CachedWeakCell();
   14092     2076439 :   if (raw_cell != nullptr) return Handle<WeakCell>(raw_cell);
   14093      232463 :   Handle<WeakCell> cell = code->GetIsolate()->factory()->NewWeakCell(code);
   14094             :   DeoptimizationData::cast(code->deoptimization_data())
   14095             :       ->SetWeakCellCache(*cell);
   14096      232463 :   return cell;
   14097             : }
   14098             : 
   14099     1154451 : WeakCell* Code::CachedWeakCell() {
   14100             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
   14101             :   Object* weak_cell_cache =
   14102             :       DeoptimizationData::cast(deoptimization_data())->WeakCellCache();
   14103     1154451 :   if (weak_cell_cache->IsWeakCell()) {
   14104             :     DCHECK(this == WeakCell::cast(weak_cell_cache)->value());
   14105      921988 :     return WeakCell::cast(weak_cell_cache);
   14106             :   }
   14107             :   return nullptr;
   14108             : }
   14109             : 
   14110       48488 : bool Code::Inlines(SharedFunctionInfo* sfi) {
   14111             :   // We can only check for inlining for optimized code.
   14112             :   DCHECK(is_optimized_code());
   14113             :   DisallowHeapAllocation no_gc;
   14114             :   DeoptimizationData* const data =
   14115             :       DeoptimizationData::cast(deoptimization_data());
   14116       48488 :   if (data->length() == 0) return false;
   14117       48485 :   if (data->SharedFunctionInfo() == sfi) return true;
   14118             :   FixedArray* const literals = data->LiteralArray();
   14119             :   int const inlined_count = data->InlinedFunctionCount()->value();
   14120       48336 :   for (int i = 0; i < inlined_count; ++i) {
   14121         198 :     if (SharedFunctionInfo::cast(literals->get(i)) == sfi) return true;
   14122             :   }
   14123             :   return false;
   14124             : }
   14125             : 
   14126        9227 : Code::OptimizedCodeIterator::OptimizedCodeIterator(Isolate* isolate) {
   14127        9227 :   isolate_ = isolate;
   14128        9227 :   Object* list = isolate->heap()->native_contexts_list();
   14129        9227 :   next_context_ = list->IsUndefined(isolate_) ? nullptr : Context::cast(list);
   14130        9227 :   current_code_ = nullptr;
   14131        9227 : }
   14132             : 
   14133       57256 : Code* Code::OptimizedCodeIterator::Next() {
   14134       66946 :   do {
   14135             :     Object* next;
   14136       76173 :     if (current_code_ != nullptr) {
   14137             :       // Get next code in the linked list.
   14138             :       next = Code::cast(current_code_)->next_code_link();
   14139       28144 :     } else if (next_context_ != nullptr) {
   14140             :       // Linked list of code exhausted. Get list of next context.
   14141       18917 :       next = next_context_->OptimizedCodeListHead();
   14142       18917 :       Object* next_context = next_context_->next_context_link();
   14143       18917 :       next_context_ = next_context->IsUndefined(isolate_)
   14144             :                           ? nullptr
   14145       18917 :                           : Context::cast(next_context);
   14146             :     } else {
   14147             :       // Exhausted contexts.
   14148             :       return nullptr;
   14149             :     }
   14150      133892 :     current_code_ = next->IsUndefined(isolate_) ? nullptr : Code::cast(next);
   14151             :   } while (current_code_ == nullptr);
   14152             :   Code* code = Code::cast(current_code_);
   14153             :   DCHECK_EQ(Code::OPTIMIZED_FUNCTION, code->kind());
   14154             :   return code;
   14155             : }
   14156             : 
   14157             : #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   14158             : 
   14159             : const char* Code::ICState2String(InlineCacheState state) {
   14160             :   switch (state) {
   14161             :     case UNINITIALIZED:
   14162             :       return "UNINITIALIZED";
   14163             :     case PREMONOMORPHIC:
   14164             :       return "PREMONOMORPHIC";
   14165             :     case MONOMORPHIC:
   14166             :       return "MONOMORPHIC";
   14167             :     case RECOMPUTE_HANDLER:
   14168             :       return "RECOMPUTE_HANDLER";
   14169             :     case POLYMORPHIC:
   14170             :       return "POLYMORPHIC";
   14171             :     case MEGAMORPHIC:
   14172             :       return "MEGAMORPHIC";
   14173             :     case GENERIC:
   14174             :       return "GENERIC";
   14175             :   }
   14176             :   UNREACHABLE();
   14177             : }
   14178             : 
   14179             : #endif  // defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   14180             : 
   14181             : #ifdef ENABLE_DISASSEMBLER
   14182             : 
   14183             : namespace {
   14184             : void print_pc(std::ostream& os, int pc) {
   14185             :   if (pc == -1) {
   14186             :     os << "NA";
   14187             :   } else {
   14188             :     os << std::hex << pc << std::dec;
   14189             :   }
   14190             : }
   14191             : }  // anonymous namespace
   14192             : 
   14193             : void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) {  // NOLINT
   14194             :   if (length() == 0) {
   14195             :     os << "Deoptimization Input Data invalidated by lazy deoptimization\n";
   14196             :     return;
   14197             :   }
   14198             : 
   14199             :   disasm::NameConverter converter;
   14200             :   int const inlined_function_count = InlinedFunctionCount()->value();
   14201             :   os << "Inlined functions (count = " << inlined_function_count << ")\n";
   14202             :   for (int id = 0; id < inlined_function_count; ++id) {
   14203             :     Object* info = LiteralArray()->get(id);
   14204             :     os << " " << Brief(SharedFunctionInfo::cast(info)) << "\n";
   14205             :   }
   14206             :   os << "\n";
   14207             :   int deopt_count = DeoptCount();
   14208             :   os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
   14209             :   if (0 != deopt_count) {
   14210             :     os << " index  bytecode-offset    pc";
   14211             :     if (FLAG_print_code_verbose) os << "  commands";
   14212             :     os << "\n";
   14213             :   }
   14214             :   for (int i = 0; i < deopt_count; i++) {
   14215             :     os << std::setw(6) << i << "  " << std::setw(15)
   14216             :        << BytecodeOffset(i).ToInt() << "  " << std::setw(4);
   14217             :     print_pc(os, Pc(i)->value());
   14218             :     os << std::setw(2);
   14219             : 
   14220             :     if (!FLAG_print_code_verbose) {
   14221             :       os << "\n";
   14222             :       continue;
   14223             :     }
   14224             : 
   14225             :     // Print details of the frame translation.
   14226             :     int translation_index = TranslationIndex(i)->value();
   14227             :     TranslationIterator iterator(TranslationByteArray(), translation_index);
   14228             :     Translation::Opcode opcode =
   14229             :         static_cast<Translation::Opcode>(iterator.Next());
   14230             :     DCHECK(Translation::BEGIN == opcode);
   14231             :     int frame_count = iterator.Next();
   14232             :     int jsframe_count = iterator.Next();
   14233             :     os << "  " << Translation::StringFor(opcode)
   14234             :        << " {frame count=" << frame_count
   14235             :        << ", js frame count=" << jsframe_count << "}\n";
   14236             : 
   14237             :     while (iterator.HasNext() &&
   14238             :            Translation::BEGIN !=
   14239             :            (opcode = static_cast<Translation::Opcode>(iterator.Next()))) {
   14240             :       os << std::setw(31) << "    " << Translation::StringFor(opcode) << " ";
   14241             : 
   14242             :       switch (opcode) {
   14243             :         case Translation::BEGIN:
   14244             :           UNREACHABLE();
   14245             :           break;
   14246             : 
   14247             :         case Translation::INTERPRETED_FRAME: {
   14248             :           int bytecode_offset = iterator.Next();
   14249             :           int shared_info_id = iterator.Next();
   14250             :           unsigned height = iterator.Next();
   14251             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14252             :           os << "{bytecode_offset=" << bytecode_offset << ", function="
   14253             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14254             :              << ", height=" << height << "}";
   14255             :           break;
   14256             :         }
   14257             : 
   14258             :         case Translation::CONSTRUCT_STUB_FRAME: {
   14259             :           int bailout_id = iterator.Next();
   14260             :           int shared_info_id = iterator.Next();
   14261             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14262             :           unsigned height = iterator.Next();
   14263             :           os << "{bailout_id=" << bailout_id << ", function="
   14264             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14265             :              << ", height=" << height << "}";
   14266             :           break;
   14267             :         }
   14268             : 
   14269             :         case Translation::BUILTIN_CONTINUATION_FRAME:
   14270             :         case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: {
   14271             :           int bailout_id = iterator.Next();
   14272             :           int shared_info_id = iterator.Next();
   14273             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14274             :           unsigned height = iterator.Next();
   14275             :           os << "{bailout_id=" << bailout_id << ", function="
   14276             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14277             :              << ", height=" << height << "}";
   14278             :           break;
   14279             :         }
   14280             : 
   14281             :         case Translation::ARGUMENTS_ADAPTOR_FRAME: {
   14282             :           int shared_info_id = iterator.Next();
   14283             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14284             :           unsigned height = iterator.Next();
   14285             :           os << "{function="
   14286             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14287             :              << ", height=" << height << "}";
   14288             :           break;
   14289             :         }
   14290             : 
   14291             :         case Translation::GETTER_STUB_FRAME:
   14292             :         case Translation::SETTER_STUB_FRAME: {
   14293             :           int shared_info_id = iterator.Next();
   14294             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14295             :           os << "{function=" << Brief(SharedFunctionInfo::cast(shared_info)
   14296             :                                           ->DebugName()) << "}";
   14297             :           break;
   14298             :         }
   14299             : 
   14300             :         case Translation::REGISTER: {
   14301             :           int reg_code = iterator.Next();
   14302             :           os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
   14303             :           break;
   14304             :         }
   14305             : 
   14306             :         case Translation::INT32_REGISTER: {
   14307             :           int reg_code = iterator.Next();
   14308             :           os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
   14309             :           break;
   14310             :         }
   14311             : 
   14312             :         case Translation::UINT32_REGISTER: {
   14313             :           int reg_code = iterator.Next();
   14314             :           os << "{input=" << converter.NameOfCPURegister(reg_code)
   14315             :              << " (unsigned)}";
   14316             :           break;
   14317             :         }
   14318             : 
   14319             :         case Translation::BOOL_REGISTER: {
   14320             :           int reg_code = iterator.Next();
   14321             :           os << "{input=" << converter.NameOfCPURegister(reg_code)
   14322             :              << " (bool)}";
   14323             :           break;
   14324             :         }
   14325             : 
   14326             :         case Translation::FLOAT_REGISTER: {
   14327             :           int reg_code = iterator.Next();
   14328             :           os << "{input="
   14329             :              << RegisterConfiguration::Default()->GetFloatRegisterName(reg_code)
   14330             :              << "}";
   14331             :           break;
   14332             :         }
   14333             : 
   14334             :         case Translation::DOUBLE_REGISTER: {
   14335             :           int reg_code = iterator.Next();
   14336             :           os << "{input="
   14337             :              << RegisterConfiguration::Default()->GetDoubleRegisterName(
   14338             :                     reg_code)
   14339             :              << "}";
   14340             :           break;
   14341             :         }
   14342             : 
   14343             :         case Translation::STACK_SLOT: {
   14344             :           int input_slot_index = iterator.Next();
   14345             :           os << "{input=" << input_slot_index << "}";
   14346             :           break;
   14347             :         }
   14348             : 
   14349             :         case Translation::INT32_STACK_SLOT: {
   14350             :           int input_slot_index = iterator.Next();
   14351             :           os << "{input=" << input_slot_index << "}";
   14352             :           break;
   14353             :         }
   14354             : 
   14355             :         case Translation::UINT32_STACK_SLOT: {
   14356             :           int input_slot_index = iterator.Next();
   14357             :           os << "{input=" << input_slot_index << " (unsigned)}";
   14358             :           break;
   14359             :         }
   14360             : 
   14361             :         case Translation::BOOL_STACK_SLOT: {
   14362             :           int input_slot_index = iterator.Next();
   14363             :           os << "{input=" << input_slot_index << " (bool)}";
   14364             :           break;
   14365             :         }
   14366             : 
   14367             :         case Translation::FLOAT_STACK_SLOT:
   14368             :         case Translation::DOUBLE_STACK_SLOT: {
   14369             :           int input_slot_index = iterator.Next();
   14370             :           os << "{input=" << input_slot_index << "}";
   14371             :           break;
   14372             :         }
   14373             : 
   14374             :         case Translation::LITERAL: {
   14375             :           int literal_index = iterator.Next();
   14376             :           Object* literal_value = LiteralArray()->get(literal_index);
   14377             :           os << "{literal_id=" << literal_index << " (" << Brief(literal_value)
   14378             :              << ")}";
   14379             :           break;
   14380             :         }
   14381             : 
   14382             :         case Translation::DUPLICATED_OBJECT: {
   14383             :           int object_index = iterator.Next();
   14384             :           os << "{object_index=" << object_index << "}";
   14385             :           break;
   14386             :         }
   14387             : 
   14388             :         case Translation::ARGUMENTS_ELEMENTS:
   14389             :         case Translation::ARGUMENTS_LENGTH: {
   14390             :           CreateArgumentsType arguments_type =
   14391             :               static_cast<CreateArgumentsType>(iterator.Next());
   14392             :           os << "{arguments_type=" << arguments_type << "}";
   14393             :           break;
   14394             :         }
   14395             : 
   14396             :         case Translation::CAPTURED_OBJECT: {
   14397             :           int args_length = iterator.Next();
   14398             :           os << "{length=" << args_length << "}";
   14399             :           break;
   14400             :         }
   14401             :       }
   14402             :       os << "\n";
   14403             :     }
   14404             :   }
   14405             : }
   14406             : 
   14407             : 
   14408             : void HandlerTable::HandlerTableRangePrint(std::ostream& os) {
   14409             :   os << "   from   to       hdlr\n";
   14410             :   for (int i = 0; i < length(); i += kRangeEntrySize) {
   14411             :     int pc_start = Smi::ToInt(get(i + kRangeStartIndex));
   14412             :     int pc_end = Smi::ToInt(get(i + kRangeEndIndex));
   14413             :     int handler_field = Smi::ToInt(get(i + kRangeHandlerIndex));
   14414             :     int handler_offset = HandlerOffsetField::decode(handler_field);
   14415             :     CatchPrediction prediction = HandlerPredictionField::decode(handler_field);
   14416             :     int data = Smi::ToInt(get(i + kRangeDataIndex));
   14417             :     os << "  (" << std::setw(4) << pc_start << "," << std::setw(4) << pc_end
   14418             :        << ")  ->  " << std::setw(4) << handler_offset
   14419             :        << " (prediction=" << prediction << ", data=" << data << ")\n";
   14420             :   }
   14421             : }
   14422             : 
   14423             : 
   14424             : void HandlerTable::HandlerTableReturnPrint(std::ostream& os) {
   14425             :   os << "   off      hdlr (c)\n";
   14426             :   for (int i = 0; i < length(); i += kReturnEntrySize) {
   14427             :     int pc_offset = Smi::ToInt(get(i + kReturnOffsetIndex));
   14428             :     int handler_field = Smi::ToInt(get(i + kReturnHandlerIndex));
   14429             :     int handler_offset = HandlerOffsetField::decode(handler_field);
   14430             :     CatchPrediction prediction = HandlerPredictionField::decode(handler_field);
   14431             :     os << "  " << std::setw(4) << pc_offset << "  ->  " << std::setw(4)
   14432             :        << handler_offset << " (prediction=" << prediction << ")\n";
   14433             :   }
   14434             : }
   14435             : 
   14436             : 
   14437             : void Code::Disassemble(const char* name, std::ostream& os) {  // NOLINT
   14438             :   os << "kind = " << Kind2String(kind()) << "\n";
   14439             :   if (is_stub()) {
   14440             :     const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this));
   14441             :     os << "major_key = " << (n == nullptr ? "null" : n) << "\n";
   14442             :   }
   14443             :   if ((name != nullptr) && (name[0] != '\0')) {
   14444             :     os << "name = " << name << "\n";
   14445             :   } else if (kind() == BYTECODE_HANDLER) {
   14446             :     name = GetIsolate()->interpreter()->LookupNameOfBytecodeHandler(this);
   14447             :     if (name != nullptr) {
   14448             :       os << "name = " << name << "\n";
   14449             :     }
   14450             :   } else {
   14451             :     // There are some handlers and ICs that we can also find names for with
   14452             :     // Builtins::Lookup.
   14453             :     name = GetIsolate()->builtins()->Lookup(instruction_start());
   14454             :     if (name != nullptr) {
   14455             :       os << "name = " << name << "\n";
   14456             :     }
   14457             :   }
   14458             :   if (kind() == OPTIMIZED_FUNCTION) {
   14459             :     os << "stack_slots = " << stack_slots() << "\n";
   14460             :   }
   14461             :   os << "compiler = " << (is_turbofanned() ? "turbofan" : "unknown") << "\n";
   14462             : 
   14463             :   os << "Instructions (size = " << instruction_size() << ")\n";
   14464             :   {
   14465             :     Isolate* isolate = GetIsolate();
   14466             :     int size = instruction_size();
   14467             :     int safepoint_offset =
   14468             :         is_turbofanned() ? static_cast<int>(safepoint_table_offset()) : size;
   14469             :     int constant_pool_offset = FLAG_enable_embedded_constant_pool
   14470             :                                    ? this->constant_pool_offset()
   14471             :                                    : size;
   14472             : 
   14473             :     // Stop before reaching any embedded tables
   14474             :     int code_size = Min(safepoint_offset, constant_pool_offset);
   14475             :     byte* begin = instruction_start();
   14476             :     byte* end = begin + code_size;
   14477             :     Disassembler::Decode(isolate, &os, begin, end, this);
   14478             : 
   14479             :     if (constant_pool_offset < size) {
   14480             :       int constant_pool_size = safepoint_offset - constant_pool_offset;
   14481             :       DCHECK_EQ(constant_pool_size & kPointerAlignmentMask, 0);
   14482             :       os << "\nConstant Pool (size = " << constant_pool_size << ")\n";
   14483             :       Vector<char> buf = Vector<char>::New(50);
   14484             :       intptr_t* ptr = reinterpret_cast<intptr_t*>(begin + constant_pool_offset);
   14485             :       for (int i = 0; i < constant_pool_size; i += kPointerSize, ptr++) {
   14486             :         SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr);
   14487             :         os << static_cast<const void*>(ptr) << "  " << buf.start() << "\n";
   14488             :       }
   14489             :     }
   14490             :   }
   14491             :   os << "\n";
   14492             : 
   14493             :   SourcePositionTableIterator it(SourcePositionTable());
   14494             :   if (!it.done()) {
   14495             :     os << "Source positions:\n pc offset  position\n";
   14496             :     for (; !it.done(); it.Advance()) {
   14497             :       os << std::setw(10) << std::hex << it.code_offset() << std::dec
   14498             :          << std::setw(10) << it.source_position().ScriptOffset()
   14499             :          << (it.is_statement() ? "  statement" : "") << "\n";
   14500             :     }
   14501             :     os << "\n";
   14502             :   }
   14503             : 
   14504             :   if (kind() == OPTIMIZED_FUNCTION) {
   14505             :     DeoptimizationData* data =
   14506             :         DeoptimizationData::cast(this->deoptimization_data());
   14507             :     data->DeoptimizationDataPrint(os);
   14508             :   }
   14509             :   os << "\n";
   14510             : 
   14511             :   if (is_turbofanned()) {
   14512             :     SafepointTable table(this);
   14513             :     os << "Safepoints (size = " << table.size() << ")\n";
   14514             :     for (unsigned i = 0; i < table.length(); i++) {
   14515             :       unsigned pc_offset = table.GetPcOffset(i);
   14516             :       os << static_cast<const void*>(instruction_start() + pc_offset) << "  ";
   14517             :       os << std::setw(6) << std::hex << pc_offset << "  " << std::setw(4);
   14518             :       int trampoline_pc = table.GetTrampolinePcOffset(i);
   14519             :       print_pc(os, trampoline_pc);
   14520             :       os << std::dec << "  ";
   14521             :       table.PrintEntry(i, os);
   14522             :       os << " (sp -> fp)  ";
   14523             :       SafepointEntry entry = table.GetEntry(i);
   14524             :       if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
   14525             :         os << std::setw(6) << entry.deoptimization_index();
   14526             :       } else {
   14527             :         os << "<none>";
   14528             :       }
   14529             :       if (entry.argument_count() > 0) {
   14530             :         os << " argc: " << entry.argument_count();
   14531             :       }
   14532             :       os << "\n";
   14533             :     }
   14534             :     os << "\n";
   14535             :   }
   14536             : 
   14537             :   if (handler_table()->length() > 0) {
   14538             :     os << "Handler Table (size = " << handler_table()->Size() << ")\n";
   14539             :     if (kind() == OPTIMIZED_FUNCTION) {
   14540             :       HandlerTable::cast(handler_table())->HandlerTableReturnPrint(os);
   14541             :     }
   14542             :     os << "\n";
   14543             :   }
   14544             : 
   14545             :   os << "RelocInfo (size = " << relocation_size() << ")\n";
   14546             :   for (RelocIterator it(this); !it.done(); it.next()) {
   14547             :     it.rinfo()->Print(GetIsolate(), os);
   14548             :   }
   14549             :   os << "\n";
   14550             : 
   14551             :   if (has_unwinding_info()) {
   14552             :     os << "UnwindingInfo (size = " << unwinding_info_size() << ")\n";
   14553             :     EhFrameDisassembler eh_frame_disassembler(unwinding_info_start(),
   14554             :                                               unwinding_info_end());
   14555             :     eh_frame_disassembler.DisassembleToStream(os);
   14556             :     os << "\n";
   14557             :   }
   14558             : }
   14559             : #endif  // ENABLE_DISASSEMBLER
   14560             : 
   14561             : 
   14562           0 : void BytecodeArray::Disassemble(std::ostream& os) {
   14563           0 :   os << "Parameter count " << parameter_count() << "\n";
   14564           0 :   os << "Frame size " << frame_size() << "\n";
   14565             : 
   14566           0 :   const uint8_t* base_address = GetFirstBytecodeAddress();
   14567           0 :   SourcePositionTableIterator source_positions(SourcePositionTable());
   14568             : 
   14569           0 :   interpreter::BytecodeArrayIterator iterator(handle(this));
   14570           0 :   while (!iterator.done()) {
   14571           0 :     if (!source_positions.done() &&
   14572           0 :         iterator.current_offset() == source_positions.code_offset()) {
   14573           0 :       os << std::setw(5) << source_positions.source_position().ScriptOffset();
   14574           0 :       os << (source_positions.is_statement() ? " S> " : " E> ");
   14575           0 :       source_positions.Advance();
   14576             :     } else {
   14577           0 :       os << "         ";
   14578             :     }
   14579           0 :     const uint8_t* current_address = base_address + iterator.current_offset();
   14580           0 :     os << reinterpret_cast<const void*>(current_address) << " @ "
   14581           0 :        << std::setw(4) << iterator.current_offset() << " : ";
   14582             :     interpreter::BytecodeDecoder::Decode(os, current_address,
   14583           0 :                                          parameter_count());
   14584           0 :     if (interpreter::Bytecodes::IsJump(iterator.current_bytecode())) {
   14585           0 :       const void* jump_target = base_address + iterator.GetJumpTargetOffset();
   14586           0 :       os << " (" << jump_target << " @ " << iterator.GetJumpTargetOffset()
   14587           0 :          << ")";
   14588             :     }
   14589           0 :     if (interpreter::Bytecodes::IsSwitch(iterator.current_bytecode())) {
   14590           0 :       os << " {";
   14591             :       bool first_entry = true;
   14592           0 :       for (const auto& entry : iterator.GetJumpTableTargetOffsets()) {
   14593           0 :         if (first_entry) {
   14594             :           first_entry = false;
   14595             :         } else {
   14596           0 :           os << ",";
   14597             :         }
   14598           0 :         os << " " << entry.case_value << ": @" << entry.target_offset;
   14599             :       }
   14600           0 :       os << " }";
   14601             :     }
   14602             :     os << std::endl;
   14603           0 :     iterator.Advance();
   14604             :   }
   14605             : 
   14606           0 :   os << "Constant pool (size = " << constant_pool()->length() << ")\n";
   14607             : #ifdef OBJECT_PRINT
   14608             :   if (constant_pool()->length() > 0) {
   14609             :     constant_pool()->Print();
   14610             :   }
   14611             : #endif
   14612             : 
   14613           0 :   os << "Handler Table (size = " << handler_table()->Size() << ")\n";
   14614             : #ifdef ENABLE_DISASSEMBLER
   14615             :   if (handler_table()->length() > 0) {
   14616             :     HandlerTable::cast(handler_table())->HandlerTableRangePrint(os);
   14617             :   }
   14618             : #endif
   14619           0 : }
   14620             : 
   14621        8341 : void BytecodeArray::CopyBytecodesTo(BytecodeArray* to) {
   14622             :   BytecodeArray* from = this;
   14623             :   DCHECK_EQ(from->length(), to->length());
   14624        8341 :   CopyBytes(to->GetFirstBytecodeAddress(), from->GetFirstBytecodeAddress(),
   14625       16682 :             from->length());
   14626        8341 : }
   14627             : 
   14628     1616788 : void BytecodeArray::MakeOlder() {
   14629             :   // BytecodeArray is aged in concurrent marker.
   14630             :   // The word must be completely within the byte code array.
   14631     1616788 :   Address age_addr = address() + kBytecodeAgeOffset;
   14632             :   DCHECK_LE((reinterpret_cast<uintptr_t>(age_addr) & ~kPointerAlignmentMask) +
   14633             :                 kPointerSize,
   14634             :             reinterpret_cast<uintptr_t>(address() + Size()));
   14635             :   Age age = bytecode_age();
   14636     1616788 :   if (age < kLastBytecodeAge) {
   14637     1158062 :     base::AsAtomic8::Release_CompareAndSwap(age_addr, age, age + 1);
   14638             :   }
   14639             : 
   14640             :   DCHECK_GE(bytecode_age(), kFirstBytecodeAge);
   14641             :   DCHECK_LE(bytecode_age(), kLastBytecodeAge);
   14642     1616788 : }
   14643             : 
   14644           0 : bool BytecodeArray::IsOld() const {
   14645           0 :   return bytecode_age() >= kIsOldBytecodeAge;
   14646             : }
   14647             : 
   14648             : // static
   14649       89745 : void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) {
   14650             :   DCHECK_GE(capacity, 0);
   14651             :   array->GetIsolate()->factory()->NewJSArrayStorage(
   14652       89745 :       array, length, capacity, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
   14653       89745 : }
   14654             : 
   14655      919774 : void JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) {
   14656             :   // We should never end in here with a pixel or external array.
   14657             :   DCHECK(array->AllowsSetLength());
   14658      919774 :   if (array->SetLengthWouldNormalize(new_length)) {
   14659        1020 :     JSObject::NormalizeElements(array);
   14660             :   }
   14661      919774 :   array->GetElementsAccessor()->SetLength(array, new_length);
   14662      919774 : }
   14663             : 
   14664             : 
   14665             : // static
   14666      125062 : void Map::AddDependentCode(Handle<Map> map,
   14667             :                            DependentCode::DependencyGroup group,
   14668             :                            Handle<Code> code) {
   14669      125062 :   Handle<WeakCell> cell = Code::WeakCellFor(code);
   14670             :   Handle<DependentCode> codes = DependentCode::InsertWeakCode(
   14671             :       Handle<DependentCode>(map->dependent_code()), group, cell);
   14672      125062 :   if (*codes != map->dependent_code()) map->set_dependent_code(*codes);
   14673      125062 : }
   14674             : 
   14675             : 
   14676      739697 : Handle<DependentCode> DependentCode::InsertCompilationDependencies(
   14677             :     Handle<DependentCode> entries, DependencyGroup group,
   14678             :     Handle<Foreign> info) {
   14679      739697 :   return Insert(entries, group, info);
   14680             : }
   14681             : 
   14682             : 
   14683      491672 : Handle<DependentCode> DependentCode::InsertWeakCode(
   14684             :     Handle<DependentCode> entries, DependencyGroup group,
   14685             :     Handle<WeakCell> code_cell) {
   14686      616734 :   return Insert(entries, group, code_cell);
   14687             : }
   14688             : 
   14689             : 
   14690     1366388 : Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
   14691             :                                             DependencyGroup group,
   14692             :                                             Handle<Object> object) {
   14693     2434188 :   if (entries->length() == 0 || entries->group() > group) {
   14694             :     // There is no such group.
   14695      310518 :     return DependentCode::New(group, object, entries);
   14696             :   }
   14697     1055870 :   if (entries->group() < group) {
   14698             :     // The group comes later in the list.
   14699             :     Handle<DependentCode> old_next(entries->next_link());
   14700        9957 :     Handle<DependentCode> new_next = Insert(old_next, group, object);
   14701        9957 :     if (!old_next.is_identical_to(new_next)) {
   14702             :       entries->set_next_link(*new_next);
   14703             :     }
   14704        9957 :     return entries;
   14705             :   }
   14706             :   DCHECK_EQ(group, entries->group());
   14707             :   int count = entries->count();
   14708             :   // Check for existing entry to avoid duplicates.
   14709   249702259 :   for (int i = 0; i < count; i++) {
   14710   249161414 :     if (entries->object_at(i) == *object) return entries;
   14711             :   }
   14712     1081690 :   if (entries->length() < kCodesStartIndex + count + 1) {
   14713      156543 :     entries = EnsureSpace(entries);
   14714             :     // Count could have changed, reload it.
   14715             :     count = entries->count();
   14716             :   }
   14717             :   entries->set_object_at(count, *object);
   14718     1081690 :   entries->set_count(count + 1);
   14719      540845 :   return entries;
   14720             : }
   14721             : 
   14722             : 
   14723      310518 : Handle<DependentCode> DependentCode::New(DependencyGroup group,
   14724             :                                          Handle<Object> object,
   14725             :                                          Handle<DependentCode> next) {
   14726             :   Isolate* isolate = next->GetIsolate();
   14727             :   Handle<DependentCode> result = Handle<DependentCode>::cast(
   14728      310518 :       isolate->factory()->NewFixedArray(kCodesStartIndex + 1, TENURED));
   14729             :   result->set_next_link(*next);
   14730      310518 :   result->set_flags(GroupField::encode(group) | CountField::encode(1));
   14731             :   result->set_object_at(0, *object);
   14732      310518 :   return result;
   14733             : }
   14734             : 
   14735             : 
   14736      156543 : Handle<DependentCode> DependentCode::EnsureSpace(
   14737             :     Handle<DependentCode> entries) {
   14738      156543 :   if (entries->Compact()) return entries;
   14739             :   Isolate* isolate = entries->GetIsolate();
   14740      154498 :   int capacity = kCodesStartIndex + DependentCode::Grow(entries->count());
   14741      154498 :   int grow_by = capacity - entries->length();
   14742             :   return Handle<DependentCode>::cast(
   14743      154498 :       isolate->factory()->CopyFixedArrayAndGrow(entries, grow_by, TENURED));
   14744             : }
   14745             : 
   14746             : 
   14747      156543 : bool DependentCode::Compact() {
   14748             :   int old_count = count();
   14749             :   int new_count = 0;
   14750     2360853 :   for (int i = 0; i < old_count; i++) {
   14751             :     Object* obj = object_at(i);
   14752     4407974 :     if (!obj->IsWeakCell() || !WeakCell::cast(obj)->cleared()) {
   14753     2181978 :       if (i != new_count) {
   14754       24034 :         copy(i, new_count);
   14755             :       }
   14756     2181978 :       new_count++;
   14757             :     }
   14758             :   }
   14759      156543 :   set_count(new_count);
   14760      178875 :   for (int i = new_count; i < old_count; i++) {
   14761             :     clear_at(i);
   14762             :   }
   14763      156543 :   return new_count < old_count;
   14764             : }
   14765             : 
   14766             : 
   14767      731056 : void DependentCode::UpdateToFinishedCode(DependencyGroup group, Foreign* info,
   14768             :                                          WeakCell* code_cell) {
   14769     1486760 :   if (this->length() == 0 || this->group() > group) {
   14770             :     // There is no such group.
   14771             :     return;
   14772             :   }
   14773      743380 :   if (this->group() < group) {
   14774             :     // The group comes later in the list.
   14775             :     next_link()->UpdateToFinishedCode(group, info, code_cell);
   14776       12324 :     return;
   14777             :   }
   14778             :   DCHECK_EQ(group, this->group());
   14779             :   DisallowHeapAllocation no_gc;
   14780             :   int count = this->count();
   14781   112477938 :   for (int i = 0; i < count; i++) {
   14782   112189113 :     if (object_at(i) == info) {
   14783             :       set_object_at(i, code_cell);
   14784             :       break;
   14785             :     }
   14786             :   }
   14787             : #ifdef DEBUG
   14788             :   for (int i = 0; i < count; i++) {
   14789             :     DCHECK(object_at(i) != info);
   14790             :   }
   14791             : #endif
   14792             : }
   14793             : 
   14794             : 
   14795        8625 : void DependentCode::RemoveCompilationDependencies(
   14796             :     DependentCode::DependencyGroup group, Foreign* info) {
   14797       17700 :   if (this->length() == 0 || this->group() > group) {
   14798             :     // There is no such group.
   14799             :     return;
   14800             :   }
   14801        8850 :   if (this->group() < group) {
   14802             :     // The group comes later in the list.
   14803             :     next_link()->RemoveCompilationDependencies(group, info);
   14804         225 :     return;
   14805             :   }
   14806             :   DCHECK_EQ(group, this->group());
   14807             :   DisallowHeapAllocation no_allocation;
   14808             :   int old_count = count();
   14809             :   // Find compilation info wrapper.
   14810             :   int info_pos = -1;
   14811       11376 :   for (int i = 0; i < old_count; i++) {
   14812        5345 :     if (object_at(i) == info) {
   14813             :       info_pos = i;
   14814             :       break;
   14815             :     }
   14816             :   }
   14817        8625 :   if (info_pos == -1) return;  // Not found.
   14818             :   // Use the last code to fill the gap.
   14819        2594 :   if (info_pos < old_count - 1) {
   14820          46 :     copy(old_count - 1, info_pos);
   14821             :   }
   14822             :   clear_at(old_count - 1);
   14823        2594 :   set_count(old_count - 1);
   14824             : 
   14825             : #ifdef DEBUG
   14826             :   for (int i = 0; i < old_count - 1; i++) {
   14827             :     DCHECK(object_at(i) != info);
   14828             :   }
   14829             : #endif
   14830             : }
   14831             : 
   14832             : 
   14833           0 : bool DependentCode::Contains(DependencyGroup group, WeakCell* code_cell) {
   14834           0 :   if (this->length() == 0 || this->group() > group) {
   14835             :     // There is no such group.
   14836             :     return false;
   14837             :   }
   14838           0 :   if (this->group() < group) {
   14839             :     // The group comes later in the list.
   14840           0 :     return next_link()->Contains(group, code_cell);
   14841             :   }
   14842             :   DCHECK_EQ(group, this->group());
   14843             :   int count = this->count();
   14844           0 :   for (int i = 0; i < count; i++) {
   14845           0 :     if (object_at(i) == code_cell) return true;
   14846             :   }
   14847             :   return false;
   14848             : }
   14849             : 
   14850             : 
   14851      125062 : bool DependentCode::IsEmpty(DependencyGroup group) {
   14852      225011 :   if (this->length() == 0 || this->group() > group) {
   14853             :     // There is no such group.
   14854             :     return true;
   14855             :   }
   14856       90462 :   if (this->group() < group) {
   14857             :     // The group comes later in the list.
   14858           0 :     return next_link()->IsEmpty(group);
   14859             :   }
   14860             :   DCHECK_EQ(group, this->group());
   14861       90462 :   return count() == 0;
   14862             : }
   14863             : 
   14864             : 
   14865    17852761 : bool DependentCode::MarkCodeForDeoptimization(
   14866             :     Isolate* isolate,
   14867             :     DependentCode::DependencyGroup group) {
   14868    17884470 :   if (this->length() == 0 || this->group() > group) {
   14869             :     // There is no such group.
   14870             :     return false;
   14871             :   }
   14872       27865 :   if (this->group() < group) {
   14873             :     // The group comes later in the list.
   14874        3379 :     return next_link()->MarkCodeForDeoptimization(isolate, group);
   14875             :   }
   14876             :   DCHECK_EQ(group, this->group());
   14877             :   DisallowHeapAllocation no_allocation_scope;
   14878             :   // Mark all the code that needs to be deoptimized.
   14879             :   bool marked = false;
   14880             :   bool invalidate_embedded_objects = group == kWeakCodeGroup;
   14881             :   int count = this->count();
   14882       72266 :   for (int i = 0; i < count; i++) {
   14883             :     Object* obj = object_at(i);
   14884       47780 :     if (obj->IsWeakCell()) {
   14885             :       WeakCell* cell = WeakCell::cast(obj);
   14886       47666 :       if (cell->cleared()) continue;
   14887             :       Code* code = Code::cast(cell->value());
   14888       14072 :       if (!code->marked_for_deoptimization()) {
   14889        5970 :         SetMarkedForDeoptimization(code, group);
   14890        5970 :         if (invalidate_embedded_objects) {
   14891        2063 :           code->InvalidateEmbeddedObjects();
   14892             :         }
   14893             :         marked = true;
   14894             :       }
   14895             :     } else {
   14896             :       DCHECK(obj->IsForeign());
   14897             :       CompilationDependencies* info =
   14898             :           reinterpret_cast<CompilationDependencies*>(
   14899             :               Foreign::cast(obj)->foreign_address());
   14900             :       info->Abort();
   14901             :     }
   14902             :   }
   14903       47780 :   for (int i = 0; i < count; i++) {
   14904             :     clear_at(i);
   14905             :   }
   14906       24486 :   set_count(0);
   14907       24486 :   return marked;
   14908             : }
   14909             : 
   14910             : 
   14911    17832590 : void DependentCode::DeoptimizeDependentCodeGroup(
   14912             :     Isolate* isolate,
   14913             :     DependentCode::DependencyGroup group) {
   14914             :   DisallowHeapAllocation no_allocation_scope;
   14915    17832590 :   bool marked = MarkCodeForDeoptimization(isolate, group);
   14916    17832590 :   if (marked) {
   14917             :     DCHECK(AllowCodeDependencyChange::IsAllowed());
   14918        2135 :     Deoptimizer::DeoptimizeMarkedCode(isolate);
   14919             :   }
   14920    17832590 : }
   14921             : 
   14922             : 
   14923        5985 : void DependentCode::SetMarkedForDeoptimization(Code* code,
   14924             :                                                DependencyGroup group) {
   14925             :   code->set_marked_for_deoptimization(true);
   14926        5985 :   if (FLAG_trace_deopt &&
   14927           0 :       (code->deoptimization_data() != code->GetHeap()->empty_fixed_array())) {
   14928             :     DeoptimizationData* deopt_data =
   14929             :         DeoptimizationData::cast(code->deoptimization_data());
   14930           0 :     CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer());
   14931             :     PrintF(scope.file(), "[marking dependent code 0x%08" V8PRIxPTR
   14932             :                          " (opt #%d) for deoptimization, reason: %s]\n",
   14933             :            reinterpret_cast<intptr_t>(code),
   14934           0 :            deopt_data->OptimizationId()->value(), DependencyGroupName(group));
   14935             :   }
   14936        5985 : }
   14937             : 
   14938             : 
   14939           0 : const char* DependentCode::DependencyGroupName(DependencyGroup group) {
   14940           0 :   switch (group) {
   14941             :     case kWeakCodeGroup:
   14942             :       return "weak-code";
   14943             :     case kTransitionGroup:
   14944           0 :       return "transition";
   14945             :     case kPrototypeCheckGroup:
   14946           0 :       return "prototype-check";
   14947             :     case kPropertyCellChangedGroup:
   14948           0 :       return "property-cell-changed";
   14949             :     case kFieldOwnerGroup:
   14950           0 :       return "field-owner";
   14951             :     case kInitialMapChangedGroup:
   14952           0 :       return "initial-map-changed";
   14953             :     case kAllocationSiteTenuringChangedGroup:
   14954           0 :       return "allocation-site-tenuring-changed";
   14955             :     case kAllocationSiteTransitionChangedGroup:
   14956           0 :       return "allocation-site-transition-changed";
   14957             :   }
   14958           0 :   UNREACHABLE();
   14959             : }
   14960             : 
   14961     2650252 : Handle<Map> Map::TransitionToPrototype(Handle<Map> map,
   14962             :                                        Handle<Object> prototype) {
   14963             :   Handle<Map> new_map =
   14964     2650252 :       TransitionsAccessor(map).GetPrototypeTransition(prototype);
   14965     2650252 :   if (new_map.is_null()) {
   14966      202818 :     new_map = Copy(map, "TransitionToPrototype");
   14967      202818 :     TransitionsAccessor(map).PutPrototypeTransition(prototype, new_map);
   14968      202818 :     Map::SetPrototype(new_map, prototype);
   14969             :   }
   14970     2650252 :   return new_map;
   14971             : }
   14972             : 
   14973             : 
   14974     2666813 : Maybe<bool> JSReceiver::SetPrototype(Handle<JSReceiver> object,
   14975             :                                      Handle<Object> value, bool from_javascript,
   14976             :                                      ShouldThrow should_throw) {
   14977     2666813 :   if (object->IsJSProxy()) {
   14978             :     return JSProxy::SetPrototype(Handle<JSProxy>::cast(object), value,
   14979         342 :                                  from_javascript, should_throw);
   14980             :   }
   14981             :   return JSObject::SetPrototype(Handle<JSObject>::cast(object), value,
   14982     2666471 :                                 from_javascript, should_throw);
   14983             : }
   14984             : 
   14985             : 
   14986             : // ES6: 9.5.2 [[SetPrototypeOf]] (V)
   14987             : // static
   14988         342 : Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value,
   14989             :                                   bool from_javascript,
   14990             :                                   ShouldThrow should_throw) {
   14991             :   Isolate* isolate = proxy->GetIsolate();
   14992         342 :   STACK_CHECK(isolate, Nothing<bool>());
   14993             :   Handle<Name> trap_name = isolate->factory()->setPrototypeOf_string();
   14994             :   // 1. Assert: Either Type(V) is Object or Type(V) is Null.
   14995             :   DCHECK(value->IsJSReceiver() || value->IsNull(isolate));
   14996             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
   14997             :   Handle<Object> handler(proxy->handler(), isolate);
   14998             :   // 3. If handler is null, throw a TypeError exception.
   14999             :   // 4. Assert: Type(handler) is Object.
   15000         342 :   if (proxy->IsRevoked()) {
   15001             :     isolate->Throw(*isolate->factory()->NewTypeError(
   15002          18 :         MessageTemplate::kProxyRevoked, trap_name));
   15003             :     return Nothing<bool>();
   15004             :   }
   15005             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot.
   15006             :   Handle<JSReceiver> target(proxy->target(), isolate);
   15007             :   // 6. Let trap be ? GetMethod(handler, "getPrototypeOf").
   15008             :   Handle<Object> trap;
   15009         666 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   15010             :       isolate, trap,
   15011             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
   15012             :       Nothing<bool>());
   15013             :   // 7. If trap is undefined, then return target.[[SetPrototypeOf]]().
   15014         333 :   if (trap->IsUndefined(isolate)) {
   15015             :     return JSReceiver::SetPrototype(target, value, from_javascript,
   15016         234 :                                     should_throw);
   15017             :   }
   15018             :   // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, V»)).
   15019          99 :   Handle<Object> argv[] = {target, value};
   15020             :   Handle<Object> trap_result;
   15021         198 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   15022             :       isolate, trap_result,
   15023             :       Execution::Call(isolate, trap, handler, arraysize(argv), argv),
   15024             :       Nothing<bool>());
   15025          90 :   bool bool_trap_result = trap_result->BooleanValue();
   15026             :   // 9. If booleanTrapResult is false, return false.
   15027          90 :   if (!bool_trap_result) {
   15028          90 :     RETURN_FAILURE(
   15029             :         isolate, should_throw,
   15030             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
   15031             :   }
   15032             :   // 10. Let extensibleTarget be ? IsExtensible(target).
   15033          54 :   Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
   15034          54 :   if (is_extensible.IsNothing()) return Nothing<bool>();
   15035             :   // 11. If extensibleTarget is true, return true.
   15036          54 :   if (is_extensible.FromJust()) {
   15037          27 :     if (bool_trap_result) return Just(true);
   15038           0 :     RETURN_FAILURE(
   15039             :         isolate, should_throw,
   15040             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
   15041             :   }
   15042             :   // 12. Let targetProto be ? target.[[GetPrototypeOf]]().
   15043             :   Handle<Object> target_proto;
   15044          54 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_proto,
   15045             :                                    JSReceiver::GetPrototype(isolate, target),
   15046             :                                    Nothing<bool>());
   15047             :   // 13. If SameValue(V, targetProto) is false, throw a TypeError exception.
   15048          36 :   if (bool_trap_result && !value->SameValue(*target_proto)) {
   15049             :     isolate->Throw(*isolate->factory()->NewTypeError(
   15050          18 :         MessageTemplate::kProxySetPrototypeOfNonExtensible));
   15051             :     return Nothing<bool>();
   15052             :   }
   15053             :   // 14. Return true.
   15054             :   return Just(true);
   15055             : }
   15056             : 
   15057             : 
   15058     2676186 : Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
   15059             :                                    Handle<Object> value, bool from_javascript,
   15060             :                                    ShouldThrow should_throw) {
   15061          35 :   Isolate* isolate = object->GetIsolate();
   15062             : 
   15063             : #ifdef DEBUG
   15064             :   int size = object->Size();
   15065             : #endif
   15066             : 
   15067     2676186 :   if (from_javascript) {
   15068      204764 :     if (object->IsAccessCheckNeeded() &&
   15069          35 :         !isolate->MayAccess(handle(isolate->context()), object)) {
   15070           0 :       isolate->ReportFailedAccessCheck(object);
   15071           0 :       RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
   15072           0 :       RETURN_FAILURE(isolate, should_throw,
   15073             :                      NewTypeError(MessageTemplate::kNoAccess));
   15074             :     }
   15075             :   } else {
   15076             :     DCHECK(!object->IsAccessCheckNeeded());
   15077             :   }
   15078             : 
   15079             :   // Silently ignore the change if value is not a JSObject or null.
   15080             :   // SpiderMonkey behaves this way.
   15081     5132140 :   if (!value->IsJSReceiver() && !value->IsNull(isolate)) return Just(true);
   15082             : 
   15083             :   bool all_extensible = object->map()->is_extensible();
   15084             :   Handle<JSObject> real_receiver = object;
   15085     2676171 :   if (from_javascript) {
   15086             :     // Find the first object in the chain whose prototype object is not
   15087             :     // hidden.
   15088             :     PrototypeIterator iter(isolate, real_receiver, kStartAtPrototype,
   15089      204729 :                            PrototypeIterator::END_AT_NON_HIDDEN);
   15090      412587 :     while (!iter.IsAtEnd()) {
   15091             :       // Casting to JSObject is fine because hidden prototypes are never
   15092             :       // JSProxies.
   15093             :       real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
   15094        3129 :       iter.Advance();
   15095        6258 :       all_extensible = all_extensible && real_receiver->map()->is_extensible();
   15096             :     }
   15097             :   }
   15098             :   Handle<Map> map(real_receiver->map());
   15099             : 
   15100             :   // Nothing to do if prototype is already set.
   15101     2676171 :   if (map->prototype() == *value) return Just(true);
   15102             : 
   15103             :   bool immutable_proto = map->is_immutable_proto();
   15104     2649787 :   if (immutable_proto) {
   15105         177 :     RETURN_FAILURE(
   15106             :         isolate, should_throw,
   15107             :         NewTypeError(MessageTemplate::kImmutablePrototypeSet, object));
   15108             :   }
   15109             : 
   15110             :   // From 8.6.2 Object Internal Methods
   15111             :   // ...
   15112             :   // In addition, if [[Extensible]] is false the value of the [[Class]] and
   15113             :   // [[Prototype]] internal properties of the object may not be modified.
   15114             :   // ...
   15115             :   // Implementation specific extensions that modify [[Class]], [[Prototype]]
   15116             :   // or [[Extensible]] must not violate the invariants defined in the preceding
   15117             :   // paragraph.
   15118     2649722 :   if (!all_extensible) {
   15119         532 :     RETURN_FAILURE(isolate, should_throw,
   15120             :                    NewTypeError(MessageTemplate::kNonExtensibleProto, object));
   15121             :   }
   15122             : 
   15123             :   // Before we can set the prototype we need to be sure prototype cycles are
   15124             :   // prevented.  It is sufficient to validate that the receiver is not in the
   15125             :   // new prototype chain.
   15126     2649466 :   if (value->IsJSReceiver()) {
   15127      632756 :     for (PrototypeIterator iter(isolate, JSReceiver::cast(*value),
   15128             :                                 kStartAtReceiver);
   15129      439112 :          !iter.IsAtEnd(); iter.Advance()) {
   15130      878386 :       if (iter.GetCurrent<JSReceiver>() == *object) {
   15131             :         // Cycle detected.
   15132         207 :         RETURN_FAILURE(isolate, should_throw,
   15133             :                        NewTypeError(MessageTemplate::kCyclicProto));
   15134             :       }
   15135             :     }
   15136             :   }
   15137             : 
   15138             :   // Set the new prototype of the object.
   15139             : 
   15140             :   isolate->UpdateArrayProtectorOnSetPrototype(real_receiver);
   15141             : 
   15142     2649385 :   Handle<Map> new_map = Map::TransitionToPrototype(map, value);
   15143             :   DCHECK(new_map->prototype() == *value);
   15144     2649385 :   JSObject::MigrateToMap(real_receiver, new_map);
   15145             : 
   15146             :   DCHECK(size == object->Size());
   15147             :   return Just(true);
   15148             : }
   15149             : 
   15150             : // static
   15151          24 : void JSObject::SetImmutableProto(Handle<JSObject> object) {
   15152             :   DCHECK(!object->IsAccessCheckNeeded());  // Never called from JS
   15153             :   Handle<Map> map(object->map());
   15154             : 
   15155             :   // Nothing to do if prototype is already set.
   15156          42 :   if (map->is_immutable_proto()) return;
   15157             : 
   15158           6 :   Handle<Map> new_map = Map::TransitionToImmutableProto(map);
   15159           6 :   object->synchronized_set_map(*new_map);
   15160             : }
   15161             : 
   15162      412214 : void JSObject::EnsureCanContainElements(Handle<JSObject> object,
   15163      412214 :                                         Arguments* args,
   15164             :                                         uint32_t first_arg,
   15165             :                                         uint32_t arg_count,
   15166             :                                         EnsureElementsMode mode) {
   15167             :   // Elements in |Arguments| are ordered backwards (because they're on the
   15168             :   // stack), but the method that's called here iterates over them in forward
   15169             :   // direction.
   15170             :   return EnsureCanContainElements(
   15171      412214 :       object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode);
   15172             : }
   15173             : 
   15174             : 
   15175   341063661 : ElementsAccessor* JSObject::GetElementsAccessor() {
   15176   341063661 :   return ElementsAccessor::ForKind(GetElementsKind());
   15177             : }
   15178             : 
   15179     8735840 : void JSObject::ValidateElements(JSObject* object) {
   15180             : #ifdef ENABLE_SLOW_DCHECKS
   15181             :   if (FLAG_enable_slow_asserts) {
   15182             :     object->GetElementsAccessor()->Validate(object);
   15183             :   }
   15184             : #endif
   15185     8735840 : }
   15186             : 
   15187             : 
   15188     4536357 : static bool ShouldConvertToSlowElements(JSObject* object, uint32_t capacity,
   15189             :                                         uint32_t index,
   15190             :                                         uint32_t* new_capacity) {
   15191             :   STATIC_ASSERT(JSObject::kMaxUncheckedOldFastElementsLength <=
   15192             :                 JSObject::kMaxUncheckedFastElementsLength);
   15193     4536357 :   if (index < capacity) {
   15194     3947791 :     *new_capacity = capacity;
   15195     3947791 :     return false;
   15196             :   }
   15197      588566 :   if (index - capacity >= JSObject::kMaxGap) return true;
   15198      672278 :   *new_capacity = JSObject::NewElementsCapacity(index + 1);
   15199             :   DCHECK_LT(index, *new_capacity);
   15200      672278 :   if (*new_capacity <= JSObject::kMaxUncheckedOldFastElementsLength ||
   15201       46568 :       (*new_capacity <= JSObject::kMaxUncheckedFastElementsLength &&
   15202             :        object->GetHeap()->InNewSpace(object))) {
   15203             :     return false;
   15204             :   }
   15205             :   // If the fast-case backing storage takes up much more memory than a
   15206             :   // dictionary backing storage would, the object should have slow elements.
   15207        1446 :   int used_elements = object->GetFastElementsUsage();
   15208             :   uint32_t size_threshold =
   15209             :       SeededNumberDictionary::kPreferFastElementsSizeFactor *
   15210        1446 :       SeededNumberDictionary::ComputeCapacity(used_elements) *
   15211        1446 :       SeededNumberDictionary::kEntrySize;
   15212        1446 :   return size_threshold <= *new_capacity;
   15213             : }
   15214             : 
   15215             : 
   15216      117372 : bool JSObject::WouldConvertToSlowElements(uint32_t index) {
   15217      117372 :   if (HasFastElements()) {
   15218             :     Handle<FixedArrayBase> backing_store(FixedArrayBase::cast(elements()));
   15219       16900 :     uint32_t capacity = static_cast<uint32_t>(backing_store->length());
   15220             :     uint32_t new_capacity;
   15221       16900 :     return ShouldConvertToSlowElements(this, capacity, index, &new_capacity);
   15222             :   }
   15223             :   return false;
   15224             : }
   15225             : 
   15226             : 
   15227         566 : static ElementsKind BestFittingFastElementsKind(JSObject* object) {
   15228         566 :   if (object->HasSloppyArgumentsElements()) {
   15229             :     return FAST_SLOPPY_ARGUMENTS_ELEMENTS;
   15230             :   }
   15231         566 :   if (object->HasStringWrapperElements()) {
   15232             :     return FAST_STRING_WRAPPER_ELEMENTS;
   15233             :   }
   15234             :   DCHECK(object->HasDictionaryElements());
   15235             :   SeededNumberDictionary* dictionary = object->element_dictionary();
   15236             :   ElementsKind kind = HOLEY_SMI_ELEMENTS;
   15237     2802120 :   for (int i = 0; i < dictionary->Capacity(); i++) {
   15238             :     Object* key = dictionary->KeyAt(i);
   15239     1400561 :     if (key->IsNumber()) {
   15240      466315 :       Object* value = dictionary->ValueAt(i);
   15241      466315 :       if (!value->IsNumber()) return HOLEY_ELEMENTS;
   15242      466258 :       if (!value->IsSmi()) {
   15243       13410 :         if (!FLAG_unbox_double_arrays) return HOLEY_ELEMENTS;
   15244             :         kind = HOLEY_DOUBLE_ELEMENTS;
   15245             :       }
   15246             :     }
   15247             :   }
   15248             :   return kind;
   15249             : }
   15250             : 
   15251             : 
   15252     1281153 : static bool ShouldConvertToFastElements(JSObject* object,
   15253             :                                         SeededNumberDictionary* dictionary,
   15254             :                                         uint32_t index,
   15255             :                                         uint32_t* new_capacity) {
   15256             :   // If properties with non-standard attributes or accessors were added, we
   15257             :   // cannot go back to fast elements.
   15258     1281153 :   if (dictionary->requires_slow_elements()) return false;
   15259             : 
   15260             :   // Adding a property with this index will require slow elements.
   15261     1253957 :   if (index >= static_cast<uint32_t>(Smi::kMaxValue)) return false;
   15262             : 
   15263     1253614 :   if (object->IsJSArray()) {
   15264             :     Object* length = JSArray::cast(object)->length();
   15265      614992 :     if (!length->IsSmi()) return false;
   15266      614152 :     *new_capacity = static_cast<uint32_t>(Smi::ToInt(length));
   15267      638622 :   } else if (object->IsJSSloppyArgumentsObject()) {
   15268             :     return false;
   15269             :   } else {
   15270      528506 :     *new_capacity = dictionary->max_number_key() + 1;
   15271             :   }
   15272     2285316 :   *new_capacity = Max(index + 1, *new_capacity);
   15273             : 
   15274     1142658 :   uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
   15275     1142658 :                              SeededNumberDictionary::kEntrySize;
   15276             : 
   15277             :   // Turn fast if the dictionary only saves 50% space.
   15278     1142658 :   return 2 * dictionary_size >= *new_capacity;
   15279             : }
   15280             : 
   15281             : 
   15282             : // static
   15283       22809 : MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object,
   15284             :                                              uint32_t index,
   15285             :                                              Handle<Object> value,
   15286             :                                              PropertyAttributes attributes) {
   15287       22809 :   MAYBE_RETURN_NULL(
   15288             :       AddDataElement(object, index, value, attributes, THROW_ON_ERROR));
   15289       22809 :   return value;
   15290             : }
   15291             : 
   15292             : 
   15293             : // static
   15294     5830619 : Maybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
   15295             :                                      Handle<Object> value,
   15296             :                                      PropertyAttributes attributes,
   15297             :                                      ShouldThrow should_throw) {
   15298             :   DCHECK(object->map()->is_extensible());
   15299             : 
   15300             :   Isolate* isolate = object->GetIsolate();
   15301             : 
   15302     5830619 :   uint32_t old_length = 0;
   15303     5830619 :   uint32_t new_capacity = 0;
   15304             : 
   15305     5830619 :   if (object->IsJSArray()) {
   15306     1828716 :     CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length));
   15307             :   }
   15308             : 
   15309             :   ElementsKind kind = object->GetElementsKind();
   15310             :   FixedArrayBase* elements = object->elements();
   15311             :   ElementsKind dictionary_kind = DICTIONARY_ELEMENTS;
   15312     5830619 :   if (IsSloppyArgumentsElementsKind(kind)) {
   15313             :     elements = SloppyArgumentsElements::cast(elements)->arguments();
   15314             :     dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
   15315     5697905 :   } else if (IsStringWrapperElementsKind(kind)) {
   15316             :     dictionary_kind = SLOW_STRING_WRAPPER_ELEMENTS;
   15317             :   }
   15318             : 
   15319     5830619 :   if (attributes != NONE) {
   15320             :     kind = dictionary_kind;
   15321     5799590 :   } else if (elements->IsSeededNumberDictionary()) {
   15322             :     kind = ShouldConvertToFastElements(*object,
   15323             :                                        SeededNumberDictionary::cast(elements),
   15324     1281153 :                                        index, &new_capacity)
   15325             :                ? BestFittingFastElementsKind(*object)
   15326     1281719 :                : dictionary_kind;
   15327     4518437 :   } else if (ShouldConvertToSlowElements(
   15328             :                  *object, static_cast<uint32_t>(elements->length()), index,
   15329     4518437 :                  &new_capacity)) {
   15330             :     kind = dictionary_kind;
   15331             :   }
   15332             : 
   15333     5830619 :   ElementsKind to = value->OptimalElementsKind();
   15334     6207974 :   if (IsHoleyOrDictionaryElementsKind(kind) || !object->IsJSArray() ||
   15335       72057 :       index > old_length) {
   15336             :     to = GetHoleyElementsKind(to);
   15337             :     kind = GetHoleyElementsKind(kind);
   15338             :   }
   15339             :   to = GetMoreGeneralElementsKind(kind, to);
   15340             :   ElementsAccessor* accessor = ElementsAccessor::ForKind(to);
   15341     5830619 :   accessor->Add(object, index, value, attributes, new_capacity);
   15342             : 
   15343     5830619 :   if (object->IsJSArray() && index >= old_length) {
   15344             :     Handle<Object> new_length =
   15345     1695378 :         isolate->factory()->NewNumberFromUint(index + 1);
   15346     1695378 :     JSArray::cast(*object)->set_length(*new_length);
   15347             :   }
   15348             : 
   15349     5830619 :   return Just(true);
   15350             : }
   15351             : 
   15352             : 
   15353      919774 : bool JSArray::SetLengthWouldNormalize(uint32_t new_length) {
   15354      919774 :   if (!HasFastElements()) return false;
   15355      901654 :   uint32_t capacity = static_cast<uint32_t>(elements()->length());
   15356             :   uint32_t new_capacity;
   15357      902674 :   return JSArray::SetLengthWouldNormalize(GetHeap(), new_length) &&
   15358             :          ShouldConvertToSlowElements(this, capacity, new_length - 1,
   15359      902674 :                                      &new_capacity);
   15360             : }
   15361             : 
   15362             : 
   15363             : const double AllocationSite::kPretenureRatio = 0.85;
   15364             : 
   15365             : 
   15366           0 : void AllocationSite::ResetPretenureDecision() {
   15367           0 :   set_pretenure_decision(kUndecided);
   15368           0 :   set_memento_found_count(0);
   15369             :   set_memento_create_count(0);
   15370           0 : }
   15371             : 
   15372        8606 : PretenureFlag AllocationSite::GetPretenureMode() const {
   15373             :   PretenureDecision mode = pretenure_decision();
   15374             :   // Zombie objects "decide" to be untenured.
   15375        8606 :   return mode == kTenure ? TENURED : NOT_TENURED;
   15376             : }
   15377             : 
   15378           0 : bool AllocationSite::IsNested() {
   15379             :   DCHECK(FLAG_trace_track_allocation_sites);
   15380           0 :   Object* current = GetHeap()->allocation_sites_list();
   15381           0 :   while (current->IsAllocationSite()) {
   15382             :     AllocationSite* current_site = AllocationSite::cast(current);
   15383           0 :     if (current_site->nested_site() == this) {
   15384             :       return true;
   15385             :     }
   15386             :     current = current_site->weak_next();
   15387             :   }
   15388             :   return false;
   15389             : }
   15390             : 
   15391             : template <AllocationSiteUpdateMode update_or_check>
   15392      546852 : bool AllocationSite::DigestTransitionFeedback(Handle<AllocationSite> site,
   15393             :                                               ElementsKind to_kind) {
   15394             :   Isolate* isolate = site->GetIsolate();
   15395             :   bool result = false;
   15396             : 
   15397      573663 :   if (site->PointsToLiteral() && site->boilerplate()->IsJSArray()) {
   15398             :     Handle<JSArray> boilerplate(JSArray::cast(site->boilerplate()), isolate);
   15399             :     ElementsKind kind = boilerplate->GetElementsKind();
   15400             :     // if kind is holey ensure that to_kind is as well.
   15401       26811 :     if (IsHoleyOrDictionaryElementsKind(kind)) {
   15402             :       to_kind = GetHoleyElementsKind(to_kind);
   15403             :     }
   15404       26811 :     if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
   15405             :       // If the array is huge, it's not likely to be defined in a local
   15406             :       // function, so we shouldn't make new instances of it very often.
   15407       16512 :       uint32_t length = 0;
   15408       16512 :       CHECK(boilerplate->length()->ToArrayLength(&length));
   15409       16512 :       if (length <= kMaximumArrayBytesToPretransition) {
   15410             :         if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) {
   15411           0 :           return true;
   15412             :         }
   15413       16512 :         if (FLAG_trace_track_allocation_sites) {
   15414           0 :           bool is_nested = site->IsNested();
   15415           0 :           PrintF("AllocationSite: JSArray %p boilerplate %supdated %s->%s\n",
   15416             :                  reinterpret_cast<void*>(*site), is_nested ? "(nested)" : " ",
   15417           0 :                  ElementsKindToString(kind), ElementsKindToString(to_kind));
   15418             :         }
   15419       16512 :         JSObject::TransitionElementsKind(boilerplate, to_kind);
   15420       16512 :         site->dependent_code()->DeoptimizeDependentCodeGroup(
   15421             :             isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
   15422             :         result = true;
   15423             :       }
   15424             :     }
   15425             :   } else {
   15426             :     // The AllocationSite is for a constructed Array.
   15427             :     ElementsKind kind = site->GetElementsKind();
   15428             :     // if kind is holey ensure that to_kind is as well.
   15429      520041 :     if (IsHoleyOrDictionaryElementsKind(kind)) {
   15430             :       to_kind = GetHoleyElementsKind(to_kind);
   15431             :     }
   15432      520041 :     if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
   15433             :       if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) return true;
   15434       18838 :       if (FLAG_trace_track_allocation_sites) {
   15435           0 :         PrintF("AllocationSite: JSArray %p site updated %s->%s\n",
   15436             :                reinterpret_cast<void*>(*site),
   15437             :                ElementsKindToString(kind),
   15438           0 :                ElementsKindToString(to_kind));
   15439             :       }
   15440       18838 :       site->SetElementsKind(to_kind);
   15441       18838 :       site->dependent_code()->DeoptimizeDependentCodeGroup(
   15442             :           isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
   15443             :       result = true;
   15444             :     }
   15445             :   }
   15446             :   return result;
   15447             : }
   15448             : 
   15449        1314 : bool AllocationSite::ShouldTrack(ElementsKind from, ElementsKind to) {
   15450        2292 :   return IsSmiElementsKind(from) &&
   15451        2292 :          IsMoreGeneralElementsKindTransition(from, to);
   15452             : }
   15453             : 
   15454           0 : const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) {
   15455           0 :   switch (decision) {
   15456             :     case kUndecided: return "undecided";
   15457           0 :     case kDontTenure: return "don't tenure";
   15458           0 :     case kMaybeTenure: return "maybe tenure";
   15459           0 :     case kTenure: return "tenure";
   15460           0 :     case kZombie: return "zombie";
   15461           0 :     default: UNREACHABLE();
   15462             :   }
   15463             :   return nullptr;
   15464             : }
   15465             : 
   15466             : template <AllocationSiteUpdateMode update_or_check>
   15467      951460 : bool JSObject::UpdateAllocationSite(Handle<JSObject> object,
   15468             :                                     ElementsKind to_kind) {
   15469      951460 :   if (!object->IsJSArray()) return false;
   15470             : 
   15471             :   Heap* heap = object->GetHeap();
   15472      674715 :   if (!heap->InNewSpace(*object)) return false;
   15473             : 
   15474             :   Handle<AllocationSite> site;
   15475             :   {
   15476             :     DisallowHeapAllocation no_allocation;
   15477             : 
   15478             :     AllocationMemento* memento =
   15479      654211 :         heap->FindAllocationMemento<Heap::kForRuntime>(object->map(), *object);
   15480      654211 :     if (memento == nullptr) return false;
   15481             : 
   15482             :     // Walk through to the Allocation Site
   15483      546852 :     site = handle(memento->GetAllocationSite());
   15484             :   }
   15485             :   return AllocationSite::DigestTransitionFeedback<update_or_check>(site,
   15486      546852 :                                                                    to_kind);
   15487             : }
   15488             : 
   15489             : template bool
   15490             : JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kCheckOnly>(
   15491             :     Handle<JSObject> object, ElementsKind to_kind);
   15492             : 
   15493             : template bool JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kUpdate>(
   15494             :     Handle<JSObject> object, ElementsKind to_kind);
   15495             : 
   15496      149966 : void JSObject::TransitionElementsKind(Handle<JSObject> object,
   15497             :                                       ElementsKind to_kind) {
   15498             :   ElementsKind from_kind = object->GetElementsKind();
   15499             : 
   15500      149966 :   if (IsHoleyElementsKind(from_kind)) {
   15501             :     to_kind = GetHoleyElementsKind(to_kind);
   15502             :   }
   15503             : 
   15504      299932 :   if (from_kind == to_kind) return;
   15505             : 
   15506             :   // This method should never be called for any other case.
   15507             :   DCHECK(IsFastElementsKind(from_kind));
   15508             :   DCHECK(IsFastElementsKind(to_kind));
   15509             :   DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
   15510             : 
   15511      149911 :   UpdateAllocationSite(object, to_kind);
   15512      297075 :   if (object->elements() == object->GetHeap()->empty_fixed_array() ||
   15513             :       IsDoubleElementsKind(from_kind) == IsDoubleElementsKind(to_kind)) {
   15514             :     // No change is needed to the elements() buffer, the transition
   15515             :     // only requires a map change.
   15516      143919 :     Handle<Map> new_map = GetElementsTransitionMap(object, to_kind);
   15517      143919 :     MigrateToMap(object, new_map);
   15518             :     if (FLAG_trace_elements_transitions) {
   15519             :       Handle<FixedArrayBase> elms(object->elements());
   15520             :       PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms);
   15521             :     }
   15522             :   } else {
   15523             :     DCHECK((IsSmiElementsKind(from_kind) && IsDoubleElementsKind(to_kind)) ||
   15524             :            (IsDoubleElementsKind(from_kind) && IsObjectElementsKind(to_kind)));
   15525        5992 :     uint32_t c = static_cast<uint32_t>(object->elements()->length());
   15526        5992 :     ElementsAccessor::ForKind(to_kind)->GrowCapacityAndConvert(object, c);
   15527             :   }
   15528             : }
   15529             : 
   15530             : 
   15531             : // static
   15532           0 : bool Map::IsValidElementsTransition(ElementsKind from_kind,
   15533             :                                     ElementsKind to_kind) {
   15534             :   // Transitions can't go backwards.
   15535           0 :   if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
   15536             :     return false;
   15537             :   }
   15538             : 
   15539             :   // Transitions from HOLEY -> PACKED are not allowed.
   15540           0 :   return !IsHoleyElementsKind(from_kind) || IsHoleyElementsKind(to_kind);
   15541             : }
   15542             : 
   15543             : 
   15544     9220908 : bool JSArray::HasReadOnlyLength(Handle<JSArray> array) {
   15545             :   Map* map = array->map();
   15546             :   // Fast path: "length" is the first fast property of arrays. Since it's not
   15547             :   // configurable, it's guaranteed to be the first in the descriptor array.
   15548     9220908 :   if (!map->is_dictionary_map()) {
   15549             :     DCHECK(map->instance_descriptors()->GetKey(0) ==
   15550             :            array->GetHeap()->length_string());
   15551    18417054 :     return map->instance_descriptors()->GetDetails(0).IsReadOnly();
   15552             :   }
   15553             : 
   15554             :   Isolate* isolate = array->GetIsolate();
   15555             :   LookupIterator it(array, isolate->factory()->length_string(), array,
   15556       12381 :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
   15557       12381 :   CHECK_EQ(LookupIterator::ACCESSOR, it.state());
   15558       12381 :   return it.IsReadOnly();
   15559             : }
   15560             : 
   15561             : 
   15562     1806226 : bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
   15563             :                                         uint32_t index) {
   15564     1806226 :   uint32_t length = 0;
   15565     1806226 :   CHECK(array->length()->ToArrayLength(&length));
   15566     1806226 :   if (length <= index) return HasReadOnlyLength(array);
   15567             :   return false;
   15568             : }
   15569             : 
   15570             : template <typename BackingStore>
   15571      284670 : static int HoleyElementsUsage(JSObject* object, BackingStore* store) {
   15572             :   Isolate* isolate = store->GetIsolate();
   15573             :   int limit = object->IsJSArray() ? Smi::ToInt(JSArray::cast(object)->length())
   15574      284670 :                                   : store->length();
   15575             :   int used = 0;
   15576   370638539 :   for (int i = 0; i < limit; ++i) {
   15577   370353869 :     if (!store->is_the_hole(isolate, i)) ++used;
   15578             :   }
   15579      284670 :   return used;
   15580             : }
   15581             : 
   15582      304659 : int JSObject::GetFastElementsUsage() {
   15583             :   FixedArrayBase* store = elements();
   15584      304659 :   switch (GetElementsKind()) {
   15585             :     case PACKED_SMI_ELEMENTS:
   15586             :     case PACKED_DOUBLE_ELEMENTS:
   15587             :     case PACKED_ELEMENTS:
   15588             :       return IsJSArray() ? Smi::ToInt(JSArray::cast(this)->length())
   15589       39918 :                          : store->length();
   15590             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
   15591             :       store = SloppyArgumentsElements::cast(store)->arguments();
   15592             :     // Fall through.
   15593             :     case HOLEY_SMI_ELEMENTS:
   15594             :     case HOLEY_ELEMENTS:
   15595             :     case FAST_STRING_WRAPPER_ELEMENTS:
   15596      284563 :       return HoleyElementsUsage(this, FixedArray::cast(store));
   15597             :     case HOLEY_DOUBLE_ELEMENTS:
   15598         137 :       if (elements()->length() == 0) return 0;
   15599         107 :       return HoleyElementsUsage(this, FixedDoubleArray::cast(store));
   15600             : 
   15601             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
   15602             :     case SLOW_STRING_WRAPPER_ELEMENTS:
   15603             :     case DICTIONARY_ELEMENTS:
   15604             :     case NO_ELEMENTS:
   15605             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
   15606             :     case TYPE##_ELEMENTS:                                                    \
   15607             : 
   15608             :     TYPED_ARRAYS(TYPED_ARRAY_CASE)
   15609             : #undef TYPED_ARRAY_CASE
   15610           0 :     UNREACHABLE();
   15611             :   }
   15612             :   return 0;
   15613             : }
   15614             : 
   15615             : 
   15616             : // Certain compilers request function template instantiation when they
   15617             : // see the definition of the other template functions in the
   15618             : // class. This requires us to have the template functions put
   15619             : // together, so even though this function belongs in objects-debug.cc,
   15620             : // we keep it here instead to satisfy certain compilers.
   15621             : #ifdef OBJECT_PRINT
   15622             : template <typename Derived, typename Shape>
   15623             : void Dictionary<Derived, Shape>::Print(std::ostream& os) {
   15624             :   DisallowHeapAllocation no_gc;
   15625             :   Isolate* isolate = this->GetIsolate();
   15626             :   Derived* dictionary = Derived::cast(this);
   15627             :   int capacity = dictionary->Capacity();
   15628             :   for (int i = 0; i < capacity; i++) {
   15629             :     Object* k = dictionary->KeyAt(i);
   15630             :     if (!Shape::IsLive(isolate, k)) continue;
   15631             :     if (!dictionary->ToKey(isolate, i, &k)) continue;
   15632             :     os << "\n   ";
   15633             :     if (k->IsString()) {
   15634             :       String::cast(k)->StringPrint(os);
   15635             :     } else {
   15636             :       os << Brief(k);
   15637             :     }
   15638             :     os << ": " << Brief(dictionary->ValueAt(i)) << " ";
   15639             :     dictionary->DetailsAt(i).PrintAsSlowTo(os);
   15640             :   }
   15641             : }
   15642             : template <typename Derived, typename Shape>
   15643             : void Dictionary<Derived, Shape>::Print() {
   15644             :   OFStream os(stdout);
   15645             :   Print(os);
   15646             : }
   15647             : #endif
   15648             : 
   15649             : 
   15650       13969 : MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
   15651             :                                                          bool* done) {
   15652             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
   15653       13969 :   return GetPropertyWithInterceptorInternal(it, it->GetInterceptor(), done);
   15654             : }
   15655             : 
   15656    42331931 : Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object,
   15657             :                                            Handle<Name> name) {
   15658             :   LookupIterator it = LookupIterator::PropertyOrElement(
   15659    42331931 :       name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   15660    42331931 :   return HasProperty(&it);
   15661             : }
   15662             : 
   15663             : 
   15664          17 : Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object,
   15665             :                                              uint32_t index) {
   15666             :   Isolate* isolate = object->GetIsolate();
   15667             :   LookupIterator it(isolate, object, index, object,
   15668             :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
   15669          17 :   return HasProperty(&it);
   15670             : }
   15671             : 
   15672             : 
   15673           5 : Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
   15674             :                                                    Handle<Name> name) {
   15675             :   LookupIterator it = LookupIterator::PropertyOrElement(
   15676           5 :       name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   15677           5 :   Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
   15678           5 :   return maybe_result.IsJust() ? Just(it.state() == LookupIterator::ACCESSOR)
   15679          10 :                                : Nothing<bool>();
   15680             : }
   15681             : 
   15682        2031 : int FixedArrayBase::GetMaxLengthForNewSpaceAllocation(ElementsKind kind) {
   15683             :   return ((kMaxRegularHeapObjectSize - FixedArrayBase::kHeaderSize) >>
   15684        2031 :           ElementsKindToShiftSize(kind));
   15685             : }
   15686             : 
   15687        1243 : bool FixedArrayBase::IsCowArray() const {
   15688        1243 :   return map() == GetHeap()->fixed_cow_array_map();
   15689             : }
   15690             : 
   15691       31702 : bool JSObject::WasConstructedFromApiFunction() {
   15692             :   auto instance_type = map()->instance_type();
   15693       31702 :   bool is_api_object = instance_type == JS_API_OBJECT_TYPE ||
   15694       31702 :                        instance_type == JS_SPECIAL_API_OBJECT_TYPE;
   15695             :   bool is_wasm_object =
   15696             :       instance_type == WASM_MEMORY_TYPE || instance_type == WASM_MODULE_TYPE ||
   15697             :       instance_type == WASM_INSTANCE_TYPE || instance_type == WASM_TABLE_TYPE;
   15698             : #ifdef ENABLE_SLOW_DCHECKS
   15699             :   if (FLAG_enable_slow_asserts) {
   15700             :     Object* maybe_constructor = map()->GetConstructor();
   15701             :     if (maybe_constructor->IsJSFunction()) {
   15702             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
   15703             :       DCHECK_EQ(constructor->shared()->IsApiFunction(),
   15704             :                 is_api_object || is_wasm_object);
   15705             :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
   15706             :       DCHECK(is_api_object || is_wasm_object);
   15707             :     } else {
   15708             :       return false;
   15709             :     }
   15710             :   }
   15711             : #endif
   15712             :   // TODO(titzer): Clean this up somehow. WebAssembly objects should not be
   15713             :   // considered "constructed from API functions" even though they have
   15714             :   // function template info, since that would make the V8 GC identify them to
   15715             :   // the embedder, e.g. the Oilpan GC.
   15716             :   USE(is_wasm_object);
   15717       31702 :   return is_api_object;
   15718             : }
   15719             : 
   15720         180 : const char* Symbol::PrivateSymbolToName() const {
   15721        6840 :   Heap* heap = GetIsolate()->heap();
   15722             : #define SYMBOL_CHECK_AND_PRINT(name) \
   15723             :   if (this == heap->name()) return #name;
   15724        6840 :   PRIVATE_SYMBOL_LIST(SYMBOL_CHECK_AND_PRINT)
   15725             : #undef SYMBOL_CHECK_AND_PRINT
   15726         180 :   return "UNKNOWN";
   15727             : }
   15728             : 
   15729             : 
   15730         192 : void Symbol::SymbolShortPrint(std::ostream& os) {
   15731         192 :   os << "<Symbol:";
   15732         192 :   if (!name()->IsUndefined(GetIsolate())) {
   15733          12 :     os << " ";
   15734             :     HeapStringAllocator allocator;
   15735             :     StringStream accumulator(&allocator);
   15736          12 :     String::cast(name())->StringShortPrint(&accumulator, false);
   15737          36 :     os << accumulator.ToCString().get();
   15738             :   } else {
   15739         180 :     os << " (" << PrivateSymbolToName() << ")";
   15740             :   }
   15741         192 :   os << ">";
   15742         192 : }
   15743             : 
   15744             : 
   15745             : // StringSharedKeys are used as keys in the eval cache.
   15746           0 : class StringSharedKey : public HashTableKey {
   15747             :  public:
   15748             :   // This tuple unambiguously identifies calls to eval() or
   15749             :   // CreateDynamicFunction() (such as through the Function() constructor).
   15750             :   // * source is the string passed into eval(). For dynamic functions, this is
   15751             :   //   the effective source for the function, some of which is implicitly
   15752             :   //   generated.
   15753             :   // * shared is the shared function info for the function containing the call
   15754             :   //   to eval(). for dynamic functions, shared is the native context closure.
   15755             :   // * When positive, position is the position in the source where eval is
   15756             :   //   called. When negative, position is the negation of the position in the
   15757             :   //   dynamic function's effective source where the ')' ends the parameters.
   15758     5151455 :   StringSharedKey(Handle<String> source, Handle<SharedFunctionInfo> shared,
   15759             :                   LanguageMode language_mode, int position)
   15760             :       : HashTableKey(CompilationCacheShape::StringSharedHash(
   15761             :             *source, *shared, language_mode, position)),
   15762             :         source_(source),
   15763             :         shared_(shared),
   15764             :         language_mode_(language_mode),
   15765    10302910 :         position_(position) {}
   15766             : 
   15767     6325764 :   bool IsMatch(Object* other) override {
   15768             :     DisallowHeapAllocation no_allocation;
   15769     6325764 :     if (!other->IsFixedArray()) {
   15770             :       DCHECK(other->IsNumber());
   15771     1994352 :       uint32_t other_hash = static_cast<uint32_t>(other->Number());
   15772     1994352 :       return Hash() == other_hash;
   15773             :     }
   15774             :     FixedArray* other_array = FixedArray::cast(other);
   15775             :     SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
   15776     4331412 :     if (shared != *shared_) return false;
   15777             :     int language_unchecked = Smi::ToInt(other_array->get(2));
   15778             :     DCHECK(is_valid_language_mode(language_unchecked));
   15779     4161951 :     LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
   15780     4161951 :     if (language_mode != language_mode_) return false;
   15781             :     int position = Smi::ToInt(other_array->get(3));
   15782     4149117 :     if (position != position_) return false;
   15783             :     String* source = String::cast(other_array->get(1));
   15784     4149100 :     return source->Equals(*source_);
   15785             :   }
   15786             : 
   15787     1319908 :   Handle<Object> AsHandle(Isolate* isolate) {
   15788     1319908 :     Handle<FixedArray> array = isolate->factory()->NewFixedArray(4);
   15789     1319908 :     array->set(0, *shared_);
   15790     1319908 :     array->set(1, *source_);
   15791     1319908 :     array->set(2, Smi::FromEnum(language_mode_));
   15792     1319908 :     array->set(3, Smi::FromInt(position_));
   15793     2639816 :     array->set_map(isolate->heap()->fixed_cow_array_map());
   15794     1319908 :     return array;
   15795             :   }
   15796             : 
   15797             :  private:
   15798             :   Handle<String> source_;
   15799             :   Handle<SharedFunctionInfo> shared_;
   15800             :   LanguageMode language_mode_;
   15801             :   int position_;
   15802             : };
   15803             : 
   15804         290 : v8::Promise::PromiseState JSPromise::status() const {
   15805         290 :   int value = flags() & kStatusMask;
   15806             :   DCHECK(value == 0 || value == 1 || value == 2);
   15807         290 :   return static_cast<v8::Promise::PromiseState>(value);
   15808             : }
   15809             : 
   15810             : // static
   15811          25 : const char* JSPromise::Status(v8::Promise::PromiseState status) {
   15812          25 :   switch (status) {
   15813             :     case v8::Promise::kFulfilled:
   15814             :       return "resolved";
   15815             :     case v8::Promise::kPending:
   15816          10 :       return "pending";
   15817             :     case v8::Promise::kRejected:
   15818           0 :       return "rejected";
   15819             :   }
   15820           0 :   UNREACHABLE();
   15821             : }
   15822             : 
   15823             : namespace {
   15824             : 
   15825      418560 : JSRegExp::Flags RegExpFlagsFromString(Handle<String> flags, bool* success) {
   15826             :   JSRegExp::Flags value = JSRegExp::kNone;
   15827             :   int length = flags->length();
   15828             :   // A longer flags string cannot be valid.
   15829      418560 :   if (length > JSRegExp::FlagCount()) return JSRegExp::Flags(0);
   15830       87040 :   for (int i = 0; i < length; i++) {
   15831             :     JSRegExp::Flag flag = JSRegExp::kNone;
   15832       87198 :     switch (flags->Get(i)) {
   15833             :       case 'g':
   15834             :         flag = JSRegExp::kGlobal;
   15835             :         break;
   15836             :       case 'i':
   15837             :         flag = JSRegExp::kIgnoreCase;
   15838       73082 :         break;
   15839             :       case 'm':
   15840             :         flag = JSRegExp::kMultiline;
   15841         464 :         break;
   15842             :       case 's':
   15843          36 :         if (FLAG_harmony_regexp_dotall) {
   15844             :           flag = JSRegExp::kDotAll;
   15845             :         } else {
   15846           0 :           return JSRegExp::Flags(0);
   15847             :         }
   15848             :         break;
   15849             :       case 'u':
   15850             :         flag = JSRegExp::kUnicode;
   15851        1180 :         break;
   15852             :       case 'y':
   15853             :         flag = JSRegExp::kSticky;
   15854         125 :         break;
   15855             :       default:
   15856          19 :         return JSRegExp::Flags(0);
   15857             :     }
   15858             :     // Duplicate flag.
   15859       87179 :     if (value & flag) return JSRegExp::Flags(0);
   15860             :     value |= flag;
   15861             :   }
   15862      418402 :   *success = true;
   15863      418402 :   return value;
   15864             : }
   15865             : 
   15866             : }  // namespace
   15867             : 
   15868             : 
   15869             : // static
   15870       99965 : MaybeHandle<JSRegExp> JSRegExp::New(Handle<String> pattern, Flags flags) {
   15871             :   Isolate* isolate = pattern->GetIsolate();
   15872       99965 :   Handle<JSFunction> constructor = isolate->regexp_function();
   15873             :   Handle<JSRegExp> regexp =
   15874       99965 :       Handle<JSRegExp>::cast(isolate->factory()->NewJSObject(constructor));
   15875             : 
   15876       99965 :   return JSRegExp::Initialize(regexp, pattern, flags);
   15877             : }
   15878             : 
   15879             : 
   15880             : // static
   15881       15754 : Handle<JSRegExp> JSRegExp::Copy(Handle<JSRegExp> regexp) {
   15882             :   Isolate* const isolate = regexp->GetIsolate();
   15883       15754 :   return Handle<JSRegExp>::cast(isolate->factory()->CopyJSObject(regexp));
   15884             : }
   15885             : 
   15886             : 
   15887             : template <typename Char>
   15888      518367 : inline int CountRequiredEscapes(Handle<String> source) {
   15889             :   DisallowHeapAllocation no_gc;
   15890             :   int escapes = 0;
   15891             :   Vector<const Char> src = source->GetCharVector<Char>();
   15892 21498062736 :   for (int i = 0; i < src.length(); i++) {
   15893 21497026002 :     if (src[i] == '\\') {
   15894             :       // Escape. Skip next character;
   15895      113730 :       i++;
   15896 10748399271 :     } else if (src[i] == '/') {
   15897             :       // Not escaped forward-slash needs escape.
   15898        1755 :       escapes++;
   15899             :     }
   15900             :   }
   15901      518367 :   return escapes;
   15902             : }
   15903             : 
   15904             : 
   15905             : template <typename Char, typename StringType>
   15906         637 : inline Handle<StringType> WriteEscapedRegExpSource(Handle<String> source,
   15907             :                                                    Handle<StringType> result) {
   15908             :   DisallowHeapAllocation no_gc;
   15909             :   Vector<const Char> src = source->GetCharVector<Char>();
   15910         637 :   Vector<Char> dst(result->GetChars(), result->length());
   15911             :   int s = 0;
   15912             :   int d = 0;
   15913       35076 :   while (s < src.length()) {
   15914       67604 :     if (src[s] == '\\') {
   15915             :       // Escape. Copy this and next character.
   15916        4126 :       dst[d++] = src[s++];
   15917        2063 :       if (s == src.length()) break;
   15918       31739 :     } else if (src[s] == '/') {
   15919             :       // Not escaped forward-slash needs escape.
   15920        3510 :       dst[d++] = '\\';
   15921             :     }
   15922      101406 :     dst[d++] = src[s++];
   15923             :   }
   15924             :   DCHECK_EQ(result->length(), d);
   15925         637 :   return result;
   15926             : }
   15927             : 
   15928             : 
   15929      518367 : MaybeHandle<String> EscapeRegExpSource(Isolate* isolate,
   15930             :                                        Handle<String> source) {
   15931             :   DCHECK(source->IsFlat());
   15932      518367 :   if (source->length() == 0) return isolate->factory()->query_colon_string();
   15933      518367 :   bool one_byte = source->IsOneByteRepresentationUnderneath();
   15934             :   int escapes = one_byte ? CountRequiredEscapes<uint8_t>(source)
   15935      518367 :                          : CountRequiredEscapes<uc16>(source);
   15936      518367 :   if (escapes == 0) return source;
   15937         637 :   int length = source->length() + escapes;
   15938         637 :   if (one_byte) {
   15939             :     Handle<SeqOneByteString> result;
   15940        1258 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   15941             :                                isolate->factory()->NewRawOneByteString(length),
   15942             :                                String);
   15943         629 :     return WriteEscapedRegExpSource<uint8_t>(source, result);
   15944             :   } else {
   15945             :     Handle<SeqTwoByteString> result;
   15946          16 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   15947             :                                isolate->factory()->NewRawTwoByteString(length),
   15948             :                                String);
   15949           8 :     return WriteEscapedRegExpSource<uc16>(source, result);
   15950             :   }
   15951             : }
   15952             : 
   15953             : 
   15954             : // static
   15955      418560 : MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
   15956             :                                            Handle<String> source,
   15957             :                                            Handle<String> flags_string) {
   15958             :   Isolate* isolate = source->GetIsolate();
   15959      418560 :   bool success = false;
   15960      418560 :   Flags flags = RegExpFlagsFromString(flags_string, &success);
   15961      418560 :   if (!success) {
   15962         316 :     THROW_NEW_ERROR(
   15963             :         isolate,
   15964             :         NewSyntaxError(MessageTemplate::kInvalidRegExpFlags, flags_string),
   15965             :         JSRegExp);
   15966             :   }
   15967      418402 :   return Initialize(regexp, source, flags);
   15968             : }
   15969             : 
   15970             : 
   15971             : // static
   15972      518367 : MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
   15973             :                                            Handle<String> source, Flags flags) {
   15974             :   Isolate* isolate = regexp->GetIsolate();
   15975             :   Factory* factory = isolate->factory();
   15976             :   // If source is the empty string we set it to "(?:)" instead as
   15977             :   // suggested by ECMA-262, 5th, section 15.10.4.1.
   15978      518367 :   if (source->length() == 0) source = factory->query_colon_string();
   15979             : 
   15980      518367 :   source = String::Flatten(source);
   15981             : 
   15982             :   Handle<String> escaped_source;
   15983     1036734 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, escaped_source,
   15984             :                              EscapeRegExpSource(isolate, source), JSRegExp);
   15985             : 
   15986     1036734 :   RETURN_ON_EXCEPTION(isolate, RegExpImpl::Compile(regexp, source, flags),
   15987             :                       JSRegExp);
   15988             : 
   15989      515911 :   regexp->set_source(*escaped_source);
   15990      515911 :   regexp->set_flags(Smi::FromInt(flags));
   15991             : 
   15992             :   Map* map = regexp->map();
   15993      515911 :   Object* constructor = map->GetConstructor();
   15994     1031822 :   if (constructor->IsJSFunction() &&
   15995             :       JSFunction::cast(constructor)->initial_map() == map) {
   15996             :     // If we still have the original map, set in-object properties directly.
   15997             :     regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, Smi::kZero,
   15998      515702 :                                   SKIP_WRITE_BARRIER);
   15999             :   } else {
   16000             :     // Map has changed, so use generic, but slower, method.
   16001         418 :     RETURN_ON_EXCEPTION(
   16002             :         isolate,
   16003             :         JSReceiver::SetProperty(regexp, factory->lastIndex_string(),
   16004             :                                 Handle<Smi>(Smi::kZero, isolate),
   16005             :                                 LanguageMode::kStrict),
   16006             :         JSRegExp);
   16007             :   }
   16008             : 
   16009      515911 :   return regexp;
   16010             : }
   16011             : 
   16012             : 
   16013             : // RegExpKey carries the source and flags of a regular expression as key.
   16014           0 : class RegExpKey : public HashTableKey {
   16015             :  public:
   16016             :   RegExpKey(Handle<String> string, JSRegExp::Flags flags)
   16017             :       : HashTableKey(
   16018             :             CompilationCacheShape::RegExpHash(*string, Smi::FromInt(flags))),
   16019             :         string_(string),
   16020     1909128 :         flags_(Smi::FromInt(flags)) {}
   16021             : 
   16022             :   // Rather than storing the key in the hash table, a pointer to the
   16023             :   // stored value is stored where the key should be.  IsMatch then
   16024             :   // compares the search key to the found object, rather than comparing
   16025             :   // a key to a key.
   16026      652889 :   bool IsMatch(Object* obj) override {
   16027             :     FixedArray* val = FixedArray::cast(obj);
   16028      652889 :     return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex)))
   16029      870465 :         && (flags_ == val->get(JSRegExp::kFlagsIndex));
   16030             :   }
   16031             : 
   16032             :   Handle<String> string_;
   16033             :   Smi* flags_;
   16034             : };
   16035             : 
   16036       39153 : Handle<String> OneByteStringKey::AsHandle(Isolate* isolate) {
   16037       39153 :   return isolate->factory()->NewOneByteInternalizedString(string_, HashField());
   16038             : }
   16039             : 
   16040           0 : Handle<String> TwoByteStringKey::AsHandle(Isolate* isolate) {
   16041           0 :   return isolate->factory()->NewTwoByteInternalizedString(string_, HashField());
   16042             : }
   16043             : 
   16044      112004 : Handle<String> SeqOneByteSubStringKey::AsHandle(Isolate* isolate) {
   16045             :   return isolate->factory()->NewOneByteInternalizedSubString(
   16046      112004 :       string_, from_, length_, HashField());
   16047             : }
   16048             : 
   16049             : 
   16050       73858 : bool SeqOneByteSubStringKey::IsMatch(Object* string) {
   16051      147716 :   Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
   16052       73858 :   return String::cast(string)->IsOneByteEqualTo(chars);
   16053             : }
   16054             : 
   16055             : 
   16056             : // InternalizedStringKey carries a string/internalized-string object as key.
   16057           0 : class InternalizedStringKey : public StringTableKey {
   16058             :  public:
   16059    12002528 :   explicit InternalizedStringKey(Handle<String> string)
   16060    12002528 :       : StringTableKey(0), string_(string) {
   16061             :     DCHECK(!string->IsInternalizedString());
   16062             :     DCHECK(string->IsFlat());
   16063             :     // Make sure hash_field is computed.
   16064    12002528 :     string->Hash();
   16065             :     set_hash_field(string->hash_field());
   16066    12002528 :   }
   16067             : 
   16068    13705434 :   bool IsMatch(Object* string) override {
   16069    13705434 :     return string_->SlowEquals(String::cast(string));
   16070             :   }
   16071             : 
   16072     1924115 :   Handle<String> AsHandle(Isolate* isolate) override {
   16073             :     // Internalize the string if possible.
   16074             :     MaybeHandle<Map> maybe_map =
   16075     1924115 :         isolate->factory()->InternalizedStringMapForString(string_);
   16076             :     Handle<Map> map;
   16077     1924115 :     if (maybe_map.ToHandle(&map)) {
   16078             :       string_->set_map_no_write_barrier(*map);
   16079             :       DCHECK(string_->IsInternalizedString());
   16080        9589 :       return string_;
   16081             :     }
   16082     1914526 :     if (FLAG_thin_strings) {
   16083             :       // External strings get special treatment, to avoid copying their
   16084             :       // contents.
   16085     1914526 :       if (string_->IsExternalOneByteString()) {
   16086             :         return isolate->factory()
   16087          10 :             ->InternalizeExternalString<ExternalOneByteString>(string_);
   16088     1914516 :       } else if (string_->IsExternalTwoByteString()) {
   16089             :         return isolate->factory()
   16090           0 :             ->InternalizeExternalString<ExternalTwoByteString>(string_);
   16091             :       }
   16092             :     }
   16093             :     // Otherwise allocate a new internalized string.
   16094             :     return isolate->factory()->NewInternalizedStringImpl(
   16095     1914516 :         string_, string_->length(), string_->hash_field());
   16096             :   }
   16097             : 
   16098             :  private:
   16099             :   Handle<String> string_;
   16100             : };
   16101             : 
   16102             : template <typename Derived, typename Shape>
   16103       56758 : void HashTable<Derived, Shape>::IteratePrefix(ObjectVisitor* v) {
   16104             :   BodyDescriptorBase::IteratePointers(this, 0, kElementsStartOffset, v);
   16105       56758 : }
   16106             : 
   16107             : template <typename Derived, typename Shape>
   16108       56800 : void HashTable<Derived, Shape>::IterateElements(ObjectVisitor* v) {
   16109             :   BodyDescriptorBase::IteratePointers(this, kElementsStartOffset,
   16110       56800 :                                       kHeaderSize + length() * kPointerSize, v);
   16111       56800 : }
   16112             : 
   16113             : template <typename Derived, typename Shape>
   16114     2126177 : Handle<Derived> HashTable<Derived, Shape>::New(
   16115             :     Isolate* isolate, int at_least_space_for, PretenureFlag pretenure,
   16116             :     MinimumCapacity capacity_option) {
   16117             :   DCHECK_LE(0, at_least_space_for);
   16118             :   DCHECK_IMPLIES(capacity_option == USE_CUSTOM_MINIMUM_CAPACITY,
   16119             :                  base::bits::IsPowerOfTwo(at_least_space_for));
   16120             : 
   16121             :   int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
   16122             :                      ? at_least_space_for
   16123     2126177 :                      : ComputeCapacity(at_least_space_for);
   16124     2126177 :   if (capacity > HashTable::kMaxCapacity) {
   16125           0 :     v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
   16126             :   }
   16127     2126177 :   return NewInternal(isolate, capacity, pretenure);
   16128             : }
   16129             : 
   16130             : template <typename Derived, typename Shape>
   16131     2126177 : Handle<Derived> HashTable<Derived, Shape>::NewInternal(
   16132             :     Isolate* isolate, int capacity, PretenureFlag pretenure) {
   16133             :   Factory* factory = isolate->factory();
   16134             :   int length = EntryToIndex(capacity);
   16135     2126177 :   Handle<FixedArray> array = factory->NewFixedArray(length, pretenure);
   16136             :   array->set_map_no_write_barrier(Shape::GetMap(isolate));
   16137             :   Handle<Derived> table = Handle<Derived>::cast(array);
   16138             : 
   16139             :   table->SetNumberOfElements(0);
   16140             :   table->SetNumberOfDeletedElements(0);
   16141             :   table->SetCapacity(capacity);
   16142     2126177 :   return table;
   16143             : }
   16144             : 
   16145             : template <typename Derived, typename Shape>
   16146      503112 : void HashTable<Derived, Shape>::Rehash(Derived* new_table) {
   16147             :   DisallowHeapAllocation no_gc;
   16148      503112 :   WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc);
   16149             : 
   16150             :   DCHECK_LT(NumberOfElements(), new_table->Capacity());
   16151             : 
   16152             :   // Copy prefix to new array.
   16153     1460027 :   for (int i = kPrefixStartIndex; i < kElementsStartIndex; i++) {
   16154      970311 :     new_table->set(i, get(i), mode);
   16155             :   }
   16156             : 
   16157             :   // Rehash the elements.
   16158             :   int capacity = this->Capacity();
   16159             :   Isolate* isolate = new_table->GetIsolate();
   16160    36457223 :   for (int i = 0; i < capacity; i++) {
   16161    35952100 :     uint32_t from_index = EntryToIndex(i);
   16162             :     Object* k = this->get(from_index);
   16163    35952100 :     if (!Shape::IsLive(isolate, k)) continue;
   16164     7844210 :     uint32_t hash = Shape::HashForObject(isolate, k);
   16165             :     uint32_t insertion_index =
   16166    46074352 :         EntryToIndex(new_table->FindInsertionEntry(hash));
   16167    71873513 :     for (int j = 0; j < Shape::kEntrySize; j++) {
   16168    97672674 :       new_table->set(insertion_index + j, get(from_index + j), mode);
   16169             :     }
   16170             :   }
   16171             :   new_table->SetNumberOfElements(NumberOfElements());
   16172             :   new_table->SetNumberOfDeletedElements(0);
   16173      503112 : }
   16174             : 
   16175             : template <typename Derived, typename Shape>
   16176   322618593 : uint32_t HashTable<Derived, Shape>::EntryForProbe(Object* k, int probe,
   16177             :                                                   uint32_t expected) {
   16178    46244265 :   uint32_t hash = Shape::HashForObject(GetIsolate(), k);
   16179   322617872 :   uint32_t capacity = this->Capacity();
   16180             :   uint32_t entry = FirstProbe(hash, capacity);
   16181   372778996 :   for (int i = 1; i < probe; i++) {
   16182   268910412 :     if (entry == expected) return expected;
   16183    50161124 :     entry = NextProbe(entry, i, capacity);
   16184             :   }
   16185             :   return entry;
   16186             : }
   16187             : 
   16188             : template <typename Derived, typename Shape>
   16189    51705677 : void HashTable<Derived, Shape>::Swap(uint32_t entry1, uint32_t entry2,
   16190             :                                      WriteBarrierMode mode) {
   16191    51705677 :   int index1 = EntryToIndex(entry1);
   16192    51705677 :   int index2 = EntryToIndex(entry2);
   16193             :   Object* temp[Shape::kEntrySize];
   16194   103417456 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   16195    51723995 :     temp[j] = get(index1 + j);
   16196             :   }
   16197    51711789 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   16198   103423568 :     set(index1 + j, get(index2 + j), mode);
   16199             :   }
   16200    51711696 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   16201    51711790 :     set(index2 + j, temp[j], mode);
   16202             :   }
   16203    51705588 : }
   16204             : 
   16205             : template <typename Derived, typename Shape>
   16206      250130 : void HashTable<Derived, Shape>::Rehash() {
   16207             :   DisallowHeapAllocation no_gc;
   16208      250130 :   WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
   16209             :   Isolate* isolate = GetIsolate();
   16210      250138 :   uint32_t capacity = Capacity();
   16211             :   bool done = false;
   16212     1411421 :   for (int probe = 1; !done; probe++) {
   16213             :     // All elements at entries given by one of the first _probe_ probes
   16214             :     // are placed correctly. Other elements might need to be moved.
   16215             :     done = true;
   16216  1276476811 :     for (uint32_t current = 0; current < capacity; current++) {
   16217  1276476811 :       Object* current_key = KeyAt(current);
   16218  1276476811 :       if (!Shape::IsLive(isolate, current_key)) continue;
   16219   306067845 :       uint32_t target = EntryForProbe(current_key, probe, current);
   16220   306067899 :       if (current == target) continue;
   16221    61829213 :       Object* target_key = KeyAt(target);
   16222    78379558 :       if (!Shape::IsLive(isolate, target_key) ||
   16223    16550346 :           EntryForProbe(target_key, probe, target) != target) {
   16224             :         // Put the current element into the correct position.
   16225    51705674 :         Swap(current, target, mode);
   16226             :         // The other element will be processed on the next iteration.
   16227    51705621 :         current--;
   16228             :       } else {
   16229             :         // The place for the current element is occupied. Leave the element
   16230             :         // for the next probe.
   16231             :         done = false;
   16232             :       }
   16233             :     }
   16234             :   }
   16235             :   // Wipe deleted entries.
   16236      250138 :   Object* the_hole = isolate->heap()->the_hole_value();
   16237      250138 :   Object* undefined = isolate->heap()->undefined_value();
   16238   239468042 :   for (uint32_t current = 0; current < capacity; current++) {
   16239   478435824 :     if (KeyAt(current) == the_hole) {
   16240    24622051 :       set(EntryToIndex(current) + kEntryKeyIndex, undefined);
   16241             :     }
   16242             :   }
   16243             :   SetNumberOfDeletedElements(0);
   16244      250130 : }
   16245             : 
   16246             : template <typename Derived, typename Shape>
   16247    37559137 : Handle<Derived> HashTable<Derived, Shape>::EnsureCapacity(
   16248             :     Handle<Derived> table, int n, PretenureFlag pretenure) {
   16249    37559137 :   if (table->HasSufficientCapacityToAdd(n)) return table;
   16250             : 
   16251             :   Isolate* isolate = table->GetIsolate();
   16252             :   int capacity = table->Capacity();
   16253      502828 :   int new_nof = table->NumberOfElements() + n;
   16254             : 
   16255             :   const int kMinCapacityForPretenure = 256;
   16256             :   bool should_pretenure = pretenure == TENURED ||
   16257             :       ((capacity > kMinCapacityForPretenure) &&
   16258      506695 :           !isolate->heap()->InNewSpace(*table));
   16259             :   Handle<Derived> new_table = HashTable::New(
   16260      502828 :       isolate, new_nof, should_pretenure ? TENURED : NOT_TENURED);
   16261             : 
   16262      502828 :   table->Rehash(*new_table);
   16263      502828 :   return new_table;
   16264             : }
   16265             : 
   16266             : template bool
   16267             : HashTable<NameDictionary, NameDictionaryShape>::HasSufficientCapacityToAdd(int);
   16268             : 
   16269             : template <typename Derived, typename Shape>
   16270    37593177 : bool HashTable<Derived, Shape>::HasSufficientCapacityToAdd(
   16271             :     int number_of_additional_elements) {
   16272             :   int capacity = Capacity();
   16273    37593177 :   int nof = NumberOfElements() + number_of_additional_elements;
   16274             :   int nod = NumberOfDeletedElements();
   16275             :   // Return true if:
   16276             :   //   50% is still free after adding number_of_additional_elements elements and
   16277             :   //   at most 50% of the free elements are deleted elements.
   16278    37593177 :   if ((nof < capacity) && ((nod <= (capacity - nof) >> 1))) {
   16279    37432537 :     int needed_free = nof >> 1;
   16280    37432537 :     if (nof + needed_free <= capacity) return true;
   16281             :   }
   16282      503113 :   return false;
   16283             : }
   16284             : 
   16285             : template <typename Derived, typename Shape>
   16286       83208 : Handle<Derived> HashTable<Derived, Shape>::Shrink(Handle<Derived> table) {
   16287             :   int capacity = table->Capacity();
   16288             :   int nof = table->NumberOfElements();
   16289             : 
   16290             :   // Shrink to fit the number of elements if only a quarter of the
   16291             :   // capacity is filled with elements.
   16292       83208 :   if (nof > (capacity >> 2)) return table;
   16293             :   // Allocate a new dictionary with room for at least the current
   16294             :   // number of elements. The allocation method will make sure that
   16295             :   // there is extra room in the dictionary for additions. Don't go
   16296             :   // lower than room for 16 elements.
   16297             :   int at_least_room_for = nof;
   16298       65093 :   if (at_least_room_for < 16) return table;
   16299             : 
   16300             :   Isolate* isolate = table->GetIsolate();
   16301             :   const int kMinCapacityForPretenure = 256;
   16302             :   bool pretenure =
   16303             :       (at_least_room_for > kMinCapacityForPretenure) &&
   16304         303 :       !isolate->heap()->InNewSpace(*table);
   16305             :   Handle<Derived> new_table = HashTable::New(
   16306             :       isolate,
   16307             :       at_least_room_for,
   16308         284 :       pretenure ? TENURED : NOT_TENURED);
   16309             : 
   16310         284 :   table->Rehash(*new_table);
   16311         284 :   return new_table;
   16312             : }
   16313             : 
   16314             : template <typename Derived, typename Shape>
   16315    60596012 : uint32_t HashTable<Derived, Shape>::FindInsertionEntry(uint32_t hash) {
   16316    60596012 :   uint32_t capacity = Capacity();
   16317             :   uint32_t entry = FirstProbe(hash, capacity);
   16318             :   uint32_t count = 1;
   16319             :   // EnsureCapacity will guarantee the hash table is never full.
   16320             :   Isolate* isolate = GetIsolate();
   16321             :   while (true) {
   16322   311615418 :     if (!Shape::IsLive(isolate, KeyAt(entry))) break;
   16323    95211697 :     entry = NextProbe(entry, count++, capacity);
   16324             :   }
   16325    95211697 :   return entry;
   16326             : }
   16327             : 
   16328             : 
   16329             : // Force instantiation of template instances class.
   16330             : // Please note this list is compiler dependent.
   16331             : 
   16332             : template class HashTable<StringTable, StringTableShape>;
   16333             : 
   16334             : template class HashTable<CompilationCacheTable, CompilationCacheShape>;
   16335             : 
   16336             : template class HashTable<ObjectHashTable, ObjectHashTableShape>;
   16337             : 
   16338             : template class HashTable<WeakHashTable, WeakHashTableShape<2>>;
   16339             : 
   16340             : template class HashTable<TemplateMap, TemplateMapShape>;
   16341             : 
   16342             : template class Dictionary<NameDictionary, NameDictionaryShape>;
   16343             : 
   16344             : template class Dictionary<GlobalDictionary, GlobalDictionaryShape>;
   16345             : 
   16346             : template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
   16347             :     HashTable<SeededNumberDictionary, SeededNumberDictionaryShape>;
   16348             : 
   16349             : template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
   16350             :     Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>;
   16351             : 
   16352             : template class Dictionary<UnseededNumberDictionary,
   16353             :                           UnseededNumberDictionaryShape>;
   16354             : 
   16355             : template Handle<NameDictionary>
   16356             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::New(
   16357             :     Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
   16358             : 
   16359             : template Handle<GlobalDictionary>
   16360             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::New(
   16361             :     Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
   16362             : 
   16363             : template Handle<SeededNumberDictionary>
   16364             :     Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>::AtPut(
   16365             :         Handle<SeededNumberDictionary>, uint32_t, Handle<Object>,
   16366             :         PropertyDetails);
   16367             : 
   16368             : template Handle<UnseededNumberDictionary>
   16369             :     Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::AtPut(
   16370             :         Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>,
   16371             :         PropertyDetails);
   16372             : 
   16373             : template Object*
   16374             : Dictionary<SeededNumberDictionary,
   16375             :            SeededNumberDictionaryShape>::SlowReverseLookup(Object* value);
   16376             : 
   16377             : template Object* Dictionary<
   16378             :     NameDictionary, NameDictionaryShape>::SlowReverseLookup(Object* value);
   16379             : 
   16380             : template Handle<NameDictionary>
   16381             : Dictionary<NameDictionary, NameDictionaryShape>::DeleteEntry(
   16382             :     Handle<NameDictionary>, int);
   16383             : 
   16384             : template Handle<SeededNumberDictionary>
   16385             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>::DeleteEntry(
   16386             :     Handle<SeededNumberDictionary>, int);
   16387             : 
   16388             : template Handle<UnseededNumberDictionary>
   16389             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::
   16390             :     DeleteEntry(Handle<UnseededNumberDictionary>, int);
   16391             : 
   16392             : template Handle<UnseededNumberDictionary>
   16393             : HashTable<UnseededNumberDictionary, UnseededNumberDictionaryShape>::New(
   16394             :     Isolate*, int, PretenureFlag, MinimumCapacity);
   16395             : 
   16396             : template Handle<NameDictionary>
   16397             : HashTable<NameDictionary, NameDictionaryShape>::New(Isolate*, int,
   16398             :                                                     PretenureFlag,
   16399             :                                                     MinimumCapacity);
   16400             : 
   16401             : template Handle<ObjectHashSet>
   16402             : HashTable<ObjectHashSet, ObjectHashSetShape>::New(Isolate*, int n,
   16403             :                                                   PretenureFlag,
   16404             :                                                   MinimumCapacity);
   16405             : 
   16406             : template Handle<NameDictionary> HashTable<
   16407             :     NameDictionary, NameDictionaryShape>::Shrink(Handle<NameDictionary>);
   16408             : 
   16409             : template Handle<UnseededNumberDictionary>
   16410             :     HashTable<UnseededNumberDictionary, UnseededNumberDictionaryShape>::Shrink(
   16411             :         Handle<UnseededNumberDictionary>);
   16412             : 
   16413             : template Handle<NameDictionary>
   16414             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::Add(
   16415             :     Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
   16416             :     int*);
   16417             : 
   16418             : template Handle<GlobalDictionary>
   16419             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::Add(
   16420             :     Handle<GlobalDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
   16421             :     int*);
   16422             : 
   16423             : template void HashTable<GlobalDictionary, GlobalDictionaryShape>::Rehash();
   16424             : 
   16425             : template Handle<SeededNumberDictionary>
   16426             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>::Add(
   16427             :     Handle<SeededNumberDictionary>, uint32_t, Handle<Object>, PropertyDetails,
   16428             :     int*);
   16429             : 
   16430             : template Handle<UnseededNumberDictionary>
   16431             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::Add(
   16432             :     Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>, PropertyDetails,
   16433             :     int*);
   16434             : 
   16435             : template Handle<NameDictionary>
   16436             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::EnsureCapacity(
   16437             :     Handle<NameDictionary>, int);
   16438             : 
   16439             : template int Dictionary<GlobalDictionary,
   16440             :                         GlobalDictionaryShape>::NumberOfEnumerableProperties();
   16441             : 
   16442             : template int
   16443             : Dictionary<NameDictionary, NameDictionaryShape>::NumberOfEnumerableProperties();
   16444             : 
   16445             : template void
   16446             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::CopyEnumKeysTo(
   16447             :     Handle<GlobalDictionary> dictionary, Handle<FixedArray> storage,
   16448             :     KeyCollectionMode mode, KeyAccumulator* accumulator);
   16449             : 
   16450             : template void
   16451             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::CopyEnumKeysTo(
   16452             :     Handle<NameDictionary> dictionary, Handle<FixedArray> storage,
   16453             :     KeyCollectionMode mode, KeyAccumulator* accumulator);
   16454             : 
   16455             : template Handle<FixedArray>
   16456             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::IterationIndices(
   16457             :     Handle<GlobalDictionary> dictionary);
   16458             : template void
   16459             : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::CollectKeysTo(
   16460             :     Handle<GlobalDictionary> dictionary, KeyAccumulator* keys);
   16461             : 
   16462             : template Handle<FixedArray>
   16463             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::IterationIndices(
   16464             :     Handle<NameDictionary> dictionary);
   16465             : template void
   16466             : BaseNameDictionary<NameDictionary, NameDictionaryShape>::CollectKeysTo(
   16467             :     Handle<NameDictionary> dictionary, KeyAccumulator* keys);
   16468             : 
   16469             : template int
   16470             : Dictionary<SeededNumberDictionary,
   16471             :            SeededNumberDictionaryShape>::NumberOfEnumerableProperties();
   16472             : 
   16473             : namespace {
   16474             : 
   16475        2930 : bool CanonicalNumericIndexString(Isolate* isolate, Handle<Object> s,
   16476             :                                  Handle<Object>* index) {
   16477             :   DCHECK(s->IsString() || s->IsSmi());
   16478             : 
   16479             :   Handle<Object> result;
   16480        2930 :   if (s->IsSmi()) {
   16481             :     result = s;
   16482             :   } else {
   16483        2912 :     result = String::ToNumber(Handle<String>::cast(s));
   16484        2912 :     if (!result->IsMinusZero()) {
   16485        5806 :       Handle<String> str = Object::ToString(isolate, result).ToHandleChecked();
   16486             :       // Avoid treating strings like "2E1" and "20" as the same key.
   16487        2903 :       if (!str->SameValue(*s)) return false;
   16488             :     }
   16489             :   }
   16490         218 :   *index = result;
   16491         218 :   return true;
   16492             : }
   16493             : 
   16494             : }  // anonymous namespace
   16495             : 
   16496             : // ES#sec-integer-indexed-exotic-objects-defineownproperty-p-desc
   16497             : // static
   16498        3119 : Maybe<bool> JSTypedArray::DefineOwnProperty(Isolate* isolate,
   16499             :                                             Handle<JSTypedArray> o,
   16500             :                                             Handle<Object> key,
   16501             :                                             PropertyDescriptor* desc,
   16502             :                                             ShouldThrow should_throw) {
   16503             :   // 1. Assert: IsPropertyKey(P) is true.
   16504             :   DCHECK(key->IsName() || key->IsNumber());
   16505             :   // 2. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot.
   16506             :   // 3. If Type(P) is String, then
   16507        3326 :   if (key->IsString() || key->IsSmi()) {
   16508             :     // 3a. Let numericIndex be ! CanonicalNumericIndexString(P)
   16509             :     // 3b. If numericIndex is not undefined, then
   16510             :     Handle<Object> numeric_index;
   16511        2930 :     if (CanonicalNumericIndexString(isolate, key, &numeric_index)) {
   16512             :       // 3b i. If IsInteger(numericIndex) is false, return false.
   16513             :       // 3b ii. If numericIndex = -0, return false.
   16514             :       // 3b iii. If numericIndex < 0, return false.
   16515             :       // FIXME: the standard allows up to 2^53 elements.
   16516             :       uint32_t index;
   16517         427 :       if (numeric_index->IsMinusZero() || !numeric_index->ToUint32(&index)) {
   16518          81 :         RETURN_FAILURE(isolate, should_throw,
   16519             :                        NewTypeError(MessageTemplate::kInvalidTypedArrayIndex));
   16520             :       }
   16521             :       // 3b iv. Let length be O.[[ArrayLength]].
   16522         191 :       uint32_t length = o->length()->Number();
   16523             :       // 3b v. If numericIndex ≥ length, return false.
   16524         191 :       if (index >= length) {
   16525          27 :         RETURN_FAILURE(isolate, should_throw,
   16526             :                        NewTypeError(MessageTemplate::kInvalidTypedArrayIndex));
   16527             :       }
   16528             :       // 3b vi. If IsAccessorDescriptor(Desc) is true, return false.
   16529         182 :       if (PropertyDescriptor::IsAccessorDescriptor(desc)) {
   16530         516 :         RETURN_FAILURE(isolate, should_throw,
   16531             :                        NewTypeError(MessageTemplate::kRedefineDisallowed, key));
   16532             :       }
   16533             :       // 3b vii. If Desc has a [[Configurable]] field and if
   16534             :       //         Desc.[[Configurable]] is true, return false.
   16535             :       // 3b viii. If Desc has an [[Enumerable]] field and if Desc.[[Enumerable]]
   16536             :       //          is false, return false.
   16537             :       // 3b ix. If Desc has a [[Writable]] field and if Desc.[[Writable]] is
   16538             :       //        false, return false.
   16539          20 :       if ((desc->has_configurable() && desc->configurable()) ||
   16540          20 :           (desc->has_enumerable() && !desc->enumerable()) ||
   16541          10 :           (desc->has_writable() && !desc->writable())) {
   16542          30 :         RETURN_FAILURE(isolate, should_throw,
   16543             :                        NewTypeError(MessageTemplate::kRedefineDisallowed, key));
   16544             :       }
   16545             :       // 3b x. If Desc has a [[Value]] field, then
   16546             :       //   3b x 1. Let value be Desc.[[Value]].
   16547             :       //   3b x 2. Return ? IntegerIndexedElementSet(O, numericIndex, value).
   16548           0 :       if (desc->has_value()) {
   16549           0 :         if (!desc->has_configurable()) desc->set_configurable(false);
   16550           0 :         if (!desc->has_enumerable()) desc->set_enumerable(true);
   16551           0 :         if (!desc->has_writable()) desc->set_writable(true);
   16552           0 :         Handle<Object> value = desc->value();
   16553           0 :         RETURN_ON_EXCEPTION_VALUE(isolate,
   16554             :                                   SetOwnElementIgnoreAttributes(
   16555             :                                       o, index, value, desc->ToAttributes()),
   16556             :                                   Nothing<bool>());
   16557             :       }
   16558             :       // 3b xi. Return true.
   16559             :       return Just(true);
   16560             :     }
   16561             :   }
   16562             :   // 4. Return ! OrdinaryDefineOwnProperty(O, P, Desc).
   16563        2901 :   return OrdinaryDefineOwnProperty(isolate, o, key, desc, should_throw);
   16564             : }
   16565             : 
   16566     9877273 : ExternalArrayType JSTypedArray::type() {
   16567     9877273 :   switch (elements()->map()->instance_type()) {
   16568             : #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size)            \
   16569             :     case FIXED_##TYPE##_ARRAY_TYPE:                                           \
   16570             :       return kExternal##Type##Array;
   16571             : 
   16572        3662 :     TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE)
   16573             : #undef INSTANCE_TYPE_TO_ARRAY_TYPE
   16574             : 
   16575             :     default:
   16576           0 :       UNREACHABLE();
   16577             :   }
   16578             : }
   16579             : 
   16580             : 
   16581       13481 : size_t JSTypedArray::element_size() {
   16582       13481 :   switch (elements()->map()->instance_type()) {
   16583             : #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \
   16584             :   case FIXED_##TYPE##_ARRAY_TYPE:                                    \
   16585             :     return size;
   16586             : 
   16587         911 :     TYPED_ARRAYS(INSTANCE_TYPE_TO_ELEMENT_SIZE)
   16588             : #undef INSTANCE_TYPE_TO_ELEMENT_SIZE
   16589             : 
   16590             :     default:
   16591           0 :       UNREACHABLE();
   16592             :   }
   16593             : }
   16594             : 
   16595             : // static
   16596       10748 : MaybeHandle<JSTypedArray> JSTypedArray::Create(Isolate* isolate,
   16597             :                                                Handle<Object> default_ctor,
   16598             :                                                int argc, Handle<Object>* argv,
   16599             :                                                const char* method_name) {
   16600             :   // 1. Let newTypedArray be ? Construct(constructor, argumentList).
   16601             :   Handle<Object> new_obj;
   16602       21496 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, new_obj,
   16603             :                              Execution::New(isolate, default_ctor, argc, argv),
   16604             :                              JSTypedArray);
   16605             : 
   16606             :   // 2. Perform ? ValidateTypedArray(newTypedArray).
   16607             :   Handle<JSTypedArray> new_array;
   16608       21496 :   ASSIGN_RETURN_ON_EXCEPTION(
   16609             :       isolate, new_array, JSTypedArray::Validate(isolate, new_obj, method_name),
   16610             :       JSTypedArray);
   16611             : 
   16612             :   // 3. If argumentList is a List of a single Number, then
   16613             :   // If newTypedArray.[[ArrayLength]] < size, throw a TypeError exception.
   16614             :   DCHECK_IMPLIES(argc == 1, argv[0]->IsSmi());
   16615       31515 :   if (argc == 1 && new_array->length_value() < argv[0]->Number()) {
   16616             :     const MessageTemplate::Template message =
   16617             :         MessageTemplate::kTypedArrayTooShort;
   16618         324 :     THROW_NEW_ERROR(isolate, NewTypeError(message), JSTypedArray);
   16619             :   }
   16620             : 
   16621             :   // 4. Return newTypedArray.
   16622       10343 :   return new_array;
   16623             : }
   16624             : 
   16625             : // static
   16626       10910 : MaybeHandle<JSTypedArray> JSTypedArray::SpeciesCreate(
   16627             :     Isolate* isolate, Handle<JSTypedArray> exemplar, int argc,
   16628             :     Handle<Object>* argv, const char* method_name) {
   16629             :   // 1. Assert: exemplar is an Object that has a [[TypedArrayName]] internal
   16630             :   // slot.
   16631             :   DCHECK(exemplar->IsJSTypedArray());
   16632             : 
   16633             :   // 2. Let defaultConstructor be the intrinsic object listed in column one of
   16634             :   // Table 51 for exemplar.[[TypedArrayName]].
   16635       10910 :   Handle<JSFunction> default_ctor = isolate->uint8_array_fun();
   16636       10910 :   switch (exemplar->type()) {
   16637             : #define TYPED_ARRAY_CTOR(Type, type, TYPE, ctype, size) \
   16638             :   case kExternal##Type##Array: {                        \
   16639             :     default_ctor = isolate->type##_array_fun();         \
   16640             :     break;                                              \
   16641             :   }
   16642             : 
   16643        1682 :     TYPED_ARRAYS(TYPED_ARRAY_CTOR)
   16644             : #undef TYPED_ARRAY_CTOR
   16645             :     default:
   16646           0 :       UNREACHABLE();
   16647             :   }
   16648             : 
   16649             :   // 3. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
   16650             :   Handle<Object> ctor;
   16651       21820 :   ASSIGN_RETURN_ON_EXCEPTION(
   16652             :       isolate, ctor,
   16653             :       Object::SpeciesConstructor(isolate, exemplar, default_ctor),
   16654             :       JSTypedArray);
   16655             : 
   16656             :   // 4. Return ? TypedArrayCreate(constructor, argumentList).
   16657       10748 :   return Create(isolate, ctor, argc, argv, method_name);
   16658             : }
   16659             : 
   16660      379548 : void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
   16661             :                                             Handle<Name> name) {
   16662             :   DCHECK(!global->HasFastProperties());
   16663             :   auto dictionary = handle(global->global_dictionary());
   16664             :   int entry = dictionary->FindEntry(name);
   16665      759096 :   if (entry == GlobalDictionary::kNotFound) return;
   16666          95 :   PropertyCell::InvalidateEntry(dictionary, entry);
   16667             : }
   16668             : 
   16669     7168421 : Handle<PropertyCell> JSGlobalObject::EnsureEmptyPropertyCell(
   16670             :     Handle<JSGlobalObject> global, Handle<Name> name,
   16671             :     PropertyCellType cell_type, int* entry_out) {
   16672             :   Isolate* isolate = global->GetIsolate();
   16673             :   DCHECK(!global->HasFastProperties());
   16674             :   Handle<GlobalDictionary> dictionary(global->global_dictionary(), isolate);
   16675             :   int entry = dictionary->FindEntry(name);
   16676             :   Handle<PropertyCell> cell;
   16677     7168421 :   if (entry != GlobalDictionary::kNotFound) {
   16678        3976 :     if (entry_out) *entry_out = entry;
   16679             :     cell = handle(dictionary->CellAt(entry));
   16680             :     PropertyCellType original_cell_type = cell->property_details().cell_type();
   16681             :     DCHECK(original_cell_type == PropertyCellType::kInvalidated ||
   16682             :            original_cell_type == PropertyCellType::kUninitialized);
   16683             :     DCHECK(cell->value()->IsTheHole(isolate));
   16684        3976 :     if (original_cell_type == PropertyCellType::kInvalidated) {
   16685        1319 :       cell = PropertyCell::InvalidateEntry(dictionary, entry);
   16686             :     }
   16687             :     PropertyDetails details(kData, NONE, cell_type);
   16688             :     cell->set_property_details(details);
   16689        3976 :     return cell;
   16690             :   }
   16691     7164445 :   cell = isolate->factory()->NewPropertyCell(name);
   16692             :   PropertyDetails details(kData, NONE, cell_type);
   16693             :   dictionary =
   16694     7164445 :       GlobalDictionary::Add(dictionary, name, cell, details, entry_out);
   16695             :   // {*entry_out} is initialized inside GlobalDictionary::Add().
   16696     7164445 :   global->SetProperties(*dictionary);
   16697     7164445 :   return cell;
   16698             : }
   16699             : 
   16700             : 
   16701             : // This class is used for looking up two character strings in the string table.
   16702             : // If we don't have a hit we don't want to waste much time so we unroll the
   16703             : // string hash calculation loop here for speed.  Doesn't work if the two
   16704             : // characters form a decimal integer, since such strings have a different hash
   16705             : // algorithm.
   16706           0 : class TwoCharHashTableKey : public StringTableKey {
   16707             :  public:
   16708             :   TwoCharHashTableKey(uint16_t c1, uint16_t c2, uint32_t seed)
   16709    10033972 :       : StringTableKey(ComputeHashField(c1, c2, seed)), c1_(c1), c2_(c2) {}
   16710             : 
   16711      944045 :   bool IsMatch(Object* o) override {
   16712             :     String* other = String::cast(o);
   16713      944045 :     if (other->length() != 2) return false;
   16714      240686 :     if (other->Get(0) != c1_) return false;
   16715      189608 :     return other->Get(1) == c2_;
   16716             :   }
   16717             : 
   16718           0 :   Handle<String> AsHandle(Isolate* isolate) override {
   16719             :     // The TwoCharHashTableKey is only used for looking in the string
   16720             :     // table, not for adding to it.
   16721           0 :     UNREACHABLE();
   16722             :   }
   16723             : 
   16724             :  private:
   16725     5016986 :   uint32_t ComputeHashField(uint16_t c1, uint16_t c2, uint32_t seed) {
   16726             :     // Char 1.
   16727             :     uint32_t hash = seed;
   16728     5016986 :     hash += c1;
   16729     5016986 :     hash += hash << 10;
   16730     5016986 :     hash ^= hash >> 6;
   16731             :     // Char 2.
   16732     5016986 :     hash += c2;
   16733     5016986 :     hash += hash << 10;
   16734     5016986 :     hash ^= hash >> 6;
   16735             :     // GetHash.
   16736     5016986 :     hash += hash << 3;
   16737     5016986 :     hash ^= hash >> 11;
   16738     5016986 :     hash += hash << 15;
   16739     5016986 :     if ((hash & String::kHashBitMask) == 0) hash = StringHasher::kZeroHash;
   16740     5016986 :     hash = (hash << String::kHashShift) | String::kIsNotArrayIndexMask;
   16741             : #ifdef DEBUG
   16742             :     // If this assert fails then we failed to reproduce the two-character
   16743             :     // version of the string hashing algorithm above.  One reason could be
   16744             :     // that we were passed two digits as characters, since the hash
   16745             :     // algorithm is different in that case.
   16746             :     uint16_t chars[2] = {c1, c2};
   16747             :     uint32_t check_hash = StringHasher::HashSequentialString(chars, 2, seed);
   16748             :     DCHECK_EQ(hash, check_hash);
   16749             : #endif
   16750     5016986 :     return hash;
   16751             :   }
   16752             : 
   16753             :   uint16_t c1_;
   16754             :   uint16_t c2_;
   16755             : };
   16756             : 
   16757     5016986 : MaybeHandle<String> StringTable::LookupTwoCharsStringIfExists(
   16758             :     Isolate* isolate,
   16759             :     uint16_t c1,
   16760             :     uint16_t c2) {
   16761             :   TwoCharHashTableKey key(c1, c2, isolate->heap()->HashSeed());
   16762             :   Handle<StringTable> string_table = isolate->factory()->string_table();
   16763             :   int entry = string_table->FindEntry(&key);
   16764     5016986 :   if (entry == kNotFound) return MaybeHandle<String>();
   16765             : 
   16766             :   Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
   16767             :   DCHECK(StringShape(*result).IsInternalized());
   16768             :   DCHECK_EQ(result->Hash(), key.Hash());
   16769      188758 :   return result;
   16770             : }
   16771             : 
   16772         300 : void StringTable::EnsureCapacityForDeserialization(Isolate* isolate,
   16773             :                                                    int expected) {
   16774             :   Handle<StringTable> table = isolate->factory()->string_table();
   16775             :   // We need a key instance for the virtual hash function.
   16776         300 :   table = StringTable::EnsureCapacity(table, expected);
   16777             :   isolate->heap()->SetRootStringTable(*table);
   16778         300 : }
   16779             : 
   16780             : namespace {
   16781             : 
   16782             : template <class StringClass>
   16783          31 : void MigrateExternalStringResource(Isolate* isolate, String* from, String* to) {
   16784             :   StringClass* cast_from = StringClass::cast(from);
   16785             :   StringClass* cast_to = StringClass::cast(to);
   16786             :   const typename StringClass::Resource* to_resource = cast_to->resource();
   16787          31 :   if (to_resource == nullptr) {
   16788             :     // |to| is a just-created internalized copy of |from|. Migrate the resource.
   16789             :     cast_to->set_resource(cast_from->resource());
   16790             :     // Zap |from|'s resource pointer to reflect the fact that |from| has
   16791             :     // relinquished ownership of its resource.
   16792             :     cast_from->set_resource(nullptr);
   16793          21 :   } else if (to_resource != cast_from->resource()) {
   16794             :     // |to| already existed and has its own resource. Finalize |from|.
   16795             :     isolate->heap()->FinalizeExternalString(from);
   16796             :   }
   16797          31 : }
   16798             : 
   16799    12049350 : void MakeStringThin(String* string, String* internalized, Isolate* isolate) {
   16800    12049350 :   if (string->IsExternalString()) {
   16801          31 :     if (internalized->IsExternalOneByteString()) {
   16802             :       MigrateExternalStringResource<ExternalOneByteString>(isolate, string,
   16803          20 :                                                            internalized);
   16804          11 :     } else if (internalized->IsExternalTwoByteString()) {
   16805             :       MigrateExternalStringResource<ExternalTwoByteString>(isolate, string,
   16806          11 :                                                            internalized);
   16807             :     } else {
   16808             :       // If the external string is duped into an existing non-external
   16809             :       // internalized string, free its resource (it's about to be rewritten
   16810             :       // into a ThinString below).
   16811             :       isolate->heap()->FinalizeExternalString(string);
   16812             :     }
   16813             :   }
   16814             : 
   16815    12049350 :   if (!string->IsInternalizedString()) {
   16816             :     DisallowHeapAllocation no_gc;
   16817    12039761 :     int old_size = string->Size();
   16818    12039761 :     isolate->heap()->NotifyObjectLayoutChange(string, old_size, no_gc);
   16819             :     bool one_byte = internalized->IsOneByteRepresentation();
   16820             :     Handle<Map> map = one_byte ? isolate->factory()->thin_one_byte_string_map()
   16821    12039761 :                                : isolate->factory()->thin_string_map();
   16822             :     DCHECK_GE(old_size, ThinString::kSize);
   16823    12039761 :     string->synchronized_set_map(*map);
   16824             :     ThinString* thin = ThinString::cast(string);
   16825    12039761 :     thin->set_actual(internalized);
   16826    12039761 :     Address thin_end = thin->address() + ThinString::kSize;
   16827    12039761 :     int size_delta = old_size - ThinString::kSize;
   16828    12039761 :     if (size_delta != 0) {
   16829             :       Heap* heap = isolate->heap();
   16830     3360588 :       heap->CreateFillerObjectAt(thin_end, size_delta, ClearRecordedSlots::kNo);
   16831             :     }
   16832             :   }
   16833    12049350 : }
   16834             : 
   16835             : }  // namespace
   16836             : 
   16837    12717887 : Handle<String> StringTable::LookupString(Isolate* isolate,
   16838             :                                          Handle<String> string) {
   16839    12717887 :   string = String::Flatten(string);
   16840    12717887 :   if (string->IsInternalizedString()) return string;
   16841             : 
   16842    12002528 :   InternalizedStringKey key(string);
   16843    12002529 :   Handle<String> result = LookupKey(isolate, &key);
   16844             : 
   16845    12002529 :   if (FLAG_thin_strings) {
   16846    12002529 :     MakeStringThin(*string, *result, isolate);
   16847             :   } else {  // !FLAG_thin_strings
   16848           0 :     if (string->IsConsString()) {
   16849             :       Handle<ConsString> cons = Handle<ConsString>::cast(string);
   16850           0 :       cons->set_first(*result);
   16851           0 :       cons->set_second(isolate->heap()->empty_string());
   16852           0 :     } else if (string->IsSlicedString()) {
   16853             :       STATIC_ASSERT(ConsString::kSize == SlicedString::kSize);
   16854             :       DisallowHeapAllocation no_gc;
   16855             :       bool one_byte = result->IsOneByteRepresentation();
   16856             :       Handle<Map> map = one_byte
   16857             :                             ? isolate->factory()->cons_one_byte_string_map()
   16858           0 :                             : isolate->factory()->cons_string_map();
   16859           0 :       string->set_map(*map);
   16860             :       Handle<ConsString> cons = Handle<ConsString>::cast(string);
   16861           0 :       cons->set_first(*result);
   16862           0 :       cons->set_second(isolate->heap()->empty_string());
   16863             :     }
   16864             :   }
   16865    12002529 :   return result;
   16866             : }
   16867             : 
   16868    60220412 : Handle<String> StringTable::LookupKey(Isolate* isolate, StringTableKey* key) {
   16869             :   Handle<StringTable> table = isolate->factory()->string_table();
   16870             :   int entry = table->FindEntry(key);
   16871             : 
   16872             :   // String already in table.
   16873    60220427 :   if (entry != kNotFound) {
   16874             :     return handle(String::cast(table->KeyAt(entry)), isolate);
   16875             :   }
   16876             : 
   16877             :   // Adding new string. Grow table if needed.
   16878    12898852 :   table = StringTable::EnsureCapacity(table, 1);
   16879             : 
   16880             :   // Create string object.
   16881    12898851 :   Handle<String> string = key->AsHandle(isolate);
   16882             :   // There must be no attempts to internalize strings that could throw
   16883             :   // InvalidStringLength error.
   16884    12898851 :   CHECK(!string.is_null());
   16885             :   DCHECK(string->HasHashCode());
   16886             : 
   16887             :   // Add the new string and return it along with the string table.
   16888    25797702 :   entry = table->FindInsertionEntry(key->Hash());
   16889    12898852 :   table->set(EntryToIndex(entry), *string);
   16890    12898852 :   table->ElementAdded();
   16891             : 
   16892             :   isolate->heap()->SetRootStringTable(*table);
   16893             :   return Handle<String>::cast(string);
   16894             : }
   16895             : 
   16896             : namespace {
   16897             : 
   16898             : class StringTableNoAllocateKey : public StringTableKey {
   16899             :  public:
   16900       47085 :   StringTableNoAllocateKey(String* string, uint32_t seed)
   16901       47085 :       : StringTableKey(0), string_(string) {
   16902             :     StringShape shape(string);
   16903       47085 :     one_byte_ = shape.HasOnlyOneByteChars();
   16904             :     DCHECK(!shape.IsInternalized());
   16905             :     DCHECK(!shape.IsThin());
   16906             :     int length = string->length();
   16907       47085 :     if (shape.IsCons() && length <= String::kMaxHashCalcLength) {
   16908         266 :       special_flattening_ = true;
   16909             :       uint32_t hash_field = 0;
   16910         266 :       if (one_byte_) {
   16911         263 :         one_byte_content_ = new uint8_t[length];
   16912         263 :         String::WriteToFlat(string, one_byte_content_, 0, length);
   16913             :         hash_field =
   16914         263 :             StringHasher::HashSequentialString(one_byte_content_, length, seed);
   16915             :       } else {
   16916           3 :         two_byte_content_ = new uint16_t[length];
   16917           3 :         String::WriteToFlat(string, two_byte_content_, 0, length);
   16918             :         hash_field =
   16919           3 :             StringHasher::HashSequentialString(two_byte_content_, length, seed);
   16920             :       }
   16921             :       string->set_hash_field(hash_field);
   16922             :     } else {
   16923       46819 :       special_flattening_ = false;
   16924       46819 :       one_byte_content_ = nullptr;
   16925       46819 :       string->Hash();
   16926             :     }
   16927             : 
   16928             :     DCHECK(string->HasHashCode());
   16929             :     set_hash_field(string->hash_field());
   16930       47085 :   }
   16931             : 
   16932       47085 :   ~StringTableNoAllocateKey() {
   16933       47085 :     if (one_byte_) {
   16934       44402 :       delete[] one_byte_content_;
   16935             :     } else {
   16936        2683 :       delete[] two_byte_content_;
   16937             :     }
   16938       47085 :   }
   16939             : 
   16940       71200 :   bool IsMatch(Object* otherstring) override {
   16941             :     String* other = String::cast(otherstring);
   16942             :     DCHECK(other->IsInternalizedString());
   16943             :     DCHECK(other->IsFlat());
   16944      142400 :     if (Hash() != other->Hash()) return false;
   16945       46821 :     int len = string_->length();
   16946       46821 :     if (len != other->length()) return false;
   16947             : 
   16948       46821 :     if (!special_flattening_) {
   16949       46603 :       if (string_->Get(0) != other->Get(0)) return false;
   16950       46603 :       if (string_->IsFlat()) {
   16951       46603 :         StringShape shape1(string_);
   16952             :         StringShape shape2(other);
   16953       90538 :         if (shape1.encoding_tag() == kOneByteStringTag &&
   16954             :             shape2.encoding_tag() == kOneByteStringTag) {
   16955       43935 :           String::FlatContent flat1 = string_->GetFlatContent();
   16956       43935 :           String::FlatContent flat2 = other->GetFlatContent();
   16957       43935 :           return CompareRawStringContents(flat1.ToOneByteVector().start(),
   16958       43935 :                                           flat2.ToOneByteVector().start(), len);
   16959             :         }
   16960        5336 :         if (shape1.encoding_tag() == kTwoByteStringTag &&
   16961             :             shape2.encoding_tag() == kTwoByteStringTag) {
   16962        2668 :           String::FlatContent flat1 = string_->GetFlatContent();
   16963        2668 :           String::FlatContent flat2 = other->GetFlatContent();
   16964        2668 :           return CompareRawStringContents(flat1.ToUC16Vector().start(),
   16965        2668 :                                           flat2.ToUC16Vector().start(), len);
   16966             :         }
   16967             :       }
   16968             :       StringComparator comparator;
   16969           0 :       return comparator.Equals(string_, other);
   16970             :     }
   16971             : 
   16972         218 :     String::FlatContent flat_content = other->GetFlatContent();
   16973         218 :     if (one_byte_) {
   16974         215 :       if (flat_content.IsOneByte()) {
   16975             :         return CompareRawStringContents(
   16976         215 :             one_byte_content_, flat_content.ToOneByteVector().start(), len);
   16977             :       } else {
   16978             :         DCHECK(flat_content.IsTwoByte());
   16979           0 :         for (int i = 0; i < len; i++) {
   16980           0 :           if (flat_content.Get(i) != one_byte_content_[i]) return false;
   16981             :         }
   16982             :         return true;
   16983             :       }
   16984             :     } else {
   16985           3 :       if (flat_content.IsTwoByte()) {
   16986             :         return CompareRawStringContents(
   16987           0 :             two_byte_content_, flat_content.ToUC16Vector().start(), len);
   16988             :       } else {
   16989             :         DCHECK(flat_content.IsOneByte());
   16990          60 :         for (int i = 0; i < len; i++) {
   16991          60 :           if (flat_content.Get(i) != two_byte_content_[i]) return false;
   16992             :         }
   16993             :         return true;
   16994             :       }
   16995             :     }
   16996             :   }
   16997             : 
   16998           0 :   MUST_USE_RESULT Handle<String> AsHandle(Isolate* isolate) override {
   16999           0 :     UNREACHABLE();
   17000             :   }
   17001             : 
   17002             :  private:
   17003             :   String* string_;
   17004             :   bool one_byte_;
   17005             :   bool special_flattening_;
   17006             :   union {
   17007             :     uint8_t* one_byte_content_;
   17008             :     uint16_t* two_byte_content_;
   17009             :   };
   17010             : };
   17011             : 
   17012             : }  // namespace
   17013             : 
   17014             : // static
   17015       47085 : Object* StringTable::LookupStringIfExists_NoAllocate(String* string) {
   17016             :   DisallowHeapAllocation no_gc;
   17017       47085 :   Heap* heap = string->GetHeap();
   17018             :   Isolate* isolate = heap->isolate();
   17019             :   StringTable* table = heap->string_table();
   17020             : 
   17021       47085 :   StringTableNoAllocateKey key(string, heap->HashSeed());
   17022             : 
   17023             :   // String could be an array index.
   17024             :   uint32_t hash = string->hash_field();
   17025             : 
   17026             :   // Valid array indices are >= 0, so they cannot be mixed up with any of
   17027             :   // the result sentinels, which are negative.
   17028             :   STATIC_ASSERT(
   17029             :       !String::ArrayIndexValueBits::is_valid(ResultSentinel::kUnsupported));
   17030             :   STATIC_ASSERT(
   17031             :       !String::ArrayIndexValueBits::is_valid(ResultSentinel::kNotFound));
   17032             : 
   17033       47085 :   if (Name::ContainsCachedArrayIndex(hash)) {
   17034          12 :     return Smi::FromInt(String::ArrayIndexValueBits::decode(hash));
   17035             :   }
   17036       47079 :   if ((hash & Name::kIsNotArrayIndexMask) == 0) {
   17037             :     // It is an indexed, but it's not cached.
   17038             :     return Smi::FromInt(ResultSentinel::kUnsupported);
   17039             :   }
   17040             : 
   17041       47062 :   int entry = table->FindEntry(isolate, &key, key.Hash());
   17042       47062 :   if (entry != kNotFound) {
   17043             :     String* internalized = String::cast(table->KeyAt(entry));
   17044       46821 :     if (FLAG_thin_strings) {
   17045       46821 :       MakeStringThin(string, internalized, isolate);
   17046             :     }
   17047       46821 :     return internalized;
   17048             :   }
   17049             :   // A string that's not an array index, and not in the string table,
   17050             :   // cannot have been used as a property name before.
   17051       47085 :   return Smi::FromInt(ResultSentinel::kNotFound);
   17052             : }
   17053             : 
   17054        8735 : String* StringTable::LookupKeyIfExists(Isolate* isolate, StringTableKey* key) {
   17055             :   Handle<StringTable> table = isolate->factory()->string_table();
   17056        8735 :   int entry = table->FindEntry(isolate, key);
   17057       11155 :   if (entry != kNotFound) return String::cast(table->KeyAt(entry));
   17058             :   return nullptr;
   17059             : }
   17060             : 
   17061      130903 : Handle<StringSet> StringSet::New(Isolate* isolate) {
   17062      130903 :   return HashTable::New(isolate, 0);
   17063             : }
   17064             : 
   17065     1769226 : Handle<StringSet> StringSet::Add(Handle<StringSet> stringset,
   17066             :                                  Handle<String> name) {
   17067     1769226 :   if (!stringset->Has(name)) {
   17068      119578 :     stringset = EnsureCapacity(stringset, 1);
   17069             :     uint32_t hash = ShapeT::Hash(name->GetIsolate(), *name);
   17070      119578 :     int entry = stringset->FindInsertionEntry(hash);
   17071      119578 :     stringset->set(EntryToIndex(entry), *name);
   17072      119578 :     stringset->ElementAdded();
   17073             :   }
   17074     1769226 :   return stringset;
   17075             : }
   17076             : 
   17077     1782602 : bool StringSet::Has(Handle<String> name) {
   17078     1782602 :   return FindEntry(*name) != kNotFound;
   17079             : }
   17080             : 
   17081       59909 : Handle<ObjectHashSet> ObjectHashSet::Add(Handle<ObjectHashSet> set,
   17082             :                                          Handle<Object> key) {
   17083             :   Isolate* isolate = set->GetIsolate();
   17084       59909 :   int32_t hash = key->GetOrCreateHash(isolate)->value();
   17085       59909 :   if (!set->Has(isolate, key, hash)) {
   17086       58240 :     set = EnsureCapacity(set, 1);
   17087      116480 :     int entry = set->FindInsertionEntry(hash);
   17088       58240 :     set->set(EntryToIndex(entry), *key);
   17089       58240 :     set->ElementAdded();
   17090             :   }
   17091       59909 :   return set;
   17092             : }
   17093             : 
   17094           0 : Handle<Object> CompilationCacheTable::Lookup(Handle<String> src,
   17095             :                                              Handle<Context> context,
   17096             :                                              LanguageMode language_mode) {
   17097             :   Isolate* isolate = GetIsolate();
   17098             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   17099           0 :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17100             :   int entry = FindEntry(&key);
   17101           0 :   if (entry == kNotFound) return isolate->factory()->undefined_value();
   17102             :   int index = EntryToIndex(entry);
   17103           0 :   if (!get(index)->IsFixedArray()) return isolate->factory()->undefined_value();
   17104           0 :   return Handle<Object>(get(index + 1), isolate);
   17105             : }
   17106             : 
   17107             : namespace {
   17108             : 
   17109             : const int kLiteralEntryLength = 2;
   17110             : const int kLiteralInitialLength = 2;
   17111             : const int kLiteralContextOffset = 0;
   17112             : const int kLiteralLiteralsOffset = 1;
   17113             : 
   17114     3139783 : int SearchLiteralsMapEntry(CompilationCacheTable* cache, int cache_entry,
   17115             :                            Context* native_context) {
   17116             :   DisallowHeapAllocation no_gc;
   17117             :   DCHECK(native_context->IsNativeContext());
   17118             :   Object* obj = cache->get(cache_entry);
   17119             : 
   17120     3139783 :   if (obj->IsFixedArray()) {
   17121             :     FixedArray* literals_map = FixedArray::cast(obj);
   17122             :     int length = literals_map->length();
   17123     6809295 :     for (int i = 0; i < length; i += kLiteralEntryLength) {
   17124     6025971 :       if (WeakCell::cast(literals_map->get(i + kLiteralContextOffset))
   17125             :               ->value() == native_context) {
   17126             :         return i;
   17127             :       }
   17128             :     }
   17129             :   }
   17130             :   return -1;
   17131             : }
   17132             : 
   17133      666274 : void AddToLiteralsMap(Handle<CompilationCacheTable> cache, int cache_entry,
   17134             :                       Handle<Context> native_context, Handle<Cell> literals) {
   17135             :   Isolate* isolate = native_context->GetIsolate();
   17136             :   DCHECK(native_context->IsNativeContext());
   17137             :   STATIC_ASSERT(kLiteralEntryLength == 2);
   17138             :   Handle<FixedArray> new_literals_map;
   17139             :   int entry;
   17140             : 
   17141             :   Object* obj = cache->get(cache_entry);
   17142             : 
   17143     1037930 :   if (!obj->IsFixedArray() || FixedArray::cast(obj)->length() == 0) {
   17144             :     new_literals_map =
   17145      294618 :         isolate->factory()->NewFixedArray(kLiteralInitialLength, TENURED);
   17146             :     entry = 0;
   17147             :   } else {
   17148             :     Handle<FixedArray> old_literals_map(FixedArray::cast(obj), isolate);
   17149      371656 :     entry = SearchLiteralsMapEntry(*cache, cache_entry, *native_context);
   17150      371656 :     if (entry >= 0) {
   17151             :       // Just set the code of the entry.
   17152             :       Handle<WeakCell> literals_cell =
   17153        1968 :           isolate->factory()->NewWeakCell(literals);
   17154        3936 :       old_literals_map->set(entry + kLiteralLiteralsOffset, *literals_cell);
   17155      666274 :       return;
   17156             :     }
   17157             : 
   17158             :     // Can we reuse an entry?
   17159             :     DCHECK_LT(entry, 0);
   17160             :     int length = old_literals_map->length();
   17161     1014330 :     for (int i = 0; i < length; i += kLiteralEntryLength) {
   17162      682851 :       if (WeakCell::cast(old_literals_map->get(i + kLiteralContextOffset))
   17163             :               ->cleared()) {
   17164             :         new_literals_map = old_literals_map;
   17165             :         entry = i;
   17166             :         break;
   17167             :       }
   17168             :     }
   17169             : 
   17170      369688 :     if (entry < 0) {
   17171             :       // Copy old optimized code map and append one new entry.
   17172             :       new_literals_map = isolate->factory()->CopyFixedArrayAndGrow(
   17173      331479 :           old_literals_map, kLiteralEntryLength, TENURED);
   17174             :       entry = old_literals_map->length();
   17175             :     }
   17176             :   }
   17177             : 
   17178      664306 :   Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals);
   17179             :   WeakCell* context_cell = native_context->self_weak_cell();
   17180             : 
   17181      664306 :   new_literals_map->set(entry + kLiteralContextOffset, context_cell);
   17182     1328612 :   new_literals_map->set(entry + kLiteralLiteralsOffset, *literals_cell);
   17183             : 
   17184             : #ifdef DEBUG
   17185             :   for (int i = 0; i < new_literals_map->length(); i += kLiteralEntryLength) {
   17186             :     WeakCell* cell =
   17187             :         WeakCell::cast(new_literals_map->get(i + kLiteralContextOffset));
   17188             :     DCHECK(cell->cleared() || cell->value()->IsNativeContext());
   17189             :     cell = WeakCell::cast(new_literals_map->get(i + kLiteralLiteralsOffset));
   17190             :     DCHECK(cell->cleared() || (cell->value()->IsCell()));
   17191             :   }
   17192             : #endif
   17193             : 
   17194             :   Object* old_literals_map = cache->get(cache_entry);
   17195      664306 :   if (old_literals_map != *new_literals_map) {
   17196      626097 :     cache->set(cache_entry, *new_literals_map);
   17197             :   }
   17198             : }
   17199             : 
   17200     2768127 : Cell* SearchLiteralsMap(CompilationCacheTable* cache, int cache_entry,
   17201             :                         Context* native_context) {
   17202             :   Cell* result = nullptr;
   17203     2768127 :   int entry = SearchLiteralsMapEntry(cache, cache_entry, native_context);
   17204     2768127 :   if (entry >= 0) {
   17205             :     FixedArray* literals_map = FixedArray::cast(cache->get(cache_entry));
   17206             :     DCHECK_LE(entry + kLiteralEntryLength, literals_map->length());
   17207             :     WeakCell* cell =
   17208     2354491 :         WeakCell::cast(literals_map->get(entry + kLiteralLiteralsOffset));
   17209             : 
   17210     2354491 :     result = cell->cleared() ? nullptr : Cell::cast(cell->value());
   17211             :   }
   17212             :   DCHECK(result == nullptr || result->IsCell());
   17213     2768127 :   return result;
   17214             : }
   17215             : 
   17216             : }  // namespace
   17217             : 
   17218      211326 : InfoVectorPair CompilationCacheTable::LookupScript(Handle<String> src,
   17219             :                                                    Handle<Context> context,
   17220             :                                                    LanguageMode language_mode) {
   17221             :   InfoVectorPair empty_result;
   17222             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   17223      211326 :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17224             :   int entry = FindEntry(&key);
   17225      211326 :   if (entry == kNotFound) return empty_result;
   17226             :   int index = EntryToIndex(entry);
   17227       92034 :   if (!get(index)->IsFixedArray()) return empty_result;
   17228       92034 :   Object* obj = get(index + 1);
   17229       92034 :   if (obj->IsSharedFunctionInfo()) {
   17230             :     Cell* literals =
   17231       92034 :         SearchLiteralsMap(this, index + 2, context->native_context());
   17232       92034 :     return InfoVectorPair(SharedFunctionInfo::cast(obj), literals);
   17233             :   }
   17234           0 :   return empty_result;
   17235             : }
   17236             : 
   17237     3620221 : InfoVectorPair CompilationCacheTable::LookupEval(
   17238             :     Handle<String> src, Handle<SharedFunctionInfo> outer_info,
   17239             :     Handle<Context> native_context, LanguageMode language_mode, int position) {
   17240             :   InfoVectorPair empty_result;
   17241     3620221 :   StringSharedKey key(src, outer_info, language_mode, position);
   17242             :   int entry = FindEntry(&key);
   17243     3620221 :   if (entry == kNotFound) return empty_result;
   17244             :   int index = EntryToIndex(entry);
   17245     2849746 :   if (!get(index)->IsFixedArray()) return empty_result;
   17246     2676093 :   Object* obj = get(EntryToIndex(entry) + 1);
   17247     2676093 :   if (obj->IsSharedFunctionInfo()) {
   17248             :     Cell* literals =
   17249     2676093 :         SearchLiteralsMap(this, EntryToIndex(entry) + 2, *native_context);
   17250     2676093 :     return InfoVectorPair(SharedFunctionInfo::cast(obj), literals);
   17251             :   }
   17252           0 :   return empty_result;
   17253             : }
   17254             : 
   17255      808106 : Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src,
   17256             :                                                    JSRegExp::Flags flags) {
   17257             :   Isolate* isolate = GetIsolate();
   17258             :   DisallowHeapAllocation no_allocation;
   17259             :   RegExpKey key(src, flags);
   17260             :   int entry = FindEntry(&key);
   17261     1398708 :   if (entry == kNotFound) return isolate->factory()->undefined_value();
   17262      435008 :   return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
   17263             : }
   17264             : 
   17265             : 
   17266           0 : Handle<CompilationCacheTable> CompilationCacheTable::Put(
   17267             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   17268             :     Handle<Context> context, LanguageMode language_mode, Handle<Object> value) {
   17269             :   Isolate* isolate = cache->GetIsolate();
   17270             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   17271           0 :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17272           0 :   Handle<Object> k = key.AsHandle(isolate);
   17273           0 :   cache = EnsureCapacity(cache, 1);
   17274           0 :   int entry = cache->FindInsertionEntry(key.Hash());
   17275           0 :   cache->set(EntryToIndex(entry), *k);
   17276           0 :   cache->set(EntryToIndex(entry) + 1, *value);
   17277           0 :   cache->ElementAdded();
   17278           0 :   return cache;
   17279             : }
   17280             : 
   17281      118424 : Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
   17282             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   17283             :     Handle<Context> context, LanguageMode language_mode,
   17284             :     Handle<SharedFunctionInfo> value, Handle<Cell> literals) {
   17285             :   Isolate* isolate = cache->GetIsolate();
   17286             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   17287             :   Handle<Context> native_context(context->native_context());
   17288      118424 :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17289      118424 :   Handle<Object> k = key.AsHandle(isolate);
   17290      118424 :   cache = EnsureCapacity(cache, 1);
   17291      236848 :   int entry = cache->FindInsertionEntry(key.Hash());
   17292      118424 :   cache->set(EntryToIndex(entry), *k);
   17293      236848 :   cache->set(EntryToIndex(entry) + 1, *value);
   17294      118424 :   AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, literals);
   17295      118424 :   cache->ElementAdded();
   17296      118424 :   return cache;
   17297             : }
   17298             : 
   17299     1201484 : Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
   17300             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   17301             :     Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
   17302             :     Handle<Context> native_context, Handle<Cell> literals, int position) {
   17303             :   Isolate* isolate = cache->GetIsolate();
   17304     1201484 :   StringSharedKey key(src, outer_info, value->language_mode(), position);
   17305             :   {
   17306     1201484 :     Handle<Object> k = key.AsHandle(isolate);
   17307             :     int entry = cache->FindEntry(&key);
   17308     1201484 :     if (entry != kNotFound) {
   17309      547850 :       cache->set(EntryToIndex(entry), *k);
   17310     1095700 :       cache->set(EntryToIndex(entry) + 1, *value);
   17311             :       // AddToLiteralsMap may allocate a new sub-array to live in the entry,
   17312             :       // but it won't change the cache array. Therefore EntryToIndex and
   17313             :       // entry remains correct.
   17314             :       AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context,
   17315      547850 :                        literals);
   17316      547850 :       return cache;
   17317             :     }
   17318             :   }
   17319             : 
   17320      653634 :   cache = EnsureCapacity(cache, 1);
   17321     1307268 :   int entry = cache->FindInsertionEntry(key.Hash());
   17322             :   Handle<Object> k =
   17323      653634 :       isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
   17324      653634 :   cache->set(EntryToIndex(entry), *k);
   17325             :   cache->set(EntryToIndex(entry) + 1, Smi::FromInt(kHashGenerations));
   17326      653634 :   cache->ElementAdded();
   17327      653634 :   return cache;
   17328             : }
   17329             : 
   17330             : 
   17331      292916 : Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
   17332             :       Handle<CompilationCacheTable> cache, Handle<String> src,
   17333             :       JSRegExp::Flags flags, Handle<FixedArray> value) {
   17334             :   RegExpKey key(src, flags);
   17335      292916 :   cache = EnsureCapacity(cache, 1);
   17336      292916 :   int entry = cache->FindInsertionEntry(key.Hash());
   17337             :   // We store the value in the key slot, and compare the search key
   17338             :   // to the stored value with a custon IsMatch function during lookups.
   17339      292916 :   cache->set(EntryToIndex(entry), *value);
   17340      585832 :   cache->set(EntryToIndex(entry) + 1, *value);
   17341      292916 :   cache->ElementAdded();
   17342      292916 :   return cache;
   17343             : }
   17344             : 
   17345             : 
   17346       37857 : void CompilationCacheTable::Age() {
   17347             :   DisallowHeapAllocation no_allocation;
   17348       37857 :   Object* the_hole_value = GetHeap()->the_hole_value();
   17349     7196718 :   for (int entry = 0, size = Capacity(); entry < size; entry++) {
   17350             :     int entry_index = EntryToIndex(entry);
   17351     7121004 :     int value_index = entry_index + 1;
   17352             : 
   17353     7121004 :     if (get(entry_index)->IsNumber()) {
   17354             :       Smi* count = Smi::cast(get(value_index));
   17355      735170 :       count = Smi::FromInt(count->value() - 1);
   17356      735170 :       if (count->value() == 0) {
   17357             :         NoWriteBarrierSet(this, entry_index, the_hole_value);
   17358             :         NoWriteBarrierSet(this, value_index, the_hole_value);
   17359       16767 :         ElementRemoved();
   17360             :       } else {
   17361             :         NoWriteBarrierSet(this, value_index, count);
   17362             :       }
   17363     6385834 :     } else if (get(entry_index)->IsFixedArray()) {
   17364             :       SharedFunctionInfo* info = SharedFunctionInfo::cast(get(value_index));
   17365      831478 :       if (info->IsInterpreted() && info->bytecode_array()->IsOld()) {
   17366       24222 :         for (int i = 0; i < kEntrySize; i++) {
   17367       24222 :           NoWriteBarrierSet(this, entry_index + i, the_hole_value);
   17368             :         }
   17369        8074 :         ElementRemoved();
   17370             :       }
   17371             :     }
   17372             :   }
   17373       37857 : }
   17374             : 
   17375             : 
   17376           0 : void CompilationCacheTable::Remove(Object* value) {
   17377             :   DisallowHeapAllocation no_allocation;
   17378           0 :   Object* the_hole_value = GetHeap()->the_hole_value();
   17379           0 :   for (int entry = 0, size = Capacity(); entry < size; entry++) {
   17380             :     int entry_index = EntryToIndex(entry);
   17381           0 :     int value_index = entry_index + 1;
   17382           0 :     if (get(value_index) == value) {
   17383           0 :       for (int i = 0; i < kEntrySize; i++) {
   17384           0 :         NoWriteBarrierSet(this, entry_index + i, the_hole_value);
   17385             :       }
   17386           0 :       ElementRemoved();
   17387             :     }
   17388             :   }
   17389           0 :   return;
   17390             : }
   17391             : 
   17392             : template <typename Derived, typename Shape>
   17393     1030413 : Handle<Derived> BaseNameDictionary<Derived, Shape>::New(
   17394             :     Isolate* isolate, int at_least_space_for, PretenureFlag pretenure,
   17395             :     MinimumCapacity capacity_option) {
   17396             :   DCHECK_LE(0, at_least_space_for);
   17397             :   Handle<Derived> dict = Dictionary<Derived, Shape>::New(
   17398     1030413 :       isolate, at_least_space_for, pretenure, capacity_option);
   17399             :   dict->SetHash(PropertyArray::kNoHashSentinel);
   17400             :   dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
   17401     1030413 :   return dict;
   17402             : }
   17403             : 
   17404             : template <typename Derived, typename Shape>
   17405    18842142 : Handle<Derived> BaseNameDictionary<Derived, Shape>::EnsureCapacity(
   17406             :     Handle<Derived> dictionary, int n) {
   17407             :   // Check whether there are enough enumeration indices to add n elements.
   17408    37684284 :   if (!PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) {
   17409             :     // If not, we generate new indices for the properties.
   17410             :     int length = dictionary->NumberOfElements();
   17411             : 
   17412           0 :     Handle<FixedArray> iteration_order = IterationIndices(dictionary);
   17413             :     DCHECK_EQ(length, iteration_order->length());
   17414             : 
   17415             :     // Iterate over the dictionary using the enumeration order and update
   17416             :     // the dictionary with new enumeration indices.
   17417           0 :     for (int i = 0; i < length; i++) {
   17418             :       int index = Smi::ToInt(iteration_order->get(i));
   17419             :       DCHECK(dictionary->IsKey(dictionary->GetIsolate(),
   17420             :                                dictionary->KeyAt(index)));
   17421             : 
   17422           0 :       int enum_index = PropertyDetails::kInitialIndex + i;
   17423             : 
   17424             :       PropertyDetails details = dictionary->DetailsAt(index);
   17425             :       PropertyDetails new_details = details.set_index(enum_index);
   17426             :       dictionary->DetailsAtPut(index, new_details);
   17427             :     }
   17428             : 
   17429             :     // Set the next enumeration index.
   17430           0 :     dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex +
   17431             :                                         length);
   17432             :   }
   17433    18842142 :   return HashTable<Derived, Shape>::EnsureCapacity(dictionary, n);
   17434             : }
   17435             : 
   17436             : template <typename Derived, typename Shape>
   17437       82841 : Handle<Derived> Dictionary<Derived, Shape>::DeleteEntry(
   17438             :     Handle<Derived> dictionary, int entry) {
   17439             :   DCHECK(Shape::kEntrySize != 3 ||
   17440             :          dictionary->DetailsAt(entry).IsConfigurable());
   17441       82841 :   dictionary->ClearEntry(entry);
   17442       82841 :   dictionary->ElementRemoved();
   17443       82841 :   return Shrink(dictionary);
   17444             : }
   17445             : 
   17446             : template <typename Derived, typename Shape>
   17447      501034 : Handle<Derived> Dictionary<Derived, Shape>::AtPut(Handle<Derived> dictionary,
   17448             :                                                   Key key, Handle<Object> value,
   17449             :                                                   PropertyDetails details) {
   17450             :   int entry = dictionary->FindEntry(key);
   17451             : 
   17452             :   // If the entry is present set the value;
   17453      501034 :   if (entry == Dictionary::kNotFound) {
   17454      499565 :     return Derived::Add(dictionary, key, value, details);
   17455             :   }
   17456             : 
   17457             :   // We don't need to copy over the enumeration index.
   17458             :   dictionary->ValueAtPut(entry, *value);
   17459             :   if (Shape::kEntrySize == 3) dictionary->DetailsAtPut(entry, details);
   17460        1469 :   return dictionary;
   17461             : }
   17462             : 
   17463             : template <typename Derived, typename Shape>
   17464    18842142 : Handle<Derived> BaseNameDictionary<Derived, Shape>::Add(
   17465             :     Handle<Derived> dictionary, Key key, Handle<Object> value,
   17466             :     PropertyDetails details, int* entry_out) {
   17467             :   // Insert element at empty or deleted entry
   17468             :   DCHECK_EQ(0, details.dictionary_index());
   17469             :   // Assign an enumeration index to the property and update
   17470             :   // SetNextEnumerationIndex.
   17471             :   int index = dictionary->NextEnumerationIndex();
   17472             :   details = details.set_index(index);
   17473    18842142 :   dictionary->SetNextEnumerationIndex(index + 1);
   17474             :   return Dictionary<Derived, Shape>::Add(dictionary, key, value, details,
   17475    18842142 :                                          entry_out);
   17476             : }
   17477             : 
   17478             : template <typename Derived, typename Shape>
   17479    23270428 : Handle<Derived> Dictionary<Derived, Shape>::Add(Handle<Derived> dictionary,
   17480             :                                                 Key key, Handle<Object> value,
   17481             :                                                 PropertyDetails details,
   17482             :                                                 int* entry_out) {
   17483             :   Isolate* isolate = dictionary->GetIsolate();
   17484    23168086 :   uint32_t hash = Shape::Hash(isolate, key);
   17485             :   // Valdate key is absent.
   17486             :   SLOW_DCHECK((dictionary->FindEntry(key) == Dictionary::kNotFound));
   17487             :   // Check whether the dictionary should be extended.
   17488    23270428 :   dictionary = Derived::EnsureCapacity(dictionary, 1);
   17489             : 
   17490             :   // Compute the key object.
   17491             :   Handle<Object> k = Shape::AsHandle(isolate, key);
   17492             : 
   17493    23270428 :   uint32_t entry = dictionary->FindInsertionEntry(hash);
   17494    46540856 :   dictionary->SetEntry(entry, *k, *value, details);
   17495             :   DCHECK(dictionary->KeyAt(entry)->IsNumber() ||
   17496             :          Shape::Unwrap(dictionary->KeyAt(entry))->IsUniqueName());
   17497    23270428 :   dictionary->ElementAdded();
   17498    23270428 :   if (entry_out) *entry_out = entry;
   17499    23270428 :   return dictionary;
   17500             : }
   17501             : 
   17502        6707 : bool SeededNumberDictionary::HasComplexElements() {
   17503        6707 :   if (!requires_slow_elements()) return false;
   17504             :   Isolate* isolate = this->GetIsolate();
   17505             :   int capacity = this->Capacity();
   17506       27285 :   for (int i = 0; i < capacity; i++) {
   17507             :     Object* k;
   17508       37885 :     if (!this->ToKey(isolate, i, &k)) continue;
   17509             :     PropertyDetails details = this->DetailsAt(i);
   17510        9720 :     if (details.kind() == kAccessor) return true;
   17511             :     PropertyAttributes attr = details.attributes();
   17512        9620 :     if (attr & ALL_ATTRIBUTES_MASK) return true;
   17513             :   }
   17514             :   return false;
   17515             : }
   17516             : 
   17517     1884295 : void SeededNumberDictionary::UpdateMaxNumberKey(
   17518             :     uint32_t key, Handle<JSObject> dictionary_holder) {
   17519             :   DisallowHeapAllocation no_allocation;
   17520             :   // If the dictionary requires slow elements an element has already
   17521             :   // been added at a high index.
   17522     1884295 :   if (requires_slow_elements()) return;
   17523             :   // Check if this index is high enough that we should require slow
   17524             :   // elements.
   17525     1834256 :   if (key > kRequiresSlowElementsLimit) {
   17526        4097 :     if (!dictionary_holder.is_null()) {
   17527        3829 :       dictionary_holder->RequireSlowElements(this);
   17528             :     }
   17529             :     set_requires_slow_elements();
   17530             :     return;
   17531             :   }
   17532             :   // Update max key value.
   17533             :   Object* max_index_object = get(kMaxNumberKeyIndex);
   17534     1830159 :   if (!max_index_object->IsSmi() || max_number_key() < key) {
   17535             :     FixedArray::set(kMaxNumberKeyIndex,
   17536     1209660 :                     Smi::FromInt(key << kRequiresSlowElementsTagSize));
   17537             :   }
   17538             : }
   17539             : 
   17540      404612 : Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
   17541             :     Handle<SeededNumberDictionary> dictionary, uint32_t key,
   17542             :     Handle<Object> value, Handle<JSObject> dictionary_holder,
   17543             :     PropertyDetails details) {
   17544      404612 :   dictionary->UpdateMaxNumberKey(key, dictionary_holder);
   17545      404612 :   return AtPut(dictionary, key, value, details);
   17546             : }
   17547             : 
   17548          40 : void SeededNumberDictionary::CopyValuesTo(FixedArray* elements) {
   17549             :   Isolate* isolate = this->GetIsolate();
   17550             :   int pos = 0;
   17551             :   int capacity = this->Capacity();
   17552             :   DisallowHeapAllocation no_gc;
   17553          40 :   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
   17554         680 :   for (int i = 0; i < capacity; i++) {
   17555             :     Object* k;
   17556         640 :     if (this->ToKey(isolate, i, &k)) {
   17557         300 :       elements->set(pos++, this->ValueAt(i), mode);
   17558             :     }
   17559             :   }
   17560             :   DCHECK_EQ(pos, elements->length());
   17561          40 : }
   17562             : 
   17563       96422 : Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
   17564             :     Handle<UnseededNumberDictionary> dictionary,
   17565             :     uint32_t key,
   17566             :     Handle<Object> value) {
   17567       96422 :   return AtPut(dictionary, key, value, PropertyDetails::Empty());
   17568             : }
   17569             : 
   17570             : template <typename Derived, typename Shape>
   17571       87649 : int Dictionary<Derived, Shape>::NumberOfEnumerableProperties() {
   17572             :   Isolate* isolate = this->GetIsolate();
   17573             :   int capacity = this->Capacity();
   17574             :   int result = 0;
   17575     8402185 :   for (int i = 0; i < capacity; i++) {
   17576             :     Object* k;
   17577    12531727 :     if (!this->ToKey(isolate, i, &k)) continue;
   17578     4115883 :     if (k->FilterKey(ENUMERABLE_STRINGS)) continue;
   17579             :     PropertyDetails details = this->DetailsAt(i);
   17580             :     PropertyAttributes attr = details.attributes();
   17581     4097345 :     if ((attr & ONLY_ENUMERABLE) == 0) result++;
   17582             :   }
   17583       87649 :   return result;
   17584             : }
   17585             : 
   17586             : 
   17587             : template <typename Dictionary>
   17588             : struct EnumIndexComparator {
   17589      654657 :   explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {}
   17590    88090467 :   bool operator()(const base::AtomicElement<Smi*>& a,
   17591             :                   const base::AtomicElement<Smi*>& b) {
   17592    88090467 :     PropertyDetails da(dict->DetailsAt(a.value()->value()));
   17593    88090467 :     PropertyDetails db(dict->DetailsAt(b.value()->value()));
   17594    88090467 :     return da.dictionary_index() < db.dictionary_index();
   17595             :   }
   17596             :   Dictionary* dict;
   17597             : };
   17598             : 
   17599             : template <typename Derived, typename Shape>
   17600       86823 : void BaseNameDictionary<Derived, Shape>::CopyEnumKeysTo(
   17601             :     Handle<Derived> dictionary, Handle<FixedArray> storage,
   17602             :     KeyCollectionMode mode, KeyAccumulator* accumulator) {
   17603             :   DCHECK_IMPLIES(mode != KeyCollectionMode::kOwnOnly, accumulator != nullptr);
   17604             :   Isolate* isolate = dictionary->GetIsolate();
   17605             :   int length = storage->length();
   17606             :   int capacity = dictionary->Capacity();
   17607             :   int properties = 0;
   17608     8355210 :   for (int i = 0; i < capacity; i++) {
   17609             :     Object* key;
   17610    13508466 :     if (!dictionary->ToKey(isolate, i, &key)) continue;
   17611             :     bool is_shadowing_key = false;
   17612     8227624 :     if (key->IsSymbol()) continue;
   17613             :     PropertyDetails details = dictionary->DetailsAt(i);
   17614     4095426 :     if (details.IsDontEnum()) {
   17615     1017638 :       if (mode == KeyCollectionMode::kIncludePrototypes) {
   17616             :         is_shadowing_key = true;
   17617             :       } else {
   17618             :         continue;
   17619             :       }
   17620             :     }
   17621     3090978 :     if (is_shadowing_key) {
   17622       13190 :       accumulator->AddShadowingKey(key);
   17623       13190 :       continue;
   17624             :     } else {
   17625             :       storage->set(properties, Smi::FromInt(i));
   17626             :     }
   17627     3077788 :     properties++;
   17628     3077788 :     if (mode == KeyCollectionMode::kOwnOnly && properties == length) break;
   17629             :   }
   17630             : 
   17631       86823 :   CHECK_EQ(length, properties);
   17632             :   DisallowHeapAllocation no_gc;
   17633             :   Derived* raw_dictionary = *dictionary;
   17634             :   FixedArray* raw_storage = *storage;
   17635             :   EnumIndexComparator<Derived> cmp(raw_dictionary);
   17636             :   // Use AtomicElement wrapper to ensure that std::sort uses atomic load and
   17637             :   // store operations that are safe for concurrent marking.
   17638             :   base::AtomicElement<Smi*>* start =
   17639             :       reinterpret_cast<base::AtomicElement<Smi*>*>(
   17640       86823 :           storage->GetFirstElementAddress());
   17641       86823 :   std::sort(start, start + length, cmp);
   17642     3164611 :   for (int i = 0; i < length; i++) {
   17643             :     int index = Smi::ToInt(raw_storage->get(i));
   17644     3077788 :     raw_storage->set(i, raw_dictionary->NameAt(index));
   17645             :   }
   17646       86823 : }
   17647             : 
   17648             : template <typename Derived, typename Shape>
   17649      528179 : Handle<FixedArray> BaseNameDictionary<Derived, Shape>::IterationIndices(
   17650             :     Handle<Derived> dictionary) {
   17651             :   Isolate* isolate = dictionary->GetIsolate();
   17652             :   int capacity = dictionary->Capacity();
   17653             :   int length = dictionary->NumberOfElements();
   17654      528179 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
   17655             :   int array_size = 0;
   17656             :   {
   17657             :     DisallowHeapAllocation no_gc;
   17658             :     Derived* raw_dictionary = *dictionary;
   17659    16440735 :     for (int i = 0; i < capacity; i++) {
   17660             :       Object* k;
   17661    25232531 :       if (!raw_dictionary->ToKey(isolate, i, &k)) continue;
   17662     6592581 :       array->set(array_size++, Smi::FromInt(i));
   17663             :     }
   17664             : 
   17665             :     DCHECK_EQ(array_size, length);
   17666             : 
   17667             :     EnumIndexComparator<Derived> cmp(raw_dictionary);
   17668             :     // Use AtomicElement wrapper to ensure that std::sort uses atomic load and
   17669             :     // store operations that are safe for concurrent marking.
   17670             :     base::AtomicElement<Smi*>* start =
   17671             :         reinterpret_cast<base::AtomicElement<Smi*>*>(
   17672      528179 :             array->GetFirstElementAddress());
   17673      528179 :     std::sort(start, start + array_size, cmp);
   17674             :   }
   17675      528179 :   array->Shrink(array_size);
   17676      528179 :   return array;
   17677             : }
   17678             : 
   17679             : template <typename Derived, typename Shape>
   17680       39655 : void BaseNameDictionary<Derived, Shape>::CollectKeysTo(
   17681             :     Handle<Derived> dictionary, KeyAccumulator* keys) {
   17682             :   Isolate* isolate = keys->isolate();
   17683             :   int capacity = dictionary->Capacity();
   17684             :   Handle<FixedArray> array =
   17685       39655 :       isolate->factory()->NewFixedArray(dictionary->NumberOfElements());
   17686             :   int array_size = 0;
   17687             :   PropertyFilter filter = keys->filter();
   17688             :   {
   17689             :     DisallowHeapAllocation no_gc;
   17690             :     Derived* raw_dictionary = *dictionary;
   17691    10079431 :     for (int i = 0; i < capacity; i++) {
   17692             :       Object* k;
   17693    17569989 :       if (!raw_dictionary->ToKey(isolate, i, &k)) continue;
   17694     4681625 :       if (k->FilterKey(filter)) continue;
   17695             :       PropertyDetails details = raw_dictionary->DetailsAt(i);
   17696     2510459 :       if ((details.attributes() & filter) != 0) {
   17697         550 :         keys->AddShadowingKey(k);
   17698         550 :         continue;
   17699             :       }
   17700     2509909 :       if (filter & ONLY_ALL_CAN_READ) {
   17701         362 :         if (details.kind() != kAccessor) continue;
   17702           0 :         Object* accessors = raw_dictionary->ValueAt(i);
   17703          26 :         if (!accessors->IsAccessorInfo()) continue;
   17704          26 :         if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
   17705             :       }
   17706     2509563 :       array->set(array_size++, Smi::FromInt(i));
   17707             :     }
   17708             : 
   17709             :     EnumIndexComparator<Derived> cmp(raw_dictionary);
   17710             :     // Use AtomicElement wrapper to ensure that std::sort uses atomic load and
   17711             :     // store operations that are safe for concurrent marking.
   17712             :     base::AtomicElement<Smi*>* start =
   17713             :         reinterpret_cast<base::AtomicElement<Smi*>*>(
   17714       39655 :             array->GetFirstElementAddress());
   17715       39655 :     std::sort(start, start + array_size, cmp);
   17716             :   }
   17717             : 
   17718             :   bool has_seen_symbol = false;
   17719     2549218 :   for (int i = 0; i < array_size; i++) {
   17720             :     int index = Smi::ToInt(array->get(i));
   17721             :     Object* key = dictionary->NameAt(index);
   17722     2509563 :     if (key->IsSymbol()) {
   17723             :       has_seen_symbol = true;
   17724             :       continue;
   17725             :     }
   17726     2491357 :     keys->AddKey(key, DO_NOT_CONVERT);
   17727             :   }
   17728       39655 :   if (has_seen_symbol) {
   17729       23988 :     for (int i = 0; i < array_size; i++) {
   17730             :       int index = Smi::ToInt(array->get(i));
   17731             :       Object* key = dictionary->NameAt(index);
   17732       23988 :       if (!key->IsSymbol()) continue;
   17733       18206 :       keys->AddKey(key, DO_NOT_CONVERT);
   17734             :     }
   17735             :   }
   17736       39655 : }
   17737             : 
   17738             : // Backwards lookup (slow).
   17739             : template <typename Derived, typename Shape>
   17740          10 : Object* Dictionary<Derived, Shape>::SlowReverseLookup(Object* value) {
   17741             :   Derived* dictionary = Derived::cast(this);
   17742             :   Isolate* isolate = dictionary->GetIsolate();
   17743             :   int capacity = dictionary->Capacity();
   17744        2570 :   for (int i = 0; i < capacity; i++) {
   17745             :     Object* k;
   17746        4060 :     if (!dictionary->ToKey(isolate, i, &k)) continue;
   17747           0 :     Object* e = dictionary->ValueAt(i);
   17748        1060 :     if (e == value) return k;
   17749             :   }
   17750          10 :   return isolate->heap()->undefined_value();
   17751             : }
   17752             : 
   17753             : 
   17754       35159 : Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key,
   17755             :                                 int32_t hash) {
   17756             :   DisallowHeapAllocation no_gc;
   17757             :   DCHECK(IsKey(isolate, *key));
   17758             : 
   17759       35159 :   int entry = FindEntry(isolate, key, hash);
   17760       35159 :   if (entry == kNotFound) return isolate->heap()->the_hole_value();
   17761       68574 :   return get(EntryToIndex(entry) + 1);
   17762             : }
   17763             : 
   17764             : 
   17765       35781 : Object* ObjectHashTable::Lookup(Handle<Object> key) {
   17766             :   DisallowHeapAllocation no_gc;
   17767             : 
   17768             :   Isolate* isolate = GetIsolate();
   17769             :   DCHECK(IsKey(isolate, *key));
   17770             : 
   17771             :   // If the object does not have an identity hash, it was never used as a key.
   17772       35781 :   Object* hash = key->GetHash();
   17773       35781 :   if (hash->IsUndefined(isolate)) {
   17774         622 :     return isolate->heap()->the_hole_value();
   17775             :   }
   17776       35159 :   return Lookup(isolate, key, Smi::ToInt(hash));
   17777             : }
   17778             : 
   17779         148 : Object* ObjectHashTable::ValueAt(int entry) {
   17780         148 :   return get(EntryToValueIndex(entry));
   17781             : }
   17782             : 
   17783           0 : Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) {
   17784           0 :   return Lookup(GetIsolate(), key, hash);
   17785             : }
   17786             : 
   17787             : 
   17788       32341 : Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
   17789             :                                              Handle<Object> key,
   17790             :                                              Handle<Object> value) {
   17791             :   Isolate* isolate = table->GetIsolate();
   17792             :   DCHECK(table->IsKey(isolate, *key));
   17793             :   DCHECK(!value->IsTheHole(isolate));
   17794             : 
   17795             :   // Make sure the key object has an identity hash code.
   17796       32341 :   int32_t hash = key->GetOrCreateHash(isolate)->value();
   17797             : 
   17798       32341 :   return Put(table, key, value, hash);
   17799             : }
   17800             : 
   17801             : 
   17802       34558 : Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
   17803             :                                              Handle<Object> key,
   17804             :                                              Handle<Object> value,
   17805             :                                              int32_t hash) {
   17806             :   Isolate* isolate = table->GetIsolate();
   17807             :   DCHECK(table->IsKey(isolate, *key));
   17808             :   DCHECK(!value->IsTheHole(isolate));
   17809             : 
   17810       34558 :   int entry = table->FindEntry(isolate, key, hash);
   17811             : 
   17812             :   // Key is already in table, just overwrite value.
   17813       34558 :   if (entry != kNotFound) {
   17814        1036 :     table->set(EntryToIndex(entry) + 1, *value);
   17815         518 :     return table;
   17816             :   }
   17817             : 
   17818             :   // Rehash if more than 33% of the entries are deleted entries.
   17819             :   // TODO(jochen): Consider to shrink the fixed array in place.
   17820       68080 :   if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) {
   17821           6 :     table->Rehash();
   17822             :   }
   17823             :   // If we're out of luck, we didn't get a GC recently, and so rehashing
   17824             :   // isn't enough to avoid a crash.
   17825       34040 :   if (!table->HasSufficientCapacityToAdd(1)) {
   17826         285 :     int nof = table->NumberOfElements() + 1;
   17827         285 :     int capacity = ObjectHashTable::ComputeCapacity(nof * 2);
   17828         285 :     if (capacity > ObjectHashTable::kMaxCapacity) {
   17829           0 :       for (size_t i = 0; i < 2; ++i) {
   17830             :         isolate->heap()->CollectAllGarbage(
   17831             :             Heap::kFinalizeIncrementalMarkingMask,
   17832           0 :             GarbageCollectionReason::kFullHashtable);
   17833             :       }
   17834           0 :       table->Rehash();
   17835             :     }
   17836             :   }
   17837             : 
   17838             :   // Check whether the hash table should be extended.
   17839       34040 :   table = EnsureCapacity(table, 1);
   17840      102120 :   table->AddEntry(table->FindInsertionEntry(hash), *key, *value);
   17841       34040 :   return table;
   17842             : }
   17843             : 
   17844             : 
   17845           6 : Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
   17846             :                                                 Handle<Object> key,
   17847             :                                                 bool* was_present) {
   17848             :   DCHECK(table->IsKey(table->GetIsolate(), *key));
   17849             : 
   17850           6 :   Object* hash = key->GetHash();
   17851           6 :   if (hash->IsUndefined(table->GetIsolate())) {
   17852           0 :     *was_present = false;
   17853           0 :     return table;
   17854             :   }
   17855             : 
   17856           6 :   return Remove(table, key, was_present, Smi::ToInt(hash));
   17857             : }
   17858             : 
   17859             : 
   17860          83 : Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
   17861             :                                                 Handle<Object> key,
   17862             :                                                 bool* was_present,
   17863             :                                                 int32_t hash) {
   17864             :   Isolate* isolate = table->GetIsolate();
   17865             :   DCHECK(table->IsKey(isolate, *key));
   17866             : 
   17867          83 :   int entry = table->FindEntry(isolate, key, hash);
   17868          83 :   if (entry == kNotFound) {
   17869           0 :     *was_present = false;
   17870           0 :     return table;
   17871             :   }
   17872             : 
   17873          83 :   *was_present = true;
   17874          83 :   table->RemoveEntry(entry);
   17875             :   return Shrink(table);
   17876             : }
   17877             : 
   17878             : 
   17879       34040 : void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
   17880       34040 :   set(EntryToIndex(entry), key);
   17881       34040 :   set(EntryToIndex(entry) + 1, value);
   17882       34040 :   ElementAdded();
   17883       34040 : }
   17884             : 
   17885             : 
   17886         173 : void ObjectHashTable::RemoveEntry(int entry) {
   17887         173 :   set_the_hole(EntryToIndex(entry));
   17888         173 :   set_the_hole(EntryToIndex(entry) + 1);
   17889         173 :   ElementRemoved();
   17890         173 : }
   17891             : 
   17892             : 
   17893      491672 : Object* WeakHashTable::Lookup(Handle<HeapObject> key) {
   17894             :   DisallowHeapAllocation no_gc;
   17895             :   Isolate* isolate = GetIsolate();
   17896             :   DCHECK(IsKey(isolate, *key));
   17897             :   int entry = FindEntry(key);
   17898      491672 :   if (entry == kNotFound) return isolate->heap()->the_hole_value();
   17899      380578 :   return get(EntryToValueIndex(entry));
   17900             : }
   17901             : 
   17902             : 
   17903      491672 : Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table,
   17904             :                                          Handle<HeapObject> key,
   17905             :                                          Handle<HeapObject> value) {
   17906             :   Isolate* isolate = key->GetIsolate();
   17907             :   DCHECK(table->IsKey(isolate, *key));
   17908             :   int entry = table->FindEntry(key);
   17909             :   // Key is already in table, just overwrite value.
   17910      491672 :   if (entry != kNotFound) {
   17911      380578 :     table->set(EntryToValueIndex(entry), *value);
   17912      380578 :     return table;
   17913             :   }
   17914             : 
   17915      111094 :   Handle<WeakCell> key_cell = isolate->factory()->NewWeakCell(key);
   17916             : 
   17917             :   // Check whether the hash table should be extended.
   17918      111094 :   table = EnsureCapacity(table, 1, TENURED);
   17919             : 
   17920      111094 :   uint32_t hash = ShapeT::Hash(isolate, key);
   17921      222188 :   table->AddEntry(table->FindInsertionEntry(hash), key_cell, value);
   17922      111094 :   return table;
   17923             : }
   17924             : 
   17925             : 
   17926      111094 : void WeakHashTable::AddEntry(int entry, Handle<WeakCell> key_cell,
   17927             :                              Handle<HeapObject> value) {
   17928             :   DisallowHeapAllocation no_allocation;
   17929      111094 :   set(EntryToIndex(entry), *key_cell);
   17930      111094 :   set(EntryToValueIndex(entry), *value);
   17931      111094 :   ElementAdded();
   17932      111094 : }
   17933             : 
   17934             : template <class Derived, int entrysize>
   17935     5630890 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate(
   17936             :     Isolate* isolate, int capacity, PretenureFlag pretenure) {
   17937             :   // Capacity must be a power of two, since we depend on being able
   17938             :   // to divide and multiple by 2 (kLoadFactor) to derive capacity
   17939             :   // from number of buckets. If we decide to change kLoadFactor
   17940             :   // to something other than 2, capacity should be stored as another
   17941             :   // field of this object.
   17942     5630890 :   capacity = base::bits::RoundUpToPowerOfTwo32(Max(kMinCapacity, capacity));
   17943     5630890 :   if (capacity > kMaxCapacity) {
   17944           0 :     v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
   17945             :   }
   17946     5630890 :   int num_buckets = capacity / kLoadFactor;
   17947             :   Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray(
   17948     5630890 :       kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure);
   17949             :   backing_store->set_map_no_write_barrier(
   17950     5630890 :       isolate->heap()->ordered_hash_table_map());
   17951             :   Handle<Derived> table = Handle<Derived>::cast(backing_store);
   17952    53184620 :   for (int i = 0; i < num_buckets; ++i) {
   17953             :     table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound));
   17954             :   }
   17955             :   table->SetNumberOfBuckets(num_buckets);
   17956             :   table->SetNumberOfElements(0);
   17957             :   table->SetNumberOfDeletedElements(0);
   17958     5630890 :   return table;
   17959             : }
   17960             : 
   17961             : template <class Derived, int entrysize>
   17962    46792909 : Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable(
   17963             :     Handle<Derived> table) {
   17964             :   DCHECK(!table->IsObsolete());
   17965             : 
   17966             :   int nof = table->NumberOfElements();
   17967             :   int nod = table->NumberOfDeletedElements();
   17968             :   int capacity = table->Capacity();
   17969    46792909 :   if ((nof + nod) < capacity) return table;
   17970             :   // Don't need to grow if we can simply clear out deleted entries instead.
   17971             :   // Note that we can't compact in place, though, so we always allocate
   17972             :   // a new table.
   17973      119313 :   return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity);
   17974             : }
   17975             : 
   17976             : template <class Derived, int entrysize>
   17977      135127 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink(
   17978             :     Handle<Derived> table) {
   17979             :   DCHECK(!table->IsObsolete());
   17980             : 
   17981             :   int nof = table->NumberOfElements();
   17982             :   int capacity = table->Capacity();
   17983      135127 :   if (nof >= (capacity >> 2)) return table;
   17984      135127 :   return Rehash(table, capacity / 2);
   17985             : }
   17986             : 
   17987             : template <class Derived, int entrysize>
   17988         236 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Clear(
   17989             :     Handle<Derived> table) {
   17990             :   DCHECK(!table->IsObsolete());
   17991             : 
   17992             :   Handle<Derived> new_table =
   17993             :       Allocate(table->GetIsolate(),
   17994             :                kMinCapacity,
   17995         472 :                table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
   17996             : 
   17997             :   table->SetNextTable(*new_table);
   17998             :   table->SetNumberOfDeletedElements(kClearedTableSentinel);
   17999             : 
   18000         236 :   return new_table;
   18001             : }
   18002             : 
   18003             : template <class Derived, int entrysize>
   18004         534 : bool OrderedHashTable<Derived, entrysize>::HasKey(Isolate* isolate,
   18005             :                                                   Derived* table, Object* key) {
   18006             :   DCHECK(table->IsOrderedHashTable());
   18007             :   DisallowHeapAllocation no_gc;
   18008         534 :   int entry = table->FindEntry(isolate, key);
   18009         534 :   return entry != kNotFound;
   18010             : }
   18011             : 
   18012    46781832 : Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
   18013             :                                            Handle<Object> key) {
   18014    46781832 :   int hash = key->GetOrCreateHash(table->GetIsolate())->value();
   18015    46781832 :   int entry = table->HashToEntry(hash);
   18016             :   // Walk the chain of the bucket and try finding the key.
   18017   112731962 :   while (entry != kNotFound) {
   18018    19168857 :     Object* candidate_key = table->KeyAt(entry);
   18019             :     // Do not add if we have the key already
   18020    19168857 :     if (candidate_key->SameValueZero(*key)) return table;
   18021    19168298 :     entry = table->NextChainEntry(entry);
   18022             :   }
   18023             : 
   18024    46781273 :   table = OrderedHashSet::EnsureGrowable(table);
   18025             :   // Read the existing bucket values.
   18026             :   int bucket = table->HashToBucket(hash);
   18027    46781273 :   int previous_entry = table->HashToEntry(hash);
   18028             :   int nof = table->NumberOfElements();
   18029             :   // Insert a new entry at the end,
   18030    46781273 :   int new_entry = nof + table->NumberOfDeletedElements();
   18031             :   int new_index = table->EntryToIndex(new_entry);
   18032    46781273 :   table->set(new_index, *key);
   18033             :   table->set(new_index + kChainOffset, Smi::FromInt(previous_entry));
   18034             :   // and point the bucket to the new entry.
   18035             :   table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
   18036    46781273 :   table->SetNumberOfElements(nof + 1);
   18037    46781273 :   return table;
   18038             : }
   18039             : 
   18040     5375650 : Handle<FixedArray> OrderedHashSet::ConvertToKeysArray(
   18041             :     Handle<OrderedHashSet> table, GetKeysConversion convert) {
   18042             :   Isolate* isolate = table->GetIsolate();
   18043             :   int length = table->NumberOfElements();
   18044             :   int nof_buckets = table->NumberOfBuckets();
   18045             :   // Convert the dictionary to a linear list.
   18046             :   Handle<FixedArray> result = Handle<FixedArray>::cast(table);
   18047             :   // From this point on table is no longer a valid OrderedHashSet.
   18048    10751300 :   result->set_map(isolate->heap()->fixed_array_map());
   18049    52156773 :   for (int i = 0; i < length; i++) {
   18050    46781123 :     int index = kHashTableStartIndex + nof_buckets + (i * kEntrySize);
   18051             :     Object* key = table->get(index);
   18052    46781123 :     if (convert == GetKeysConversion::kConvertToString) {
   18053             :       uint32_t index_value;
   18054     4320215 :       if (key->ToArrayIndex(&index_value)) {
   18055      512810 :         key = *isolate->factory()->Uint32ToString(index_value);
   18056             :       } else {
   18057     4063810 :         CHECK(key->IsName());
   18058             :       }
   18059             :     }
   18060    46781123 :     result->set(i, key);
   18061             :   }
   18062     5375650 :   result->Shrink(length);
   18063     5375650 :   return result;
   18064             : }
   18065             : 
   18066             : template <class Derived, int entrysize>
   18067      254440 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
   18068             :     Handle<Derived> table, int new_capacity) {
   18069             :   Isolate* isolate = table->GetIsolate();
   18070             :   DCHECK(!table->IsObsolete());
   18071             : 
   18072             :   Handle<Derived> new_table =
   18073             :       Allocate(isolate, new_capacity,
   18074      254440 :                isolate->heap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
   18075             :   int nof = table->NumberOfElements();
   18076             :   int nod = table->NumberOfDeletedElements();
   18077             :   int new_buckets = new_table->NumberOfBuckets();
   18078             :   int new_entry = 0;
   18079             :   int removed_holes_index = 0;
   18080             : 
   18081             :   DisallowHeapAllocation no_gc;
   18082     4744873 :   for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
   18083     4490433 :     Object* key = table->KeyAt(old_entry);
   18084     4490433 :     if (key->IsTheHole(isolate)) {
   18085      213270 :       table->SetRemovedIndexAt(removed_holes_index++, old_entry);
   18086             :       continue;
   18087             :     }
   18088             : 
   18089     4277163 :     Object* hash = key->GetHash();
   18090     4277162 :     int bucket = Smi::ToInt(hash) & (new_buckets - 1);
   18091     4277162 :     Object* chain_entry = new_table->get(kHashTableStartIndex + bucket);
   18092             :     new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
   18093             :     int new_index = new_table->EntryToIndex(new_entry);
   18094             :     int old_index = table->EntryToIndex(old_entry);
   18095     8567800 :     for (int i = 0; i < entrysize; ++i) {
   18096     4290636 :       Object* value = table->get(old_index + i);
   18097     8581272 :       new_table->set(new_index + i, value);
   18098             :     }
   18099     8554328 :     new_table->set(new_index + kChainOffset, chain_entry);
   18100     4277163 :     ++new_entry;
   18101             :   }
   18102             : 
   18103             :   DCHECK_EQ(nod, removed_holes_index);
   18104             : 
   18105             :   new_table->SetNumberOfElements(nof);
   18106             :   table->SetNextTable(*new_table);
   18107             : 
   18108      254440 :   return new_table;
   18109             : }
   18110             : 
   18111             : template <class Derived, int entrysize>
   18112          96 : bool OrderedHashTable<Derived, entrysize>::Delete(Isolate* isolate,
   18113             :                                                   Derived* table, Object* key) {
   18114             :   DisallowHeapAllocation no_gc;
   18115          96 :   int entry = table->FindEntry(isolate, key);
   18116          96 :   if (entry == kNotFound) return false;
   18117             : 
   18118             :   int nof = table->NumberOfElements();
   18119             :   int nod = table->NumberOfDeletedElements();
   18120             :   int index = table->EntryToIndex(entry);
   18121             : 
   18122          48 :   Object* hole = isolate->heap()->the_hole_value();
   18123         120 :   for (int i = 0; i < entrysize; ++i) {
   18124          72 :     table->set(index + i, hole);
   18125             :   }
   18126             : 
   18127          48 :   table->SetNumberOfElements(nof - 1);
   18128          48 :   table->SetNumberOfDeletedElements(nod + 1);
   18129             : 
   18130          48 :   return true;
   18131             : }
   18132             : 
   18133       78003 : Object* OrderedHashMap::GetHash(Isolate* isolate, Object* key) {
   18134             :   DisallowHeapAllocation no_gc;
   18135             : 
   18136       78003 :   Object* hash = key->GetHash();
   18137             :   // If the object does not have an identity hash, it was never used as a key
   18138       78003 :   if (hash->IsUndefined(isolate)) return Smi::FromInt(-1);
   18139             :   DCHECK(hash->IsSmi());
   18140             :   DCHECK_GE(Smi::cast(hash)->value(), 0);
   18141       77652 :   return hash;
   18142             : }
   18143             : 
   18144          96 : Handle<OrderedHashMap> OrderedHashMap::Add(Handle<OrderedHashMap> table,
   18145             :                                            Handle<Object> key,
   18146             :                                            Handle<Object> value) {
   18147          96 :   int hash = key->GetOrCreateHash(table->GetIsolate())->value();
   18148          96 :   int entry = table->HashToEntry(hash);
   18149             :   // Walk the chain of the bucket and try finding the key.
   18150             :   {
   18151             :     DisallowHeapAllocation no_gc;
   18152             :     Object* raw_key = *key;
   18153         222 :     while (entry != kNotFound) {
   18154          54 :       Object* candidate_key = table->KeyAt(entry);
   18155             :       // Do not add if we have the key already
   18156          54 :       if (candidate_key->SameValueZero(raw_key)) return table;
   18157          30 :       entry = table->NextChainEntry(entry);
   18158             :     }
   18159             :   }
   18160             : 
   18161          72 :   table = OrderedHashMap::EnsureGrowable(table);
   18162             :   // Read the existing bucket values.
   18163             :   int bucket = table->HashToBucket(hash);
   18164          72 :   int previous_entry = table->HashToEntry(hash);
   18165             :   int nof = table->NumberOfElements();
   18166             :   // Insert a new entry at the end,
   18167          72 :   int new_entry = nof + table->NumberOfDeletedElements();
   18168             :   int new_index = table->EntryToIndex(new_entry);
   18169          72 :   table->set(new_index, *key);
   18170         144 :   table->set(new_index + kValueOffset, *value);
   18171             :   table->set(new_index + kChainOffset, Smi::FromInt(previous_entry));
   18172             :   // and point the bucket to the new entry.
   18173             :   table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
   18174          72 :   table->SetNumberOfElements(nof + 1);
   18175          72 :   return table;
   18176             : }
   18177             : 
   18178             : template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Allocate(
   18179             :     Isolate* isolate, int capacity, PretenureFlag pretenure);
   18180             : 
   18181             : template Handle<OrderedHashSet> OrderedHashTable<
   18182             :     OrderedHashSet, 1>::EnsureGrowable(Handle<OrderedHashSet> table);
   18183             : 
   18184             : template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Shrink(
   18185             :     Handle<OrderedHashSet> table);
   18186             : 
   18187             : template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Clear(
   18188             :     Handle<OrderedHashSet> table);
   18189             : 
   18190             : template bool OrderedHashTable<OrderedHashSet, 1>::HasKey(Isolate* isolate,
   18191             :                                                           OrderedHashSet* table,
   18192             :                                                           Object* key);
   18193             : 
   18194             : template bool OrderedHashTable<OrderedHashSet, 1>::Delete(Isolate* isolate,
   18195             :                                                           OrderedHashSet* table,
   18196             :                                                           Object* key);
   18197             : 
   18198             : template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Allocate(
   18199             :     Isolate* isolate, int capacity, PretenureFlag pretenure);
   18200             : 
   18201             : template Handle<OrderedHashMap> OrderedHashTable<
   18202             :     OrderedHashMap, 2>::EnsureGrowable(Handle<OrderedHashMap> table);
   18203             : 
   18204             : template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Shrink(
   18205             :     Handle<OrderedHashMap> table);
   18206             : 
   18207             : template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Clear(
   18208             :     Handle<OrderedHashMap> table);
   18209             : 
   18210             : template bool OrderedHashTable<OrderedHashMap, 2>::HasKey(Isolate* isolate,
   18211             :                                                           OrderedHashMap* table,
   18212             :                                                           Object* key);
   18213             : 
   18214             : template bool OrderedHashTable<OrderedHashMap, 2>::Delete(Isolate* isolate,
   18215             :                                                           OrderedHashMap* table,
   18216             :                                                           Object* key);
   18217             : 
   18218             : template <>
   18219             : Handle<SmallOrderedHashSet>
   18220           0 : SmallOrderedHashTable<SmallOrderedHashSet>::Allocate(Isolate* isolate,
   18221             :                                                      int capacity,
   18222             :                                                      PretenureFlag pretenure) {
   18223          36 :   return isolate->factory()->NewSmallOrderedHashSet(capacity, pretenure);
   18224             : }
   18225             : 
   18226             : template <>
   18227             : Handle<SmallOrderedHashMap>
   18228           0 : SmallOrderedHashTable<SmallOrderedHashMap>::Allocate(Isolate* isolate,
   18229             :                                                      int capacity,
   18230             :                                                      PretenureFlag pretenure) {
   18231          36 :   return isolate->factory()->NewSmallOrderedHashMap(capacity, pretenure);
   18232             : }
   18233             : 
   18234             : template <class Derived>
   18235         108 : void SmallOrderedHashTable<Derived>::Initialize(Isolate* isolate,
   18236             :                                                 int capacity) {
   18237         108 :   int num_buckets = capacity / kLoadFactor;
   18238             :   int num_chains = capacity;
   18239             : 
   18240             :   SetNumberOfBuckets(num_buckets);
   18241             :   SetNumberOfElements(0);
   18242             :   SetNumberOfDeletedElements(0);
   18243             : 
   18244             :   byte* hashtable_start =
   18245         108 :       FIELD_ADDR(this, kHeaderSize + (kBucketsStartOffset * kOneByteSize));
   18246         108 :   memset(hashtable_start, kNotFound, num_buckets + num_chains);
   18247             : 
   18248         108 :   if (isolate->heap()->InNewSpace(this)) {
   18249             :     MemsetPointer(RawField(this, GetDataTableStartOffset()),
   18250             :                   isolate->heap()->the_hole_value(),
   18251         108 :                   capacity * Derived::kEntrySize);
   18252             :   } else {
   18253           0 :     for (int i = 0; i < capacity; i++) {
   18254           0 :       for (int j = 0; j < Derived::kEntrySize; i++) {
   18255           0 :         SetDataEntry(i, j, isolate->heap()->the_hole_value());
   18256             :       }
   18257             :     }
   18258             :   }
   18259             : 
   18260             : #ifdef DEBUG
   18261             :   for (int i = 0; i < num_buckets; ++i) {
   18262             :     DCHECK_EQ(kNotFound, GetFirstEntry(i));
   18263             :   }
   18264             : 
   18265             :   for (int i = 0; i < num_chains; ++i) {
   18266             :     DCHECK_EQ(kNotFound, GetNextEntry(i));
   18267             :   }
   18268             : #endif  // DEBUG
   18269         108 : }
   18270             : 
   18271        1584 : Handle<SmallOrderedHashSet> SmallOrderedHashSet::Add(
   18272             :     Handle<SmallOrderedHashSet> table, Handle<Object> key) {
   18273             :   Isolate* isolate = table->GetIsolate();
   18274        1584 :   if (table->HasKey(isolate, key)) return table;
   18275             : 
   18276        1560 :   if (table->UsedCapacity() >= table->Capacity()) {
   18277          36 :     table = SmallOrderedHashSet::Grow(table);
   18278             :   }
   18279             : 
   18280        1560 :   int hash = key->GetOrCreateHash(table->GetIsolate())->value();
   18281             :   int nof = table->NumberOfElements();
   18282             : 
   18283             :   // Read the existing bucket values.
   18284             :   int bucket = table->HashToBucket(hash);
   18285             :   int previous_entry = table->HashToFirstEntry(hash);
   18286             : 
   18287             :   // Insert a new entry at the end,
   18288        1560 :   int new_entry = nof + table->NumberOfDeletedElements();
   18289             : 
   18290        1560 :   table->SetDataEntry(new_entry, SmallOrderedHashSet::kKeyIndex, *key);
   18291        1560 :   table->SetFirstEntry(bucket, new_entry);
   18292             :   table->SetNextEntry(new_entry, previous_entry);
   18293             : 
   18294             :   // and update book keeping.
   18295        1560 :   table->SetNumberOfElements(nof + 1);
   18296             : 
   18297        1560 :   return table;
   18298             : }
   18299             : 
   18300        1584 : Handle<SmallOrderedHashMap> SmallOrderedHashMap::Add(
   18301             :     Handle<SmallOrderedHashMap> table, Handle<Object> key,
   18302             :     Handle<Object> value) {
   18303             :   Isolate* isolate = table->GetIsolate();
   18304        1584 :   if (table->HasKey(isolate, key)) return table;
   18305             : 
   18306        1560 :   if (table->UsedCapacity() >= table->Capacity()) {
   18307          36 :     table = SmallOrderedHashMap::Grow(table);
   18308             :   }
   18309             : 
   18310        1560 :   int hash = key->GetOrCreateHash(table->GetIsolate())->value();
   18311             :   int nof = table->NumberOfElements();
   18312             : 
   18313             :   // Read the existing bucket values.
   18314             :   int bucket = table->HashToBucket(hash);
   18315             :   int previous_entry = table->HashToFirstEntry(hash);
   18316             : 
   18317             :   // Insert a new entry at the end,
   18318        1560 :   int new_entry = nof + table->NumberOfDeletedElements();
   18319             : 
   18320        1560 :   table->SetDataEntry(new_entry, SmallOrderedHashMap::kValueIndex, *value);
   18321        1560 :   table->SetDataEntry(new_entry, SmallOrderedHashMap::kKeyIndex, *key);
   18322        1560 :   table->SetFirstEntry(bucket, new_entry);
   18323             :   table->SetNextEntry(new_entry, previous_entry);
   18324             : 
   18325             :   // and update book keeping.
   18326        1560 :   table->SetNumberOfElements(nof + 1);
   18327             : 
   18328        1560 :   return table;
   18329             : }
   18330             : 
   18331             : template <class Derived>
   18332        9564 : bool SmallOrderedHashTable<Derived>::HasKey(Isolate* isolate,
   18333             :                                             Handle<Object> key) {
   18334             :   DisallowHeapAllocation no_gc;
   18335             :   Object* raw_key = *key;
   18336        9564 :   Object* hash = key->GetHash();
   18337             : 
   18338        9564 :   if (hash->IsUndefined(isolate)) return false;
   18339             :   int entry = HashToFirstEntry(Smi::ToInt(hash));
   18340             : 
   18341             :   // Walk the chain in the bucket to find the key.
   18342       34404 :   while (entry != kNotFound) {
   18343             :     Object* candidate_key = KeyAt(entry);
   18344       21696 :     if (candidate_key->SameValueZero(raw_key)) return true;
   18345             :     entry = GetNextEntry(entry);
   18346             :   }
   18347             :   return false;
   18348             : }
   18349             : 
   18350             : template <class Derived>
   18351          72 : Handle<Derived> SmallOrderedHashTable<Derived>::Rehash(Handle<Derived> table,
   18352             :                                                        int new_capacity) {
   18353             :   DCHECK_GE(kMaxCapacity, new_capacity);
   18354             :   Isolate* isolate = table->GetIsolate();
   18355             : 
   18356             :   Handle<Derived> new_table = SmallOrderedHashTable<Derived>::Allocate(
   18357             :       isolate, new_capacity,
   18358          72 :       isolate->heap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
   18359             :   int nof = table->NumberOfElements();
   18360             :   int nod = table->NumberOfDeletedElements();
   18361             :   int new_entry = 0;
   18362             : 
   18363             :   {
   18364             :     DisallowHeapAllocation no_gc;
   18365        3096 :     for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
   18366             :       Object* key = table->KeyAt(old_entry);
   18367        3024 :       if (key->IsTheHole(isolate)) continue;
   18368             : 
   18369        3024 :       int hash = Smi::ToInt(key->GetHash());
   18370             :       int bucket = new_table->HashToBucket(hash);
   18371             :       int chain = new_table->GetFirstEntry(bucket);
   18372             : 
   18373        3024 :       new_table->SetFirstEntry(bucket, new_entry);
   18374             :       new_table->SetNextEntry(new_entry, chain);
   18375             : 
   18376        7560 :       for (int i = 0; i < Derived::kEntrySize; ++i) {
   18377             :         Object* value = table->GetDataEntry(old_entry, i);
   18378        4536 :         new_table->SetDataEntry(new_entry, i, value);
   18379             :       }
   18380             : 
   18381        3024 :       ++new_entry;
   18382             :     }
   18383             : 
   18384             :     new_table->SetNumberOfElements(nof);
   18385             :   }
   18386          72 :   return new_table;
   18387             : }
   18388             : 
   18389             : template <class Derived>
   18390          72 : Handle<Derived> SmallOrderedHashTable<Derived>::Grow(Handle<Derived> table) {
   18391             :   int capacity = table->Capacity();
   18392             :   int new_capacity = capacity;
   18393             : 
   18394             :   // Don't need to grow if we can simply clear out deleted entries instead.
   18395             :   // TODO(gsathya): Compact in place, instead of allocating a new table.
   18396          72 :   if (table->NumberOfDeletedElements() < (capacity >> 1)) {
   18397          72 :     new_capacity = capacity << 1;
   18398             : 
   18399             :     // The max capacity of our table is 254. We special case for 256 to
   18400             :     // account for our growth strategy, otherwise we would only fill up
   18401             :     // to 128 entries in our table.
   18402          72 :     if (new_capacity == kGrowthHack) {
   18403             :       new_capacity = kMaxCapacity;
   18404             :     }
   18405             : 
   18406             :     // TODO(gsathya): Transition to OrderedHashTable for size > kMaxCapacity.
   18407             :   }
   18408             : 
   18409          72 :   return Rehash(table, new_capacity);
   18410             : }
   18411             : 
   18412             : template bool SmallOrderedHashTable<SmallOrderedHashSet>::HasKey(
   18413             :     Isolate* isolate, Handle<Object> key);
   18414             : template Handle<SmallOrderedHashSet>
   18415             : SmallOrderedHashTable<SmallOrderedHashSet>::Rehash(
   18416             :     Handle<SmallOrderedHashSet> table, int new_capacity);
   18417             : template Handle<SmallOrderedHashSet> SmallOrderedHashTable<
   18418             :     SmallOrderedHashSet>::Grow(Handle<SmallOrderedHashSet> table);
   18419             : template void SmallOrderedHashTable<SmallOrderedHashSet>::Initialize(
   18420             :     Isolate* isolate, int capacity);
   18421             : 
   18422             : template bool SmallOrderedHashTable<SmallOrderedHashMap>::HasKey(
   18423             :     Isolate* isolate, Handle<Object> key);
   18424             : template Handle<SmallOrderedHashMap>
   18425             : SmallOrderedHashTable<SmallOrderedHashMap>::Rehash(
   18426             :     Handle<SmallOrderedHashMap> table, int new_capacity);
   18427             : template Handle<SmallOrderedHashMap> SmallOrderedHashTable<
   18428             :     SmallOrderedHashMap>::Grow(Handle<SmallOrderedHashMap> table);
   18429             : template void SmallOrderedHashTable<SmallOrderedHashMap>::Initialize(
   18430             :     Isolate* isolate, int capacity);
   18431             : 
   18432             : template<class Derived, class TableType>
   18433         194 : void OrderedHashTableIterator<Derived, TableType>::Transition() {
   18434             :   DisallowHeapAllocation no_allocation;
   18435             :   TableType* table = TableType::cast(this->table());
   18436         388 :   if (!table->IsObsolete()) return;
   18437             : 
   18438             :   int index = Smi::ToInt(this->index());
   18439           0 :   while (table->IsObsolete()) {
   18440             :     TableType* next_table = table->NextTable();
   18441             : 
   18442           0 :     if (index > 0) {
   18443             :       int nod = table->NumberOfDeletedElements();
   18444             : 
   18445           0 :       if (nod == TableType::kClearedTableSentinel) {
   18446             :         index = 0;
   18447             :       } else {
   18448             :         int old_index = index;
   18449           0 :         for (int i = 0; i < nod; ++i) {
   18450             :           int removed_index = table->RemovedIndexAt(i);
   18451           0 :           if (removed_index >= old_index) break;
   18452           0 :           --index;
   18453             :         }
   18454             :       }
   18455             :     }
   18456             : 
   18457             :     table = next_table;
   18458             :   }
   18459             : 
   18460           0 :   set_table(table);
   18461           0 :   set_index(Smi::FromInt(index));
   18462             : }
   18463             : 
   18464             : 
   18465             : template<class Derived, class TableType>
   18466         194 : bool OrderedHashTableIterator<Derived, TableType>::HasMore() {
   18467             :   DisallowHeapAllocation no_allocation;
   18468             :   Isolate* isolate = this->GetIsolate();
   18469             : 
   18470         194 :   Transition();
   18471             : 
   18472             :   TableType* table = TableType::cast(this->table());
   18473             :   int index = Smi::ToInt(this->index());
   18474         194 :   int used_capacity = table->UsedCapacity();
   18475             : 
   18476         562 :   while (index < used_capacity && table->KeyAt(index)->IsTheHole(isolate)) {
   18477           0 :     index++;
   18478             :   }
   18479             : 
   18480         194 :   set_index(Smi::FromInt(index));
   18481             : 
   18482         194 :   if (index < used_capacity) return true;
   18483             : 
   18484          20 :   set_table(isolate->heap()->empty_ordered_hash_table());
   18485          20 :   return false;
   18486             : }
   18487             : 
   18488             : template bool
   18489             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::HasMore();
   18490             : 
   18491             : template void
   18492             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::MoveNext();
   18493             : 
   18494             : template Object*
   18495             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::CurrentKey();
   18496             : 
   18497             : template void
   18498             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Transition();
   18499             : 
   18500             : 
   18501             : template bool
   18502             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::HasMore();
   18503             : 
   18504             : template void
   18505             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::MoveNext();
   18506             : 
   18507             : template Object*
   18508             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::CurrentKey();
   18509             : 
   18510             : template void
   18511             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Transition();
   18512             : 
   18513             : 
   18514         413 : void JSSet::Initialize(Handle<JSSet> set, Isolate* isolate) {
   18515         413 :   Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
   18516         413 :   set->set_table(*table);
   18517         413 : }
   18518             : 
   18519             : 
   18520          33 : void JSSet::Clear(Handle<JSSet> set) {
   18521             :   Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
   18522          33 :   table = OrderedHashSet::Clear(table);
   18523          33 :   set->set_table(*table);
   18524          33 : }
   18525             : 
   18526             : 
   18527          13 : void JSMap::Initialize(Handle<JSMap> map, Isolate* isolate) {
   18528          13 :   Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
   18529          13 :   map->set_table(*table);
   18530          13 : }
   18531             : 
   18532             : 
   18533         203 : void JSMap::Clear(Handle<JSMap> map) {
   18534             :   Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
   18535         203 :   table = OrderedHashMap::Clear(table);
   18536         203 :   map->set_table(*table);
   18537         203 : }
   18538             : 
   18539             : 
   18540       83169 : void JSWeakCollection::Initialize(Handle<JSWeakCollection> weak_collection,
   18541             :                                   Isolate* isolate) {
   18542       83169 :   Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
   18543       83169 :   weak_collection->set_table(*table);
   18544       83169 : }
   18545             : 
   18546             : 
   18547        2217 : void JSWeakCollection::Set(Handle<JSWeakCollection> weak_collection,
   18548             :                            Handle<Object> key, Handle<Object> value,
   18549             :                            int32_t hash) {
   18550             :   DCHECK(key->IsJSReceiver() || key->IsSymbol());
   18551             :   Handle<ObjectHashTable> table(
   18552             :       ObjectHashTable::cast(weak_collection->table()));
   18553             :   DCHECK(table->IsKey(table->GetIsolate(), *key));
   18554             :   Handle<ObjectHashTable> new_table =
   18555        2217 :       ObjectHashTable::Put(table, key, value, hash);
   18556        2217 :   weak_collection->set_table(*new_table);
   18557        2217 :   if (*table != *new_table) {
   18558             :     // Zap the old table since we didn't record slots for its elements.
   18559         173 :     table->FillWithHoles(0, table->length());
   18560             :   }
   18561        2217 : }
   18562             : 
   18563             : 
   18564          77 : bool JSWeakCollection::Delete(Handle<JSWeakCollection> weak_collection,
   18565             :                               Handle<Object> key, int32_t hash) {
   18566             :   DCHECK(key->IsJSReceiver() || key->IsSymbol());
   18567             :   Handle<ObjectHashTable> table(
   18568             :       ObjectHashTable::cast(weak_collection->table()));
   18569             :   DCHECK(table->IsKey(table->GetIsolate(), *key));
   18570          77 :   bool was_present = false;
   18571             :   Handle<ObjectHashTable> new_table =
   18572          77 :       ObjectHashTable::Remove(table, key, &was_present, hash);
   18573          77 :   weak_collection->set_table(*new_table);
   18574          77 :   if (*table != *new_table) {
   18575             :     // Zap the old table since we didn't record slots for its elements.
   18576           0 :     table->FillWithHoles(0, table->length());
   18577             :   }
   18578          77 :   return was_present;
   18579             : }
   18580             : 
   18581          30 : Handle<JSArray> JSWeakCollection::GetEntries(Handle<JSWeakCollection> holder,
   18582             :                                              int max_entries) {
   18583             :   Isolate* isolate = holder->GetIsolate();
   18584             :   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   18585          30 :   if (max_entries == 0 || max_entries > table->NumberOfElements()) {
   18586             :     max_entries = table->NumberOfElements();
   18587             :   }
   18588          30 :   int values_per_entry = holder->IsJSWeakMap() ? 2 : 1;
   18589             :   Handle<FixedArray> entries =
   18590          30 :       isolate->factory()->NewFixedArray(max_entries * values_per_entry);
   18591             :   // Recompute max_values because GC could have removed elements from the table.
   18592          30 :   if (max_entries > table->NumberOfElements()) {
   18593             :     max_entries = table->NumberOfElements();
   18594             :   }
   18595             : 
   18596             :   {
   18597             :     DisallowHeapAllocation no_gc;
   18598             :     int count = 0;
   18599         180 :     for (int i = 0;
   18600         150 :          count / values_per_entry < max_entries && i < table->Capacity(); i++) {
   18601             :       Object* key;
   18602          60 :       if (table->ToKey(isolate, i, &key)) {
   18603          40 :         entries->set(count++, key);
   18604          20 :         if (values_per_entry > 1) {
   18605          20 :           Object* value = table->Lookup(handle(key, isolate));
   18606          20 :           entries->set(count++, value);
   18607             :         }
   18608             :       }
   18609             :     }
   18610             :     DCHECK_EQ(max_entries * values_per_entry, count);
   18611             :   }
   18612          30 :   return isolate->factory()->NewJSArrayWithElements(entries);
   18613             : }
   18614             : 
   18615             : // static
   18616      156515 : MaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor,
   18617             :                                 Handle<JSReceiver> new_target, double tv) {
   18618             :   Isolate* const isolate = constructor->GetIsolate();
   18619             :   Handle<JSObject> result;
   18620      313030 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   18621             :                              JSObject::New(constructor, new_target), JSDate);
   18622      156515 :   if (-DateCache::kMaxTimeInMs <= tv && tv <= DateCache::kMaxTimeInMs) {
   18623      156002 :     tv = DoubleToInteger(tv) + 0.0;
   18624             :   } else {
   18625             :     tv = std::numeric_limits<double>::quiet_NaN();
   18626             :   }
   18627      156515 :   Handle<Object> value = isolate->factory()->NewNumber(tv);
   18628      313030 :   Handle<JSDate>::cast(result)->SetValue(*value, std::isnan(tv));
   18629      156515 :   return Handle<JSDate>::cast(result);
   18630             : }
   18631             : 
   18632             : 
   18633             : // static
   18634      159235 : double JSDate::CurrentTimeValue(Isolate* isolate) {
   18635      159235 :   if (FLAG_log_internal_timer_events) LOG(isolate, CurrentTimeEvent());
   18636             : 
   18637             :   // According to ECMA-262, section 15.9.1, page 117, the precision of
   18638             :   // the number in a Date object representing a particular instant in
   18639             :   // time is milliseconds. Therefore, we floor the result of getting
   18640             :   // the OS time.
   18641      318470 :   return Floor(V8::GetCurrentPlatform()->CurrentClockTimeMillis());
   18642             : }
   18643             : 
   18644             : 
   18645             : // static
   18646       11057 : Object* JSDate::GetField(Object* object, Smi* index) {
   18647             :   return JSDate::cast(object)->DoGetField(
   18648       11057 :       static_cast<FieldIndex>(index->value()));
   18649             : }
   18650             : 
   18651             : 
   18652       11057 : Object* JSDate::DoGetField(FieldIndex index) {
   18653             :   DCHECK_NE(index, kDateValue);
   18654             : 
   18655       16490 :   DateCache* date_cache = GetIsolate()->date_cache();
   18656             : 
   18657       11057 :   if (index < kFirstUncachedField) {
   18658             :     Object* stamp = cache_stamp();
   18659       10866 :     if (stamp != date_cache->stamp() && stamp->IsSmi()) {
   18660             :       // Since the stamp is not NaN, the value is also not NaN.
   18661             :       int64_t local_time_ms =
   18662         378 :           date_cache->ToLocal(static_cast<int64_t>(value()->Number()));
   18663         378 :       SetCachedFields(local_time_ms, date_cache);
   18664             :     }
   18665        5433 :     switch (index) {
   18666         895 :       case kYear: return year();
   18667         245 :       case kMonth: return month();
   18668          73 :       case kDay: return day();
   18669           0 :       case kWeekday: return weekday();
   18670        3142 :       case kHour: return hour();
   18671         852 :       case kMinute: return min();
   18672         226 :       case kSecond: return sec();
   18673           0 :       default: UNREACHABLE();
   18674             :     }
   18675             :   }
   18676             : 
   18677        5624 :   if (index >= kFirstUTCField) {
   18678        5460 :     return GetUTCField(index, value()->Number(), date_cache);
   18679             :   }
   18680             : 
   18681             :   double time = value()->Number();
   18682         164 :   if (std::isnan(time)) return GetIsolate()->heap()->nan_value();
   18683             : 
   18684         109 :   int64_t local_time_ms = date_cache->ToLocal(static_cast<int64_t>(time));
   18685             :   int days = DateCache::DaysFromTime(local_time_ms);
   18686             : 
   18687         109 :   if (index == kDays) return Smi::FromInt(days);
   18688             : 
   18689             :   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
   18690         218 :   if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000);
   18691             :   DCHECK_EQ(index, kTimeInDay);
   18692           0 :   return Smi::FromInt(time_in_day_ms);
   18693             : }
   18694             : 
   18695             : 
   18696        5460 : Object* JSDate::GetUTCField(FieldIndex index,
   18697             :                             double value,
   18698             :                             DateCache* date_cache) {
   18699             :   DCHECK_GE(index, kFirstUTCField);
   18700             : 
   18701       10570 :   if (std::isnan(value)) return GetIsolate()->heap()->nan_value();
   18702             : 
   18703         350 :   int64_t time_ms = static_cast<int64_t>(value);
   18704             : 
   18705         350 :   if (index == kTimezoneOffset) {
   18706          19 :     return Smi::FromInt(date_cache->TimezoneOffset(time_ms));
   18707             :   }
   18708             : 
   18709             :   int days = DateCache::DaysFromTime(time_ms);
   18710             : 
   18711         340 :   if (index == kWeekdayUTC) return Smi::FromInt(date_cache->Weekday(days));
   18712             : 
   18713         322 :   if (index <= kDayUTC) {
   18714             :     int year, month, day;
   18715         120 :     date_cache->YearMonthDayFromDays(days, &year, &month, &day);
   18716         157 :     if (index == kYearUTC) return Smi::FromInt(year);
   18717         119 :     if (index == kMonthUTC) return Smi::FromInt(month);
   18718             :     DCHECK_EQ(index, kDayUTC);
   18719          94 :     return Smi::FromInt(day);
   18720             :   }
   18721             : 
   18722             :   int time_in_day_ms = DateCache::TimeInDay(time_ms, days);
   18723         202 :   switch (index) {
   18724         188 :     case kHourUTC: return Smi::FromInt(time_in_day_ms / (60 * 60 * 1000));
   18725          90 :     case kMinuteUTC: return Smi::FromInt((time_in_day_ms / (60 * 1000)) % 60);
   18726          72 :     case kSecondUTC: return Smi::FromInt((time_in_day_ms / 1000) % 60);
   18727          54 :     case kMillisecondUTC: return Smi::FromInt(time_in_day_ms % 1000);
   18728           0 :     case kDaysUTC: return Smi::FromInt(days);
   18729           0 :     case kTimeInDayUTC: return Smi::FromInt(time_in_day_ms);
   18730           0 :     default: UNREACHABLE();
   18731             :   }
   18732             : 
   18733             :   UNREACHABLE();
   18734             : }
   18735             : 
   18736             : 
   18737             : // static
   18738       11201 : Handle<Object> JSDate::SetValue(Handle<JSDate> date, double v) {
   18739             :   Isolate* const isolate = date->GetIsolate();
   18740       11201 :   Handle<Object> value = isolate->factory()->NewNumber(v);
   18741             :   bool value_is_nan = std::isnan(v);
   18742       22402 :   date->SetValue(*value, value_is_nan);
   18743       11201 :   return value;
   18744             : }
   18745             : 
   18746             : 
   18747      167716 : void JSDate::SetValue(Object* value, bool is_value_nan) {
   18748      167716 :   set_value(value);
   18749      167716 :   if (is_value_nan) {
   18750       11206 :     HeapNumber* nan = GetIsolate()->heap()->nan_value();
   18751       11206 :     set_cache_stamp(nan, SKIP_WRITE_BARRIER);
   18752       11206 :     set_year(nan, SKIP_WRITE_BARRIER);
   18753       11206 :     set_month(nan, SKIP_WRITE_BARRIER);
   18754       11206 :     set_day(nan, SKIP_WRITE_BARRIER);
   18755       11206 :     set_hour(nan, SKIP_WRITE_BARRIER);
   18756       11206 :     set_min(nan, SKIP_WRITE_BARRIER);
   18757       11206 :     set_sec(nan, SKIP_WRITE_BARRIER);
   18758       11206 :     set_weekday(nan, SKIP_WRITE_BARRIER);
   18759             :   } else {
   18760      156510 :     set_cache_stamp(Smi::FromInt(DateCache::kInvalidStamp), SKIP_WRITE_BARRIER);
   18761             :   }
   18762      167716 : }
   18763             : 
   18764             : 
   18765         756 : void JSDate::SetCachedFields(int64_t local_time_ms, DateCache* date_cache) {
   18766             :   int days = DateCache::DaysFromTime(local_time_ms);
   18767             :   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
   18768             :   int year, month, day;
   18769         378 :   date_cache->YearMonthDayFromDays(days, &year, &month, &day);
   18770             :   int weekday = date_cache->Weekday(days);
   18771         378 :   int hour = time_in_day_ms / (60 * 60 * 1000);
   18772         378 :   int min = (time_in_day_ms / (60 * 1000)) % 60;
   18773         378 :   int sec = (time_in_day_ms / 1000) % 60;
   18774         378 :   set_cache_stamp(date_cache->stamp());
   18775         756 :   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
   18776         756 :   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
   18777         756 :   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
   18778         378 :   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
   18779         378 :   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
   18780         378 :   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
   18781         378 :   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
   18782         378 : }
   18783             : 
   18784             : namespace {
   18785             : 
   18786             : Script* ScriptFromJSValue(Object* in) {
   18787             :   DCHECK(in->IsJSValue());
   18788             :   JSValue* jsvalue = JSValue::cast(in);
   18789             :   DCHECK(jsvalue->value()->IsScript());
   18790             :   return Script::cast(jsvalue->value());
   18791             : }
   18792             : 
   18793             : }  // namespace
   18794             : 
   18795       10681 : int JSMessageObject::GetLineNumber() const {
   18796       10681 :   if (start_position() == -1) return Message::kNoLineNumberInfo;
   18797             : 
   18798       10606 :   Handle<Script> the_script = handle(ScriptFromJSValue(script()));
   18799             : 
   18800             :   Script::PositionInfo info;
   18801             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   18802       10606 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   18803       10606 :                                offset_flag)) {
   18804             :     return Message::kNoLineNumberInfo;
   18805             :   }
   18806             : 
   18807       10606 :   return info.line + 1;
   18808             : }
   18809             : 
   18810       16928 : int JSMessageObject::GetColumnNumber() const {
   18811       16928 :   if (start_position() == -1) return -1;
   18812             : 
   18813       16823 :   Handle<Script> the_script = handle(ScriptFromJSValue(script()));
   18814             : 
   18815             :   Script::PositionInfo info;
   18816             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   18817       16823 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   18818       16823 :                                offset_flag)) {
   18819             :     return -1;
   18820             :   }
   18821             : 
   18822       16823 :   return info.column;  // Note: No '+1' in contrast to GetLineNumber.
   18823             : }
   18824             : 
   18825        7666 : Handle<String> JSMessageObject::GetSourceLine() const {
   18826             :   Handle<Script> the_script = handle(ScriptFromJSValue(script()));
   18827             : 
   18828             :   Isolate* isolate = the_script->GetIsolate();
   18829        7666 :   if (the_script->type() == Script::TYPE_WASM) {
   18830             :     return isolate->factory()->empty_string();
   18831             :   }
   18832             : 
   18833             :   Script::PositionInfo info;
   18834             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   18835        7666 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   18836        7666 :                                offset_flag)) {
   18837             :     return isolate->factory()->empty_string();
   18838             :   }
   18839             : 
   18840        7666 :   Handle<String> src = handle(String::cast(the_script->source()), isolate);
   18841        7666 :   return isolate->factory()->NewSubString(src, info.line_start, info.line_end);
   18842             : }
   18843             : 
   18844        2334 : void JSArrayBuffer::Neuter() {
   18845        2334 :   CHECK(is_neuterable());
   18846        2334 :   CHECK(is_external());
   18847             :   set_backing_store(nullptr);
   18848        2334 :   set_byte_length(Smi::kZero);
   18849             :   set_allocation_base(nullptr);
   18850             :   set_allocation_length(0);
   18851             :   set_was_neutered(true);
   18852             :   // Invalidate the neutering protector.
   18853             :   Isolate* const isolate = GetIsolate();
   18854        2334 :   if (isolate->IsArrayBufferNeuteringIntact()) {
   18855         236 :     isolate->InvalidateArrayBufferNeuteringProtector();
   18856             :   }
   18857        2334 : }
   18858             : 
   18859      241350 : void JSArrayBuffer::FreeBackingStore() {
   18860      241350 :   if (allocation_base() == nullptr) {
   18861      241385 :     return;
   18862             :   }
   18863             :   using AllocationMode = ArrayBuffer::Allocator::AllocationMode;
   18864             :   const size_t length = allocation_length();
   18865             :   const AllocationMode mode = allocation_mode();
   18866      241344 :   GetIsolate()->array_buffer_allocator()->Free(allocation_base(), length, mode);
   18867             : 
   18868             :   // Zero out the backing store and allocation base to avoid dangling
   18869             :   // pointers.
   18870             :   set_backing_store(nullptr);
   18871             :   // TODO(eholk): set_byte_length(0) once we aren't using Smis for the
   18872             :   // byte_length. We can't do it now because the GC needs to call
   18873             :   // FreeBackingStore while it is collecting.
   18874             :   set_allocation_base(nullptr);
   18875             :   set_allocation_length(0);
   18876             : }
   18877             : 
   18878         784 : void JSArrayBuffer::Setup(Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
   18879             :                           bool is_external, void* data, size_t allocated_length,
   18880             :                           SharedFlag shared) {
   18881             :   return Setup(array_buffer, isolate, is_external, data, allocated_length, data,
   18882      229257 :                allocated_length, shared);
   18883             : }
   18884             : 
   18885      248497 : void JSArrayBuffer::Setup(Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
   18886             :                           bool is_external, void* allocation_base,
   18887             :                           size_t allocation_length, void* data,
   18888             :                           size_t byte_length, SharedFlag shared) {
   18889             :   DCHECK_EQ(array_buffer->GetEmbedderFieldCount(),
   18890             :             v8::ArrayBuffer::kEmbedderFieldCount);
   18891      745491 :   for (int i = 0; i < v8::ArrayBuffer::kEmbedderFieldCount; i++) {
   18892      496994 :     array_buffer->SetEmbedderField(i, Smi::kZero);
   18893             :   }
   18894             :   array_buffer->set_bit_field(0);
   18895             :   array_buffer->set_is_external(is_external);
   18896      248497 :   array_buffer->set_is_neuterable(shared == SharedFlag::kNotShared);
   18897      248497 :   array_buffer->set_is_shared(shared == SharedFlag::kShared);
   18898             : 
   18899             :   Handle<Object> heap_byte_length =
   18900      248497 :       isolate->factory()->NewNumberFromSize(byte_length);
   18901      248570 :   CHECK(heap_byte_length->IsSmi() || heap_byte_length->IsHeapNumber());
   18902      248497 :   array_buffer->set_byte_length(*heap_byte_length);
   18903             :   // Initialize backing store at last to avoid handling of |JSArrayBuffers| that
   18904             :   // are currently being constructed in the |ArrayBufferTracker|. The
   18905             :   // registration method below handles the case of registering a buffer that has
   18906             :   // already been promoted.
   18907             :   array_buffer->set_backing_store(data);
   18908             : 
   18909             :   array_buffer->set_allocation_base(data);
   18910             :   array_buffer->set_allocation_length(allocation_length);
   18911             : 
   18912      248497 :   if (data && !is_external) {
   18913      231341 :     isolate->heap()->RegisterNewArrayBuffer(*array_buffer);
   18914             :   }
   18915      248497 : }
   18916             : 
   18917             : namespace {
   18918             : 
   18919             : inline int ConvertToMb(size_t size) {
   18920        6294 :   return static_cast<int>(size / static_cast<size_t>(MB));
   18921             : }
   18922             : 
   18923             : }  // namespace
   18924             : 
   18925      228474 : bool JSArrayBuffer::SetupAllocatingData(Handle<JSArrayBuffer> array_buffer,
   18926      445858 :                                         Isolate* isolate,
   18927             :                                         size_t allocated_length,
   18928             :                                         bool initialize, SharedFlag shared) {
   18929             :   void* data;
   18930      228474 :   CHECK_NOT_NULL(isolate->array_buffer_allocator());
   18931      228474 :   if (allocated_length != 0) {
   18932      217384 :     if (allocated_length >= MB)
   18933             :       isolate->counters()->array_buffer_big_allocations()->AddSample(
   18934         296 :           ConvertToMb(allocated_length));
   18935      217384 :     if (shared == SharedFlag::kShared)
   18936             :       isolate->counters()->shared_array_allocations()->AddSample(
   18937        5997 :           ConvertToMb(allocated_length));
   18938      217384 :     if (initialize) {
   18939      216383 :       data = isolate->array_buffer_allocator()->Allocate(allocated_length);
   18940             :     } else {
   18941             :       data = isolate->array_buffer_allocator()->AllocateUninitialized(
   18942        1001 :           allocated_length);
   18943             :     }
   18944      217384 :     if (data == nullptr) {
   18945             :       isolate->counters()->array_buffer_new_size_failures()->AddSample(
   18946           1 :           ConvertToMb(allocated_length));
   18947           1 :       return false;
   18948             :     }
   18949             :   } else {
   18950             :     data = nullptr;
   18951             :   }
   18952             : 
   18953             :   const bool is_external = false;
   18954             :   JSArrayBuffer::Setup(array_buffer, isolate, is_external, data,
   18955             :                        allocated_length, shared);
   18956      228473 :   return true;
   18957             : }
   18958             : 
   18959             : 
   18960       12367 : Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer(
   18961             :     Handle<JSTypedArray> typed_array) {
   18962             : 
   18963             :   Handle<Map> map(typed_array->map());
   18964       12367 :   Isolate* isolate = typed_array->GetIsolate();
   18965             : 
   18966             :   DCHECK(IsFixedTypedArrayElementsKind(map->elements_kind()));
   18967             : 
   18968             :   Handle<FixedTypedArrayBase> fixed_typed_array(
   18969             :       FixedTypedArrayBase::cast(typed_array->elements()));
   18970             : 
   18971             :   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(typed_array->buffer()),
   18972             :                                isolate);
   18973             :   void* backing_store =
   18974             :       isolate->array_buffer_allocator()->AllocateUninitialized(
   18975       24734 :           fixed_typed_array->DataSize());
   18976             :   buffer->set_is_external(false);
   18977             :   DCHECK(buffer->byte_length()->IsSmi() ||
   18978             :          buffer->byte_length()->IsHeapNumber());
   18979             :   DCHECK(NumberToInt32(buffer->byte_length()) == fixed_typed_array->DataSize());
   18980             :   // Initialize backing store at last to avoid handling of |JSArrayBuffers| that
   18981             :   // are currently being constructed in the |ArrayBufferTracker|. The
   18982             :   // registration method below handles the case of registering a buffer that has
   18983             :   // already been promoted.
   18984             :   buffer->set_backing_store(backing_store);
   18985             :   buffer->set_allocation_base(backing_store);
   18986       12367 :   buffer->set_allocation_length(NumberToSize(buffer->byte_length()));
   18987             :   // RegisterNewArrayBuffer expects a valid length for adjusting counters.
   18988       12367 :   isolate->heap()->RegisterNewArrayBuffer(*buffer);
   18989             :   memcpy(buffer->backing_store(),
   18990             :          fixed_typed_array->DataPtr(),
   18991       12367 :          fixed_typed_array->DataSize());
   18992             :   Handle<FixedTypedArrayBase> new_elements =
   18993             :       isolate->factory()->NewFixedTypedArrayWithExternalPointer(
   18994             :           fixed_typed_array->length(), typed_array->type(),
   18995       24734 :           static_cast<uint8_t*>(buffer->backing_store()));
   18996             : 
   18997       12367 :   typed_array->set_elements(*new_elements);
   18998             : 
   18999       12367 :   return buffer;
   19000             : }
   19001             : 
   19002             : 
   19003    19700823 : Handle<JSArrayBuffer> JSTypedArray::GetBuffer() {
   19004             :   Handle<JSArrayBuffer> array_buffer(JSArrayBuffer::cast(buffer()),
   19005             :                                      GetIsolate());
   19006    39401607 :   if (array_buffer->was_neutered() ||
   19007             :       array_buffer->backing_store() != nullptr) {
   19008    19688457 :     return array_buffer;
   19009             :   }
   19010             :   Handle<JSTypedArray> self(this);
   19011       12367 :   return MaterializeArrayBuffer(self);
   19012             : }
   19013             : 
   19014       19912 : Handle<PropertyCell> PropertyCell::InvalidateEntry(
   19015             :     Handle<GlobalDictionary> dictionary, int entry) {
   19016             :   Isolate* isolate = dictionary->GetIsolate();
   19017             :   // Swap with a copy.
   19018             :   Handle<PropertyCell> cell(dictionary->CellAt(entry));
   19019             :   Handle<Name> name(cell->name(), isolate);
   19020       19912 :   Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell(name);
   19021       19912 :   new_cell->set_value(cell->value());
   19022             :   dictionary->ValueAtPut(entry, *new_cell);
   19023             :   bool is_the_hole = cell->value()->IsTheHole(isolate);
   19024             :   // Cell is officially mutable henceforth.
   19025             :   PropertyDetails details = cell->property_details();
   19026             :   details = details.set_cell_type(is_the_hole ? PropertyCellType::kUninitialized
   19027       19912 :                                               : PropertyCellType::kMutable);
   19028             :   new_cell->set_property_details(details);
   19029             :   // Old cell is ready for invalidation.
   19030       19912 :   if (is_the_hole) {
   19031       17432 :     cell->set_value(isolate->heap()->undefined_value());
   19032             :   } else {
   19033       22392 :     cell->set_value(isolate->heap()->the_hole_value());
   19034             :   }
   19035             :   details = details.set_cell_type(PropertyCellType::kInvalidated);
   19036             :   cell->set_property_details(details);
   19037             :   cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19038       19912 :       isolate, DependentCode::kPropertyCellChangedGroup);
   19039       19912 :   return new_cell;
   19040             : }
   19041             : 
   19042             : 
   19043           0 : PropertyCellConstantType PropertyCell::GetConstantType() {
   19044           0 :   if (value()->IsSmi()) return PropertyCellConstantType::kSmi;
   19045           0 :   return PropertyCellConstantType::kStableMap;
   19046             : }
   19047             : 
   19048             : 
   19049      860231 : static bool RemainsConstantType(Handle<PropertyCell> cell,
   19050             :                                 Handle<Object> value) {
   19051             :   // TODO(dcarney): double->smi and smi->double transition from kConstant
   19052     1654047 :   if (cell->value()->IsSmi() && value->IsSmi()) {
   19053             :     return true;
   19054      134536 :   } else if (cell->value()->IsHeapObject() && value->IsHeapObject()) {
   19055             :     return HeapObject::cast(cell->value())->map() ==
   19056      122095 :                HeapObject::cast(*value)->map() &&
   19057       65661 :            HeapObject::cast(*value)->map()->is_stable();
   19058             :   }
   19059             :   return false;
   19060             : }
   19061             : 
   19062             : 
   19063     9471597 : PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell,
   19064             :                                            Handle<Object> value,
   19065             :                                            PropertyDetails details) {
   19066             :   PropertyCellType type = details.cell_type();
   19067             :   Isolate* isolate = cell->GetIsolate();
   19068             :   DCHECK(!value->IsTheHole(isolate));
   19069     9471597 :   if (cell->value()->IsTheHole(isolate)) {
   19070     7173698 :     switch (type) {
   19071             :       // Only allow a cell to transition once into constant state.
   19072             :       case PropertyCellType::kUninitialized:
   19073     7173698 :         if (value->IsUndefined(isolate)) return PropertyCellType::kUndefined;
   19074     5752462 :         return PropertyCellType::kConstant;
   19075             :       case PropertyCellType::kInvalidated:
   19076             :         return PropertyCellType::kMutable;
   19077             :       default:
   19078           0 :         UNREACHABLE();
   19079             :     }
   19080             :   }
   19081     2297899 :   switch (type) {
   19082             :     case PropertyCellType::kUndefined:
   19083             :       return PropertyCellType::kConstant;
   19084             :     case PropertyCellType::kConstant:
   19085       62907 :       if (*value == cell->value()) return PropertyCellType::kConstant;
   19086             :     // Fall through.
   19087             :     case PropertyCellType::kConstantType:
   19088      860231 :       if (RemainsConstantType(cell, value)) {
   19089             :         return PropertyCellType::kConstantType;
   19090             :       }
   19091             :     // Fall through.
   19092             :     case PropertyCellType::kMutable:
   19093             :       return PropertyCellType::kMutable;
   19094             :   }
   19095           0 :   UNREACHABLE();
   19096             : }
   19097             : 
   19098     2305281 : Handle<PropertyCell> PropertyCell::PrepareForValue(
   19099             :     Handle<GlobalDictionary> dictionary, int entry, Handle<Object> value,
   19100             :     PropertyDetails details) {
   19101             :   Isolate* isolate = dictionary->GetIsolate();
   19102             :   DCHECK(!value->IsTheHole(isolate));
   19103             :   Handle<PropertyCell> cell(dictionary->CellAt(entry));
   19104             :   const PropertyDetails original_details = cell->property_details();
   19105             :   // Data accesses could be cached in ics or optimized code.
   19106             :   bool invalidate =
   19107     6907569 :       (original_details.kind() == kData && details.kind() == kAccessor) ||
   19108     2297633 :       (!original_details.IsReadOnly() && details.IsReadOnly());
   19109             :   int index;
   19110             :   PropertyCellType old_type = original_details.cell_type();
   19111             :   // Preserve the enumeration index unless the property was deleted or never
   19112             :   // initialized.
   19113     2305281 :   if (cell->value()->IsTheHole(isolate)) {
   19114             :     index = dictionary->NextEnumerationIndex();
   19115        7382 :     dictionary->SetNextEnumerationIndex(index + 1);
   19116             :   } else {
   19117             :     index = original_details.dictionary_index();
   19118             :   }
   19119             :   DCHECK_LT(0, index);
   19120             :   details = details.set_index(index);
   19121             : 
   19122     2305281 :   PropertyCellType new_type = UpdatedType(cell, value, original_details);
   19123     2305281 :   if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry);
   19124             : 
   19125             :   // Install new property details.
   19126             :   details = details.set_cell_type(new_type);
   19127             :   cell->set_property_details(details);
   19128             : 
   19129             :   // Deopt when transitioning from a constant type.
   19130     3258323 :   if (!invalidate && (old_type != new_type ||
   19131             :                       original_details.IsReadOnly() != details.IsReadOnly())) {
   19132             :     cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19133     1344535 :         isolate, DependentCode::kPropertyCellChangedGroup);
   19134             :   }
   19135     2305281 :   return cell;
   19136             : }
   19137             : 
   19138             : 
   19139             : // static
   19140         856 : void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell,
   19141             :                                             Handle<Object> new_value) {
   19142         856 :   if (cell->value() != *new_value) {
   19143         856 :     cell->set_value(*new_value);
   19144             :     Isolate* isolate = cell->GetIsolate();
   19145             :     cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19146         856 :         isolate, DependentCode::kPropertyCellChangedGroup);
   19147             :   }
   19148         856 : }
   19149             : 
   19150        1420 : int JSGeneratorObject::source_position() const {
   19151        1420 :   CHECK(is_suspended());
   19152             :   DCHECK(function()->shared()->HasBytecodeArray());
   19153             : 
   19154             :   int code_offset = Smi::ToInt(input_or_debug_pos());
   19155             : 
   19156             :   // The stored bytecode offset is relative to a different base than what
   19157             :   // is used in the source position table, hence the subtraction.
   19158        1420 :   code_offset -= BytecodeArray::kHeaderSize - kHeapObjectTag;
   19159             :   AbstractCode* code =
   19160             :       AbstractCode::cast(function()->shared()->bytecode_array());
   19161        1420 :   return code->SourcePosition(code_offset);
   19162             : }
   19163             : 
   19164             : // static
   19165        6622 : AccessCheckInfo* AccessCheckInfo::Get(Isolate* isolate,
   19166             :                                       Handle<JSObject> receiver) {
   19167             :   DisallowHeapAllocation no_gc;
   19168             :   DCHECK(receiver->map()->is_access_check_needed());
   19169        6622 :   Object* maybe_constructor = receiver->map()->GetConstructor();
   19170        6622 :   if (maybe_constructor->IsFunctionTemplateInfo()) {
   19171             :     Object* data_obj =
   19172             :         FunctionTemplateInfo::cast(maybe_constructor)->access_check_info();
   19173         174 :     if (data_obj->IsUndefined(isolate)) return nullptr;
   19174         174 :     return AccessCheckInfo::cast(data_obj);
   19175             :   }
   19176             :   // Might happen for a detached context.
   19177        6448 :   if (!maybe_constructor->IsJSFunction()) return nullptr;
   19178             :   JSFunction* constructor = JSFunction::cast(maybe_constructor);
   19179             :   // Might happen for the debug context.
   19180        6421 :   if (!constructor->shared()->IsApiFunction()) return nullptr;
   19181             : 
   19182             :   Object* data_obj =
   19183             :       constructor->shared()->get_api_func_data()->access_check_info();
   19184        4251 :   if (data_obj->IsUndefined(isolate)) return nullptr;
   19185             : 
   19186        3694 :   return AccessCheckInfo::cast(data_obj);
   19187             : }
   19188             : 
   19189        4247 : bool JSReceiver::HasProxyInPrototype(Isolate* isolate) {
   19190       17548 :   for (PrototypeIterator iter(isolate, this, kStartAtReceiver,
   19191             :                               PrototypeIterator::END_AT_NULL);
   19192       13301 :        !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) {
   19193       26658 :     if (iter.GetCurrent<Object>()->IsJSProxy()) return true;
   19194             :   }
   19195        4219 :   return false;
   19196             : }
   19197             : 
   19198       16583 : bool JSReceiver::HasComplexElements() {
   19199       16583 :   if (IsJSProxy()) return true;
   19200             :   JSObject* this_object = JSObject::cast(this);
   19201       16583 :   if (this_object->HasIndexedInterceptor()) {
   19202             :     return true;
   19203             :   }
   19204       16583 :   if (!this_object->HasDictionaryElements()) return false;
   19205        6707 :   return this_object->element_dictionary()->HasComplexElements();
   19206             : }
   19207             : 
   19208     6267008 : MaybeHandle<Name> FunctionTemplateInfo::TryGetCachedPropertyName(
   19209             :     Isolate* isolate, Handle<Object> getter) {
   19210     6267008 :   if (getter->IsFunctionTemplateInfo()) {
   19211             :     Handle<FunctionTemplateInfo> fti =
   19212             :         Handle<FunctionTemplateInfo>::cast(getter);
   19213             :     // Check if the accessor uses a cached property.
   19214        1085 :     if (!fti->cached_property_name()->IsTheHole(isolate)) {
   19215         104 :       return handle(Name::cast(fti->cached_property_name()));
   19216             :     }
   19217             :   }
   19218     6266904 :   return MaybeHandle<Name>();
   19219             : }
   19220             : 
   19221             : // static
   19222         683 : ElementsKind JSArrayIterator::ElementsKindForInstanceType(InstanceType type) {
   19223             :   DCHECK_GE(type, FIRST_ARRAY_ITERATOR_TYPE);
   19224             :   DCHECK_LE(type, LAST_ARRAY_ITERATOR_TYPE);
   19225             : 
   19226         683 :   if (type <= LAST_ARRAY_KEY_ITERATOR_TYPE) {
   19227             :     // Should be ignored for key iterators.
   19228             :     return PACKED_ELEMENTS;
   19229             :   } else {
   19230             :     ElementsKind kind;
   19231         675 :     if (type < FIRST_ARRAY_VALUE_ITERATOR_TYPE) {
   19232             :       // Convert `type` to a value iterator from an entries iterator
   19233             :       type = static_cast<InstanceType>(type +
   19234             :                                        (FIRST_ARRAY_VALUE_ITERATOR_TYPE -
   19235          14 :                                         FIRST_ARRAY_KEY_VALUE_ITERATOR_TYPE));
   19236             :       DCHECK_GE(type, FIRST_ARRAY_VALUE_ITERATOR_TYPE);
   19237             :       DCHECK_LE(type, LAST_ARRAY_ITERATOR_TYPE);
   19238             :     }
   19239             : 
   19240         675 :     if (type <= JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE) {
   19241             :       kind =
   19242          50 :           static_cast<ElementsKind>(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND +
   19243          50 :                                     (type - FIRST_ARRAY_VALUE_ITERATOR_TYPE));
   19244             :       DCHECK_LE(kind, LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND);
   19245         625 :     } else if (type < JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE) {
   19246             :       kind = static_cast<ElementsKind>(
   19247         625 :           FIRST_FAST_ELEMENTS_KIND +
   19248         625 :           (type - JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE));
   19249             :       DCHECK_LE(kind, LAST_FAST_ELEMENTS_KIND);
   19250             :     } else {
   19251             :       // For any slow element cases, the actual elements kind is not known.
   19252             :       // Simply
   19253             :       // return a slow elements kind in this case. Users of this function must
   19254             :       // not
   19255             :       // depend on this.
   19256             :       return DICTIONARY_ELEMENTS;
   19257             :     }
   19258             :     DCHECK_LE(kind, LAST_ELEMENTS_KIND);
   19259         675 :     return kind;
   19260             :   }
   19261             : }
   19262             : }  // namespace internal
   19263             : }  // namespace v8

Generated by: LCOV version 1.10