LCOV - code coverage report
Current view: top level - src - objects.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 6064 6755 89.8 %
Date: 2017-04-26 Functions: 843 946 89.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 <unordered_map>
      12             : #include <unordered_set>
      13             : 
      14             : #include "src/objects-inl.h"
      15             : 
      16             : #include "src/accessors.h"
      17             : #include "src/allocation-site-scopes.h"
      18             : #include "src/api-arguments-inl.h"
      19             : #include "src/api-natives.h"
      20             : #include "src/api.h"
      21             : #include "src/arguments.h"
      22             : #include "src/base/bits.h"
      23             : #include "src/base/utils/random-number-generator.h"
      24             : #include "src/bootstrapper.h"
      25             : #include "src/builtins/builtins.h"
      26             : #include "src/code-stubs.h"
      27             : #include "src/codegen.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/full-codegen/full-codegen.h"
      43             : #include "src/globals.h"
      44             : #include "src/ic/ic.h"
      45             : #include "src/identity-map.h"
      46             : #include "src/interpreter/bytecode-array-iterator.h"
      47             : #include "src/interpreter/bytecode-decoder.h"
      48             : #include "src/interpreter/interpreter.h"
      49             : #include "src/isolate-inl.h"
      50             : #include "src/keys.h"
      51             : #include "src/list.h"
      52             : #include "src/log.h"
      53             : #include "src/lookup.h"
      54             : #include "src/macro-assembler.h"
      55             : #include "src/map-updater.h"
      56             : #include "src/messages.h"
      57             : #include "src/objects-body-descriptors-inl.h"
      58             : #include "src/objects/code-cache-inl.h"
      59             : #include "src/objects/compilation-cache-inl.h"
      60             : #include "src/objects/frame-array-inl.h"
      61             : #include "src/property-descriptor.h"
      62             : #include "src/prototype.h"
      63             : #include "src/regexp/jsregexp.h"
      64             : #include "src/safepoint-table.h"
      65             : #include "src/snapshot/code-serializer.h"
      66             : #include "src/source-position-table.h"
      67             : #include "src/string-builder.h"
      68             : #include "src/string-search.h"
      69             : #include "src/string-stream.h"
      70             : #include "src/utils.h"
      71             : #include "src/wasm/wasm-module.h"
      72             : #include "src/wasm/wasm-objects.h"
      73             : #include "src/zone/zone.h"
      74             : 
      75             : #ifdef ENABLE_DISASSEMBLER
      76             : #include "src/disasm.h"
      77             : #include "src/disassembler.h"
      78             : #include "src/eh-frame.h"
      79             : #endif
      80             : 
      81             : namespace v8 {
      82             : namespace internal {
      83             : 
      84       20244 : std::ostream& operator<<(std::ostream& os, InstanceType instance_type) {
      85       20244 :   switch (instance_type) {
      86             : #define WRITE_TYPE(TYPE) \
      87             :   case TYPE:             \
      88             :     return os << #TYPE;
      89           0 :     INSTANCE_TYPE_LIST(WRITE_TYPE)
      90             : #undef WRITE_TYPE
      91             :   }
      92           0 :   UNREACHABLE();
      93             :   return os << "UNKNOWN";  // Keep the compiler happy.
      94             : }
      95             : 
      96    10650139 : Handle<FieldType> Object::OptimalType(Isolate* isolate,
      97             :                                       Representation representation) {
      98    10650139 :   if (representation.IsNone()) return FieldType::None(isolate);
      99    10210057 :   if (FLAG_track_field_types) {
     100    15195444 :     if (representation.IsHeapObject() && IsHeapObject()) {
     101             :       // We can track only JavaScript objects with stable maps.
     102             :       Handle<Map> map(HeapObject::cast(this)->map(), isolate);
     103     8983409 :       if (map->is_stable() && map->IsJSReceiverMap()) {
     104     1604105 :         return FieldType::Class(map, isolate);
     105             :       }
     106             :     }
     107             :   }
     108     8605953 :   return FieldType::Any(isolate);
     109             : }
     110             : 
     111        9188 : MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
     112             :                                          Handle<Object> object,
     113             :                                          Handle<Context> native_context,
     114             :                                          const char* method_name) {
     115        9188 :   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
     116             :   Handle<JSFunction> constructor;
     117        9188 :   if (object->IsSmi()) {
     118         623 :     constructor = handle(native_context->number_function(), isolate);
     119             :   } else {
     120             :     int constructor_function_index =
     121             :         Handle<HeapObject>::cast(object)->map()->GetConstructorFunctionIndex();
     122        8565 :     if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
     123        1696 :       if (method_name != nullptr) {
     124        2154 :         THROW_NEW_ERROR(
     125             :             isolate,
     126             :             NewTypeError(
     127             :                 MessageTemplate::kCalledOnNullOrUndefined,
     128             :                 isolate->factory()->NewStringFromAsciiChecked(method_name)),
     129             :             JSReceiver);
     130             :       }
     131        1956 :       THROW_NEW_ERROR(isolate,
     132             :                       NewTypeError(MessageTemplate::kUndefinedOrNullToObject),
     133             :                       JSReceiver);
     134             :     }
     135             :     constructor = handle(
     136             :         JSFunction::cast(native_context->get(constructor_function_index)),
     137        6869 :         isolate);
     138             :   }
     139        7492 :   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
     140        7492 :   Handle<JSValue>::cast(result)->set_value(*object);
     141             :   return result;
     142             : }
     143             : 
     144             : // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
     145             : // static
     146       51871 : MaybeHandle<JSReceiver> Object::ConvertReceiver(Isolate* isolate,
     147             :                                                 Handle<Object> object) {
     148       51871 :   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
     149        1124 :   if (*object == isolate->heap()->null_value() ||
     150             :       object->IsUndefined(isolate)) {
     151         313 :     return isolate->global_proxy();
     152             :   }
     153         249 :   return Object::ToObject(isolate, object);
     154             : }
     155             : 
     156             : // static
     157     3454975 : MaybeHandle<Object> Object::ConvertToNumber(Isolate* isolate,
     158             :                                             Handle<Object> input) {
     159             :   while (true) {
     160     3461161 :     if (input->IsNumber()) {
     161             :       return input;
     162             :     }
     163     3437107 :     if (input->IsString()) {
     164       91719 :       return String::ToNumber(Handle<String>::cast(input));
     165             :     }
     166     3345388 :     if (input->IsOddball()) {
     167     3332801 :       return Oddball::ToNumber(Handle<Oddball>::cast(input));
     168             :     }
     169       12587 :     if (input->IsSymbol()) {
     170       10966 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber),
     171             :                       Object);
     172             :     }
     173       14208 :     ASSIGN_RETURN_ON_EXCEPTION(
     174             :         isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
     175             :                                                 ToPrimitiveHint::kNumber),
     176             :         Object);
     177             :   }
     178             : }
     179             : 
     180             : // static
     181       29747 : MaybeHandle<Object> Object::ConvertToInteger(Isolate* isolate,
     182             :                                              Handle<Object> input) {
     183       59494 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ConvertToNumber(isolate, input),
     184             :                              Object);
     185       29393 :   if (input->IsSmi()) return input;
     186       27129 :   return isolate->factory()->NewNumber(DoubleToInteger(input->Number()));
     187             : }
     188             : 
     189             : // static
     190        1232 : MaybeHandle<Object> Object::ConvertToInt32(Isolate* isolate,
     191             :                                            Handle<Object> input) {
     192        2464 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ConvertToNumber(isolate, input),
     193             :                              Object);
     194        1143 :   if (input->IsSmi()) return input;
     195         401 :   return isolate->factory()->NewNumberFromInt(DoubleToInt32(input->Number()));
     196             : }
     197             : 
     198             : // static
     199      533104 : MaybeHandle<Object> Object::ConvertToUint32(Isolate* isolate,
     200             :                                             Handle<Object> input) {
     201     1066208 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ConvertToNumber(isolate, input),
     202             :                              Object);
     203      533075 :   if (input->IsSmi()) return handle(Smi::cast(*input)->ToUint32Smi(), isolate);
     204         363 :   return isolate->factory()->NewNumberFromUint(DoubleToUint32(input->Number()));
     205             : }
     206             : 
     207             : // static
     208     4574502 : MaybeHandle<Name> Object::ConvertToName(Isolate* isolate,
     209             :                                         Handle<Object> input) {
     210     9149004 :   ASSIGN_RETURN_ON_EXCEPTION(
     211             :       isolate, input, Object::ToPrimitive(input, ToPrimitiveHint::kString),
     212             :       Name);
     213     4574247 :   if (input->IsName()) return Handle<Name>::cast(input);
     214      136620 :   return ToString(isolate, input);
     215             : }
     216             : 
     217             : // ES6 7.1.14
     218             : // static
     219         744 : MaybeHandle<Object> Object::ConvertToPropertyKey(Isolate* isolate,
     220             :                                                  Handle<Object> value) {
     221             :   // 1. Let key be ToPrimitive(argument, hint String).
     222             :   MaybeHandle<Object> maybe_key =
     223         744 :       Object::ToPrimitive(value, ToPrimitiveHint::kString);
     224             :   // 2. ReturnIfAbrupt(key).
     225             :   Handle<Object> key;
     226         744 :   if (!maybe_key.ToHandle(&key)) return key;
     227             :   // 3. If Type(key) is Symbol, then return key.
     228         744 :   if (key->IsSymbol()) return key;
     229             :   // 4. Return ToString(key).
     230             :   // Extending spec'ed behavior, we'd be happy to return an element index.
     231         744 :   if (key->IsSmi()) return key;
     232         744 :   if (key->IsHeapNumber()) {
     233             :     uint32_t uint_value;
     234          43 :     if (value->ToArrayLength(&uint_value) &&
     235          14 :         uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) {
     236           0 :       return handle(Smi::FromInt(static_cast<int>(uint_value)), isolate);
     237             :     }
     238             :   }
     239        1488 :   return Object::ToString(isolate, key);
     240             : }
     241             : 
     242             : // static
     243     8540016 : MaybeHandle<String> Object::ConvertToString(Isolate* isolate,
     244             :                                             Handle<Object> input) {
     245             :   while (true) {
     246     8821482 :     if (input->IsOddball()) {
     247             :       return handle(Handle<Oddball>::cast(input)->to_string(), isolate);
     248             :     }
     249     6259494 :     if (input->IsNumber()) {
     250      424483 :       return isolate->factory()->NumberToString(input);
     251             :     }
     252     5835011 :     if (input->IsSymbol()) {
     253        6428 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToString),
     254             :                       String);
     255             :     }
     256    11663594 :     ASSIGN_RETURN_ON_EXCEPTION(
     257             :         isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
     258             :                                                 ToPrimitiveHint::kString),
     259             :         String);
     260             :     // The previous isString() check happened in Object::ToString and thus we
     261             :     // put it at the end of the loop in this helper.
     262     5814673 :     if (input->IsString()) {
     263             :       return Handle<String>::cast(input);
     264             :     }
     265             :   }
     266             : }
     267             : 
     268             : namespace {
     269             : 
     270       42081 : bool IsErrorObject(Isolate* isolate, Handle<Object> object) {
     271       42081 :   if (!object->IsJSReceiver()) return false;
     272             :   Handle<Symbol> symbol = isolate->factory()->stack_trace_symbol();
     273       42081 :   return JSReceiver::HasOwnProperty(Handle<JSReceiver>::cast(object), symbol)
     274       84162 :       .FromMaybe(false);
     275             : }
     276             : 
     277       37544 : Handle<String> AsStringOrEmpty(Isolate* isolate, Handle<Object> object) {
     278             :   return object->IsString() ? Handle<String>::cast(object)
     279       75088 :                             : isolate->factory()->empty_string();
     280             : }
     281             : 
     282        5094 : Handle<String> NoSideEffectsErrorToString(Isolate* isolate,
     283             :                                           Handle<Object> input) {
     284        5094 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
     285             : 
     286             :   Handle<Name> name_key = isolate->factory()->name_string();
     287        5094 :   Handle<Object> name = JSReceiver::GetDataProperty(receiver, name_key);
     288        5094 :   Handle<String> name_str = AsStringOrEmpty(isolate, name);
     289             : 
     290             :   Handle<Name> msg_key = isolate->factory()->message_string();
     291        5094 :   Handle<Object> msg = JSReceiver::GetDataProperty(receiver, msg_key);
     292        5094 :   Handle<String> msg_str = AsStringOrEmpty(isolate, msg);
     293             : 
     294        5094 :   if (name_str->length() == 0) return msg_str;
     295        5064 :   if (msg_str->length() == 0) return name_str;
     296             : 
     297        4923 :   IncrementalStringBuilder builder(isolate);
     298        4923 :   builder.AppendString(name_str);
     299             :   builder.AppendCString(": ");
     300        4923 :   builder.AppendString(msg_str);
     301             : 
     302        9846 :   return builder.Finish().ToHandleChecked();
     303             : }
     304             : 
     305             : }  // namespace
     306             : 
     307             : // static
     308     3697969 : Handle<String> Object::NoSideEffectsToString(Isolate* isolate,
     309             :                                              Handle<Object> input) {
     310     3697969 :   DisallowJavascriptExecution no_js(isolate);
     311             : 
     312     8920790 :   if (input->IsString() || input->IsNumber() || input->IsOddball()) {
     313     7307096 :     return Object::ToString(isolate, input).ToHandleChecked();
     314       44421 :   } else if (input->IsFunction()) {
     315             :     // -- F u n c t i o n
     316             :     Handle<String> fun_str;
     317         858 :     if (input->IsJSBoundFunction()) {
     318           0 :       fun_str = JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(input));
     319             :     } else {
     320             :       DCHECK(input->IsJSFunction());
     321         858 :       fun_str = JSFunction::ToString(Handle<JSFunction>::cast(input));
     322             :     }
     323             : 
     324         858 :     if (fun_str->length() > 128) {
     325          15 :       IncrementalStringBuilder builder(isolate);
     326          15 :       builder.AppendString(isolate->factory()->NewSubString(fun_str, 0, 111));
     327             :       builder.AppendCString("...<omitted>...");
     328             :       builder.AppendString(isolate->factory()->NewSubString(
     329          15 :           fun_str, fun_str->length() - 2, fun_str->length()));
     330             : 
     331          30 :       return builder.Finish().ToHandleChecked();
     332             :     }
     333         843 :     return fun_str;
     334       43563 :   } else if (input->IsSymbol()) {
     335             :     // -- S y m b o l
     336             :     Handle<Symbol> symbol = Handle<Symbol>::cast(input);
     337             : 
     338        1482 :     IncrementalStringBuilder builder(isolate);
     339             :     builder.AppendCString("Symbol(");
     340        1482 :     if (symbol->name()->IsString()) {
     341         838 :       builder.AppendString(handle(String::cast(symbol->name()), isolate));
     342             :     }
     343             :     builder.AppendCharacter(')');
     344             : 
     345        2964 :     return builder.Finish().ToHandleChecked();
     346       42081 :   } else if (input->IsJSReceiver()) {
     347             :     // -- J S R e c e i v e r
     348       42081 :     Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
     349             :     Handle<Object> to_string = JSReceiver::GetDataProperty(
     350       42081 :         receiver, isolate->factory()->toString_string());
     351             : 
     352      126243 :     if (IsErrorObject(isolate, input) ||
     353      116085 :         *to_string == *isolate->error_to_string()) {
     354             :       // When internally formatting error objects, use a side-effects-free
     355             :       // version of Error.prototype.toString independent of the actually
     356             :       // installed toString method.
     357       36833 :       return NoSideEffectsErrorToString(isolate, input);
     358       73974 :     } else if (*to_string == *isolate->object_to_string()) {
     359             :       Handle<Object> ctor = JSReceiver::GetDataProperty(
     360       27790 :           receiver, isolate->factory()->constructor_string());
     361       27790 :       if (ctor->IsFunction()) {
     362             :         Handle<String> ctor_name;
     363       27356 :         if (ctor->IsJSBoundFunction()) {
     364             :           ctor_name = JSBoundFunction::GetName(
     365             :                           isolate, Handle<JSBoundFunction>::cast(ctor))
     366           0 :                           .ToHandleChecked();
     367       27356 :         } else if (ctor->IsJSFunction()) {
     368             :           Handle<Object> ctor_name_obj =
     369       27356 :               JSFunction::GetName(isolate, Handle<JSFunction>::cast(ctor));
     370       27356 :           ctor_name = AsStringOrEmpty(isolate, ctor_name_obj);
     371             :         }
     372             : 
     373       27356 :         if (ctor_name->length() != 0) {
     374       26645 :           IncrementalStringBuilder builder(isolate);
     375             :           builder.AppendCString("#<");
     376       26645 :           builder.AppendString(ctor_name);
     377             :           builder.AppendCString(">");
     378             : 
     379       53290 :           return builder.Finish().ToHandleChecked();
     380             :         }
     381             :       }
     382             :     }
     383             :   }
     384             : 
     385             :   // At this point, input is either none of the above or a JSReceiver.
     386             : 
     387             :   Handle<JSReceiver> receiver;
     388       10342 :   if (input->IsJSReceiver()) {
     389             :     receiver = Handle<JSReceiver>::cast(input);
     390             :   } else {
     391             :     // This is the only case where Object::ToObject throws.
     392             :     DCHECK(!input->IsSmi());
     393             :     int constructor_function_index =
     394             :         Handle<HeapObject>::cast(input)->map()->GetConstructorFunctionIndex();
     395           0 :     if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
     396           0 :       return isolate->factory()->NewStringFromAsciiChecked("[object Unknown]");
     397             :     }
     398             : 
     399             :     receiver = Object::ToObject(isolate, input, isolate->native_context())
     400           0 :                    .ToHandleChecked();
     401             :   }
     402             : 
     403       10342 :   Handle<String> builtin_tag = handle(receiver->class_name(), isolate);
     404             :   Handle<Object> tag_obj = JSReceiver::GetDataProperty(
     405       10342 :       receiver, isolate->factory()->to_string_tag_symbol());
     406             :   Handle<String> tag =
     407       10342 :       tag_obj->IsString() ? Handle<String>::cast(tag_obj) : builtin_tag;
     408             : 
     409       10342 :   IncrementalStringBuilder builder(isolate);
     410             :   builder.AppendCString("[object ");
     411       10342 :   builder.AppendString(tag);
     412             :   builder.AppendCString("]");
     413             : 
     414       20684 :   return builder.Finish().ToHandleChecked();
     415             : }
     416             : 
     417             : // static
     418        1058 : MaybeHandle<Object> Object::ConvertToLength(Isolate* isolate,
     419             :                                             Handle<Object> input) {
     420        2116 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
     421         918 :   if (input->IsSmi()) {
     422         672 :     int value = std::max(Smi::cast(*input)->value(), 0);
     423             :     return handle(Smi::FromInt(value), isolate);
     424             :   }
     425         694 :   double len = DoubleToInteger(input->Number());
     426         694 :   if (len <= 0.0) {
     427             :     return handle(Smi::kZero, isolate);
     428         212 :   } else if (len >= kMaxSafeInteger) {
     429             :     len = kMaxSafeInteger;
     430             :   }
     431         212 :   return isolate->factory()->NewNumber(len);
     432             : }
     433             : 
     434             : // static
     435        5303 : MaybeHandle<Object> Object::ConvertToIndex(
     436             :     Isolate* isolate, Handle<Object> input,
     437             :     MessageTemplate::Template error_index) {
     438        5303 :   if (input->IsUndefined(isolate)) return handle(Smi::kZero, isolate);
     439        4932 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
     440        3224 :   if (input->IsSmi() && Smi::cast(*input)->value() >= 0) return input;
     441        2408 :   double len = DoubleToInteger(input->Number()) + 0.0;
     442        2408 :   auto js_len = isolate->factory()->NewNumber(len);
     443        2408 :   if (len < 0.0 || len > kMaxSafeInteger) {
     444        1400 :     THROW_NEW_ERROR(isolate, NewRangeError(error_index, js_len), Object);
     445             :   }
     446             :   return js_len;
     447             : }
     448             : 
     449     7197291 : bool Object::BooleanValue() {
     450     7746941 :   if (IsSmi()) return Smi::cast(this)->value() != 0;
     451             :   DCHECK(IsHeapObject());
     452             :   Isolate* isolate = HeapObject::cast(this)->GetIsolate();
     453     9295178 :   if (IsBoolean()) return IsTrue(isolate);
     454     4000108 :   if (IsNullOrUndefined(isolate)) return false;
     455     3865696 :   if (IsUndetectable()) return false;  // Undetectable object is false.
     456     4626247 :   if (IsString()) return String::cast(this)->length() != 0;
     457     3169526 :   if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue();
     458             :   return true;
     459             : }
     460             : 
     461             : 
     462             : namespace {
     463             : 
     464             : // TODO(bmeurer): Maybe we should introduce a marker interface Number,
     465             : // where we put all these methods at some point?
     466             : ComparisonResult NumberCompare(double x, double y) {
     467      222871 :   if (std::isnan(x) || std::isnan(y)) {
     468             :     return ComparisonResult::kUndefined;
     469       89080 :   } else if (x < y) {
     470             :     return ComparisonResult::kLessThan;
     471       51564 :   } else if (x > y) {
     472             :     return ComparisonResult::kGreaterThan;
     473             :   } else {
     474             :     return ComparisonResult::kEqual;
     475             :   }
     476             : }
     477             : 
     478             : 
     479             : bool NumberEquals(double x, double y) {
     480             :   // Must check explicitly for NaN's on Windows, but -0 works fine.
     481        6795 :   if (std::isnan(x)) return false;
     482        6658 :   if (std::isnan(y)) return false;
     483        6557 :   return x == y;
     484             : }
     485             : 
     486             : 
     487        6795 : bool NumberEquals(const Object* x, const Object* y) {
     488        6795 :   return NumberEquals(x->Number(), y->Number());
     489             : }
     490             : 
     491             : 
     492             : bool NumberEquals(Handle<Object> x, Handle<Object> y) {
     493        5146 :   return NumberEquals(*x, *y);
     494             : }
     495             : 
     496             : }  // namespace
     497             : 
     498             : 
     499             : // static
     500      224205 : Maybe<ComparisonResult> Object::Compare(Handle<Object> x, Handle<Object> y) {
     501             :   // ES6 section 7.2.11 Abstract Relational Comparison step 3 and 4.
     502      896604 :   if (!Object::ToPrimitive(x, ToPrimitiveHint::kNumber).ToHandle(&x) ||
     503      448194 :       !Object::ToPrimitive(y, ToPrimitiveHint::kNumber).ToHandle(&y)) {
     504             :     return Nothing<ComparisonResult>();
     505             :   }
     506      289087 :   if (x->IsString() && y->IsString()) {
     507             :     // ES6 section 7.2.11 Abstract Relational Comparison step 5.
     508             :     return Just(
     509         938 :         String::Compare(Handle<String>::cast(x), Handle<String>::cast(y)));
     510             :   }
     511             :   // ES6 section 7.2.11 Abstract Relational Comparison step 6.
     512      668949 :   if (!Object::ToNumber(x).ToHandle(&x) || !Object::ToNumber(y).ToHandle(&y)) {
     513             :     return Nothing<ComparisonResult>();
     514             :   }
     515             :   return Just(NumberCompare(x->Number(), y->Number()));
     516             : }
     517             : 
     518             : 
     519             : // static
     520      193238 : Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
     521             :   // This is the generic version of Abstract Equality Comparison; a version in
     522             :   // JavaScript land is available in the EqualStub and NotEqualStub. Whenever
     523             :   // you change something functionality wise in here, remember to update the
     524             :   // TurboFan code stubs as well.
     525             :   while (true) {
     526      193245 :     if (x->IsNumber()) {
     527        5070 :       if (y->IsNumber()) {
     528             :         return Just(NumberEquals(x, y));
     529         112 :       } else if (y->IsBoolean()) {
     530           0 :         return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
     531         112 :       } else if (y->IsString()) {
     532         112 :         return Just(NumberEquals(x, String::ToNumber(Handle<String>::cast(y))));
     533           0 :       } else if (y->IsJSReceiver()) {
     534           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     535           0 :                  .ToHandle(&y)) {
     536             :           return Nothing<bool>();
     537             :         }
     538             :       } else {
     539             :         return Just(false);
     540             :       }
     541      188175 :     } else if (x->IsString()) {
     542      168455 :       if (y->IsString()) {
     543             :         return Just(
     544      168379 :             String::Equals(Handle<String>::cast(x), Handle<String>::cast(y)));
     545          76 :       } else if (y->IsNumber()) {
     546          76 :         x = String::ToNumber(Handle<String>::cast(x));
     547             :         return Just(NumberEquals(x, y));
     548           0 :       } else if (y->IsBoolean()) {
     549           0 :         x = String::ToNumber(Handle<String>::cast(x));
     550           0 :         return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
     551           0 :       } else if (y->IsJSReceiver()) {
     552           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     553           0 :                  .ToHandle(&y)) {
     554             :           return Nothing<bool>();
     555             :         }
     556             :       } else {
     557             :         return Just(false);
     558             :       }
     559       19720 :     } else if (x->IsBoolean()) {
     560         700 :       if (y->IsOddball()) {
     561             :         return Just(x.is_identical_to(y));
     562           0 :       } else if (y->IsNumber()) {
     563           0 :         return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
     564           0 :       } else if (y->IsString()) {
     565           0 :         y = String::ToNumber(Handle<String>::cast(y));
     566           0 :         return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
     567           0 :       } else if (y->IsJSReceiver()) {
     568           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     569           0 :                  .ToHandle(&y)) {
     570             :           return Nothing<bool>();
     571             :         }
     572           0 :         x = Oddball::ToNumber(Handle<Oddball>::cast(x));
     573             :       } else {
     574             :         return Just(false);
     575             :       }
     576       19020 :     } else if (x->IsSymbol()) {
     577          63 :       if (y->IsSymbol()) {
     578             :         return Just(x.is_identical_to(y));
     579           0 :       } else if (y->IsJSReceiver()) {
     580           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     581           0 :                  .ToHandle(&y)) {
     582             :           return Nothing<bool>();
     583             :         }
     584             :       } else {
     585             :         return Just(false);
     586             :       }
     587       18957 :     } else if (x->IsJSReceiver()) {
     588       18835 :       if (y->IsJSReceiver()) {
     589             :         return Just(x.is_identical_to(y));
     590           7 :       } else if (y->IsUndetectable()) {
     591             :         return Just(x->IsUndetectable());
     592           7 :       } else if (y->IsBoolean()) {
     593           0 :         y = Oddball::ToNumber(Handle<Oddball>::cast(y));
     594           7 :       } else if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x))
     595          14 :                       .ToHandle(&x)) {
     596             :         return Nothing<bool>();
     597             :       }
     598             :     } else {
     599         244 :       return Just(x->IsUndetectable() && y->IsUndetectable());
     600             :     }
     601             :   }
     602             : }
     603             : 
     604             : 
     605       16129 : bool Object::StrictEquals(Object* that) {
     606       16129 :   if (this->IsNumber()) {
     607        2466 :     if (!that->IsNumber()) return false;
     608        1649 :     return NumberEquals(this, that);
     609       13663 :   } else if (this->IsString()) {
     610       12013 :     if (!that->IsString()) return false;
     611       11922 :     return String::cast(this)->Equals(String::cast(that));
     612             :   }
     613        1650 :   return this == that;
     614             : }
     615             : 
     616             : 
     617             : // static
     618       22073 : Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
     619       22073 :   if (object->IsNumber()) return isolate->factory()->number_string();
     620       21229 :   if (object->IsOddball()) return handle(Oddball::cast(*object)->type_of());
     621       19076 :   if (object->IsUndetectable()) {
     622             :     return isolate->factory()->undefined_string();
     623             :   }
     624       19076 :   if (object->IsString()) return isolate->factory()->string_string();
     625       17832 :   if (object->IsSymbol()) return isolate->factory()->symbol_string();
     626       17759 :   if (object->IsString()) return isolate->factory()->string_string();
     627       17759 :   if (object->IsCallable()) return isolate->factory()->function_string();
     628             :   return isolate->factory()->object_string();
     629             : }
     630             : 
     631             : 
     632             : // static
     633       43229 : MaybeHandle<Object> Object::Multiply(Isolate* isolate, Handle<Object> lhs,
     634             :                                      Handle<Object> rhs) {
     635       83480 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     636        6054 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     637        5410 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     638             :   }
     639       42907 :   return isolate->factory()->NewNumber(lhs->Number() * rhs->Number());
     640             : }
     641             : 
     642             : 
     643             : // static
     644       11601 : MaybeHandle<Object> Object::Divide(Isolate* isolate, Handle<Object> lhs,
     645             :                                    Handle<Object> rhs) {
     646       23143 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     647         172 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     648         160 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     649             :   }
     650       11595 :   return isolate->factory()->NewNumber(lhs->Number() / rhs->Number());
     651             : }
     652             : 
     653             : 
     654             : // static
     655        5188 : MaybeHandle<Object> Object::Modulus(Isolate* isolate, Handle<Object> lhs,
     656             :                                     Handle<Object> rhs) {
     657       10310 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     658         162 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     659         150 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     660             :   }
     661        5182 :   return isolate->factory()->NewNumber(modulo(lhs->Number(), rhs->Number()));
     662             : }
     663             : 
     664             : 
     665             : // static
     666      226109 : MaybeHandle<Object> Object::Add(Isolate* isolate, Handle<Object> lhs,
     667             :                                 Handle<Object> rhs) {
     668      403720 :   if (lhs->IsNumber() && rhs->IsNumber()) {
     669      172810 :     return isolate->factory()->NewNumber(lhs->Number() + rhs->Number());
     670       96789 :   } else if (lhs->IsString() && rhs->IsString()) {
     671             :     return isolate->factory()->NewConsString(Handle<String>::cast(lhs),
     672       73824 :                                              Handle<String>::cast(rhs));
     673             :   }
     674       32774 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToPrimitive(lhs), Object);
     675       27548 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToPrimitive(rhs), Object);
     676       19865 :   if (lhs->IsString() || rhs->IsString()) {
     677       23562 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToString(isolate, rhs),
     678             :                                Object);
     679       23550 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToString(isolate, lhs),
     680             :                                Object);
     681             :     return isolate->factory()->NewConsString(Handle<String>::cast(lhs),
     682       22590 :                                              Handle<String>::cast(rhs));
     683             :   }
     684        3974 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     685        3950 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     686        1495 :   return isolate->factory()->NewNumber(lhs->Number() + rhs->Number());
     687             : }
     688             : 
     689             : 
     690             : // static
     691       19324 : MaybeHandle<Object> Object::Subtract(Isolate* isolate, Handle<Object> lhs,
     692             :                                      Handle<Object> rhs) {
     693       38520 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     694         394 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     695         382 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     696             :   }
     697       19318 :   return isolate->factory()->NewNumber(lhs->Number() - rhs->Number());
     698             : }
     699             : 
     700             : 
     701             : // static
     702        9220 : MaybeHandle<Object> Object::ShiftLeft(Isolate* isolate, Handle<Object> lhs,
     703             :                                       Handle<Object> rhs) {
     704       18383 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     705         170 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     706         158 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     707             :   }
     708        9214 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs)
     709        9214 :                                               << (NumberToUint32(*rhs) & 0x1F));
     710             : }
     711             : 
     712             : 
     713             : // static
     714       20886 : MaybeHandle<Object> Object::ShiftRight(Isolate* isolate, Handle<Object> lhs,
     715             :                                        Handle<Object> rhs) {
     716       41700 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     717         238 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     718         226 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     719             :   }
     720       20880 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) >>
     721       20880 :                                               (NumberToUint32(*rhs) & 0x1F));
     722             : }
     723             : 
     724             : 
     725             : // static
     726       10307 : MaybeHandle<Object> Object::ShiftRightLogical(Isolate* isolate,
     727             :                                               Handle<Object> lhs,
     728             :                                               Handle<Object> rhs) {
     729       20486 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     730         326 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     731         314 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     732             :   }
     733       10301 :   return isolate->factory()->NewNumberFromUint(NumberToUint32(*lhs) >>
     734       10301 :                                                (NumberToUint32(*rhs) & 0x1F));
     735             : }
     736             : 
     737             : 
     738             : // static
     739       19596 : MaybeHandle<Object> Object::BitwiseAnd(Isolate* isolate, Handle<Object> lhs,
     740             :                                        Handle<Object> rhs) {
     741       38203 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     742        3682 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     743        3670 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     744             :   }
     745       19590 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) &
     746       19590 :                                               NumberToInt32(*rhs));
     747             : }
     748             : 
     749             : 
     750             : // static
     751       64128 : MaybeHandle<Object> Object::BitwiseOr(Isolate* isolate, Handle<Object> lhs,
     752             :                                       Handle<Object> rhs) {
     753      126788 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     754        4614 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     755        4550 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     756             :   }
     757       64096 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) |
     758       64096 :                                               NumberToInt32(*rhs));
     759             : }
     760             : 
     761             : 
     762             : // static
     763        8276 : MaybeHandle<Object> Object::BitwiseXor(Isolate* isolate, Handle<Object> lhs,
     764             :                                        Handle<Object> rhs) {
     765       16396 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     766         398 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     767         386 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     768             :   }
     769        8270 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) ^
     770        8270 :                                               NumberToInt32(*rhs));
     771             : }
     772             : 
     773             : // static
     774      178699 : MaybeHandle<Object> Object::OrdinaryHasInstance(Isolate* isolate,
     775             :                                                 Handle<Object> callable,
     776             :                                                 Handle<Object> object) {
     777             :   // The {callable} must have a [[Call]] internal method.
     778      178699 :   if (!callable->IsCallable()) return isolate->factory()->false_value();
     779             : 
     780             :   // Check if {callable} is a bound function, and if so retrieve its
     781             :   // [[BoundTargetFunction]] and use that instead of {callable}.
     782      178639 :   if (callable->IsJSBoundFunction()) {
     783             :     Handle<Object> bound_callable(
     784             :         Handle<JSBoundFunction>::cast(callable)->bound_target_function(),
     785             :         isolate);
     786         409 :     return Object::InstanceOf(isolate, object, bound_callable);
     787             :   }
     788             : 
     789             :   // If {object} is not a receiver, return false.
     790      178230 :   if (!object->IsJSReceiver()) return isolate->factory()->false_value();
     791             : 
     792             :   // Get the "prototype" of {callable}; raise an error if it's not a receiver.
     793             :   Handle<Object> prototype;
     794      333454 :   ASSIGN_RETURN_ON_EXCEPTION(
     795             :       isolate, prototype,
     796             :       Object::GetProperty(callable, isolate->factory()->prototype_string()),
     797             :       Object);
     798      166727 :   if (!prototype->IsJSReceiver()) {
     799      331042 :     THROW_NEW_ERROR(
     800             :         isolate,
     801             :         NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype),
     802             :         Object);
     803             :   }
     804             : 
     805             :   // Return whether or not {prototype} is in the prototype chain of {object}.
     806             :   Maybe<bool> result = JSReceiver::HasInPrototypeChain(
     807        1206 :       isolate, Handle<JSReceiver>::cast(object), prototype);
     808        1206 :   if (result.IsNothing()) return MaybeHandle<Object>();
     809        1156 :   return isolate->factory()->ToBoolean(result.FromJust());
     810             : }
     811             : 
     812             : // static
     813         493 : MaybeHandle<Object> Object::InstanceOf(Isolate* isolate, Handle<Object> object,
     814             :                                        Handle<Object> callable) {
     815             :   // The {callable} must be a receiver.
     816         493 :   if (!callable->IsJSReceiver()) {
     817           0 :     THROW_NEW_ERROR(isolate,
     818             :                     NewTypeError(MessageTemplate::kNonObjectInInstanceOfCheck),
     819             :                     Object);
     820             :   }
     821             : 
     822             :   // Lookup the @@hasInstance method on {callable}.
     823             :   Handle<Object> inst_of_handler;
     824         986 :   ASSIGN_RETURN_ON_EXCEPTION(
     825             :       isolate, inst_of_handler,
     826             :       JSReceiver::GetMethod(Handle<JSReceiver>::cast(callable),
     827             :                             isolate->factory()->has_instance_symbol()),
     828             :       Object);
     829         493 :   if (!inst_of_handler->IsUndefined(isolate)) {
     830             :     // Call the {inst_of_handler} on the {callable}.
     831             :     Handle<Object> result;
     832         972 :     ASSIGN_RETURN_ON_EXCEPTION(
     833             :         isolate, result,
     834             :         Execution::Call(isolate, inst_of_handler, callable, 1, &object),
     835             :         Object);
     836         479 :     return isolate->factory()->ToBoolean(result->BooleanValue());
     837             :   }
     838             : 
     839             :   // The {callable} must have a [[Call]] internal method.
     840           7 :   if (!callable->IsCallable()) {
     841          14 :     THROW_NEW_ERROR(
     842             :         isolate, NewTypeError(MessageTemplate::kNonCallableInInstanceOfCheck),
     843             :         Object);
     844             :   }
     845             : 
     846             :   // Fall back to OrdinaryHasInstance with {callable} and {object}.
     847             :   Handle<Object> result;
     848           0 :   ASSIGN_RETURN_ON_EXCEPTION(
     849             :       isolate, result,
     850             :       JSReceiver::OrdinaryHasInstance(isolate, callable, object), Object);
     851             :   return result;
     852             : }
     853             : 
     854     1792631 : Maybe<bool> Object::IsArray(Handle<Object> object) {
     855     1792631 :   if (object->IsJSArray()) return Just(true);
     856     1745689 :   if (object->IsJSProxy()) {
     857             :     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
     858             :     Isolate* isolate = proxy->GetIsolate();
     859        1689 :     if (proxy->IsRevoked()) {
     860             :       isolate->Throw(*isolate->factory()->NewTypeError(
     861             :           MessageTemplate::kProxyRevoked,
     862         252 :           isolate->factory()->NewStringFromAsciiChecked("IsArray")));
     863             :       return Nothing<bool>();
     864             :     }
     865        1605 :     return Object::IsArray(handle(proxy->target(), isolate));
     866             :   }
     867             :   return Just(false);
     868             : }
     869             : 
     870             : 
     871             : // static
     872    17848324 : MaybeHandle<Object> Object::GetMethod(Handle<JSReceiver> receiver,
     873             :                                       Handle<Name> name) {
     874             :   Handle<Object> func;
     875             :   Isolate* isolate = receiver->GetIsolate();
     876    35696648 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, func,
     877             :                              JSReceiver::GetProperty(receiver, name), Object);
     878    17805259 :   if (func->IsNullOrUndefined(isolate)) {
     879             :     return isolate->factory()->undefined_value();
     880             :   }
     881     1628908 :   if (!func->IsCallable()) {
     882         728 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kPropertyNotFunction,
     883             :                                           func, name, receiver),
     884             :                     Object);
     885             :   }
     886             :   return func;
     887             : }
     888             : 
     889             : namespace {
     890       26820 : MaybeHandle<FixedArray> CreateListFromArrayLikeFastPath(
     891             :     Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
     892       51929 :   if (element_types != ElementTypes::kAll || !object->IsJSArray()) {
     893             :     return MaybeHandle<FixedArray>();
     894             :   }
     895             :   Handle<JSArray> array = Handle<JSArray>::cast(object);
     896             :   uint32_t length;
     897        3166 :   if (!array->HasArrayPrototype(isolate) ||
     898        3113 :       !array->length()->ToUint32(&length) || !array->HasFastElements() ||
     899         444 :       !JSObject::PrototypeHasNoElements(isolate, *array)) {
     900             :     return MaybeHandle<FixedArray>();
     901             :   }
     902         360 :   return array->GetElementsAccessor()->CreateListFromArray(isolate, array);
     903             : }
     904             : }  // namespace
     905             : 
     906             : // static
     907       26820 : MaybeHandle<FixedArray> Object::CreateListFromArrayLike(
     908             :     Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
     909             :   // Fast-path for JS_ARRAY_TYPE.
     910             :   MaybeHandle<FixedArray> fast_result =
     911       26820 :       CreateListFromArrayLikeFastPath(isolate, object, element_types);
     912       26820 :   if (!fast_result.is_null()) return fast_result;
     913             :   // 1. ReturnIfAbrupt(object).
     914             :   // 2. (default elementTypes -- not applicable.)
     915             :   // 3. If Type(obj) is not Object, throw a TypeError exception.
     916       26460 :   if (!object->IsJSReceiver()) {
     917        1773 :     THROW_NEW_ERROR(isolate,
     918             :                     NewTypeError(MessageTemplate::kCalledOnNonObject,
     919             :                                  isolate->factory()->NewStringFromAsciiChecked(
     920             :                                      "CreateListFromArrayLike")),
     921             :                     FixedArray);
     922             :   }
     923             : 
     924             :   // 4. Let len be ? ToLength(? Get(obj, "length")).
     925             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
     926             :   Handle<Object> raw_length_number;
     927       51738 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, raw_length_number,
     928             :                              Object::GetLengthFromArrayLike(isolate, receiver),
     929             :                              FixedArray);
     930             :   uint32_t len;
     931       51612 :   if (!raw_length_number->ToUint32(&len) ||
     932       25799 :       len > static_cast<uint32_t>(FixedArray::kMaxLength)) {
     933          84 :     THROW_NEW_ERROR(isolate,
     934             :                     NewRangeError(MessageTemplate::kInvalidArrayLength),
     935             :                     FixedArray);
     936             :   }
     937             :   // 5. Let list be an empty List.
     938       25771 :   Handle<FixedArray> list = isolate->factory()->NewFixedArray(len);
     939             :   // 6. Let index be 0.
     940             :   // 7. Repeat while index < len:
     941    62455083 :   for (uint32_t index = 0; index < len; ++index) {
     942             :     // 7a. Let indexName be ToString(index).
     943             :     // 7b. Let next be ? Get(obj, indexName).
     944             :     Handle<Object> next;
     945   124858848 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, next,
     946             :                                JSReceiver::GetElement(isolate, receiver, index),
     947             :                                FixedArray);
     948    62429368 :     switch (element_types) {
     949             :       case ElementTypes::kAll:
     950             :         // Nothing to do.
     951             :         break;
     952             :       case ElementTypes::kStringAndSymbol: {
     953             :         // 7c. If Type(next) is not an element of elementTypes, throw a
     954             :         //     TypeError exception.
     955        4247 :         if (!next->IsName()) {
     956         112 :           THROW_NEW_ERROR(isolate,
     957             :                           NewTypeError(MessageTemplate::kNotPropertyName, next),
     958             :                           FixedArray);
     959             :         }
     960             :         // 7d. Append next as the last element of list.
     961             :         // Internalize on the fly so we can use pointer identity later.
     962        4191 :         next = isolate->factory()->InternalizeName(Handle<Name>::cast(next));
     963        4191 :         break;
     964             :       }
     965             :     }
     966   124858624 :     list->set(index, *next);
     967             :     // 7e. Set index to index + 1. (See loop header.)
     968             :   }
     969             :   // 8. Return list.
     970             :   return list;
     971             : }
     972             : 
     973             : 
     974             : // static
     975       61941 : MaybeHandle<Object> Object::GetLengthFromArrayLike(Isolate* isolate,
     976             :                                                    Handle<Object> object) {
     977             :   Handle<Object> val;
     978             :   Handle<Object> key = isolate->factory()->length_string();
     979      123882 :   ASSIGN_RETURN_ON_EXCEPTION(
     980             :       isolate, val, Runtime::GetObjectProperty(isolate, object, key), Object);
     981       61827 :   return Object::ToLength(isolate, val);
     982             : }
     983             : 
     984             : // static
     985   167014786 : Maybe<bool> JSReceiver::HasProperty(LookupIterator* it) {
     986   166986048 :   for (; it->IsFound(); it->Next()) {
     987    43860599 :     switch (it->state()) {
     988             :       case LookupIterator::NOT_FOUND:
     989             :       case LookupIterator::TRANSITION:
     990           0 :         UNREACHABLE();
     991             :       case LookupIterator::JSPROXY:
     992             :         return JSProxy::HasProperty(it->isolate(), it->GetHolder<JSProxy>(),
     993      136398 :                                     it->GetName());
     994             :       case LookupIterator::INTERCEPTOR: {
     995             :         Maybe<PropertyAttributes> result =
     996         246 :             JSObject::GetPropertyAttributesWithInterceptor(it);
     997         321 :         if (result.IsNothing()) return Nothing<bool>();
     998         246 :         if (result.FromJust() != ABSENT) return Just(true);
     999         171 :         break;
    1000             :       }
    1001             :       case LookupIterator::ACCESS_CHECK: {
    1002       39338 :         if (it->HasAccess()) break;
    1003             :         Maybe<PropertyAttributes> result =
    1004          48 :             JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
    1005          96 :         if (result.IsNothing()) return Nothing<bool>();
    1006           0 :         return Just(result.FromJust() != ABSENT);
    1007             :       }
    1008             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1009             :         // TypedArray out-of-bounds access.
    1010             :         return Just(false);
    1011             :       case LookupIterator::ACCESSOR:
    1012             :       case LookupIterator::DATA:
    1013             :         return Just(true);
    1014             :     }
    1015             :   }
    1016             :   return Just(false);
    1017             : }
    1018             : 
    1019             : 
    1020             : // static
    1021   416928103 : MaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
    1022   384267026 :   for (; it->IsFound(); it->Next()) {
    1023   158434512 :     switch (it->state()) {
    1024             :       case LookupIterator::NOT_FOUND:
    1025             :       case LookupIterator::TRANSITION:
    1026           0 :         UNREACHABLE();
    1027             :       case LookupIterator::JSPROXY: {
    1028             :         bool was_found;
    1029             :         MaybeHandle<Object> result =
    1030             :             JSProxy::GetProperty(it->isolate(), it->GetHolder<JSProxy>(),
    1031      440536 :                                  it->GetName(), it->GetReceiver(), &was_found);
    1032      220268 :         if (!was_found) it->NotFound();
    1033      220268 :         return result;
    1034             :       }
    1035             :       case LookupIterator::INTERCEPTOR: {
    1036             :         bool done;
    1037             :         Handle<Object> result;
    1038       13447 :         ASSIGN_RETURN_ON_EXCEPTION(
    1039             :             it->isolate(), result,
    1040             :             JSObject::GetPropertyWithInterceptor(it, &done), Object);
    1041        5102 :         if (done) return result;
    1042        1901 :         break;
    1043             :       }
    1044             :       case LookupIterator::ACCESS_CHECK:
    1045     1262459 :         if (it->HasAccess()) break;
    1046        1378 :         return JSObject::GetPropertyWithFailedAccessCheck(it);
    1047             :       case LookupIterator::ACCESSOR:
    1048    10153584 :         return GetPropertyWithAccessor(it);
    1049             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1050             :         return it->isolate()->factory()->undefined_value();
    1051             :       case LookupIterator::DATA:
    1052   146788302 :         return it->GetDataValue();
    1053             :     }
    1054             :   }
    1055             :   return it->isolate()->factory()->undefined_value();
    1056             : }
    1057             : 
    1058             : 
    1059             : // static
    1060      220268 : MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate,
    1061             :                                          Handle<JSProxy> proxy,
    1062             :                                          Handle<Name> name,
    1063             :                                          Handle<Object> receiver,
    1064             :                                          bool* was_found) {
    1065      220268 :   *was_found = true;
    1066             : 
    1067             :   DCHECK(!name->IsPrivate());
    1068      220268 :   STACK_CHECK(isolate, MaybeHandle<Object>());
    1069             :   Handle<Name> trap_name = isolate->factory()->get_string();
    1070             :   // 1. Assert: IsPropertyKey(P) is true.
    1071             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    1072             :   Handle<Object> handler(proxy->handler(), isolate);
    1073             :   // 3. If handler is null, throw a TypeError exception.
    1074             :   // 4. Assert: Type(handler) is Object.
    1075      220044 :   if (proxy->IsRevoked()) {
    1076         112 :     THROW_NEW_ERROR(isolate,
    1077             :                     NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
    1078             :                     Object);
    1079             :   }
    1080             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    1081             :   Handle<JSReceiver> target(proxy->target(), isolate);
    1082             :   // 6. Let trap be ? GetMethod(handler, "get").
    1083             :   Handle<Object> trap;
    1084      439976 :   ASSIGN_RETURN_ON_EXCEPTION(
    1085             :       isolate, trap,
    1086             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), Object);
    1087             :   // 7. If trap is undefined, then
    1088      177853 :   if (trap->IsUndefined(isolate)) {
    1089             :     // 7.a Return target.[[Get]](P, Receiver).
    1090             :     LookupIterator it =
    1091      100978 :         LookupIterator::PropertyOrElement(isolate, receiver, name, target);
    1092      100978 :     MaybeHandle<Object> result = Object::GetProperty(&it);
    1093      201956 :     *was_found = it.IsFound();
    1094      100978 :     return result;
    1095             :   }
    1096             :   // 8. Let trapResult be ? Call(trap, handler, «target, P, Receiver»).
    1097             :   Handle<Object> trap_result;
    1098       76875 :   Handle<Object> args[] = {target, name, receiver};
    1099      153750 :   ASSIGN_RETURN_ON_EXCEPTION(
    1100             :       isolate, trap_result,
    1101             :       Execution::Call(isolate, trap, handler, arraysize(args), args), Object);
    1102             :   // 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
    1103             :   PropertyDescriptor target_desc;
    1104             :   Maybe<bool> target_found =
    1105       74323 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    1106       74323 :   MAYBE_RETURN_NULL(target_found);
    1107             :   // 10. If targetDesc is not undefined, then
    1108       74323 :   if (target_found.FromJust()) {
    1109             :     // 10.a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is
    1110             :     //       false and targetDesc.[[Writable]] is false, then
    1111             :     // 10.a.i. If SameValue(trapResult, targetDesc.[[Value]]) is false,
    1112             :     //        throw a TypeError exception.
    1113        6800 :     bool inconsistent = PropertyDescriptor::IsDataDescriptor(&target_desc) &&
    1114        1043 :                         !target_desc.configurable() &&
    1115        6988 :                         !target_desc.writable() &&
    1116         132 :                         !trap_result->SameValue(*target_desc.value());
    1117        6856 :     if (inconsistent) {
    1118          84 :       THROW_NEW_ERROR(
    1119             :           isolate, NewTypeError(MessageTemplate::kProxyGetNonConfigurableData,
    1120             :                                 name, target_desc.value(), trap_result),
    1121             :           Object);
    1122             :     }
    1123             :     // 10.b. If IsAccessorDescriptor(targetDesc) and targetDesc.[[Configurable]]
    1124             :     //       is false and targetDesc.[[Get]] is undefined, then
    1125             :     // 10.b.i. If trapResult is not undefined, throw a TypeError exception.
    1126          56 :     inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
    1127          56 :                    !target_desc.configurable() &&
    1128        6842 :                    target_desc.get()->IsUndefined(isolate) &&
    1129             :                    !trap_result->IsUndefined(isolate);
    1130        6814 :     if (inconsistent) {
    1131          28 :       THROW_NEW_ERROR(
    1132             :           isolate,
    1133             :           NewTypeError(MessageTemplate::kProxyGetNonConfigurableAccessor, name,
    1134             :                        trap_result),
    1135             :           Object);
    1136             :     }
    1137             :   }
    1138             :   // 11. Return trap_result
    1139             :   return trap_result;
    1140             : }
    1141             : 
    1142             : 
    1143    14870391 : Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) {
    1144    14197946 :   for (; it->IsFound(); it->Next()) {
    1145     7058035 :     switch (it->state()) {
    1146             :       case LookupIterator::INTERCEPTOR:
    1147             :       case LookupIterator::NOT_FOUND:
    1148             :       case LookupIterator::TRANSITION:
    1149           0 :         UNREACHABLE();
    1150             :       case LookupIterator::ACCESS_CHECK:
    1151             :         // Support calling this method without an active context, but refuse
    1152             :         // access to access-checked objects in that case.
    1153      891019 :         if (it->isolate()->context() != nullptr && it->HasAccess()) continue;
    1154             :       // Fall through.
    1155             :       case LookupIterator::JSPROXY:
    1156             :         it->NotFound();
    1157        3209 :         return it->isolate()->factory()->undefined_value();
    1158             :       case LookupIterator::ACCESSOR:
    1159             :         // TODO(verwaest): For now this doesn't call into AccessorInfo, since
    1160             :         // clients don't need it. Update once relevant.
    1161             :         it->NotFound();
    1162      627901 :         return it->isolate()->factory()->undefined_value();
    1163             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1164           0 :         return it->isolate()->factory()->undefined_value();
    1165             :       case LookupIterator::DATA:
    1166     5536303 :         return it->GetDataValue();
    1167             :     }
    1168             :   }
    1169       40938 :   return it->isolate()->factory()->undefined_value();
    1170             : }
    1171             : 
    1172             : 
    1173    62870206 : bool Object::ToInt32(int32_t* value) {
    1174    62870206 :   if (IsSmi()) {
    1175    62868679 :     *value = Smi::cast(this)->value();
    1176    62868679 :     return true;
    1177             :   }
    1178        1527 :   if (IsHeapNumber()) {
    1179             :     double num = HeapNumber::cast(this)->value();
    1180        1478 :     if (FastI2D(FastD2I(num)) == num) {
    1181          77 :       *value = FastD2I(num);
    1182          77 :       return true;
    1183             :     }
    1184             :   }
    1185             :   return false;
    1186             : }
    1187             : 
    1188     3891714 : Handle<SharedFunctionInfo> FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(
    1189             :     Isolate* isolate, Handle<FunctionTemplateInfo> info) {
    1190             :   Object* current_info = info->shared_function_info();
    1191     3891717 :   if (current_info->IsSharedFunctionInfo()) {
    1192             :     return handle(SharedFunctionInfo::cast(current_info), isolate);
    1193             :   }
    1194             : 
    1195             :   Handle<Object> class_name(info->class_name(), isolate);
    1196             :   Handle<String> name = class_name->IsString()
    1197             :                             ? Handle<String>::cast(class_name)
    1198     7461323 :                             : isolate->factory()->empty_string();
    1199     3761998 :   Handle<Code> code = isolate->builtins()->HandleApiCall();
    1200     3761997 :   bool is_constructor = !info->remove_prototype();
    1201             :   Handle<SharedFunctionInfo> result =
    1202     7523994 :       isolate->factory()->NewSharedFunctionInfo(name, code, is_constructor);
    1203     3761995 :   if (is_constructor) {
    1204     7441614 :     result->SetConstructStub(*isolate->builtins()->JSConstructStubApi());
    1205             :   }
    1206             : 
    1207             :   result->set_length(info->length());
    1208     3824671 :   if (class_name->IsString()) result->set_instance_class_name(*class_name);
    1209             :   result->set_api_func_data(*info);
    1210             :   result->DontAdaptArguments();
    1211             :   DCHECK(result->IsApiFunction());
    1212             : 
    1213     3761998 :   info->set_shared_function_info(*result);
    1214     3761997 :   return result;
    1215             : }
    1216             : 
    1217       18284 : bool FunctionTemplateInfo::IsTemplateFor(Map* map) {
    1218             :   // There is a constraint on the object; check.
    1219       18284 :   if (!map->IsJSObjectMap()) return false;
    1220             :   // Fetch the constructor function of the object.
    1221       18284 :   Object* cons_obj = map->GetConstructor();
    1222             :   Object* type;
    1223       18284 :   if (cons_obj->IsJSFunction()) {
    1224             :     JSFunction* fun = JSFunction::cast(cons_obj);
    1225             :     type = fun->shared()->function_data();
    1226          18 :   } else if (cons_obj->IsFunctionTemplateInfo()) {
    1227             :     type = FunctionTemplateInfo::cast(cons_obj);
    1228             :   } else {
    1229             :     return false;
    1230             :   }
    1231             :   // Iterate through the chain of inheriting function templates to
    1232             :   // see if the required one occurs.
    1233       18885 :   while (type->IsFunctionTemplateInfo()) {
    1234       10921 :     if (type == this) return true;
    1235             :     type = FunctionTemplateInfo::cast(type)->parent_template();
    1236             :   }
    1237             :   // Didn't find the required type in the inheritance chain.
    1238             :   return false;
    1239             : }
    1240             : 
    1241             : 
    1242             : // static
    1243      380233 : Handle<TemplateList> TemplateList::New(Isolate* isolate, int size) {
    1244             :   Handle<FixedArray> list =
    1245      380233 :       isolate->factory()->NewFixedArray(kLengthIndex + size);
    1246             :   list->set(kLengthIndex, Smi::kZero);
    1247      380233 :   return Handle<TemplateList>::cast(list);
    1248             : }
    1249             : 
    1250             : // static
    1251     6575955 : Handle<TemplateList> TemplateList::Add(Isolate* isolate,
    1252             :                                        Handle<TemplateList> list,
    1253             :                                        Handle<i::Object> value) {
    1254             :   STATIC_ASSERT(kFirstElementIndex == 1);
    1255     6575955 :   int index = list->length() + 1;
    1256             :   Handle<i::FixedArray> fixed_array = Handle<FixedArray>::cast(list);
    1257     6575955 :   fixed_array = FixedArray::SetAndGrow(fixed_array, index, value);
    1258             :   fixed_array->set(kLengthIndex, Smi::FromInt(index));
    1259     6575955 :   return Handle<TemplateList>::cast(fixed_array);
    1260             : }
    1261             : 
    1262             : // static
    1263     2465542 : MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
    1264             :                                     Handle<JSReceiver> new_target,
    1265             :                                     Handle<AllocationSite> site) {
    1266             :   // If called through new, new.target can be:
    1267             :   // - a subclass of constructor,
    1268             :   // - a proxy wrapper around constructor, or
    1269             :   // - the constructor itself.
    1270             :   // If called through Reflect.construct, it's guaranteed to be a constructor.
    1271     4930994 :   Isolate* const isolate = constructor->GetIsolate();
    1272             :   DCHECK(constructor->IsConstructor());
    1273             :   DCHECK(new_target->IsConstructor());
    1274             :   DCHECK(!constructor->has_initial_map() ||
    1275             :          constructor->initial_map()->instance_type() != JS_FUNCTION_TYPE);
    1276             : 
    1277             :   Handle<Map> initial_map;
    1278     4931084 :   ASSIGN_RETURN_ON_EXCEPTION(
    1279             :       isolate, initial_map,
    1280             :       JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject);
    1281             :   Handle<JSObject> result =
    1282     2465497 :       isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site);
    1283     2465497 :   if (initial_map->is_dictionary_map()) {
    1284             :     Handle<NameDictionary> dictionary =
    1285           0 :         NameDictionary::New(isolate, NameDictionary::kInitialCapacity);
    1286           0 :     result->set_properties(*dictionary);
    1287             :   }
    1288     2465497 :   isolate->counters()->constructed_objects()->Increment();
    1289     2465497 :   isolate->counters()->constructed_objects_runtime()->Increment();
    1290             :   return result;
    1291             : }
    1292             : 
    1293     2496984 : void JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
    1294             :   DCHECK(object->HasFastSmiOrObjectElements() ||
    1295             :          object->HasFastStringWrapperElements());
    1296             :   FixedArray* raw_elems = FixedArray::cast(object->elements());
    1297     2496984 :   Heap* heap = object->GetHeap();
    1298     4968182 :   if (raw_elems->map() != heap->fixed_cow_array_map()) return;
    1299       25786 :   Isolate* isolate = heap->isolate();
    1300             :   Handle<FixedArray> elems(raw_elems, isolate);
    1301             :   Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap(
    1302       25786 :       elems, isolate->factory()->fixed_array_map());
    1303       25786 :   object->set_elements(*writable_elems);
    1304       25786 :   isolate->counters()->cow_arrays_converted()->Increment();
    1305             : }
    1306             : 
    1307             : 
    1308             : // ES6 9.5.1
    1309             : // static
    1310     5702696 : MaybeHandle<Object> JSProxy::GetPrototype(Handle<JSProxy> proxy) {
    1311             :   Isolate* isolate = proxy->GetIsolate();
    1312             :   Handle<String> trap_name = isolate->factory()->getPrototypeOf_string();
    1313             : 
    1314     5702696 :   STACK_CHECK(isolate, MaybeHandle<Object>());
    1315             : 
    1316             :   // 1. Let handler be the value of the [[ProxyHandler]] internal slot.
    1317             :   // 2. If handler is null, throw a TypeError exception.
    1318             :   // 3. Assert: Type(handler) is Object.
    1319             :   // 4. Let target be the value of the [[ProxyTarget]] internal slot.
    1320     5702696 :   if (proxy->IsRevoked()) {
    1321          56 :     THROW_NEW_ERROR(isolate,
    1322             :                     NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
    1323             :                     Object);
    1324             :   }
    1325             :   Handle<JSReceiver> target(proxy->target(), isolate);
    1326             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    1327             : 
    1328             :   // 5. Let trap be ? GetMethod(handler, "getPrototypeOf").
    1329             :   Handle<Object> trap;
    1330    11405336 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, trap, GetMethod(handler, trap_name),
    1331             :                              Object);
    1332             :   // 6. If trap is undefined, then return target.[[GetPrototypeOf]]().
    1333     5702668 :   if (trap->IsUndefined(isolate)) {
    1334     4202080 :     return JSReceiver::GetPrototype(isolate, target);
    1335             :   }
    1336             :   // 7. Let handlerProto be ? Call(trap, handler, «target»).
    1337             :   Handle<Object> argv[] = {target};
    1338             :   Handle<Object> handler_proto;
    1339     3001176 :   ASSIGN_RETURN_ON_EXCEPTION(
    1340             :       isolate, handler_proto,
    1341             :       Execution::Call(isolate, trap, handler, arraysize(argv), argv), Object);
    1342             :   // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError.
    1343     1500476 :   if (!(handler_proto->IsJSReceiver() || handler_proto->IsNull(isolate))) {
    1344          28 :     THROW_NEW_ERROR(isolate,
    1345             :                     NewTypeError(MessageTemplate::kProxyGetPrototypeOfInvalid),
    1346             :                     Object);
    1347             :   }
    1348             :   // 9. Let extensibleTarget be ? IsExtensible(target).
    1349     1500420 :   Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
    1350     1500420 :   MAYBE_RETURN_NULL(is_extensible);
    1351             :   // 10. If extensibleTarget is true, return handlerProto.
    1352     1500420 :   if (is_extensible.FromJust()) return handler_proto;
    1353             :   // 11. Let targetProto be ? target.[[GetPrototypeOf]]().
    1354             :   Handle<Object> target_proto;
    1355           0 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, target_proto,
    1356             :                              JSReceiver::GetPrototype(isolate, target), Object);
    1357             :   // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError.
    1358           0 :   if (!handler_proto->SameValue(*target_proto)) {
    1359           0 :     THROW_NEW_ERROR(
    1360             :         isolate,
    1361             :         NewTypeError(MessageTemplate::kProxyGetPrototypeOfNonExtensible),
    1362             :         Object);
    1363             :   }
    1364             :   // 13. Return handlerProto.
    1365             :   return handler_proto;
    1366             : }
    1367             : 
    1368    10154135 : MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
    1369             :   Isolate* isolate = it->isolate();
    1370    10154135 :   Handle<Object> structure = it->GetAccessors();
    1371             :   Handle<Object> receiver = it->GetReceiver();
    1372             : 
    1373             :   // We should never get here to initialize a const with the hole value since a
    1374             :   // const declaration would conflict with the getter.
    1375             :   DCHECK(!structure->IsForeign());
    1376             : 
    1377             :   // API style callbacks.
    1378    10154135 :   if (structure->IsAccessorInfo()) {
    1379             :     Handle<JSObject> holder = it->GetHolder<JSObject>();
    1380      887279 :     Handle<Name> name = it->GetName();
    1381             :     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
    1382      887279 :     if (!info->IsCompatibleReceiver(*receiver)) {
    1383         210 :       THROW_NEW_ERROR(isolate,
    1384             :                       NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
    1385             :                                    name, receiver),
    1386             :                       Object);
    1387             :     }
    1388             : 
    1389             :     v8::AccessorNameGetterCallback call_fun =
    1390             :         v8::ToCData<v8::AccessorNameGetterCallback>(info->getter());
    1391      887174 :     if (call_fun == nullptr) return isolate->factory()->undefined_value();
    1392             : 
    1393      901230 :     if (info->is_sloppy() && !receiver->IsJSReceiver()) {
    1394          36 :       ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
    1395             :                                  Object::ConvertReceiver(isolate, receiver),
    1396             :                                  Object);
    1397             :     }
    1398             : 
    1399             :     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
    1400             :                                    Object::DONT_THROW);
    1401      887034 :     Handle<Object> result = args.Call(call_fun, name);
    1402      887034 :     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1403      886799 :     if (result.is_null()) return isolate->factory()->undefined_value();
    1404             :     Handle<Object> reboxed_result = handle(*result, isolate);
    1405      879695 :     if (info->replace_on_access() && receiver->IsJSReceiver()) {
    1406             :       args.Call(reinterpret_cast<GenericNamedPropertySetterCallback>(
    1407             :                     &Accessors::ReconfigureToDataProperty),
    1408           0 :                 name, result);
    1409           0 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1410             :     }
    1411             :     return reboxed_result;
    1412             :   }
    1413             : 
    1414             :   // AccessorPair with 'cached' private property.
    1415     9266856 :   if (it->TryLookupCachedProperty()) {
    1416          58 :     return Object::GetProperty(it);
    1417             :   }
    1418             : 
    1419             :   // Regular accessor.
    1420             :   Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate);
    1421     9266798 :   if (getter->IsFunctionTemplateInfo()) {
    1422             :     return Builtins::InvokeApiFunction(
    1423             :         isolate, false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0,
    1424         313 :         nullptr, isolate->factory()->undefined_value());
    1425     9266485 :   } else if (getter->IsCallable()) {
    1426             :     // TODO(rossberg): nicer would be to cast to some JSCallable here...
    1427             :     return Object::GetPropertyWithDefinedGetter(
    1428     9258024 :         receiver, Handle<JSReceiver>::cast(getter));
    1429             :   }
    1430             :   // Getter is not a function.
    1431             :   return isolate->factory()->undefined_value();
    1432             : }
    1433             : 
    1434             : // static
    1435           0 : Address AccessorInfo::redirect(Isolate* isolate, Address address,
    1436             :                                AccessorComponent component) {
    1437             :   ApiFunction fun(address);
    1438             :   DCHECK_EQ(ACCESSOR_GETTER, component);
    1439             :   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
    1440      246012 :   return ExternalReference(&fun, type, isolate).address();
    1441             : }
    1442             : 
    1443      124405 : Address AccessorInfo::redirected_getter() const {
    1444             :   Address accessor = v8::ToCData<Address>(getter());
    1445      124405 :   if (accessor == nullptr) return nullptr;
    1446      123006 :   return redirect(GetIsolate(), accessor, ACCESSOR_GETTER);
    1447             : }
    1448             : 
    1449       39810 : bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate,
    1450             :                                            Handle<AccessorInfo> info,
    1451             :                                            Handle<Map> map) {
    1452       39810 :   if (!info->HasExpectedReceiverType()) return true;
    1453          72 :   if (!map->IsJSObjectMap()) return false;
    1454             :   return FunctionTemplateInfo::cast(info->expected_receiver_type())
    1455          72 :       ->IsTemplateFor(*map);
    1456             : }
    1457             : 
    1458     1980949 : Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
    1459             :                                             Handle<Object> value,
    1460             :                                             ShouldThrow should_throw) {
    1461             :   Isolate* isolate = it->isolate();
    1462     1980949 :   Handle<Object> structure = it->GetAccessors();
    1463             :   Handle<Object> receiver = it->GetReceiver();
    1464             : 
    1465             :   // We should never get here to initialize a const with the hole value since a
    1466             :   // const declaration would conflict with the setter.
    1467             :   DCHECK(!structure->IsForeign());
    1468             : 
    1469             :   // API style callbacks.
    1470     1980949 :   if (structure->IsAccessorInfo()) {
    1471             :     Handle<JSObject> holder = it->GetHolder<JSObject>();
    1472     1782979 :     Handle<Name> name = it->GetName();
    1473             :     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
    1474     1782978 :     if (!info->IsCompatibleReceiver(*receiver)) {
    1475             :       isolate->Throw(*isolate->factory()->NewTypeError(
    1476         210 :           MessageTemplate::kIncompatibleMethodReceiver, name, receiver));
    1477             :       return Nothing<bool>();
    1478             :     }
    1479             : 
    1480             :     // The actual type of call_fun is either v8::AccessorNameSetterCallback or
    1481             :     // i::Accesors::AccessorNameBooleanSetterCallback, depending on whether the
    1482             :     // AccessorInfo was created by the API or internally (see accessors.cc).
    1483             :     // Here we handle both cases using GenericNamedPropertySetterCallback and
    1484             :     // its Call method.
    1485             :     GenericNamedPropertySetterCallback call_fun =
    1486             :         v8::ToCData<GenericNamedPropertySetterCallback>(info->setter());
    1487             : 
    1488     1782873 :     if (call_fun == nullptr) {
    1489             :       // TODO(verwaest): We should not get here anymore once all AccessorInfos
    1490             :       // are marked as special_data_property. They cannot both be writable and
    1491             :       // not have a setter.
    1492             :       return Just(true);
    1493             :     }
    1494             : 
    1495     1923555 :     if (info->is_sloppy() && !receiver->IsJSReceiver()) {
    1496           0 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1497             :           isolate, receiver, Object::ConvertReceiver(isolate, receiver),
    1498             :           Nothing<bool>());
    1499             :     }
    1500             : 
    1501             :     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
    1502             :                                    should_throw);
    1503     1782796 :     Handle<Object> result = args.Call(call_fun, name, value);
    1504             :     // In the case of AccessorNameSetterCallback, we know that the result value
    1505             :     // cannot have been set, so the result of Call will be null.  In the case of
    1506             :     // AccessorNameBooleanSetterCallback, the result will either be null
    1507             :     // (signalling an exception) or a boolean Oddball.
    1508     1782795 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    1509     1782530 :     if (result.is_null()) return Just(true);
    1510             :     DCHECK(result->BooleanValue() || should_throw == DONT_THROW);
    1511     1641841 :     return Just(result->BooleanValue());
    1512             :   }
    1513             : 
    1514             :   // Regular accessor.
    1515             :   Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
    1516      197970 :   if (setter->IsFunctionTemplateInfo()) {
    1517         159 :     Handle<Object> argv[] = {value};
    1518         318 :     RETURN_ON_EXCEPTION_VALUE(
    1519             :         isolate, Builtins::InvokeApiFunction(
    1520             :                      isolate, false, Handle<FunctionTemplateInfo>::cast(setter),
    1521             :                      receiver, arraysize(argv), argv,
    1522             :                      isolate->factory()->undefined_value()),
    1523             :         Nothing<bool>());
    1524             :     return Just(true);
    1525      197811 :   } else if (setter->IsCallable()) {
    1526             :     // TODO(rossberg): nicer would be to cast to some JSCallable here...
    1527             :     return SetPropertyWithDefinedSetter(
    1528      179220 :         receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
    1529             :   }
    1530             : 
    1531       45750 :   RETURN_FAILURE(isolate, should_throw,
    1532             :                  NewTypeError(MessageTemplate::kNoSetterInCallback,
    1533             :                               it->GetName(), it->GetHolder<JSObject>()));
    1534             : }
    1535             : 
    1536             : 
    1537     9258024 : MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
    1538             :     Handle<Object> receiver,
    1539             :     Handle<JSReceiver> getter) {
    1540             :   Isolate* isolate = getter->GetIsolate();
    1541             : 
    1542             :   // Platforms with simulators like arm/arm64 expose a funny issue. If the
    1543             :   // simulator has a separate JS stack pointer from the C++ stack pointer, it
    1544             :   // can miss C++ stack overflows in the stack guard at the start of JavaScript
    1545             :   // functions. It would be very expensive to check the C++ stack pointer at
    1546             :   // that location. The best solution seems to be to break the impasse by
    1547             :   // adding checks at possible recursion points. What's more, we don't put
    1548             :   // this stack check behind the USE_SIMULATOR define in order to keep
    1549             :   // behavior the same between hardware and simulators.
    1550             :   StackLimitCheck check(isolate);
    1551     9258024 :   if (check.JsHasOverflowed()) {
    1552          28 :     isolate->StackOverflow();
    1553             :     return MaybeHandle<Object>();
    1554             :   }
    1555             : 
    1556     9257996 :   return Execution::Call(isolate, getter, receiver, 0, NULL);
    1557             : }
    1558             : 
    1559             : 
    1560      179220 : Maybe<bool> Object::SetPropertyWithDefinedSetter(Handle<Object> receiver,
    1561             :                                                  Handle<JSReceiver> setter,
    1562             :                                                  Handle<Object> value,
    1563             :                                                  ShouldThrow should_throw) {
    1564             :   Isolate* isolate = setter->GetIsolate();
    1565             : 
    1566      179220 :   Handle<Object> argv[] = { value };
    1567      358440 :   RETURN_ON_EXCEPTION_VALUE(isolate, Execution::Call(isolate, setter, receiver,
    1568             :                                                      arraysize(argv), argv),
    1569             :                             Nothing<bool>());
    1570             :   return Just(true);
    1571             : }
    1572             : 
    1573             : 
    1574             : // static
    1575        4210 : bool JSObject::AllCanRead(LookupIterator* it) {
    1576             :   // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
    1577             :   // which have already been checked.
    1578             :   DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
    1579             :          it->state() == LookupIterator::INTERCEPTOR);
    1580        5552 :   for (it->Next(); it->IsFound(); it->Next()) {
    1581        1429 :     if (it->state() == LookupIterator::ACCESSOR) {
    1582         146 :       auto accessors = it->GetAccessors();
    1583         146 :       if (accessors->IsAccessorInfo()) {
    1584          92 :         if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
    1585             :       }
    1586        1283 :     } else if (it->state() == LookupIterator::INTERCEPTOR) {
    1587        1472 :       if (it->GetInterceptor()->all_can_read()) return true;
    1588         547 :     } else if (it->state() == LookupIterator::JSPROXY) {
    1589             :       // Stop lookupiterating. And no, AllCanNotRead.
    1590             :       return false;
    1591             :     }
    1592             :   }
    1593             :   return false;
    1594             : }
    1595             : 
    1596             : namespace {
    1597             : 
    1598        5313 : MaybeHandle<Object> GetPropertyWithInterceptorInternal(
    1599       10598 :     LookupIterator* it, Handle<InterceptorInfo> interceptor, bool* done) {
    1600        5313 :   *done = false;
    1601             :   Isolate* isolate = it->isolate();
    1602             :   // Make sure that the top context does not change when doing callbacks or
    1603             :   // interceptor calls.
    1604             :   AssertNoContextChange ncc(isolate);
    1605             : 
    1606        5313 :   if (interceptor->getter()->IsUndefined(isolate)) {
    1607             :     return isolate->factory()->undefined_value();
    1608             :   }
    1609             : 
    1610             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1611             :   Handle<Object> result;
    1612             :   Handle<Object> receiver = it->GetReceiver();
    1613        5285 :   if (!receiver->IsJSReceiver()) {
    1614          38 :     ASSIGN_RETURN_ON_EXCEPTION(
    1615             :         isolate, receiver, Object::ConvertReceiver(isolate, receiver), Object);
    1616             :   }
    1617             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1618             :                                  *holder, Object::DONT_THROW);
    1619             : 
    1620        5285 :   if (it->IsElement()) {
    1621             :     uint32_t index = it->index();
    1622             :     v8::IndexedPropertyGetterCallback getter =
    1623             :         v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
    1624        2471 :     result = args.Call(getter, index);
    1625             :   } else {
    1626        2814 :     Handle<Name> name = it->name();
    1627             :     DCHECK(!name->IsPrivate());
    1628             : 
    1629             :     DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
    1630             : 
    1631             :     v8::GenericNamedPropertyGetterCallback getter =
    1632             :         v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
    1633             :             interceptor->getter());
    1634        2814 :     result = args.Call(getter, name);
    1635             :   }
    1636             : 
    1637        5285 :   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1638        5257 :   if (result.is_null()) return isolate->factory()->undefined_value();
    1639        3288 :   *done = true;
    1640             :   // Rebox handle before return
    1641             :   return handle(*result, isolate);
    1642             : }
    1643             : 
    1644      281223 : Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptorInternal(
    1645      562338 :     LookupIterator* it, Handle<InterceptorInfo> interceptor) {
    1646             :   Isolate* isolate = it->isolate();
    1647             :   // Make sure that the top context does not change when doing
    1648             :   // callbacks or interceptor calls.
    1649             :   AssertNoContextChange ncc(isolate);
    1650             :   HandleScope scope(isolate);
    1651             : 
    1652             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1653             :   DCHECK_IMPLIES(!it->IsElement() && it->name()->IsSymbol(),
    1654             :                  interceptor->can_intercept_symbols());
    1655             :   Handle<Object> receiver = it->GetReceiver();
    1656      281223 :   if (!receiver->IsJSReceiver()) {
    1657          28 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1658             :                                      Object::ConvertReceiver(isolate, receiver),
    1659             :                                      Nothing<PropertyAttributes>());
    1660             :   }
    1661             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1662             :                                  *holder, Object::DONT_THROW);
    1663      281223 :   if (!interceptor->query()->IsUndefined(isolate)) {
    1664             :     Handle<Object> result;
    1665         268 :     if (it->IsElement()) {
    1666             :       uint32_t index = it->index();
    1667             :       v8::IndexedPropertyQueryCallback query =
    1668             :           v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
    1669         102 :       result = args.Call(query, index);
    1670             :     } else {
    1671         166 :       Handle<Name> name = it->name();
    1672             :       DCHECK(!name->IsPrivate());
    1673             :       v8::GenericNamedPropertyQueryCallback query =
    1674             :           v8::ToCData<v8::GenericNamedPropertyQueryCallback>(
    1675             :               interceptor->query());
    1676         166 :       result = args.Call(query, name);
    1677             :     }
    1678         268 :     if (!result.is_null()) {
    1679             :       int32_t value;
    1680          62 :       CHECK(result->ToInt32(&value));
    1681          62 :       return Just(static_cast<PropertyAttributes>(value));
    1682             :     }
    1683      280955 :   } else if (!interceptor->getter()->IsUndefined(isolate)) {
    1684             :     // TODO(verwaest): Use GetPropertyWithInterceptor?
    1685             :     Handle<Object> result;
    1686      280847 :     if (it->IsElement()) {
    1687             :       uint32_t index = it->index();
    1688             :       v8::IndexedPropertyGetterCallback getter =
    1689             :           v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
    1690      280250 :       result = args.Call(getter, index);
    1691             :     } else {
    1692         597 :       Handle<Name> name = it->name();
    1693             :       DCHECK(!name->IsPrivate());
    1694             :       v8::GenericNamedPropertyGetterCallback getter =
    1695             :           v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
    1696             :               interceptor->getter());
    1697         597 :       result = args.Call(getter, name);
    1698             :     }
    1699      280847 :     if (!result.is_null()) return Just(DONT_ENUM);
    1700             :   }
    1701             : 
    1702      280682 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
    1703             :   return Just(ABSENT);
    1704             : }
    1705             : 
    1706      225683 : Maybe<bool> SetPropertyWithInterceptorInternal(
    1707      660931 :     LookupIterator* it, Handle<InterceptorInfo> interceptor,
    1708             :     Object::ShouldThrow should_throw, Handle<Object> value) {
    1709             :   Isolate* isolate = it->isolate();
    1710             :   // Make sure that the top context does not change when doing callbacks or
    1711             :   // interceptor calls.
    1712             :   AssertNoContextChange ncc(isolate);
    1713             : 
    1714      225683 :   if (interceptor->setter()->IsUndefined(isolate)) return Just(false);
    1715             : 
    1716             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1717             :   bool result;
    1718             :   Handle<Object> receiver = it->GetReceiver();
    1719      217624 :   if (!receiver->IsJSReceiver()) {
    1720           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1721             :                                      Object::ConvertReceiver(isolate, receiver),
    1722             :                                      Nothing<bool>());
    1723             :   }
    1724             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1725             :                                  *holder, should_throw);
    1726             : 
    1727      217624 :   if (it->IsElement()) {
    1728             :     uint32_t index = it->index();
    1729             :     v8::IndexedPropertySetterCallback setter =
    1730             :         v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
    1731             :     // TODO(neis): In the future, we may want to actually return the
    1732             :     // interceptor's result, which then should be a boolean.
    1733      153226 :     result = !args.Call(setter, index, value).is_null();
    1734             :   } else {
    1735      141011 :     Handle<Name> name = it->name();
    1736             :     DCHECK(!name->IsPrivate());
    1737             : 
    1738             :     DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
    1739             : 
    1740             :     v8::GenericNamedPropertySetterCallback setter =
    1741             :         v8::ToCData<v8::GenericNamedPropertySetterCallback>(
    1742             :             interceptor->setter());
    1743      282022 :     result = !args.Call(setter, name, value).is_null();
    1744             :   }
    1745             : 
    1746      217624 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    1747             :   return Just(result);
    1748             : }
    1749             : 
    1750         208 : Maybe<bool> DefinePropertyWithInterceptorInternal(
    1751         400 :     LookupIterator* it, Handle<InterceptorInfo> interceptor,
    1752             :     Object::ShouldThrow should_throw, PropertyDescriptor& desc) {
    1753             :   Isolate* isolate = it->isolate();
    1754             :   // Make sure that the top context does not change when doing callbacks or
    1755             :   // interceptor calls.
    1756             :   AssertNoContextChange ncc(isolate);
    1757             : 
    1758         208 :   if (interceptor->definer()->IsUndefined(isolate)) return Just(false);
    1759             : 
    1760             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1761             :   bool result;
    1762             :   Handle<Object> receiver = it->GetReceiver();
    1763          96 :   if (!receiver->IsJSReceiver()) {
    1764           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1765             :                                      Object::ConvertReceiver(isolate, receiver),
    1766             :                                      Nothing<bool>());
    1767             :   }
    1768             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1769             :                                  *holder, should_throw);
    1770             : 
    1771             :   std::unique_ptr<v8::PropertyDescriptor> descriptor(
    1772          96 :       new v8::PropertyDescriptor());
    1773          96 :   if (PropertyDescriptor::IsAccessorDescriptor(&desc)) {
    1774             :     descriptor.reset(new v8::PropertyDescriptor(
    1775          70 :         v8::Utils::ToLocal(desc.get()), v8::Utils::ToLocal(desc.set())));
    1776          61 :   } else if (PropertyDescriptor::IsDataDescriptor(&desc)) {
    1777          49 :     if (desc.has_writable()) {
    1778             :       descriptor.reset(new v8::PropertyDescriptor(
    1779          21 :           v8::Utils::ToLocal(desc.value()), desc.writable()));
    1780             :     } else {
    1781             :       descriptor.reset(
    1782          84 :           new v8::PropertyDescriptor(v8::Utils::ToLocal(desc.value())));
    1783             :     }
    1784             :   }
    1785          96 :   if (desc.has_enumerable()) {
    1786          14 :     descriptor->set_enumerable(desc.enumerable());
    1787             :   }
    1788          96 :   if (desc.has_configurable()) {
    1789          14 :     descriptor->set_configurable(desc.configurable());
    1790             :   }
    1791             : 
    1792          96 :   if (it->IsElement()) {
    1793             :     uint32_t index = it->index();
    1794             :     v8::IndexedPropertyDefinerCallback definer =
    1795             :         v8::ToCData<v8::IndexedPropertyDefinerCallback>(interceptor->definer());
    1796          54 :     result = !args.Call(definer, index, *descriptor).is_null();
    1797             :   } else {
    1798          69 :     Handle<Name> name = it->name();
    1799             :     DCHECK(!name->IsPrivate());
    1800             : 
    1801             :     DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
    1802             : 
    1803             :     v8::GenericNamedPropertyDefinerCallback definer =
    1804             :         v8::ToCData<v8::GenericNamedPropertyDefinerCallback>(
    1805             :             interceptor->definer());
    1806         138 :     result = !args.Call(definer, name, *descriptor).is_null();
    1807             :   }
    1808             : 
    1809          96 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    1810             :   return Just(result);
    1811             : }
    1812             : 
    1813             : }  // namespace
    1814             : 
    1815        1378 : MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
    1816        1463 :     LookupIterator* it) {
    1817             :   Isolate* isolate = it->isolate();
    1818        1378 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    1819             :   Handle<InterceptorInfo> interceptor =
    1820        1378 :       it->GetInterceptorForFailedAccessCheck();
    1821        1378 :   if (interceptor.is_null()) {
    1822        1229 :     while (AllCanRead(it)) {
    1823          55 :       if (it->state() == LookupIterator::ACCESSOR) {
    1824          62 :         return GetPropertyWithAccessor(it);
    1825             :       }
    1826             :       DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    1827             :       bool done;
    1828             :       Handle<Object> result;
    1829          72 :       ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
    1830             :                                  GetPropertyWithInterceptor(it, &done), Object);
    1831          36 :       if (done) return result;
    1832             :     }
    1833             : 
    1834             :   } else {
    1835             :     Handle<Object> result;
    1836             :     bool done;
    1837         399 :     ASSIGN_RETURN_ON_EXCEPTION(
    1838             :         isolate, result,
    1839             :         GetPropertyWithInterceptorInternal(it, interceptor, &done), Object);
    1840         147 :     if (done) return result;
    1841             :   }
    1842             : 
    1843             :   // Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns
    1844             :   // undefined.
    1845        1258 :   Handle<Name> name = it->GetName();
    1846        1294 :   if (name->IsSymbol() && Symbol::cast(*name)->is_well_known_symbol()) {
    1847             :     return it->factory()->undefined_value();
    1848             :   }
    1849             : 
    1850        1228 :   isolate->ReportFailedAccessCheck(checked);
    1851        1228 :   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1852             :   return it->factory()->undefined_value();
    1853             : }
    1854             : 
    1855             : 
    1856         145 : Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
    1857         157 :     LookupIterator* it) {
    1858             :   Isolate* isolate = it->isolate();
    1859         145 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    1860             :   Handle<InterceptorInfo> interceptor =
    1861         145 :       it->GetInterceptorForFailedAccessCheck();
    1862         145 :   if (interceptor.is_null()) {
    1863         145 :     while (AllCanRead(it)) {
    1864          12 :       if (it->state() == LookupIterator::ACCESSOR) {
    1865             :         return Just(it->property_attributes());
    1866             :       }
    1867             :       DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    1868           0 :       auto result = GetPropertyAttributesWithInterceptor(it);
    1869           0 :       if (isolate->has_scheduled_exception()) break;
    1870           0 :       if (result.IsJust() && result.FromJust() != ABSENT) return result;
    1871             :     }
    1872             :   } else {
    1873             :     Maybe<PropertyAttributes> result =
    1874           0 :         GetPropertyAttributesWithInterceptorInternal(it, interceptor);
    1875           0 :     if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>();
    1876           0 :     if (result.FromMaybe(ABSENT) != ABSENT) return result;
    1877             :   }
    1878         133 :   isolate->ReportFailedAccessCheck(checked);
    1879         133 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
    1880             :   return Just(ABSENT);
    1881             : }
    1882             : 
    1883             : 
    1884             : // static
    1885         327 : bool JSObject::AllCanWrite(LookupIterator* it) {
    1886         464 :   for (; it->IsFound() && it->state() != LookupIterator::JSPROXY; it->Next()) {
    1887         149 :     if (it->state() == LookupIterator::ACCESSOR) {
    1888          30 :       Handle<Object> accessors = it->GetAccessors();
    1889          30 :       if (accessors->IsAccessorInfo()) {
    1890          18 :         if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
    1891             :       }
    1892             :     }
    1893             :   }
    1894             :   return false;
    1895             : }
    1896             : 
    1897             : 
    1898         137 : Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck(
    1899         137 :     LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) {
    1900             :   Isolate* isolate = it->isolate();
    1901         137 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    1902             :   Handle<InterceptorInfo> interceptor =
    1903         137 :       it->GetInterceptorForFailedAccessCheck();
    1904         137 :   if (interceptor.is_null()) {
    1905          95 :     if (AllCanWrite(it)) {
    1906          12 :       return SetPropertyWithAccessor(it, value, should_throw);
    1907             :     }
    1908             :   } else {
    1909             :     Maybe<bool> result = SetPropertyWithInterceptorInternal(
    1910          42 :         it, interceptor, should_throw, value);
    1911          84 :     if (isolate->has_pending_exception()) return Nothing<bool>();
    1912          28 :     if (result.IsJust()) return result;
    1913             :   }
    1914          83 :   isolate->ReportFailedAccessCheck(checked);
    1915          83 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    1916             :   return Just(true);
    1917             : }
    1918             : 
    1919             : 
    1920      407218 : void JSObject::SetNormalizedProperty(Handle<JSObject> object,
    1921             :                                      Handle<Name> name,
    1922             :                                      Handle<Object> value,
    1923             :                                      PropertyDetails details) {
    1924             :   DCHECK(!object->HasFastProperties());
    1925      407218 :   if (!name->IsUniqueName()) {
    1926             :     name = object->GetIsolate()->factory()->InternalizeString(
    1927           0 :         Handle<String>::cast(name));
    1928             :   }
    1929             : 
    1930      407218 :   if (object->IsJSGlobalObject()) {
    1931             :     Handle<GlobalDictionary> dictionary(object->global_dictionary());
    1932             : 
    1933        9729 :     int entry = dictionary->FindEntry(name);
    1934        9729 :     if (entry == GlobalDictionary::kNotFound) {
    1935             :       Isolate* isolate = object->GetIsolate();
    1936        1150 :       auto cell = isolate->factory()->NewPropertyCell();
    1937        1150 :       cell->set_value(*value);
    1938             :       auto cell_type = value->IsUndefined(isolate)
    1939             :                            ? PropertyCellType::kUndefined
    1940        1150 :                            : PropertyCellType::kConstant;
    1941             :       details = details.set_cell_type(cell_type);
    1942             :       value = cell;
    1943        1150 :       dictionary = GlobalDictionary::Add(dictionary, name, value, details);
    1944        1150 :       object->set_properties(*dictionary);
    1945             :     } else {
    1946             :       Handle<PropertyCell> cell =
    1947        8579 :           PropertyCell::PrepareForValue(dictionary, entry, value, details);
    1948        8579 :       cell->set_value(*value);
    1949             :     }
    1950             :   } else {
    1951             :     Handle<NameDictionary> dictionary(object->property_dictionary());
    1952             : 
    1953      397489 :     int entry = dictionary->FindEntry(name);
    1954      397489 :     if (entry == NameDictionary::kNotFound) {
    1955      146558 :       dictionary = NameDictionary::Add(dictionary, name, value, details);
    1956      146558 :       object->set_properties(*dictionary);
    1957             :     } else {
    1958             :       PropertyDetails original_details = dictionary->DetailsAt(entry);
    1959             :       int enumeration_index = original_details.dictionary_index();
    1960             :       DCHECK(enumeration_index > 0);
    1961             :       details = details.set_index(enumeration_index);
    1962             :       dictionary->SetEntry(entry, name, value, details);
    1963             :     }
    1964             :   }
    1965      407218 : }
    1966             : 
    1967             : // static
    1968        2619 : Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate,
    1969             :                                             Handle<JSReceiver> object,
    1970             :                                             Handle<Object> proto) {
    1971        2619 :   PrototypeIterator iter(isolate, object, kStartAtReceiver);
    1972             :   while (true) {
    1973     5804637 :     if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
    1974     5804468 :     if (iter.IsAtEnd()) return Just(false);
    1975     5803131 :     if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) {
    1976             :       return Just(true);
    1977             :     }
    1978             :   }
    1979             : }
    1980             : 
    1981             : namespace {
    1982             : 
    1983         686 : bool HasExcludedProperty(
    1984             :     const ScopedVector<Handle<Object>>* excluded_properties,
    1985             :     Handle<Object> search_element) {
    1986             :   // TODO(gsathya): Change this to be a hashtable.
    1987        2184 :   for (int i = 0; i < excluded_properties->length(); i++) {
    1988        1764 :     if (search_element->SameValue(*excluded_properties->at(i))) {
    1989             :       return true;
    1990             :     }
    1991             :   }
    1992             : 
    1993             :   return false;
    1994             : }
    1995             : 
    1996        1306 : MUST_USE_RESULT Maybe<bool> FastAssign(
    1997             :     Handle<JSReceiver> target, Handle<Object> source,
    1998             :     const ScopedVector<Handle<Object>>* excluded_properties, bool use_set) {
    1999             :   // Non-empty strings are the only non-JSReceivers that need to be handled
    2000             :   // explicitly by Object.assign.
    2001        1306 :   if (!source->IsJSReceiver()) {
    2002          70 :     return Just(!source->IsString() || String::cast(*source)->length() == 0);
    2003             :   }
    2004             : 
    2005             :   // If the target is deprecated, the object will be updated on first store. If
    2006             :   // the source for that store equals the target, this will invalidate the
    2007             :   // cached representation of the source. Preventively upgrade the target.
    2008             :   // Do this on each iteration since any property load could cause deprecation.
    2009        1264 :   if (target->map()->is_deprecated()) {
    2010          30 :     JSObject::MigrateInstance(Handle<JSObject>::cast(target));
    2011             :   }
    2012             : 
    2013             :   Isolate* isolate = target->GetIsolate();
    2014             :   Handle<Map> map(JSReceiver::cast(*source)->map(), isolate);
    2015             : 
    2016        1264 :   if (!map->IsJSObjectMap()) return Just(false);
    2017        1124 :   if (!map->OnlyHasSimpleProperties()) return Just(false);
    2018             : 
    2019             :   Handle<JSObject> from = Handle<JSObject>::cast(source);
    2020        1011 :   if (from->elements() != isolate->heap()->empty_fixed_array()) {
    2021             :     return Just(false);
    2022             :   }
    2023             : 
    2024             :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    2025             :   int length = map->NumberOfOwnDescriptors();
    2026             : 
    2027             :   bool stable = true;
    2028             : 
    2029        2071 :   for (int i = 0; i < length; i++) {
    2030             :     Handle<Name> next_key(descriptors->GetKey(i), isolate);
    2031             :     Handle<Object> prop_value;
    2032             :     // Directly decode from the descriptor array if |from| did not change shape.
    2033        1214 :     if (stable) {
    2034        1186 :       PropertyDetails details = descriptors->GetDetails(i);
    2035        1186 :       if (!details.IsEnumerable()) continue;
    2036        1068 :       if (details.kind() == kData) {
    2037        1068 :         if (details.location() == kDescriptor) {
    2038           0 :           prop_value = handle(descriptors->GetValue(i), isolate);
    2039             :         } else {
    2040        1068 :           Representation representation = details.representation();
    2041        1068 :           FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    2042        1068 :           prop_value = JSObject::FastPropertyAt(from, representation, index);
    2043             :         }
    2044             :       } else {
    2045           0 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2046             :             isolate, prop_value, JSReceiver::GetProperty(from, next_key),
    2047             :             Nothing<bool>());
    2048           0 :         stable = from->map() == *map;
    2049             :       }
    2050             :     } else {
    2051             :       // If the map did change, do a slower lookup. We are still guaranteed that
    2052             :       // the object has a simple shape, and that the key is a name.
    2053             :       LookupIterator it(from, next_key, from,
    2054          28 :                         LookupIterator::OWN_SKIP_INTERCEPTOR);
    2055          42 :       if (!it.IsFound()) continue;
    2056             :       DCHECK(it.state() == LookupIterator::DATA ||
    2057             :              it.state() == LookupIterator::ACCESSOR);
    2058          28 :       if (!it.IsEnumerable()) continue;
    2059          28 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2060             :           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
    2061             :     }
    2062             : 
    2063        1082 :     if (use_set) {
    2064         284 :       LookupIterator it(target, next_key, target);
    2065         284 :       bool call_to_js = it.IsFound() && it.state() != LookupIterator::DATA;
    2066             :       Maybe<bool> result = Object::SetProperty(
    2067         284 :           &it, prop_value, STRICT, Object::CERTAINLY_NOT_STORE_FROM_KEYED);
    2068         284 :       if (result.IsNothing()) return result;
    2069         284 :       if (stable && call_to_js) stable = from->map() == *map;
    2070             :     } else {
    2071        2394 :       if (excluded_properties != nullptr &&
    2072        1694 :           HasExcludedProperty(excluded_properties, next_key)) {
    2073         154 :         continue;
    2074             :       }
    2075             : 
    2076             :       // 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue).
    2077             :       bool success;
    2078             :       LookupIterator it = LookupIterator::PropertyOrElement(
    2079         644 :           isolate, target, next_key, &success, LookupIterator::OWN);
    2080         644 :       CHECK(success);
    2081        1288 :       CHECK(
    2082             :           JSObject::CreateDataProperty(&it, prop_value, Object::THROW_ON_ERROR)
    2083             :               .FromJust());
    2084             :     }
    2085             :   }
    2086             : 
    2087             :   return Just(true);
    2088             : }
    2089             : }  // namespace
    2090             : 
    2091             : // static
    2092        1306 : Maybe<bool> JSReceiver::SetOrCopyDataProperties(
    2093             :     Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
    2094             :     const ScopedVector<Handle<Object>>* excluded_properties, bool use_set) {
    2095             :   Maybe<bool> fast_assign =
    2096        1306 :       FastAssign(target, source, excluded_properties, use_set);
    2097        1306 :   if (fast_assign.IsNothing()) return Nothing<bool>();
    2098        1264 :   if (fast_assign.FromJust()) return Just(true);
    2099             : 
    2100         786 :   Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked();
    2101             :   // 3b. Let keys be ? from.[[OwnPropertyKeys]]().
    2102             :   Handle<FixedArray> keys;
    2103         786 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2104             :       isolate, keys,
    2105             :       KeyAccumulator::GetKeys(from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
    2106             :                               GetKeysConversion::kKeepNumbers),
    2107             :       Nothing<bool>());
    2108             : 
    2109             :   // 4. Repeat for each element nextKey of keys in List order,
    2110        1403 :   for (int j = 0; j < keys->length(); ++j) {
    2111             :     Handle<Object> next_key(keys->get(j), isolate);
    2112             :     // 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey).
    2113             :     PropertyDescriptor desc;
    2114             :     Maybe<bool> found =
    2115         589 :         JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc);
    2116         631 :     if (found.IsNothing()) return Nothing<bool>();
    2117             :     // 4a ii. If desc is not undefined and desc.[[Enumerable]] is true, then
    2118        1178 :     if (found.FromJust() && desc.enumerable()) {
    2119             :       // 4a ii 1. Let propValue be ? Get(from, nextKey).
    2120             :       Handle<Object> prop_value;
    2121        1108 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2122             :           isolate, prop_value,
    2123             :           Runtime::GetObjectProperty(isolate, from, next_key), Nothing<bool>());
    2124             : 
    2125         491 :       if (use_set) {
    2126             :         // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true).
    2127             :         Handle<Object> status;
    2128         310 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2129             :             isolate, status, Runtime::SetObjectProperty(
    2130             :                                  isolate, target, next_key, prop_value, STRICT),
    2131             :             Nothing<bool>());
    2132             :       } else {
    2133         574 :         if (excluded_properties != nullptr &&
    2134         238 :             HasExcludedProperty(excluded_properties, next_key)) {
    2135         112 :           continue;
    2136             :         }
    2137             : 
    2138             :         // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue).
    2139             :         bool success;
    2140             :         LookupIterator it = LookupIterator::PropertyOrElement(
    2141         224 :             isolate, target, next_key, &success, LookupIterator::OWN);
    2142         224 :         CHECK(success);
    2143         448 :         CHECK(JSObject::CreateDataProperty(&it, prop_value,
    2144             :                                            Object::THROW_ON_ERROR)
    2145             :                   .FromJust());
    2146             :       }
    2147             :     }
    2148             :   }
    2149             : 
    2150             :   return Just(true);
    2151             : }
    2152             : 
    2153      281064 : Map* Object::GetPrototypeChainRootMap(Isolate* isolate) {
    2154             :   DisallowHeapAllocation no_alloc;
    2155      250874 :   if (IsSmi()) {
    2156             :     Context* native_context = isolate->context()->native_context();
    2157       30190 :     return native_context->number_function()->initial_map();
    2158             :   }
    2159             : 
    2160             :   // The object is either a number, a string, a symbol, a boolean, a real JS
    2161             :   // object, or a Harmony proxy.
    2162             :   HeapObject* heap_object = HeapObject::cast(this);
    2163      220684 :   return heap_object->map()->GetPrototypeChainRootMap(isolate);
    2164             : }
    2165             : 
    2166     9868298 : Map* Map::GetPrototypeChainRootMap(Isolate* isolate) {
    2167             :   DisallowHeapAllocation no_alloc;
    2168     9493742 :   if (IsJSReceiverMap()) {
    2169             :     return this;
    2170             :   }
    2171             :   int constructor_function_index = GetConstructorFunctionIndex();
    2172      374570 :   if (constructor_function_index != Map::kNoConstructorFunctionIndex) {
    2173             :     Context* native_context = isolate->context()->native_context();
    2174             :     JSFunction* constructor_function =
    2175             :         JSFunction::cast(native_context->get(constructor_function_index));
    2176      374556 :     return constructor_function->initial_map();
    2177             :   }
    2178          28 :   return isolate->heap()->null_value()->map();
    2179             : }
    2180             : 
    2181             : namespace {
    2182             : 
    2183             : // Returns a non-SMI for JSObjects, but returns the hash code for simple
    2184             : // objects.  This avoids a double lookup in the cases where we know we will
    2185             : // add the hash to the JSObject if it does not already exist.
    2186   107544730 : Object* GetSimpleHash(Object* object) {
    2187             :   // The object is either a Smi, a HeapNumber, a name, an odd-ball, a real JS
    2188             :   // object, or a Harmony proxy.
    2189   107544730 :   if (object->IsSmi()) {
    2190             :     uint32_t hash =
    2191     1079997 :         ComputeIntegerHash(Smi::cast(object)->value(), kZeroHashSeed);
    2192     2159994 :     return Smi::FromInt(hash & Smi::kMaxValue);
    2193             :   }
    2194   106464735 :   if (object->IsHeapNumber()) {
    2195             :     double num = HeapNumber::cast(object)->value();
    2196        8922 :     if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue);
    2197        8217 :     if (i::IsMinusZero(num)) num = 0;
    2198        8217 :     if (IsSmiDouble(num)) {
    2199         600 :       return Smi::FromInt(FastD2I(num))->GetHash();
    2200             :     }
    2201             :     uint32_t hash = ComputeLongHash(double_to_uint64(num));
    2202       15234 :     return Smi::FromInt(hash & Smi::kMaxValue);
    2203             :   }
    2204   106455805 :   if (object->IsName()) {
    2205             :     uint32_t hash = Name::cast(object)->Hash();
    2206   212862188 :     return Smi::FromInt(hash);
    2207             :   }
    2208       24711 :   if (object->IsOddball()) {
    2209             :     uint32_t hash = Oddball::cast(object)->to_string()->Hash();
    2210        4396 :     return Smi::FromInt(hash);
    2211             :   }
    2212             :   DCHECK(object->IsJSReceiver());
    2213             :   // Simply return the receiver as it is guaranteed to not be a SMI.
    2214             :   return object;
    2215             : }
    2216             : 
    2217             : }  // namespace
    2218             : 
    2219    12997117 : Object* Object::GetHash() {
    2220    12997117 :   Object* hash = GetSimpleHash(this);
    2221    12997118 :   if (hash->IsSmi()) return hash;
    2222             : 
    2223             :   DisallowHeapAllocation no_gc;
    2224             :   DCHECK(IsJSReceiver());
    2225             :   JSReceiver* receiver = JSReceiver::cast(this);
    2226             :   Isolate* isolate = receiver->GetIsolate();
    2227       16991 :   return JSReceiver::GetIdentityHash(isolate, handle(receiver, isolate));
    2228             : }
    2229             : 
    2230    94547635 : Smi* Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) {
    2231    94547635 :   Object* hash = GetSimpleHash(*object);
    2232    94547629 :   if (hash->IsSmi()) return Smi::cast(hash);
    2233             : 
    2234             :   DCHECK(object->IsJSReceiver());
    2235             :   return JSReceiver::GetOrCreateIdentityHash(isolate,
    2236        5522 :                                              Handle<JSReceiver>::cast(object));
    2237             : }
    2238             : 
    2239             : 
    2240     1906031 : bool Object::SameValue(Object* other) {
    2241     1906031 :   if (other == this) return true;
    2242             : 
    2243             :   // The object is either a number, a name, an odd-ball,
    2244             :   // a real JS object, or a Harmony proxy.
    2245     1582761 :   if (IsNumber() && other->IsNumber()) {
    2246             :     double this_value = Number();
    2247             :     double other_value = other->Number();
    2248             :     // SameValue(NaN, NaN) is true.
    2249       32466 :     if (this_value != other_value) {
    2250       29029 :       return std::isnan(this_value) && std::isnan(other_value);
    2251             :     }
    2252             :     // SameValue(0.0, -0.0) is false.
    2253        3437 :     return (std::signbit(this_value) == std::signbit(other_value));
    2254             :   }
    2255     2925314 :   if (IsString() && other->IsString()) {
    2256     1420853 :     return String::cast(this)->Equals(String::cast(other));
    2257             :   }
    2258             :   return false;
    2259             : }
    2260             : 
    2261             : 
    2262    50536535 : bool Object::SameValueZero(Object* other) {
    2263    50536535 :   if (other == this) return true;
    2264             : 
    2265             :   // The object is either a number, a name, an odd-ball,
    2266             :   // a real JS object, or a Harmony proxy.
    2267    50948206 :   if (IsNumber() && other->IsNumber()) {
    2268             :     double this_value = Number();
    2269             :     double other_value = other->Number();
    2270             :     // +0 == -0 is true
    2271      410323 :     return this_value == other_value ||
    2272          17 :            (std::isnan(this_value) && std::isnan(other_value));
    2273             :   }
    2274   100234702 :   if (IsString() && other->IsString()) {
    2275    50109739 :     return String::cast(this)->Equals(String::cast(other));
    2276             :   }
    2277             :   return false;
    2278             : }
    2279             : 
    2280             : 
    2281       71765 : MaybeHandle<Object> Object::ArraySpeciesConstructor(
    2282             :     Isolate* isolate, Handle<Object> original_array) {
    2283       71765 :   Handle<Object> default_species = isolate->array_function();
    2284      138462 :   if (original_array->IsJSArray() &&
    2285      203551 :       Handle<JSArray>::cast(original_array)->HasArrayPrototype(isolate) &&
    2286             :       isolate->IsArraySpeciesLookupChainIntact()) {
    2287             :     return default_species;
    2288             :   }
    2289             :   Handle<Object> constructor = isolate->factory()->undefined_value();
    2290        7541 :   Maybe<bool> is_array = Object::IsArray(original_array);
    2291        7541 :   MAYBE_RETURN_NULL(is_array);
    2292        7541 :   if (is_array.FromJust()) {
    2293        5088 :     ASSIGN_RETURN_ON_EXCEPTION(
    2294             :         isolate, constructor,
    2295             :         Object::GetProperty(original_array,
    2296             :                             isolate->factory()->constructor_string()),
    2297             :         Object);
    2298        2530 :     if (constructor->IsConstructor()) {
    2299             :       Handle<Context> constructor_context;
    2300        4572 :       ASSIGN_RETURN_ON_EXCEPTION(
    2301             :           isolate, constructor_context,
    2302             :           JSReceiver::GetFunctionRealm(Handle<JSReceiver>::cast(constructor)),
    2303             :           Object);
    2304        4600 :       if (*constructor_context != *isolate->native_context() &&
    2305             :           *constructor == constructor_context->array_function()) {
    2306             :         constructor = isolate->factory()->undefined_value();
    2307             :       }
    2308             :     }
    2309        2530 :     if (constructor->IsJSReceiver()) {
    2310        4516 :       ASSIGN_RETURN_ON_EXCEPTION(
    2311             :           isolate, constructor,
    2312             :           JSReceiver::GetProperty(Handle<JSReceiver>::cast(constructor),
    2313             :                                   isolate->factory()->species_symbol()),
    2314             :           Object);
    2315        2244 :       if (constructor->IsNull(isolate)) {
    2316             :         constructor = isolate->factory()->undefined_value();
    2317             :       }
    2318             :     }
    2319             :   }
    2320        7513 :   if (constructor->IsUndefined(isolate)) {
    2321             :     return default_species;
    2322             :   } else {
    2323        2200 :     if (!constructor->IsConstructor()) {
    2324           0 :       THROW_NEW_ERROR(isolate,
    2325             :           NewTypeError(MessageTemplate::kSpeciesNotConstructor),
    2326             :           Object);
    2327             :     }
    2328             :     return constructor;
    2329             :   }
    2330             : }
    2331             : 
    2332             : // ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
    2333       14360 : MUST_USE_RESULT MaybeHandle<Object> Object::SpeciesConstructor(
    2334             :     Isolate* isolate, Handle<JSReceiver> recv,
    2335             :     Handle<JSFunction> default_ctor) {
    2336             :   Handle<Object> ctor_obj;
    2337       28720 :   ASSIGN_RETURN_ON_EXCEPTION(
    2338             :       isolate, ctor_obj,
    2339             :       JSObject::GetProperty(recv, isolate->factory()->constructor_string()),
    2340             :       Object);
    2341             : 
    2342       14360 :   if (ctor_obj->IsUndefined(isolate)) return default_ctor;
    2343             : 
    2344       14346 :   if (!ctor_obj->IsJSReceiver()) {
    2345           0 :     THROW_NEW_ERROR(isolate,
    2346             :                     NewTypeError(MessageTemplate::kConstructorNotReceiver),
    2347             :                     Object);
    2348             :   }
    2349             : 
    2350       14346 :   Handle<JSReceiver> ctor = Handle<JSReceiver>::cast(ctor_obj);
    2351             : 
    2352             :   Handle<Object> species;
    2353       28692 :   ASSIGN_RETURN_ON_EXCEPTION(
    2354             :       isolate, species,
    2355             :       JSObject::GetProperty(ctor, isolate->factory()->species_symbol()),
    2356             :       Object);
    2357             : 
    2358       14346 :   if (species->IsNullOrUndefined(isolate)) {
    2359             :     return default_ctor;
    2360             :   }
    2361             : 
    2362       14346 :   if (species->IsConstructor()) return species;
    2363             : 
    2364           0 :   THROW_NEW_ERROR(
    2365             :       isolate, NewTypeError(MessageTemplate::kSpeciesNotConstructor), Object);
    2366             : }
    2367             : 
    2368       35238 : bool Object::IterationHasObservableEffects() {
    2369             :   // Check that this object is an array.
    2370       35238 :   if (!IsJSArray()) return true;
    2371             :   JSArray* array = JSArray::cast(this);
    2372             :   Isolate* isolate = array->GetIsolate();
    2373             : 
    2374             :   // Check that we have the original ArrayPrototype.
    2375       35238 :   if (!array->map()->prototype()->IsJSObject()) return true;
    2376             :   JSObject* array_proto = JSObject::cast(array->map()->prototype());
    2377       35223 :   if (!isolate->is_initial_array_prototype(array_proto)) return true;
    2378             : 
    2379             :   // Check that the ArrayPrototype hasn't been modified in a way that would
    2380             :   // affect iteration.
    2381       34971 :   if (!isolate->IsArrayIteratorLookupChainIntact()) return true;
    2382             : 
    2383             :   // Check that the map of the initial array iterator hasn't changed.
    2384       65490 :   Map* iterator_map = isolate->initial_array_iterator_prototype()->map();
    2385       32745 :   if (!isolate->is_initial_array_iterator_prototype_map(iterator_map)) {
    2386             :     return true;
    2387             :   }
    2388             : 
    2389             :   // For FastPacked kinds, iteration will have the same effect as simply
    2390             :   // accessing each property in order.
    2391             :   ElementsKind array_kind = array->GetElementsKind();
    2392       32745 :   if (IsFastPackedElementsKind(array_kind)) return false;
    2393             : 
    2394             :   // For FastHoley kinds, an element access on a hole would cause a lookup on
    2395             :   // the prototype. This could have different results if the prototype has been
    2396             :   // changed.
    2397       12300 :   if (IsFastHoleyElementsKind(array_kind) &&
    2398        6150 :       isolate->IsFastArrayConstructorPrototypeChainIntact()) {
    2399             :     return false;
    2400             :   }
    2401         242 :   return true;
    2402             : }
    2403             : 
    2404          14 : void Object::ShortPrint(FILE* out) {
    2405          14 :   OFStream os(out);
    2406          14 :   os << Brief(this);
    2407          14 : }
    2408             : 
    2409             : 
    2410         260 : void Object::ShortPrint(StringStream* accumulator) {
    2411         260 :   std::ostringstream os;
    2412         260 :   os << Brief(this);
    2413         520 :   accumulator->Add(os.str().c_str());
    2414         260 : }
    2415             : 
    2416             : 
    2417           0 : void Object::ShortPrint(std::ostream& os) { os << Brief(this); }
    2418             : 
    2419             : 
    2420        1714 : std::ostream& operator<<(std::ostream& os, const Brief& v) {
    2421        3428 :   if (v.value->IsSmi()) {
    2422             :     Smi::cast(v.value)->SmiPrint(os);
    2423             :   } else {
    2424             :     // TODO(svenpanne) Const-correct HeapObjectShortPrint!
    2425             :     HeapObject* obj = const_cast<HeapObject*>(HeapObject::cast(v.value));
    2426        1356 :     obj->HeapObjectShortPrint(os);
    2427             :   }
    2428        1714 :   return os;
    2429             : }
    2430             : 
    2431         189 : void Smi::SmiPrint(std::ostream& os) const {  // NOLINT
    2432         547 :   os << value();
    2433         189 : }
    2434             : 
    2435     6108158 : Handle<String> String::SlowFlatten(Handle<ConsString> cons,
    2436             :                                    PretenureFlag pretenure) {
    2437             :   DCHECK(cons->second()->length() != 0);
    2438             : 
    2439             :   // TurboFan can create cons strings with empty first parts.
    2440    12216329 :   while (cons->first()->length() == 0) {
    2441             :     // We do not want to call this function recursively. Therefore we call
    2442             :     // String::Flatten only in those cases where String::SlowFlatten is not
    2443             :     // called again.
    2444          60 :     if (cons->second()->IsConsString() && !cons->second()->IsFlat()) {
    2445             :       cons = handle(ConsString::cast(cons->second()));
    2446             :     } else {
    2447          34 :       return String::Flatten(handle(cons->second()));
    2448             :     }
    2449             :   }
    2450             : 
    2451             :   DCHECK(AllowHeapAllocation::IsAllowed());
    2452             :   Isolate* isolate = cons->GetIsolate();
    2453             :   int length = cons->length();
    2454             :   PretenureFlag tenure = isolate->heap()->InNewSpace(*cons) ? pretenure
    2455     6108124 :                                                             : TENURED;
    2456             :   Handle<SeqString> result;
    2457     6108124 :   if (cons->IsOneByteRepresentation()) {
    2458             :     Handle<SeqOneByteString> flat = isolate->factory()->NewRawOneByteString(
    2459    11746354 :         length, tenure).ToHandleChecked();
    2460             :     DisallowHeapAllocation no_gc;
    2461    11746354 :     WriteToFlat(*cons, flat->GetChars(), 0, length);
    2462             :     result = flat;
    2463             :   } else {
    2464             :     Handle<SeqTwoByteString> flat = isolate->factory()->NewRawTwoByteString(
    2465      469894 :         length, tenure).ToHandleChecked();
    2466             :     DisallowHeapAllocation no_gc;
    2467      469894 :     WriteToFlat(*cons, flat->GetChars(), 0, length);
    2468             :     result = flat;
    2469             :   }
    2470     6108124 :   cons->set_first(*result);
    2471    12216248 :   cons->set_second(isolate->heap()->empty_string());
    2472             :   DCHECK(result->IsFlat());
    2473     6108124 :   return result;
    2474             : }
    2475             : 
    2476             : 
    2477             : 
    2478         468 : bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
    2479             :   // Externalizing twice leaks the external resource, so it's
    2480             :   // prohibited by the API.
    2481             :   DCHECK(!this->IsExternalString());
    2482             :   DCHECK(!resource->IsCompressible());
    2483             : #ifdef ENABLE_SLOW_DCHECKS
    2484             :   if (FLAG_enable_slow_asserts) {
    2485             :     // Assert that the resource and the string are equivalent.
    2486             :     DCHECK(static_cast<size_t>(this->length()) == resource->length());
    2487             :     ScopedVector<uc16> smart_chars(this->length());
    2488             :     String::WriteToFlat(this, smart_chars.start(), 0, this->length());
    2489             :     DCHECK(memcmp(smart_chars.start(),
    2490             :                   resource->data(),
    2491             :                   resource->length() * sizeof(smart_chars[0])) == 0);
    2492             :   }
    2493             : #endif  // DEBUG
    2494         468 :   int size = this->Size();  // Byte size of the original string.
    2495             :   // Abort if size does not allow in-place conversion.
    2496         468 :   if (size < ExternalString::kShortSize) return false;
    2497         274 :   Heap* heap = GetHeap();
    2498             :   bool is_one_byte = this->IsOneByteRepresentation();
    2499             :   bool is_internalized = this->IsInternalizedString();
    2500             :   bool has_pointers = StringShape(this).IsIndirect();
    2501             : 
    2502             :   // Morph the string to an external string by replacing the map and
    2503             :   // reinitializing the fields.  This won't work if the space the existing
    2504             :   // string occupies is too small for a regular  external string.
    2505             :   // Instead, we resort to a short external string instead, omitting
    2506             :   // the field caching the address of the backing store.  When we encounter
    2507             :   // short external strings in generated code, we need to bailout to runtime.
    2508             :   Map* new_map;
    2509         468 :   if (size < ExternalString::kSize) {
    2510             :     new_map = is_internalized
    2511             :         ? (is_one_byte
    2512             :            ? heap->short_external_internalized_string_with_one_byte_data_map()
    2513             :            : heap->short_external_internalized_string_map())
    2514             :         : (is_one_byte ? heap->short_external_string_with_one_byte_data_map()
    2515         327 :                        : heap->short_external_string_map());
    2516             :   } else {
    2517             :     new_map = is_internalized
    2518             :         ? (is_one_byte
    2519             :            ? heap->external_internalized_string_with_one_byte_data_map()
    2520             :            : heap->external_internalized_string_map())
    2521             :         : (is_one_byte ? heap->external_string_with_one_byte_data_map()
    2522         543 :                        : heap->external_string_map());
    2523             :   }
    2524             : 
    2525             :   // Byte size of the external String object.
    2526         468 :   int new_size = this->SizeFromMap(new_map);
    2527         468 :   heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
    2528         936 :                              ClearRecordedSlots::kNo);
    2529         468 :   if (has_pointers) {
    2530          88 :     heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
    2531             :   }
    2532             : 
    2533             :   // We are storing the new map using release store after creating a filler for
    2534             :   // the left-over space to avoid races with the sweeper thread.
    2535         468 :   this->synchronized_set_map(new_map);
    2536             : 
    2537             :   ExternalTwoByteString* self = ExternalTwoByteString::cast(this);
    2538             :   self->set_resource(resource);
    2539         468 :   if (is_internalized) self->Hash();  // Force regeneration of the hash value.
    2540             : 
    2541         468 :   heap->AdjustLiveBytes(this, new_size - size);
    2542         468 :   return true;
    2543             : }
    2544             : 
    2545             : 
    2546         458 : bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
    2547             :   // Externalizing twice leaks the external resource, so it's
    2548             :   // prohibited by the API.
    2549             :   DCHECK(!this->IsExternalString());
    2550             :   DCHECK(!resource->IsCompressible());
    2551             : #ifdef ENABLE_SLOW_DCHECKS
    2552             :   if (FLAG_enable_slow_asserts) {
    2553             :     // Assert that the resource and the string are equivalent.
    2554             :     DCHECK(static_cast<size_t>(this->length()) == resource->length());
    2555             :     if (this->IsTwoByteRepresentation()) {
    2556             :       ScopedVector<uint16_t> smart_chars(this->length());
    2557             :       String::WriteToFlat(this, smart_chars.start(), 0, this->length());
    2558             :       DCHECK(String::IsOneByte(smart_chars.start(), this->length()));
    2559             :     }
    2560             :     ScopedVector<char> smart_chars(this->length());
    2561             :     String::WriteToFlat(this, smart_chars.start(), 0, this->length());
    2562             :     DCHECK(memcmp(smart_chars.start(),
    2563             :                   resource->data(),
    2564             :                   resource->length() * sizeof(smart_chars[0])) == 0);
    2565             :   }
    2566             : #endif  // DEBUG
    2567         458 :   int size = this->Size();  // Byte size of the original string.
    2568             :   // Abort if size does not allow in-place conversion.
    2569         458 :   if (size < ExternalString::kShortSize) return false;
    2570          52 :   Heap* heap = GetHeap();
    2571             :   bool is_internalized = this->IsInternalizedString();
    2572             :   bool has_pointers = StringShape(this).IsIndirect();
    2573             : 
    2574             :   // Morph the string to an external string by replacing the map and
    2575             :   // reinitializing the fields.  This won't work if the space the existing
    2576             :   // string occupies is too small for a regular  external string.
    2577             :   // Instead, we resort to a short external string instead, omitting
    2578             :   // the field caching the address of the backing store.  When we encounter
    2579             :   // short external strings in generated code, we need to bailout to runtime.
    2580             :   Map* new_map;
    2581         458 :   if (size < ExternalString::kSize) {
    2582             :     new_map = is_internalized
    2583             :                   ? heap->short_external_one_byte_internalized_string_map()
    2584          13 :                   : heap->short_external_one_byte_string_map();
    2585             :   } else {
    2586             :     new_map = is_internalized
    2587             :                   ? heap->external_one_byte_internalized_string_map()
    2588         445 :                   : heap->external_one_byte_string_map();
    2589             :   }
    2590             : 
    2591             :   // Byte size of the external String object.
    2592         458 :   int new_size = this->SizeFromMap(new_map);
    2593         458 :   heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
    2594         916 :                              ClearRecordedSlots::kNo);
    2595         458 :   if (has_pointers) {
    2596         394 :     heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
    2597             :   }
    2598             : 
    2599             :   // We are storing the new map using release store after creating a filler for
    2600             :   // the left-over space to avoid races with the sweeper thread.
    2601         458 :   this->synchronized_set_map(new_map);
    2602             : 
    2603             :   ExternalOneByteString* self = ExternalOneByteString::cast(this);
    2604             :   self->set_resource(resource);
    2605         458 :   if (is_internalized) self->Hash();  // Force regeneration of the hash value.
    2606             : 
    2607         458 :   heap->AdjustLiveBytes(this, new_size - size);
    2608         458 :   return true;
    2609             : }
    2610             : 
    2611          94 : void String::StringShortPrint(StringStream* accumulator, bool show_details) {
    2612             :   int len = length();
    2613          94 :   if (len > kMaxShortPrintLength) {
    2614           0 :     accumulator->Add("<Very long string[%u]>", len);
    2615           0 :     return;
    2616             :   }
    2617             : 
    2618          94 :   if (!LooksValid()) {
    2619           0 :     accumulator->Add("<Invalid String>");
    2620           0 :     return;
    2621             :   }
    2622             : 
    2623             :   StringCharacterStream stream(this);
    2624             : 
    2625             :   bool truncated = false;
    2626          94 :   if (len > kMaxShortPrintLength) {
    2627             :     len = kMaxShortPrintLength;
    2628             :     truncated = true;
    2629             :   }
    2630             :   bool one_byte = true;
    2631         782 :   for (int i = 0; i < len; i++) {
    2632         688 :     uint16_t c = stream.GetNext();
    2633             : 
    2634         688 :     if (c < 32 || c >= 127) {
    2635             :       one_byte = false;
    2636             :     }
    2637             :   }
    2638          94 :   stream.Reset(this);
    2639          94 :   if (one_byte) {
    2640         171 :     if (show_details) accumulator->Add("<String[%u]: ", length());
    2641         688 :     for (int i = 0; i < len; i++) {
    2642         688 :       accumulator->Put(static_cast<char>(stream.GetNext()));
    2643             :     }
    2644          94 :     if (show_details) accumulator->Put('>');
    2645             :   } else {
    2646             :     // Backslash indicates that the string contains control
    2647             :     // characters and that backslashes are therefore escaped.
    2648           0 :     if (show_details) accumulator->Add("<String[%u]\\: ", length());
    2649           0 :     for (int i = 0; i < len; i++) {
    2650           0 :       uint16_t c = stream.GetNext();
    2651           0 :       if (c == '\n') {
    2652           0 :         accumulator->Add("\\n");
    2653           0 :       } else if (c == '\r') {
    2654           0 :         accumulator->Add("\\r");
    2655           0 :       } else if (c == '\\') {
    2656           0 :         accumulator->Add("\\\\");
    2657           0 :       } else if (c < 32 || c > 126) {
    2658           0 :         accumulator->Add("\\x%02x", c);
    2659             :       } else {
    2660           0 :         accumulator->Put(static_cast<char>(c));
    2661             :       }
    2662             :     }
    2663           0 :     if (truncated) {
    2664           0 :       accumulator->Put('.');
    2665           0 :       accumulator->Put('.');
    2666           0 :       accumulator->Put('.');
    2667             :     }
    2668           0 :     if (show_details) accumulator->Put('>');
    2669             :   }
    2670             :   return;
    2671             : }
    2672             : 
    2673             : 
    2674          28 : void String::PrintUC16(std::ostream& os, int start, int end) {  // NOLINT
    2675          28 :   if (end < 0) end = length();
    2676             :   StringCharacterStream stream(this, start);
    2677         560 :   for (int i = start; i < end && stream.HasMore(); i++) {
    2678        1064 :     os << AsUC16(stream.GetNext());
    2679             :   }
    2680          28 : }
    2681             : 
    2682             : 
    2683         840 : void JSObject::JSObjectShortPrint(StringStream* accumulator) {
    2684         840 :   switch (map()->instance_type()) {
    2685             :     case JS_ARRAY_TYPE: {
    2686             :       double length = JSArray::cast(this)->length()->IsUndefined(GetIsolate())
    2687             :                           ? 0
    2688         201 :                           : JSArray::cast(this)->length()->Number();
    2689         201 :       accumulator->Add("<JSArray[%u]>", static_cast<uint32_t>(length));
    2690         201 :       break;
    2691             :     }
    2692             :     case JS_BOUND_FUNCTION_TYPE: {
    2693             :       JSBoundFunction* bound_function = JSBoundFunction::cast(this);
    2694           0 :       accumulator->Add("<JSBoundFunction");
    2695             :       accumulator->Add(
    2696             :           " (BoundTargetFunction %p)>",
    2697           0 :           reinterpret_cast<void*>(bound_function->bound_target_function()));
    2698           0 :       break;
    2699             :     }
    2700             :     case JS_WEAK_MAP_TYPE: {
    2701           0 :       accumulator->Add("<JSWeakMap>");
    2702           0 :       break;
    2703             :     }
    2704             :     case JS_WEAK_SET_TYPE: {
    2705           0 :       accumulator->Add("<JSWeakSet>");
    2706           0 :       break;
    2707             :     }
    2708             :     case JS_REGEXP_TYPE: {
    2709          30 :       accumulator->Add("<JSRegExp");
    2710             :       JSRegExp* regexp = JSRegExp::cast(this);
    2711          30 :       if (regexp->source()->IsString()) {
    2712          30 :         accumulator->Add(" ");
    2713          30 :         String::cast(regexp->source())->StringShortPrint(accumulator);
    2714             :       }
    2715          30 :       accumulator->Add(">");
    2716             : 
    2717          30 :       break;
    2718             :     }
    2719             :     case JS_FUNCTION_TYPE: {
    2720             :       JSFunction* function = JSFunction::cast(this);
    2721          73 :       Object* fun_name = function->shared()->DebugName();
    2722             :       bool printed = false;
    2723          73 :       if (fun_name->IsString()) {
    2724             :         String* str = String::cast(fun_name);
    2725          73 :         if (str->length() > 0) {
    2726          73 :           accumulator->Add("<JSFunction ");
    2727          73 :           accumulator->Put(str);
    2728             :           printed = true;
    2729             :         }
    2730             :       }
    2731          73 :       if (!printed) {
    2732           0 :         accumulator->Add("<JSFunction");
    2733             :       }
    2734          73 :       if (FLAG_trace_file_names) {
    2735             :         Object* source_name =
    2736             :             Script::cast(function->shared()->script())->name();
    2737           0 :         if (source_name->IsString()) {
    2738             :           String* str = String::cast(source_name);
    2739           0 :           if (str->length() > 0) {
    2740           0 :             accumulator->Add(" <");
    2741           0 :             accumulator->Put(str);
    2742           0 :             accumulator->Add(">");
    2743             :           }
    2744             :         }
    2745             :       }
    2746             :       accumulator->Add(" (sfi = %p)",
    2747          73 :                        reinterpret_cast<void*>(function->shared()));
    2748          73 :       accumulator->Put('>');
    2749          73 :       break;
    2750             :     }
    2751             :     case JS_GENERATOR_OBJECT_TYPE: {
    2752           0 :       accumulator->Add("<JSGenerator>");
    2753           0 :       break;
    2754             :     }
    2755             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE: {
    2756           0 :       accumulator->Add("<JS AsyncGenerator>");
    2757           0 :       break;
    2758             :     }
    2759             : 
    2760             :     // All other JSObjects are rather similar to each other (JSObject,
    2761             :     // JSGlobalProxy, JSGlobalObject, JSUndetectable, JSValue).
    2762             :     default: {
    2763             :       Map* map_of_this = map();
    2764             :       Heap* heap = GetHeap();
    2765         536 :       Object* constructor = map_of_this->GetConstructor();
    2766             :       bool printed = false;
    2767        1072 :       if (constructor->IsHeapObject() &&
    2768         536 :           !heap->Contains(HeapObject::cast(constructor))) {
    2769           0 :         accumulator->Add("!!!INVALID CONSTRUCTOR!!!");
    2770             :       } else {
    2771             :         bool global_object = IsJSGlobalProxy();
    2772         536 :         if (constructor->IsJSFunction()) {
    2773         536 :           if (!heap->Contains(JSFunction::cast(constructor)->shared())) {
    2774           0 :             accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!");
    2775             :           } else {
    2776             :             Object* constructor_name =
    2777             :                 JSFunction::cast(constructor)->shared()->name();
    2778         536 :             if (constructor_name->IsString()) {
    2779             :               String* str = String::cast(constructor_name);
    2780         536 :               if (str->length() > 0) {
    2781         472 :                 accumulator->Add(global_object ? "<GlobalObject " : "<");
    2782         472 :                 accumulator->Put(str);
    2783             :                 accumulator->Add(
    2784             :                     " %smap = %p",
    2785             :                     map_of_this->is_deprecated() ? "deprecated-" : "",
    2786         472 :                     map_of_this);
    2787             :                 printed = true;
    2788             :               }
    2789             :             }
    2790             :           }
    2791           0 :         } else if (constructor->IsFunctionTemplateInfo()) {
    2792           0 :           accumulator->Add(global_object ? "<RemoteObject>" : "<RemoteObject>");
    2793             :           printed = true;
    2794             :         }
    2795         536 :         if (!printed) {
    2796          64 :           accumulator->Add("<JS%sObject", global_object ? "Global " : "");
    2797             :         }
    2798             :       }
    2799         536 :       if (IsJSValue()) {
    2800          15 :         accumulator->Add(" value = ");
    2801          15 :         JSValue::cast(this)->value()->ShortPrint(accumulator);
    2802             :       }
    2803         536 :       accumulator->Put('>');
    2804         536 :       break;
    2805             :     }
    2806             :   }
    2807         840 : }
    2808             : 
    2809             : 
    2810           0 : void JSObject::PrintElementsTransition(
    2811             :     FILE* file, Handle<JSObject> object,
    2812             :     ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
    2813             :     ElementsKind to_kind, Handle<FixedArrayBase> to_elements) {
    2814           0 :   if (from_kind != to_kind) {
    2815           0 :     OFStream os(file);
    2816           0 :     os << "elements transition [" << ElementsKindToString(from_kind) << " -> "
    2817           0 :        << ElementsKindToString(to_kind) << "] in ";
    2818           0 :     JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true);
    2819           0 :     PrintF(file, " for ");
    2820           0 :     object->ShortPrint(file);
    2821           0 :     PrintF(file, " from ");
    2822           0 :     from_elements->ShortPrint(file);
    2823           0 :     PrintF(file, " to ");
    2824           0 :     to_elements->ShortPrint(file);
    2825           0 :     PrintF(file, "\n");
    2826             :   }
    2827           0 : }
    2828             : 
    2829             : 
    2830             : // static
    2831      217515 : MaybeHandle<JSFunction> Map::GetConstructorFunction(
    2832             :     Handle<Map> map, Handle<Context> native_context) {
    2833      217515 :   if (map->IsPrimitiveMap()) {
    2834             :     int const constructor_function_index = map->GetConstructorFunctionIndex();
    2835       35986 :     if (constructor_function_index != kNoConstructorFunctionIndex) {
    2836             :       return handle(
    2837             :           JSFunction::cast(native_context->get(constructor_function_index)));
    2838             :     }
    2839             :   }
    2840             :   return MaybeHandle<JSFunction>();
    2841             : }
    2842             : 
    2843             : 
    2844           0 : void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
    2845             :                                PropertyAttributes attributes) {
    2846           0 :   OFStream os(file);
    2847           0 :   os << "[reconfiguring]";
    2848             :   Name* name = instance_descriptors()->GetKey(modify_index);
    2849           0 :   if (name->IsString()) {
    2850           0 :     String::cast(name)->PrintOn(file);
    2851             :   } else {
    2852           0 :     os << "{symbol " << static_cast<void*>(name) << "}";
    2853             :   }
    2854           0 :   os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: ";
    2855           0 :   os << attributes << " [";
    2856           0 :   JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
    2857           0 :   os << "]\n";
    2858           0 : }
    2859             : 
    2860           0 : void Map::PrintGeneralization(
    2861             :     FILE* file, const char* reason, int modify_index, int split,
    2862             :     int descriptors, bool descriptor_to_field,
    2863             :     Representation old_representation, Representation new_representation,
    2864             :     MaybeHandle<FieldType> old_field_type, MaybeHandle<Object> old_value,
    2865             :     MaybeHandle<FieldType> new_field_type, MaybeHandle<Object> new_value) {
    2866           0 :   OFStream os(file);
    2867           0 :   os << "[generalizing]";
    2868             :   Name* name = instance_descriptors()->GetKey(modify_index);
    2869           0 :   if (name->IsString()) {
    2870           0 :     String::cast(name)->PrintOn(file);
    2871             :   } else {
    2872           0 :     os << "{symbol " << static_cast<void*>(name) << "}";
    2873             :   }
    2874           0 :   os << ":";
    2875           0 :   if (descriptor_to_field) {
    2876           0 :     os << "c";
    2877             :   } else {
    2878           0 :     os << old_representation.Mnemonic() << "{";
    2879           0 :     if (old_field_type.is_null()) {
    2880           0 :       os << Brief(*(old_value.ToHandleChecked()));
    2881             :     } else {
    2882           0 :       old_field_type.ToHandleChecked()->PrintTo(os);
    2883             :     }
    2884           0 :     os << "}";
    2885             :   }
    2886           0 :   os << "->" << new_representation.Mnemonic() << "{";
    2887           0 :   if (new_field_type.is_null()) {
    2888           0 :     os << Brief(*(new_value.ToHandleChecked()));
    2889             :   } else {
    2890           0 :     new_field_type.ToHandleChecked()->PrintTo(os);
    2891             :   }
    2892           0 :   os << "} (";
    2893           0 :   if (strlen(reason) > 0) {
    2894           0 :     os << reason;
    2895             :   } else {
    2896           0 :     os << "+" << (descriptors - split) << " maps";
    2897             :   }
    2898           0 :   os << ") [";
    2899           0 :   JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
    2900           0 :   os << "]\n";
    2901           0 : }
    2902             : 
    2903             : 
    2904           0 : void JSObject::PrintInstanceMigration(FILE* file,
    2905             :                                       Map* original_map,
    2906             :                                       Map* new_map) {
    2907           0 :   if (new_map->is_dictionary_map()) {
    2908           0 :     PrintF(file, "[migrating to slow]\n");
    2909           0 :     return;
    2910             :   }
    2911           0 :   PrintF(file, "[migrating]");
    2912             :   DescriptorArray* o = original_map->instance_descriptors();
    2913             :   DescriptorArray* n = new_map->instance_descriptors();
    2914           0 :   for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) {
    2915           0 :     Representation o_r = o->GetDetails(i).representation();
    2916           0 :     Representation n_r = n->GetDetails(i).representation();
    2917           0 :     if (!o_r.Equals(n_r)) {
    2918           0 :       String::cast(o->GetKey(i))->PrintOn(file);
    2919           0 :       PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic());
    2920           0 :     } else if (o->GetDetails(i).location() == kDescriptor &&
    2921           0 :                n->GetDetails(i).location() == kField) {
    2922             :       Name* name = o->GetKey(i);
    2923           0 :       if (name->IsString()) {
    2924           0 :         String::cast(name)->PrintOn(file);
    2925             :       } else {
    2926           0 :         PrintF(file, "{symbol %p}", static_cast<void*>(name));
    2927             :       }
    2928           0 :       PrintF(file, " ");
    2929             :     }
    2930             :   }
    2931           0 :   if (original_map->elements_kind() != new_map->elements_kind()) {
    2932             :     PrintF(file, "elements_kind[%i->%i]", original_map->elements_kind(),
    2933           0 :            new_map->elements_kind());
    2934             :   }
    2935           0 :   PrintF(file, "\n");
    2936             : }
    2937             : 
    2938             : 
    2939        1356 : void HeapObject::HeapObjectShortPrint(std::ostream& os) {  // NOLINT
    2940             :   Heap* heap = GetHeap();
    2941             :   Isolate* isolate = heap->isolate();
    2942        1356 :   if (!heap->Contains(this)) {
    2943           0 :     os << "!!!INVALID POINTER!!!";
    2944           0 :     return;
    2945             :   }
    2946        1356 :   if (!heap->Contains(map())) {
    2947           0 :     os << "!!!INVALID MAP!!!";
    2948           0 :     return;
    2949             :   }
    2950             : 
    2951        1356 :   os << this << " ";
    2952             : 
    2953        1356 :   if (IsString()) {
    2954             :     HeapStringAllocator allocator;
    2955             :     StringStream accumulator(&allocator);
    2956          47 :     String::cast(this)->StringShortPrint(&accumulator);
    2957         141 :     os << accumulator.ToCString().get();
    2958             :     return;
    2959             :   }
    2960        1309 :   if (IsJSObject()) {
    2961             :     HeapStringAllocator allocator;
    2962             :     StringStream accumulator(&allocator);
    2963         840 :     JSObject::cast(this)->JSObjectShortPrint(&accumulator);
    2964        2520 :     os << accumulator.ToCString().get();
    2965             :     return;
    2966             :   }
    2967         469 :   switch (map()->instance_type()) {
    2968             :     case MAP_TYPE:
    2969           0 :       os << "<Map(" << ElementsKindToString(Map::cast(this)->elements_kind())
    2970           0 :          << ")>";
    2971           0 :       break;
    2972             :     case FIXED_ARRAY_TYPE:
    2973           0 :       os << "<FixedArray[" << FixedArray::cast(this)->length() << "]>";
    2974           0 :       break;
    2975             :     case FIXED_DOUBLE_ARRAY_TYPE:
    2976           0 :       os << "<FixedDoubleArray[" << FixedDoubleArray::cast(this)->length()
    2977           0 :          << "]>";
    2978           0 :       break;
    2979             :     case BYTE_ARRAY_TYPE:
    2980           0 :       os << "<ByteArray[" << ByteArray::cast(this)->length() << "]>";
    2981           0 :       break;
    2982             :     case BYTECODE_ARRAY_TYPE:
    2983           0 :       os << "<BytecodeArray[" << BytecodeArray::cast(this)->length() << "]>";
    2984           0 :       break;
    2985             :     case TRANSITION_ARRAY_TYPE:
    2986           0 :       os << "<TransitionArray[" << TransitionArray::cast(this)->length()
    2987           0 :          << "]>";
    2988           0 :       break;
    2989             :     case FREE_SPACE_TYPE:
    2990           0 :       os << "<FreeSpace[" << FreeSpace::cast(this)->size() << "]>";
    2991           0 :       break;
    2992             : #define TYPED_ARRAY_SHORT_PRINT(Type, type, TYPE, ctype, size)                \
    2993             :   case FIXED_##TYPE##_ARRAY_TYPE:                                             \
    2994             :     os << "<Fixed" #Type "Array[" << Fixed##Type##Array::cast(this)->length() \
    2995             :        << "]>";                                                               \
    2996             :     break;
    2997             : 
    2998           0 :     TYPED_ARRAYS(TYPED_ARRAY_SHORT_PRINT)
    2999             : #undef TYPED_ARRAY_SHORT_PRINT
    3000             : 
    3001             :     case SHARED_FUNCTION_INFO_TYPE: {
    3002             :       SharedFunctionInfo* shared = SharedFunctionInfo::cast(this);
    3003           0 :       std::unique_ptr<char[]> debug_name = shared->DebugName()->ToCString();
    3004           0 :       if (debug_name[0] != 0) {
    3005           0 :         os << "<SharedFunctionInfo " << debug_name.get() << ">";
    3006             :       } else {
    3007           0 :         os << "<SharedFunctionInfo>";
    3008             :       }
    3009             :       break;
    3010             :     }
    3011             :     case JS_MESSAGE_OBJECT_TYPE:
    3012           0 :       os << "<JSMessageObject>";
    3013           0 :       break;
    3014             : #define MAKE_STRUCT_CASE(NAME, Name, name) \
    3015             :   case NAME##_TYPE:                        \
    3016             :     os << "<" #Name ">";                   \
    3017             :     break;
    3018           0 :   STRUCT_LIST(MAKE_STRUCT_CASE)
    3019             : #undef MAKE_STRUCT_CASE
    3020             :     case CODE_TYPE: {
    3021             :       Code* code = Code::cast(this);
    3022           0 :       os << "<Code " << Code::Kind2String(code->kind()) << ">";
    3023           0 :       break;
    3024             :     }
    3025             :     case ODDBALL_TYPE: {
    3026         122 :       if (IsUndefined(isolate)) {
    3027          75 :         os << "<undefined>";
    3028          47 :       } else if (IsTheHole(isolate)) {
    3029           0 :         os << "<the_hole>";
    3030          47 :       } else if (IsNull(isolate)) {
    3031          17 :         os << "<null>";
    3032          30 :       } else if (IsTrue(isolate)) {
    3033          15 :         os << "<true>";
    3034          15 :       } else if (IsFalse(isolate)) {
    3035          15 :         os << "<false>";
    3036             :       } else {
    3037           0 :         os << "<Odd Oddball: ";
    3038           0 :         os << Oddball::cast(this)->to_string()->ToCString().get();
    3039           0 :         os << ">";
    3040             :       }
    3041             :       break;
    3042             :     }
    3043             :     case SYMBOL_TYPE: {
    3044             :       Symbol* symbol = Symbol::cast(this);
    3045         227 :       symbol->SymbolShortPrint(os);
    3046         227 :       break;
    3047             :     }
    3048             :     case HEAP_NUMBER_TYPE: {
    3049         105 :       os << "<Number ";
    3050             :       HeapNumber::cast(this)->HeapNumberPrint(os);
    3051         105 :       os << ">";
    3052         105 :       break;
    3053             :     }
    3054             :     case MUTABLE_HEAP_NUMBER_TYPE: {
    3055           0 :       os << "<MutableNumber ";
    3056             :       HeapNumber::cast(this)->HeapNumberPrint(os);
    3057             :       os << '>';
    3058             :       break;
    3059             :     }
    3060             :     case JS_PROXY_TYPE:
    3061          15 :       os << "<JSProxy>";
    3062          15 :       break;
    3063             :     case FOREIGN_TYPE:
    3064           0 :       os << "<Foreign>";
    3065           0 :       break;
    3066             :     case CELL_TYPE: {
    3067           0 :       os << "<Cell value= ";
    3068             :       HeapStringAllocator allocator;
    3069             :       StringStream accumulator(&allocator);
    3070           0 :       Cell::cast(this)->value()->ShortPrint(&accumulator);
    3071           0 :       os << accumulator.ToCString().get();
    3072             :       os << '>';
    3073             :       break;
    3074             :     }
    3075             :     case PROPERTY_CELL_TYPE: {
    3076           0 :       os << "<PropertyCell value=";
    3077             :       HeapStringAllocator allocator;
    3078             :       StringStream accumulator(&allocator);
    3079             :       PropertyCell* cell = PropertyCell::cast(this);
    3080           0 :       cell->value()->ShortPrint(&accumulator);
    3081           0 :       os << accumulator.ToCString().get();
    3082             :       os << '>';
    3083             :       break;
    3084             :     }
    3085             :     case WEAK_CELL_TYPE: {
    3086           0 :       os << "<WeakCell value= ";
    3087             :       HeapStringAllocator allocator;
    3088             :       StringStream accumulator(&allocator);
    3089           0 :       WeakCell::cast(this)->value()->ShortPrint(&accumulator);
    3090           0 :       os << accumulator.ToCString().get();
    3091             :       os << '>';
    3092             :       break;
    3093             :     }
    3094             :     default:
    3095           0 :       os << "<Other heap object (" << map()->instance_type() << ")>";
    3096           0 :       break;
    3097             :   }
    3098             : }
    3099             : 
    3100             : 
    3101    33403871 : void HeapObject::Iterate(ObjectVisitor* v) { IterateFast<ObjectVisitor>(v); }
    3102             : 
    3103             : 
    3104         682 : void HeapObject::IterateBody(ObjectVisitor* v) {
    3105             :   Map* m = map();
    3106         682 :   IterateBodyFast<ObjectVisitor>(m->instance_type(), SizeFromMap(m), v);
    3107         682 : }
    3108             : 
    3109             : 
    3110    52843115 : void HeapObject::IterateBody(InstanceType type, int object_size,
    3111             :                              ObjectVisitor* v) {
    3112             :   IterateBodyFast<ObjectVisitor>(type, object_size, v);
    3113    52813816 : }
    3114             : 
    3115             : 
    3116             : struct CallIsValidSlot {
    3117             :   template <typename BodyDescriptor>
    3118             :   static bool apply(HeapObject* obj, int offset, int) {
    3119             :     return BodyDescriptor::IsValidSlot(obj, offset);
    3120             :   }
    3121             : };
    3122             : 
    3123             : 
    3124           0 : bool HeapObject::IsValidSlot(int offset) {
    3125             :   DCHECK_NE(0, offset);
    3126             :   return BodyDescriptorApply<CallIsValidSlot, bool>(map()->instance_type(),
    3127           0 :                                                     this, offset, 0);
    3128             : }
    3129             : 
    3130             : 
    3131           0 : bool HeapNumber::HeapNumberBooleanValue() {
    3132       64743 :   return DoubleToBoolean(value());
    3133             : }
    3134             : 
    3135             : 
    3136       16569 : void HeapNumber::HeapNumberPrint(std::ostream& os) {  // NOLINT
    3137             :   os << value();
    3138       16569 : }
    3139             : 
    3140             : 
    3141             : #define FIELD_ADDR_CONST(p, offset) \
    3142             :   (reinterpret_cast<const byte*>(p) + offset - kHeapObjectTag)
    3143             : 
    3144             : #define READ_INT32_FIELD(p, offset) \
    3145             :   (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset)))
    3146             : 
    3147             : #define READ_INT64_FIELD(p, offset) \
    3148             :   (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset)))
    3149             : 
    3150             : #define READ_BYTE_FIELD(p, offset) \
    3151             :   (*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset)))
    3152             : 
    3153    65542419 : String* JSReceiver::class_name() {
    3154    65542420 :   if (IsFunction()) {
    3155    31014906 :     return GetHeap()->Function_string();
    3156             :   }
    3157    34527514 :   Object* maybe_constructor = map()->GetConstructor();
    3158    34527514 :   if (maybe_constructor->IsJSFunction()) {
    3159             :     JSFunction* constructor = JSFunction::cast(maybe_constructor);
    3160    34527447 :     return String::cast(constructor->shared()->instance_class_name());
    3161          67 :   } else if (maybe_constructor->IsFunctionTemplateInfo()) {
    3162             :     FunctionTemplateInfo* info = FunctionTemplateInfo::cast(maybe_constructor);
    3163             :     return info->class_name()->IsString() ? String::cast(info->class_name())
    3164           1 :                                           : GetHeap()->empty_string();
    3165             :   }
    3166             : 
    3167             :   // If the constructor is not present, return "Object".
    3168          66 :   return GetHeap()->Object_string();
    3169             : }
    3170             : 
    3171             : 
    3172             : // static
    3173     7689709 : Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
    3174             :   Isolate* isolate = receiver->GetIsolate();
    3175             : 
    3176             :   // If the object was instantiated simply with base == new.target, the
    3177             :   // constructor on the map provides the most accurate name.
    3178             :   // Don't provide the info for prototypes, since their constructors are
    3179             :   // reclaimed and replaced by Object in OptimizeAsPrototype.
    3180    23068382 :   if (!receiver->IsJSProxy() && receiver->map()->new_target_is_base() &&
    3181             :       !receiver->map()->is_prototype_map()) {
    3182     7471617 :     Object* maybe_constructor = receiver->map()->GetConstructor();
    3183     7471617 :     if (maybe_constructor->IsJSFunction()) {
    3184             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
    3185             :       String* name = String::cast(constructor->shared()->name());
    3186     5036080 :       if (name->length() == 0) name = constructor->shared()->inferred_name();
    3187     9334015 :       if (name->length() != 0 &&
    3188     4297935 :           !name->Equals(isolate->heap()->Object_string())) {
    3189             :         return handle(name, isolate);
    3190             :       }
    3191     2435537 :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
    3192             :       FunctionTemplateInfo* info =
    3193             :           FunctionTemplateInfo::cast(maybe_constructor);
    3194           0 :       if (info->class_name()->IsString()) {
    3195             :         return handle(String::cast(info->class_name()), isolate);
    3196             :       }
    3197             :     }
    3198             :   }
    3199             : 
    3200             :   Handle<Object> maybe_tag = JSReceiver::GetDataProperty(
    3201     4364013 :       receiver, isolate->factory()->to_string_tag_symbol());
    3202     4364013 :   if (maybe_tag->IsString()) return Handle<String>::cast(maybe_tag);
    3203             : 
    3204     3649531 :   PrototypeIterator iter(isolate, receiver);
    3205     4273712 :   if (iter.IsAtEnd()) return handle(receiver->class_name());
    3206     3025350 :   Handle<JSReceiver> start = PrototypeIterator::GetCurrent<JSReceiver>(iter);
    3207             :   LookupIterator it(receiver, isolate->factory()->constructor_string(), start,
    3208     3025350 :                     LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
    3209     3025350 :   Handle<Object> maybe_constructor = JSReceiver::GetDataProperty(&it);
    3210             :   Handle<String> result = isolate->factory()->Object_string();
    3211     3025350 :   if (maybe_constructor->IsJSFunction()) {
    3212             :     JSFunction* constructor = JSFunction::cast(*maybe_constructor);
    3213             :     String* name = String::cast(constructor->shared()->name());
    3214     3025236 :     if (name->length() == 0) name = constructor->shared()->inferred_name();
    3215     3025236 :     if (name->length() > 0) result = handle(name, isolate);
    3216             :   }
    3217             : 
    3218             :   return result.is_identical_to(isolate->factory()->Object_string())
    3219      476583 :              ? handle(receiver->class_name())
    3220     5574117 :              : result;
    3221             : }
    3222             : 
    3223         491 : Handle<Context> JSReceiver::GetCreationContext() {
    3224             :   JSReceiver* receiver = this;
    3225         996 :   while (receiver->IsJSBoundFunction()) {
    3226             :     receiver = JSBoundFunction::cast(receiver)->bound_target_function();
    3227             :   }
    3228         491 :   Object* constructor = receiver->map()->GetConstructor();
    3229             :   JSFunction* function;
    3230         491 :   if (constructor->IsJSFunction()) {
    3231             :     function = JSFunction::cast(constructor);
    3232          14 :   } else if (constructor->IsFunctionTemplateInfo()) {
    3233             :     // Remote objects don't have a creation context.
    3234           2 :     return Handle<Context>::null();
    3235             :   } else {
    3236             :     // Functions have null as a constructor,
    3237             :     // but any JSFunction knows its context immediately.
    3238          12 :     CHECK(receiver->IsJSFunction());
    3239             :     function = JSFunction::cast(receiver);
    3240             :   }
    3241             : 
    3242         489 :   return function->has_context()
    3243             :              ? Handle<Context>(function->context()->native_context())
    3244         489 :              : Handle<Context>::null();
    3245             : }
    3246             : 
    3247     9708462 : Handle<Object> Map::WrapFieldType(Handle<FieldType> type) {
    3248    10969450 :   if (type->IsClass()) return Map::WeakCellForMap(type->AsClass());
    3249     8447477 :   return type;
    3250             : }
    3251             : 
    3252    67479806 : FieldType* Map::UnwrapFieldType(Object* wrapped_type) {
    3253             :   Object* value = wrapped_type;
    3254    67479806 :   if (value->IsWeakCell()) {
    3255     9719651 :     if (WeakCell::cast(value)->cleared()) return FieldType::None();
    3256             :     value = WeakCell::cast(value)->value();
    3257             :   }
    3258    67479691 :   return FieldType::cast(value);
    3259             : }
    3260             : 
    3261     8783253 : MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, Handle<Name> name,
    3262             :                                     Handle<FieldType> type,
    3263             :                                     PropertyAttributes attributes,
    3264             :                                     PropertyConstness constness,
    3265             :                                     Representation representation,
    3266             :                                     TransitionFlag flag) {
    3267             :   DCHECK(DescriptorArray::kNotFound ==
    3268             :          map->instance_descriptors()->Search(
    3269             :              *name, map->NumberOfOwnDescriptors()));
    3270             : 
    3271             :   // Ensure the descriptor array does not get too big.
    3272     8783253 :   if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
    3273             :     return MaybeHandle<Map>();
    3274             :   }
    3275             : 
    3276             :   Isolate* isolate = map->GetIsolate();
    3277             : 
    3278             :   // Compute the new index for new field.
    3279     8783136 :   int index = map->NextFreePropertyIndex();
    3280             : 
    3281     8783134 :   if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) {
    3282        4195 :     representation = Representation::Tagged();
    3283        4195 :     type = FieldType::Any(isolate);
    3284             :   }
    3285             : 
    3286     8783134 :   Handle<Object> wrapped_type(WrapFieldType(type));
    3287             : 
    3288             :   DCHECK_IMPLIES(!FLAG_track_constant_fields, constness == kMutable);
    3289             :   Descriptor d = Descriptor::DataField(name, index, attributes, constness,
    3290     8783134 :                                        representation, wrapped_type);
    3291     8783134 :   Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag);
    3292     8783138 :   int unused_property_fields = new_map->unused_property_fields() - 1;
    3293     8783138 :   if (unused_property_fields < 0) {
    3294     2329585 :     unused_property_fields += JSObject::kFieldsAdded;
    3295             :   }
    3296             :   new_map->set_unused_property_fields(unused_property_fields);
    3297             :   return new_map;
    3298             : }
    3299             : 
    3300             : 
    3301     6722403 : MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map,
    3302             :                                        Handle<Name> name,
    3303             :                                        Handle<Object> constant,
    3304             :                                        PropertyAttributes attributes,
    3305             :                                        TransitionFlag flag) {
    3306             :   // Ensure the descriptor array does not get too big.
    3307     6722403 :   if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
    3308             :     return MaybeHandle<Map>();
    3309             :   }
    3310             : 
    3311             :   if (FLAG_track_constant_fields) {
    3312             :     Isolate* isolate = map->GetIsolate();
    3313             :     Representation representation = constant->OptimalRepresentation();
    3314             :     Handle<FieldType> type = constant->OptimalType(isolate, representation);
    3315             :     return CopyWithField(map, name, type, attributes, kConst, representation,
    3316             :                          flag);
    3317             :   } else {
    3318             :     // Allocate new instance descriptors with (name, constant) added.
    3319     6722403 :     Descriptor d = Descriptor::DataConstant(name, 0, constant, attributes);
    3320     6722405 :     Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag);
    3321             :     return new_map;
    3322             :   }
    3323             : }
    3324             : 
    3325           0 : const char* Representation::Mnemonic() const {
    3326           0 :   switch (kind_) {
    3327             :     case kNone: return "v";
    3328           0 :     case kTagged: return "t";
    3329           0 :     case kSmi: return "s";
    3330           0 :     case kDouble: return "d";
    3331           0 :     case kInteger32: return "i";
    3332           0 :     case kHeapObject: return "h";
    3333           0 :     case kExternal: return "x";
    3334             :     default:
    3335           0 :       UNREACHABLE();
    3336             :       return NULL;
    3337             :   }
    3338             : }
    3339             : 
    3340           0 : bool Map::TransitionRemovesTaggedField(Map* target) {
    3341             :   int inobject = GetInObjectProperties();
    3342             :   int target_inobject = target->GetInObjectProperties();
    3343           0 :   for (int i = target_inobject; i < inobject; i++) {
    3344           0 :     FieldIndex index = FieldIndex::ForPropertyIndex(this, i);
    3345           0 :     if (!IsUnboxedDoubleField(index)) return true;
    3346             :   }
    3347             :   return false;
    3348             : }
    3349             : 
    3350           0 : bool Map::TransitionChangesTaggedFieldToUntaggedField(Map* target) {
    3351             :   int inobject = GetInObjectProperties();
    3352             :   int target_inobject = target->GetInObjectProperties();
    3353             :   int limit = Min(inobject, target_inobject);
    3354           0 :   for (int i = 0; i < limit; i++) {
    3355           0 :     FieldIndex index = FieldIndex::ForPropertyIndex(target, i);
    3356           0 :     if (!IsUnboxedDoubleField(index) && target->IsUnboxedDoubleField(index)) {
    3357           0 :       return true;
    3358             :     }
    3359             :   }
    3360             :   return false;
    3361             : }
    3362             : 
    3363           0 : bool Map::TransitionRequiresSynchronizationWithGC(Map* target) {
    3364           0 :   return TransitionRemovesTaggedField(target) ||
    3365           0 :          TransitionChangesTaggedFieldToUntaggedField(target);
    3366             : }
    3367             : 
    3368      147124 : bool Map::InstancesNeedRewriting(Map* target) {
    3369      147124 :   int target_number_of_fields = target->NumberOfFields();
    3370             :   int target_inobject = target->GetInObjectProperties();
    3371             :   int target_unused = target->unused_property_fields();
    3372             :   int old_number_of_fields;
    3373             : 
    3374             :   return InstancesNeedRewriting(target, target_number_of_fields,
    3375             :                                 target_inobject, target_unused,
    3376      147124 :                                 &old_number_of_fields);
    3377             : }
    3378             : 
    3379    26143404 : bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
    3380             :                                  int target_inobject, int target_unused,
    3381             :                                  int* old_number_of_fields) {
    3382             :   // If fields were added (or removed), rewrite the instance.
    3383    26143404 :   *old_number_of_fields = NumberOfFields();
    3384             :   DCHECK(target_number_of_fields >= *old_number_of_fields);
    3385    26143405 :   if (target_number_of_fields != *old_number_of_fields) return true;
    3386             : 
    3387             :   // If smi descriptors were replaced by double descriptors, rewrite.
    3388             :   DescriptorArray* old_desc = instance_descriptors();
    3389             :   DescriptorArray* new_desc = target->instance_descriptors();
    3390             :   int limit = NumberOfOwnDescriptors();
    3391    50164247 :   for (int i = 0; i < limit; i++) {
    3392    72794266 :     if (new_desc->GetDetails(i).representation().IsDouble() !=
    3393    72794268 :         old_desc->GetDetails(i).representation().IsDouble()) {
    3394             :       return true;
    3395             :     }
    3396             :   }
    3397             : 
    3398             :   // If no fields were added, and no inobject properties were removed, setting
    3399             :   // the map is sufficient.
    3400    13767115 :   if (target_inobject == GetInObjectProperties()) return false;
    3401             :   // In-object slack tracking may have reduced the object size of the new map.
    3402             :   // In that case, succeed if all existing fields were inobject, and they still
    3403             :   // fit within the new inobject size.
    3404             :   DCHECK(target_inobject < GetInObjectProperties());
    3405         509 :   if (target_number_of_fields <= target_inobject) {
    3406             :     DCHECK(target_number_of_fields + target_unused == target_inobject);
    3407             :     return false;
    3408             :   }
    3409             :   // Otherwise, properties will need to be moved to the backing store.
    3410           0 :   return true;
    3411             : }
    3412             : 
    3413             : 
    3414             : // static
    3415     5501812 : void JSObject::UpdatePrototypeUserRegistration(Handle<Map> old_map,
    3416             :                                                Handle<Map> new_map,
    3417             :                                                Isolate* isolate) {
    3418             :   DCHECK(old_map->is_prototype_map());
    3419             :   DCHECK(new_map->is_prototype_map());
    3420     5501812 :   bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
    3421     5501812 :   new_map->set_prototype_info(old_map->prototype_info());
    3422     5501813 :   old_map->set_prototype_info(Smi::kZero);
    3423     5501812 :   if (FLAG_trace_prototype_users) {
    3424             :     PrintF("Moving prototype_info %p from map %p to map %p.\n",
    3425             :            reinterpret_cast<void*>(new_map->prototype_info()),
    3426             :            reinterpret_cast<void*>(*old_map),
    3427           0 :            reinterpret_cast<void*>(*new_map));
    3428             :   }
    3429     5501812 :   if (was_registered) {
    3430      284542 :     if (new_map->prototype_info()->IsPrototypeInfo()) {
    3431             :       // The new map isn't registered with its prototype yet; reflect this fact
    3432             :       // in the PrototypeInfo it just inherited from the old map.
    3433             :       PrototypeInfo::cast(new_map->prototype_info())
    3434             :           ->set_registry_slot(PrototypeInfo::UNREGISTERED);
    3435             :     }
    3436      284542 :     JSObject::LazyRegisterPrototypeUser(new_map, isolate);
    3437             :   }
    3438     5501812 : }
    3439             : 
    3440             : namespace {
    3441             : // To migrate a fast instance to a fast map:
    3442             : // - First check whether the instance needs to be rewritten. If not, simply
    3443             : //   change the map.
    3444             : // - Otherwise, allocate a fixed array large enough to hold all fields, in
    3445             : //   addition to unused space.
    3446             : // - Copy all existing properties in, in the following order: backing store
    3447             : //   properties, unused fields, inobject properties.
    3448             : // - If all allocation succeeded, commit the state atomically:
    3449             : //   * Copy inobject properties from the backing store back into the object.
    3450             : //   * Trim the difference in instance size of the object. This also cleanly
    3451             : //     frees inobject properties that moved to the backing store.
    3452             : //   * If there are properties left in the backing store, trim of the space used
    3453             : //     to temporarily store the inobject properties.
    3454             : //   * If there are properties left in the backing store, install the backing
    3455             : //     store.
    3456    52843403 : void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
    3457             :   Isolate* isolate = object->GetIsolate();
    3458             :   Handle<Map> old_map(object->map());
    3459             :   // In case of a regular transition.
    3460   105686795 :   if (new_map->GetBackPointer() == *old_map) {
    3461             :     // If the map does not add named properties, simply set the map.
    3462    26847117 :     if (old_map->NumberOfOwnDescriptors() ==
    3463             :         new_map->NumberOfOwnDescriptors()) {
    3464      686146 :       object->synchronized_set_map(*new_map);
    3465      686135 :       return;
    3466             :     }
    3467             : 
    3468             :     PropertyDetails details = new_map->GetLastDescriptorDetails();
    3469    26160983 :     int target_index = details.field_index() - new_map->GetInObjectProperties();
    3470    31520180 :     bool have_space = old_map->unused_property_fields() > 0 ||
    3471     9289388 :                       (details.location() == kField && target_index >= 0 &&
    3472             :                        object->properties()->length() > target_index);
    3473             :     // Either new_map adds an kDescriptor property, or a kField property for
    3474             :     // which there is still space, and which does not require a mutable double
    3475             :     // box (an out-of-object double).
    3476    52321966 :     if (details.location() == kDescriptor ||
    3477    18043579 :         (have_space &&
    3478     5436580 :          ((FLAG_unbox_double_fields && object->properties()->length() == 0) ||
    3479             :           !details.representation().IsDouble()))) {
    3480    21510796 :       object->synchronized_set_map(*new_map);
    3481    21510795 :       return;
    3482             :     }
    3483             : 
    3484             :     // If there is still space in the object, we need to allocate a mutable
    3485             :     // double box.
    3486     4650187 :     if (have_space) {
    3487             :       FieldIndex index =
    3488        5492 :           FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
    3489             :       DCHECK(details.representation().IsDouble());
    3490             :       DCHECK(!new_map->IsUnboxedDoubleField(index));
    3491             :       Handle<Object> value = isolate->factory()->NewMutableHeapNumber();
    3492        5492 :       object->RawFastPropertyAtPut(index, *value);
    3493        5492 :       object->synchronized_set_map(*new_map);
    3494             :       return;
    3495             :     }
    3496             : 
    3497             :     // This migration is a transition from a map that has run out of property
    3498             :     // space. Extend the backing store.
    3499     4644695 :     int grow_by = new_map->unused_property_fields() + 1;
    3500     4644694 :     Handle<FixedArray> old_storage = handle(object->properties(), isolate);
    3501             :     Handle<FixedArray> new_storage =
    3502     4644694 :         isolate->factory()->CopyFixedArrayAndGrow(old_storage, grow_by);
    3503             : 
    3504             :     // Properly initialize newly added property.
    3505             :     Handle<Object> value;
    3506     4644694 :     if (details.representation().IsDouble()) {
    3507             :       value = isolate->factory()->NewMutableHeapNumber();
    3508             :     } else {
    3509             :       value = isolate->factory()->uninitialized_value();
    3510             :     }
    3511             :     DCHECK_EQ(kField, details.location());
    3512             :     DCHECK_EQ(kData, details.kind());
    3513             :     DCHECK(target_index >= 0);  // Must be a backing store index.
    3514     4644694 :     new_storage->set(target_index, *value);
    3515             : 
    3516             :     // From here on we cannot fail and we shouldn't GC anymore.
    3517             :     DisallowHeapAllocation no_allocation;
    3518             : 
    3519             :     // Set the new property value and do the map transition.
    3520     4644694 :     object->set_properties(*new_storage);
    3521     4644695 :     object->synchronized_set_map(*new_map);
    3522     4644695 :     return;
    3523             :   }
    3524             : 
    3525             :   int old_number_of_fields;
    3526    25996282 :   int number_of_fields = new_map->NumberOfFields();
    3527             :   int inobject = new_map->GetInObjectProperties();
    3528             :   int unused = new_map->unused_property_fields();
    3529             : 
    3530             :   // Nothing to do if no functions were converted to fields and no smis were
    3531             :   // converted to doubles.
    3532    25996282 :   if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
    3533    25996280 :                                        unused, &old_number_of_fields)) {
    3534    13620021 :     object->synchronized_set_map(*new_map);
    3535    13620023 :     return;
    3536             :   }
    3537             : 
    3538    12376261 :   int total_size = number_of_fields + unused;
    3539    12376261 :   int external = total_size - inobject;
    3540             : 
    3541    12376261 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size);
    3542             : 
    3543             :   Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
    3544             :   Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors());
    3545             :   int old_nof = old_map->NumberOfOwnDescriptors();
    3546             :   int new_nof = new_map->NumberOfOwnDescriptors();
    3547             : 
    3548             :   // This method only supports generalizing instances to at least the same
    3549             :   // number of properties.
    3550             :   DCHECK(old_nof <= new_nof);
    3551             : 
    3552   105629574 :   for (int i = 0; i < old_nof; i++) {
    3553    93253311 :     PropertyDetails details = new_descriptors->GetDetails(i);
    3554    93253317 :     if (details.location() != kField) continue;
    3555             :     DCHECK_EQ(kData, details.kind());
    3556    63107157 :     PropertyDetails old_details = old_descriptors->GetDetails(i);
    3557             :     Representation old_representation = old_details.representation();
    3558             :     Representation representation = details.representation();
    3559             :     Handle<Object> value;
    3560    63107158 :     if (old_details.location() == kDescriptor) {
    3561     1950275 :       if (old_details.kind() == kAccessor) {
    3562             :         // In case of kAccessor -> kData property reconfiguration, the property
    3563             :         // must already be prepared for data of certain type.
    3564             :         DCHECK(!details.representation().IsNone());
    3565     1513561 :         if (details.representation().IsDouble()) {
    3566             :           value = isolate->factory()->NewMutableHeapNumber();
    3567             :         } else {
    3568             :           value = isolate->factory()->uninitialized_value();
    3569             :         }
    3570             :       } else {
    3571             :         DCHECK_EQ(kData, old_details.kind());
    3572             :         value = handle(old_descriptors->GetValue(i), isolate);
    3573             :         DCHECK(!old_representation.IsDouble() && !representation.IsDouble());
    3574             :       }
    3575             :     } else {
    3576             :       DCHECK_EQ(kField, old_details.location());
    3577    61156883 :       FieldIndex index = FieldIndex::ForDescriptor(*old_map, i);
    3578    61156882 :       if (object->IsUnboxedDoubleField(index)) {
    3579             :         uint64_t old_bits = object->RawFastDoublePropertyAsBitsAt(index);
    3580             :         value = isolate->factory()->NewHeapNumberFromBits(
    3581        4883 :             old_bits, representation.IsDouble() ? MUTABLE : IMMUTABLE);
    3582             : 
    3583             :       } else {
    3584    61152000 :         value = handle(object->RawFastPropertyAt(index), isolate);
    3585    61152000 :         if (!old_representation.IsDouble() && representation.IsDouble()) {
    3586             :           DCHECK_IMPLIES(old_representation.IsNone(),
    3587             :                          value->IsUninitialized(isolate));
    3588        2849 :           value = Object::NewStorageFor(isolate, value, representation);
    3589    61149151 :         } else if (old_representation.IsDouble() &&
    3590             :                    !representation.IsDouble()) {
    3591          19 :           value = Object::WrapForRead(isolate, value, old_representation);
    3592             :         }
    3593             :       }
    3594             :     }
    3595             :     DCHECK(!(representation.IsDouble() && value->IsSmi()));
    3596    63107157 :     int target_index = new_descriptors->GetFieldIndex(i) - inobject;
    3597    63107157 :     if (target_index < 0) target_index += total_size;
    3598    63107157 :     array->set(target_index, *value);
    3599             :   }
    3600             : 
    3601    43615733 :   for (int i = old_nof; i < new_nof; i++) {
    3602    43615733 :     PropertyDetails details = new_descriptors->GetDetails(i);
    3603    43615733 :     if (details.location() != kField) continue;
    3604             :     DCHECK_EQ(kData, details.kind());
    3605             :     Handle<Object> value;
    3606    43615733 :     if (details.representation().IsDouble()) {
    3607             :       value = isolate->factory()->NewMutableHeapNumber();
    3608             :     } else {
    3609             :       value = isolate->factory()->uninitialized_value();
    3610             :     }
    3611    43615733 :     int target_index = new_descriptors->GetFieldIndex(i) - inobject;
    3612    43615733 :     if (target_index < 0) target_index += total_size;
    3613    43615733 :     array->set(target_index, *value);
    3614             :   }
    3615             : 
    3616             :   // From here on we cannot fail and we shouldn't GC anymore.
    3617             :   DisallowHeapAllocation no_allocation;
    3618             : 
    3619    12376263 :   Heap* heap = isolate->heap();
    3620             : 
    3621    12376263 :   heap->NotifyObjectLayoutChange(*object, no_allocation);
    3622             : 
    3623             :   // Copy (real) inobject properties. If necessary, stop at number_of_fields to
    3624             :   // avoid overwriting |one_pointer_filler_map|.
    3625             :   int limit = Min(inobject, number_of_fields);
    3626    47766808 :   for (int i = 0; i < limit; i++) {
    3627    35390545 :     FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
    3628    35390545 :     Object* value = array->get(external + i);
    3629             :     // Can't use JSObject::FastPropertyAtPut() because proper map was not set
    3630             :     // yet.
    3631    35390545 :     if (new_map->IsUnboxedDoubleField(index)) {
    3632             :       DCHECK(value->IsMutableHeapNumber());
    3633             :       // Ensure that all bits of the double value are preserved.
    3634             :       object->RawFastDoublePropertyAsBitsAtPut(
    3635             :           index, HeapNumber::cast(value)->value_as_bits());
    3636       45562 :       if (i < old_number_of_fields && !old_map->IsUnboxedDoubleField(index)) {
    3637             :         // Transition from tagged to untagged slot.
    3638             :         heap->ClearRecordedSlot(*object,
    3639        1903 :                                 HeapObject::RawField(*object, index.offset()));
    3640             :       } else {
    3641             :         DCHECK(!heap->HasRecordedSlot(
    3642             :             *object, HeapObject::RawField(*object, index.offset())));
    3643             :       }
    3644             :     } else {
    3645    35351030 :       object->RawFastPropertyAtPut(index, value);
    3646             :     }
    3647             :   }
    3648             : 
    3649             : 
    3650             :   // If there are properties in the new backing store, trim it to the correct
    3651             :   // size and install the backing store into the object.
    3652    12376263 :   if (external > 0) {
    3653     6740143 :     heap->RightTrimFixedArray(*array, inobject);
    3654     6740143 :     object->set_properties(*array);
    3655             :   }
    3656             : 
    3657             :   // Create filler object past the new instance size.
    3658             :   int new_instance_size = new_map->instance_size();
    3659    12376260 :   int instance_size_delta = old_map->instance_size() - new_instance_size;
    3660             :   DCHECK(instance_size_delta >= 0);
    3661             : 
    3662    12376260 :   if (instance_size_delta > 0) {
    3663          17 :     Address address = object->address();
    3664             :     heap->CreateFillerObjectAt(address + new_instance_size, instance_size_delta,
    3665          17 :                                ClearRecordedSlots::kYes);
    3666          34 :     heap->AdjustLiveBytes(*object, -instance_size_delta);
    3667             :   }
    3668             : 
    3669             :   // We are storing the new map using release store after creating a filler for
    3670             :   // the left-over space to avoid races with the sweeper thread.
    3671    12376260 :   object->synchronized_set_map(*new_map);
    3672             : }
    3673             : 
    3674     1318662 : void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
    3675             :                        int expected_additional_properties) {
    3676             :   // The global object is always normalized.
    3677             :   DCHECK(!object->IsJSGlobalObject());
    3678             :   // JSGlobalProxy must never be normalized
    3679             :   DCHECK(!object->IsJSGlobalProxy());
    3680             : 
    3681     1318662 :   Isolate* isolate = object->GetIsolate();
    3682             :   HandleScope scope(isolate);
    3683             :   Handle<Map> map(object->map());
    3684             : 
    3685             :   // Allocate new content.
    3686             :   int real_size = map->NumberOfOwnDescriptors();
    3687             :   int property_count = real_size;
    3688     1318662 :   if (expected_additional_properties > 0) {
    3689       94869 :     property_count += expected_additional_properties;
    3690             :   } else {
    3691             :     // Make space for two more properties.
    3692     1223793 :     property_count += NameDictionary::kInitialCapacity;
    3693             :   }
    3694             :   Handle<NameDictionary> dictionary =
    3695     1318662 :       NameDictionary::New(isolate, property_count);
    3696             : 
    3697             :   Handle<DescriptorArray> descs(map->instance_descriptors());
    3698     8438109 :   for (int i = 0; i < real_size; i++) {
    3699     5800785 :     PropertyDetails details = descs->GetDetails(i);
    3700             :     Handle<Name> key(descs->GetKey(i));
    3701             :     Handle<Object> value;
    3702     5800785 :     if (details.location() == kField) {
    3703     4467019 :       FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    3704     4467019 :       if (details.kind() == kData) {
    3705     4467019 :         if (object->IsUnboxedDoubleField(index)) {
    3706             :           double old_value = object->RawFastDoublePropertyAt(index);
    3707             :           value = isolate->factory()->NewHeapNumber(old_value);
    3708             :         } else {
    3709     4466123 :           value = handle(object->RawFastPropertyAt(index), isolate);
    3710     4466123 :           if (details.representation().IsDouble()) {
    3711             :             DCHECK(value->IsMutableHeapNumber());
    3712             :             Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
    3713             :             value = isolate->factory()->NewHeapNumber(old->value());
    3714             :           }
    3715             :         }
    3716             :       } else {
    3717             :         DCHECK_EQ(kAccessor, details.kind());
    3718           0 :         value = handle(object->RawFastPropertyAt(index), isolate);
    3719             :       }
    3720             : 
    3721             :     } else {
    3722             :       DCHECK_EQ(kDescriptor, details.location());
    3723             :       value = handle(descs->GetValue(i), isolate);
    3724             :     }
    3725             :     DCHECK(!value.is_null());
    3726             :     PropertyDetails d(details.kind(), details.attributes(), i + 1,
    3727     5800785 :                       PropertyCellType::kNoCell);
    3728     5800785 :     dictionary = NameDictionary::Add(dictionary, key, value, d);
    3729             :   }
    3730             : 
    3731             :   // Copy the next enumeration index from instance descriptor.
    3732     1318662 :   dictionary->SetNextEnumerationIndex(real_size + 1);
    3733             : 
    3734             :   // From here on we cannot fail and we shouldn't GC anymore.
    3735             :   DisallowHeapAllocation no_allocation;
    3736             : 
    3737     1318662 :   Heap* heap = isolate->heap();
    3738     1318662 :   heap->NotifyObjectLayoutChange(*object, no_allocation);
    3739             : 
    3740             :   // Resize the object in the heap if necessary.
    3741             :   int new_instance_size = new_map->instance_size();
    3742     1318662 :   int instance_size_delta = map->instance_size() - new_instance_size;
    3743             :   DCHECK(instance_size_delta >= 0);
    3744             : 
    3745     1318662 :   if (instance_size_delta > 0) {
    3746      452771 :     heap->CreateFillerObjectAt(object->address() + new_instance_size,
    3747      452771 :                                instance_size_delta, ClearRecordedSlots::kYes);
    3748      905542 :     heap->AdjustLiveBytes(*object, -instance_size_delta);
    3749             :   }
    3750             : 
    3751             :   // We are storing the new map using release store after creating a filler for
    3752             :   // the left-over space to avoid races with the sweeper thread.
    3753     1318662 :   object->synchronized_set_map(*new_map);
    3754             : 
    3755     1318662 :   object->set_properties(*dictionary);
    3756             : 
    3757             :   // Ensure that in-object space of slow-mode object does not contain random
    3758             :   // garbage.
    3759             :   int inobject_properties = new_map->GetInObjectProperties();
    3760     1318662 :   if (inobject_properties) {
    3761             :     Heap* heap = isolate->heap();
    3762             :     heap->ClearRecordedSlotRange(
    3763      588350 :         object->address() + map->GetInObjectPropertyOffset(0),
    3764     1176700 :         object->address() + new_instance_size);
    3765             : 
    3766     3469050 :     for (int i = 0; i < inobject_properties; i++) {
    3767     2880700 :       FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
    3768     2880700 :       object->RawFastPropertyAtPut(index, Smi::kZero);
    3769             :     }
    3770             :   }
    3771             : 
    3772     1318662 :   isolate->counters()->props_to_dictionary()->Increment();
    3773             : 
    3774             : #ifdef DEBUG
    3775             :   if (FLAG_trace_normalization) {
    3776             :     OFStream os(stdout);
    3777             :     os << "Object properties have been normalized:\n";
    3778             :     object->Print(os);
    3779             :   }
    3780             : #endif
    3781     1318662 : }
    3782             : 
    3783             : }  // namespace
    3784             : 
    3785             : // static
    3786    55443037 : void JSObject::NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
    3787             :                                Isolate* isolate) {
    3788   110886074 :   if (!old_map->is_prototype_map()) return;
    3789             : 
    3790             :   InvalidatePrototypeChains(*old_map);
    3791             : 
    3792             :   // If the map was registered with its prototype before, ensure that it
    3793             :   // registers with its new prototype now. This preserves the invariant that
    3794             :   // when a map on a prototype chain is registered with its prototype, then
    3795             :   // all prototypes further up the chain are also registered with their
    3796             :   // respective prototypes.
    3797     5501812 :   UpdatePrototypeUserRegistration(old_map, new_map, isolate);
    3798             : }
    3799             : 
    3800    69258317 : void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
    3801             :                             int expected_additional_properties) {
    3802   138516636 :   if (object->map() == *new_map) return;
    3803             :   Handle<Map> old_map(object->map());
    3804    54813056 :   NotifyMapChange(old_map, new_map, new_map->GetIsolate());
    3805             : 
    3806    54813057 :   if (old_map->is_dictionary_map()) {
    3807             :     // For slow-to-fast migrations JSObject::MigrateSlowToFast()
    3808             :     // must be used instead.
    3809      650992 :     CHECK(new_map->is_dictionary_map());
    3810             : 
    3811             :     // Slow-to-slow migration is trivial.
    3812      650992 :     object->set_map(*new_map);
    3813    54162065 :   } else if (!new_map->is_dictionary_map()) {
    3814    52843403 :     MigrateFastToFast(object, new_map);
    3815    52843400 :     if (old_map->is_prototype_map()) {
    3816             :       DCHECK(!old_map->is_stable());
    3817             :       DCHECK(new_map->is_stable());
    3818             :       // Clear out the old descriptor array to avoid problems to sharing
    3819             :       // the descriptor array without using an explicit.
    3820             :       old_map->InitializeDescriptors(
    3821             :           old_map->GetHeap()->empty_descriptor_array(),
    3822     4902951 :           LayoutDescriptor::FastPointerLayout());
    3823             :       // Ensure that no transition was inserted for prototype migrations.
    3824             :       DCHECK_EQ(
    3825             :           0, TransitionArray::NumberOfTransitions(old_map->raw_transitions()));
    3826             :       DCHECK(new_map->GetBackPointer()->IsUndefined(new_map->GetIsolate()));
    3827             :     }
    3828             :   } else {
    3829     1318662 :     MigrateFastToSlow(object, new_map, expected_additional_properties);
    3830             :   }
    3831             : 
    3832             :   // Careful: Don't allocate here!
    3833             :   // For some callers of this method, |object| might be in an inconsistent
    3834             :   // state now: the new map might have a new elements_kind, but the object's
    3835             :   // elements pointer hasn't been updated yet. Callers will fix this, but in
    3836             :   // the meantime, (indirectly) calling JSObjectVerify() must be avoided.
    3837             :   // When adding code here, add a DisallowHeapAllocation too.
    3838             : }
    3839             : 
    3840      237841 : void JSObject::ForceSetPrototype(Handle<JSObject> object,
    3841             :                                  Handle<Object> proto) {
    3842             :   // object.__proto__ = proto;
    3843             :   Handle<Map> old_map = Handle<Map>(object->map());
    3844      237841 :   Handle<Map> new_map = Map::Copy(old_map, "ForceSetPrototype");
    3845      237841 :   Map::SetPrototype(new_map, proto, FAST_PROTOTYPE);
    3846      237841 :   JSObject::MigrateToMap(object, new_map);
    3847      237841 : }
    3848             : 
    3849    56079468 : int Map::NumberOfFields() {
    3850             :   DescriptorArray* descriptors = instance_descriptors();
    3851             :   int result = 0;
    3852   920305806 :   for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
    3853   808146863 :     if (descriptors->GetDetails(i).location() == kField) result++;
    3854             :   }
    3855    56079475 :   return result;
    3856             : }
    3857             : 
    3858     9538819 : void DescriptorArray::GeneralizeAllFields() {
    3859     9538819 :   int length = number_of_descriptors();
    3860    57942138 :   for (int i = 0; i < length; i++) {
    3861    38864494 :     PropertyDetails details = GetDetails(i);
    3862             :     details = details.CopyWithRepresentation(Representation::Tagged());
    3863    38864497 :     if (details.location() == kField) {
    3864             :       DCHECK_EQ(kData, details.kind());
    3865             :       details = details.CopyWithConstness(kMutable);
    3866     5113417 :       SetValue(i, FieldType::Any());
    3867             :     }
    3868             :     set(ToDetailsIndex(i), details.AsSmi());
    3869             :   }
    3870     9538823 : }
    3871             : 
    3872     1947577 : Handle<Map> Map::CopyGeneralizeAllFields(Handle<Map> map,
    3873             :                                          ElementsKind elements_kind,
    3874             :                                          int modify_index, PropertyKind kind,
    3875             :                                          PropertyAttributes attributes,
    3876             :                                          const char* reason) {
    3877             :   Isolate* isolate = map->GetIsolate();
    3878             :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
    3879             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    3880             :   Handle<DescriptorArray> descriptors =
    3881             :       DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors);
    3882     1947581 :   descriptors->GeneralizeAllFields();
    3883             : 
    3884             :   Handle<LayoutDescriptor> new_layout_descriptor(
    3885             :       LayoutDescriptor::FastPointerLayout(), isolate);
    3886             :   Handle<Map> new_map = CopyReplaceDescriptors(
    3887             :       map, descriptors, new_layout_descriptor, OMIT_TRANSITION,
    3888     1947579 :       MaybeHandle<Name>(), reason, SPECIAL_TRANSITION);
    3889             : 
    3890             :   // Unless the instance is being migrated, ensure that modify_index is a field.
    3891     1947579 :   if (modify_index >= 0) {
    3892     1947475 :     PropertyDetails details = descriptors->GetDetails(modify_index);
    3893     1950723 :     if (details.constness() != kMutable || details.location() != kField ||
    3894             :         details.attributes() != attributes) {
    3895             :       int field_index = details.location() == kField
    3896             :                             ? details.field_index()
    3897     3892140 :                             : new_map->NumberOfFields();
    3898             :       Descriptor d = Descriptor::DataField(
    3899             :           handle(descriptors->GetKey(modify_index), isolate), field_index,
    3900     1946288 :           attributes, Representation::Tagged());
    3901     1946289 :       descriptors->Replace(modify_index, &d);
    3902     1946288 :       if (details.location() != kField) {
    3903     1945850 :         int unused_property_fields = new_map->unused_property_fields() - 1;
    3904     1945850 :         if (unused_property_fields < 0) {
    3905     1597991 :           unused_property_fields += JSObject::kFieldsAdded;
    3906             :         }
    3907             :         new_map->set_unused_property_fields(unused_property_fields);
    3908             :       }
    3909             :     } else {
    3910             :       DCHECK(details.attributes() == attributes);
    3911             :     }
    3912             : 
    3913     1947474 :     if (FLAG_trace_generalization) {
    3914           0 :       MaybeHandle<FieldType> field_type = FieldType::None(isolate);
    3915           0 :       if (details.location() == kField) {
    3916             :         field_type = handle(
    3917           0 :             map->instance_descriptors()->GetFieldType(modify_index), isolate);
    3918             :       }
    3919             :       map->PrintGeneralization(
    3920             :           stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(),
    3921             :           new_map->NumberOfOwnDescriptors(), details.location() == kDescriptor,
    3922             :           details.representation(), Representation::Tagged(), field_type,
    3923             :           MaybeHandle<Object>(), FieldType::Any(isolate),
    3924           0 :           MaybeHandle<Object>());
    3925             :     }
    3926             :   }
    3927             :   new_map->set_elements_kind(elements_kind);
    3928     1947578 :   return new_map;
    3929             : }
    3930             : 
    3931             : 
    3932      324090 : void Map::DeprecateTransitionTree() {
    3933      648180 :   if (is_deprecated()) return;
    3934             :   Object* transitions = raw_transitions();
    3935      324090 :   int num_transitions = TransitionArray::NumberOfTransitions(transitions);
    3936      482884 :   for (int i = 0; i < num_transitions; ++i) {
    3937      158794 :     TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree();
    3938             :   }
    3939             :   DCHECK(!constructor_or_backpointer()->IsFunctionTemplateInfo());
    3940             :   deprecate();
    3941             :   dependent_code()->DeoptimizeDependentCodeGroup(
    3942      324090 :       GetIsolate(), DependentCode::kTransitionGroup);
    3943      324090 :   NotifyLeafMapLayoutChange();
    3944             : }
    3945             : 
    3946             : 
    3947             : // Installs |new_descriptors| over the current instance_descriptors to ensure
    3948             : // proper sharing of descriptor arrays.
    3949      167507 : void Map::ReplaceDescriptors(DescriptorArray* new_descriptors,
    3950             :                              LayoutDescriptor* new_layout_descriptor) {
    3951             :   Isolate* isolate = GetIsolate();
    3952             :   // Don't overwrite the empty descriptor array or initial map's descriptors.
    3953      216919 :   if (NumberOfOwnDescriptors() == 0 || GetBackPointer()->IsUndefined(isolate)) {
    3954      167507 :     return;
    3955             :   }
    3956             : 
    3957             :   DescriptorArray* to_replace = instance_descriptors();
    3958       48988 :   isolate->heap()->incremental_marking()->IterateBlackObject(to_replace);
    3959             :   Map* current = this;
    3960      255030 :   while (current->instance_descriptors() == to_replace) {
    3961      157465 :     Object* next = current->GetBackPointer();
    3962      157465 :     if (next->IsUndefined(isolate)) break;  // Stop overwriting at initial map.
    3963             :     current->SetEnumLength(kInvalidEnumCacheSentinel);
    3964      157054 :     current->UpdateDescriptors(new_descriptors, new_layout_descriptor);
    3965             :     current = Map::cast(next);
    3966             :   }
    3967             :   set_owns_descriptors(false);
    3968             : }
    3969             : 
    3970             : 
    3971     2118690 : Map* Map::FindRootMap() {
    3972             :   Map* result = this;
    3973             :   Isolate* isolate = GetIsolate();
    3974             :   while (true) {
    3975     9994548 :     Object* back = result->GetBackPointer();
    3976     9994548 :     if (back->IsUndefined(isolate)) {
    3977             :       // Initial map always owns descriptors and doesn't have unused entries
    3978             :       // in the descriptor array.
    3979             :       DCHECK(result->owns_descriptors());
    3980             :       DCHECK_EQ(result->NumberOfOwnDescriptors(),
    3981             :                 result->instance_descriptors()->number_of_descriptors());
    3982     2118690 :       return result;
    3983             :     }
    3984             :     result = Map::cast(back);
    3985             :   }
    3986             : }
    3987             : 
    3988             : 
    3989      967624 : Map* Map::FindFieldOwner(int descriptor) {
    3990             :   DisallowHeapAllocation no_allocation;
    3991             :   DCHECK_EQ(kField, instance_descriptors()->GetDetails(descriptor).location());
    3992             :   Map* result = this;
    3993             :   Isolate* isolate = GetIsolate();
    3994             :   while (true) {
    3995     3425250 :     Object* back = result->GetBackPointer();
    3996     3425250 :     if (back->IsUndefined(isolate)) break;
    3997             :     Map* parent = Map::cast(back);
    3998     3425250 :     if (parent->NumberOfOwnDescriptors() <= descriptor) break;
    3999             :     result = parent;
    4000             :   }
    4001      967624 :   return result;
    4002             : }
    4003             : 
    4004      551166 : void Map::UpdateFieldType(int descriptor, Handle<Name> name,
    4005             :                           PropertyConstness new_constness,
    4006             :                           Representation new_representation,
    4007             :                           Handle<Object> new_wrapped_type) {
    4008             :   DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell());
    4009             :   // We store raw pointers in the queue, so no allocations are allowed.
    4010             :   DisallowHeapAllocation no_allocation;
    4011      551166 :   PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
    4012      551166 :   if (details.location() != kField) return;
    4013             :   DCHECK_EQ(kData, details.kind());
    4014             : 
    4015      551166 :   Zone zone(GetIsolate()->allocator(), ZONE_NAME);
    4016      551166 :   ZoneQueue<Map*> backlog(&zone);
    4017     1102332 :   backlog.push(this);
    4018             : 
    4019     4104071 :   while (!backlog.empty()) {
    4020     3001739 :     Map* current = backlog.front();
    4021             :     backlog.pop();
    4022             : 
    4023             :     Object* transitions = current->raw_transitions();
    4024     3001739 :     int num_transitions = TransitionArray::NumberOfTransitions(transitions);
    4025     5452312 :     for (int i = 0; i < num_transitions; ++i) {
    4026     2450573 :       Map* target = TransitionArray::GetTarget(transitions, i);
    4027             :       backlog.push(target);
    4028             :     }
    4029             :     DescriptorArray* descriptors = current->instance_descriptors();
    4030     3001739 :     PropertyDetails details = descriptors->GetDetails(descriptor);
    4031             : 
    4032             :     // Currently constness change implies map change.
    4033             :     DCHECK_IMPLIES(new_constness != details.constness(),
    4034             :                    FLAG_modify_map_inplace);
    4035             : 
    4036             :     // It is allowed to change representation here only from None to something.
    4037             :     DCHECK(details.representation().Equals(new_representation) ||
    4038             :            details.representation().IsNone());
    4039             : 
    4040             :     // Skip if already updated the shared descriptor.
    4041     3001739 :     if ((FLAG_modify_map_inplace && new_constness != details.constness()) ||
    4042             :         descriptors->GetValue(descriptor) != *new_wrapped_type) {
    4043             :       DCHECK_IMPLIES(!FLAG_track_constant_fields, new_constness == kMutable);
    4044             :       Descriptor d = Descriptor::DataField(
    4045             :           name, descriptors->GetFieldIndex(descriptor), details.attributes(),
    4046      551218 :           new_constness, new_representation, new_wrapped_type);
    4047      551218 :       descriptors->Replace(descriptor, &d);
    4048             :     }
    4049      551166 :   }
    4050             : }
    4051             : 
    4052           0 : bool FieldTypeIsCleared(Representation rep, FieldType* type) {
    4053     4666473 :   return type->IsNone() && rep.IsHeapObject();
    4054             : }
    4055             : 
    4056             : 
    4057             : // static
    4058     2082491 : Handle<FieldType> Map::GeneralizeFieldType(Representation rep1,
    4059             :                                            Handle<FieldType> type1,
    4060             :                                            Representation rep2,
    4061             :                                            Handle<FieldType> type2,
    4062             :                                            Isolate* isolate) {
    4063             :   // Cleared field types need special treatment. They represent lost knowledge,
    4064             :   // so we must be conservative, so their generalization with any other type
    4065             :   // is "Any".
    4066     4164920 :   if (FieldTypeIsCleared(rep1, *type1) || FieldTypeIsCleared(rep2, *type2)) {
    4067        9601 :     return FieldType::Any(isolate);
    4068             :   }
    4069     2072890 :   if (type1->NowIs(type2)) return type2;
    4070      177137 :   if (type2->NowIs(type1)) return type1;
    4071       99162 :   return FieldType::Any(isolate);
    4072             : }
    4073             : 
    4074             : 
    4075             : // static
    4076      886657 : void Map::GeneralizeField(Handle<Map> map, int modify_index,
    4077             :                           PropertyConstness new_constness,
    4078             :                           Representation new_representation,
    4079             :                           Handle<FieldType> new_field_type) {
    4080             :   Isolate* isolate = map->GetIsolate();
    4081             : 
    4082             :   // Check if we actually need to generalize the field type at all.
    4083             :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
    4084      886657 :   PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
    4085             :   PropertyConstness old_constness = old_details.constness();
    4086             :   Representation old_representation = old_details.representation();
    4087             :   Handle<FieldType> old_field_type(old_descriptors->GetFieldType(modify_index),
    4088      886657 :                                    isolate);
    4089             : 
    4090             :   // Return if the current map is general enough to hold requested contness and
    4091             :   // representation/field type.
    4092      886657 :   if (((FLAG_modify_map_inplace &&
    4093             :         IsGeneralizableTo(new_constness, old_constness)) ||
    4094      886657 :        (!FLAG_modify_map_inplace && (old_constness == new_constness))) &&
    4095      485319 :       old_representation.Equals(new_representation) &&
    4096     1371933 :       !FieldTypeIsCleared(new_representation, *new_field_type) &&
    4097             :       // Checking old_field_type for being cleared is not necessary because
    4098             :       // the NowIs check below would fail anyway in that case.
    4099      485276 :       new_field_type->NowIs(old_field_type)) {
    4100             :     DCHECK(GeneralizeFieldType(old_representation, old_field_type,
    4101             :                                new_representation, new_field_type, isolate)
    4102             :                ->NowIs(old_field_type));
    4103      335491 :     return;
    4104             :   }
    4105             : 
    4106             :   // Determine the field owner.
    4107      551166 :   Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
    4108             :   Handle<DescriptorArray> descriptors(
    4109             :       field_owner->instance_descriptors(), isolate);
    4110             :   DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index));
    4111             : 
    4112             :   new_field_type =
    4113             :       Map::GeneralizeFieldType(old_representation, old_field_type,
    4114      551166 :                                new_representation, new_field_type, isolate);
    4115             :   if (FLAG_modify_map_inplace) {
    4116             :     new_constness = GeneralizeConstness(old_constness, new_constness);
    4117             :   }
    4118             : 
    4119      551166 :   PropertyDetails details = descriptors->GetDetails(modify_index);
    4120             :   Handle<Name> name(descriptors->GetKey(modify_index));
    4121             : 
    4122      551166 :   Handle<Object> wrapped_type(WrapFieldType(new_field_type));
    4123             :   field_owner->UpdateFieldType(modify_index, name, new_constness,
    4124      551166 :                                new_representation, wrapped_type);
    4125             :   field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
    4126      551166 :       isolate, DependentCode::kFieldOwnerGroup);
    4127             : 
    4128      551166 :   if (FLAG_trace_generalization) {
    4129             :     map->PrintGeneralization(
    4130             :         stdout, "field type generalization", modify_index,
    4131             :         map->NumberOfOwnDescriptors(), map->NumberOfOwnDescriptors(), false,
    4132             :         details.representation(), details.representation(), old_field_type,
    4133           0 :         MaybeHandle<Object>(), new_field_type, MaybeHandle<Object>());
    4134             :   }
    4135             : }
    4136             : 
    4137             : // TODO(ishell): remove.
    4138             : // static
    4139         596 : Handle<Map> Map::ReconfigureProperty(Handle<Map> map, int modify_index,
    4140             :                                      PropertyKind new_kind,
    4141             :                                      PropertyAttributes new_attributes,
    4142             :                                      Representation new_representation,
    4143             :                                      Handle<FieldType> new_field_type) {
    4144             :   DCHECK_EQ(kData, new_kind);  // Only kData case is supported.
    4145         596 :   MapUpdater mu(map->GetIsolate(), map);
    4146             :   return mu.ReconfigureToDataField(modify_index, new_attributes, kConst,
    4147         596 :                                    new_representation, new_field_type);
    4148             : }
    4149             : 
    4150             : // TODO(ishell): remove.
    4151             : // static
    4152      652950 : Handle<Map> Map::ReconfigureElementsKind(Handle<Map> map,
    4153             :                                          ElementsKind new_elements_kind) {
    4154      652950 :   MapUpdater mu(map->GetIsolate(), map);
    4155      652950 :   return mu.ReconfigureElementsKind(new_elements_kind);
    4156             : }
    4157             : 
    4158             : // Generalize all fields and update the transition tree.
    4159        1700 : Handle<Map> Map::GeneralizeAllFields(Handle<Map> map) {
    4160             :   Isolate* isolate = map->GetIsolate();
    4161        1700 :   Handle<FieldType> any_type = FieldType::Any(isolate);
    4162             : 
    4163             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    4164        7226 :   for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) {
    4165        1913 :     PropertyDetails details = descriptors->GetDetails(i);
    4166        1913 :     if (details.location() == kField) {
    4167             :       DCHECK_EQ(kData, details.kind());
    4168        1013 :       MapUpdater mu(isolate, map);
    4169             :       map = mu.ReconfigureToDataField(i, details.attributes(), kMutable,
    4170        1013 :                                       Representation::Tagged(), any_type);
    4171             :     }
    4172             :   }
    4173        1700 :   return map;
    4174             : }
    4175             : 
    4176             : 
    4177             : // static
    4178      359200 : MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) {
    4179             :   DisallowHeapAllocation no_allocation;
    4180             :   DisallowDeoptimization no_deoptimization(old_map->GetIsolate());
    4181             : 
    4182      359200 :   if (!old_map->is_deprecated()) return old_map;
    4183             : 
    4184             :   // Check the state of the root map.
    4185        2635 :   Map* root_map = old_map->FindRootMap();
    4186        2635 :   if (root_map->is_deprecated()) {
    4187           0 :     JSFunction* constructor = JSFunction::cast(root_map->GetConstructor());
    4188             :     DCHECK(constructor->has_initial_map());
    4189             :     DCHECK(constructor->initial_map()->is_dictionary_map());
    4190           0 :     if (constructor->initial_map()->elements_kind() !=
    4191             :         old_map->elements_kind()) {
    4192             :       return MaybeHandle<Map>();
    4193             :     }
    4194             :     return handle(constructor->initial_map());
    4195             :   }
    4196        2635 :   if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>();
    4197             : 
    4198             :   ElementsKind from_kind = root_map->elements_kind();
    4199             :   ElementsKind to_kind = old_map->elements_kind();
    4200        2551 :   if (from_kind != to_kind) {
    4201             :     // Try to follow existing elements kind transitions.
    4202             :     root_map = root_map->LookupElementsTransitionMap(to_kind);
    4203          18 :     if (root_map == NULL) return MaybeHandle<Map>();
    4204             :     // From here on, use the map with correct elements kind as root map.
    4205             :   }
    4206        2551 :   Map* new_map = root_map->TryReplayPropertyTransitions(*old_map);
    4207        2551 :   if (new_map == nullptr) return MaybeHandle<Map>();
    4208             :   return handle(new_map);
    4209             : }
    4210             : 
    4211      154198 : Map* Map::TryReplayPropertyTransitions(Map* old_map) {
    4212             :   DisallowHeapAllocation no_allocation;
    4213             :   DisallowDeoptimization no_deoptimization(GetIsolate());
    4214             : 
    4215             :   int root_nof = NumberOfOwnDescriptors();
    4216             : 
    4217             :   int old_nof = old_map->NumberOfOwnDescriptors();
    4218             :   DescriptorArray* old_descriptors = old_map->instance_descriptors();
    4219             : 
    4220             :   Map* new_map = this;
    4221      163534 :   for (int i = root_nof; i < old_nof; ++i) {
    4222       13900 :     PropertyDetails old_details = old_descriptors->GetDetails(i);
    4223             :     Map* transition = TransitionArray::SearchTransition(
    4224             :         new_map, old_details.kind(), old_descriptors->GetKey(i),
    4225       13900 :         old_details.attributes());
    4226       13900 :     if (transition == NULL) return nullptr;
    4227             :     new_map = transition;
    4228             :     DescriptorArray* new_descriptors = new_map->instance_descriptors();
    4229             : 
    4230        9416 :     PropertyDetails new_details = new_descriptors->GetDetails(i);
    4231             :     DCHECK_EQ(old_details.kind(), new_details.kind());
    4232             :     DCHECK_EQ(old_details.attributes(), new_details.attributes());
    4233        9416 :     if (!IsGeneralizableTo(old_details.constness(), new_details.constness())) {
    4234             :       return nullptr;
    4235             :     }
    4236             :     DCHECK(IsGeneralizableTo(old_details.location(), new_details.location()));
    4237       28248 :     if (!old_details.representation().fits_into(new_details.representation())) {
    4238             :       return nullptr;
    4239             :     }
    4240        9364 :     if (new_details.location() == kField) {
    4241        9185 :       if (new_details.kind() == kData) {
    4242        9185 :         FieldType* new_type = new_descriptors->GetFieldType(i);
    4243             :         // Cleared field types need special treatment. They represent lost
    4244             :         // knowledge, so we must first generalize the new_type to "Any".
    4245        9185 :         if (FieldTypeIsCleared(new_details.representation(), new_type)) {
    4246             :           return nullptr;
    4247             :         }
    4248             :         DCHECK_EQ(kData, old_details.kind());
    4249        9185 :         if (old_details.location() == kField) {
    4250        7049 :           FieldType* old_type = old_descriptors->GetFieldType(i);
    4251       14098 :           if (FieldTypeIsCleared(old_details.representation(), old_type) ||
    4252        7049 :               !old_type->NowIs(new_type)) {
    4253             :             return nullptr;
    4254             :           }
    4255             :         } else {
    4256             :           DCHECK_EQ(kDescriptor, old_details.location());
    4257             :           DCHECK(!FLAG_track_constant_fields);
    4258             :           Object* old_value = old_descriptors->GetValue(i);
    4259        2136 :           if (!new_type->NowContains(old_value)) {
    4260             :             return nullptr;
    4261             :           }
    4262             :         }
    4263             : 
    4264             :       } else {
    4265             :         DCHECK_EQ(kAccessor, new_details.kind());
    4266             : #ifdef DEBUG
    4267             :         FieldType* new_type = new_descriptors->GetFieldType(i);
    4268             :         DCHECK(new_type->IsAny());
    4269             : #endif
    4270           0 :         UNREACHABLE();
    4271             :       }
    4272             :     } else {
    4273             :       DCHECK_EQ(kDescriptor, new_details.location());
    4274             :       Object* old_value = old_descriptors->GetValue(i);
    4275             :       Object* new_value = new_descriptors->GetValue(i);
    4276         179 :       if (old_details.location() == kField || old_value != new_value) {
    4277             :         return nullptr;
    4278             :       }
    4279             :     }
    4280             :   }
    4281      149634 :   if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr;
    4282      149634 :   return new_map;
    4283             : }
    4284             : 
    4285             : 
    4286             : // static
    4287    41308178 : Handle<Map> Map::Update(Handle<Map> map) {
    4288    41308178 :   if (!map->is_deprecated()) return map;
    4289       10342 :   MapUpdater mu(map->GetIsolate(), map);
    4290       10342 :   return mu.Update();
    4291             : }
    4292             : 
    4293      225641 : Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
    4294             :                                                  ShouldThrow should_throw,
    4295             :                                                  Handle<Object> value) {
    4296             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    4297             :   return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(),
    4298      225641 :                                             should_throw, value);
    4299             : }
    4300             : 
    4301     4262159 : MaybeHandle<Object> Object::SetProperty(Handle<Object> object,
    4302             :                                         Handle<Name> name, Handle<Object> value,
    4303             :                                         LanguageMode language_mode,
    4304             :                                         StoreFromKeyed store_mode) {
    4305     4262159 :   LookupIterator it(object, name);
    4306     4262159 :   MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode));
    4307             :   return value;
    4308             : }
    4309             : 
    4310             : 
    4311    34000822 : Maybe<bool> Object::SetPropertyInternal(LookupIterator* it,
    4312             :                                         Handle<Object> value,
    4313             :                                         LanguageMode language_mode,
    4314             :                                         StoreFromKeyed store_mode,
    4315             :                                         bool* found) {
    4316    16764916 :   it->UpdateProtector();
    4317             :   DCHECK(it->IsFound());
    4318             :   ShouldThrow should_throw =
    4319    16764916 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    4320             : 
    4321             :   // Make sure that the top context does not change when doing callbacks or
    4322             :   // interceptor calls.
    4323             :   AssertNoContextChange ncc(it->isolate());
    4324             : 
    4325      312981 :   do {
    4326    16922925 :     switch (it->state()) {
    4327             :       case LookupIterator::NOT_FOUND:
    4328           0 :         UNREACHABLE();
    4329             : 
    4330             :       case LookupIterator::ACCESS_CHECK:
    4331       87928 :         if (it->HasAccess()) break;
    4332             :         // Check whether it makes sense to reuse the lookup iterator. Here it
    4333             :         // might still call into setters up the prototype chain.
    4334             :         return JSObject::SetPropertyWithFailedAccessCheck(it, value,
    4335         131 :                                                           should_throw);
    4336             : 
    4337             :       case LookupIterator::JSPROXY:
    4338             :         return JSProxy::SetProperty(it->GetHolder<JSProxy>(), it->GetName(),
    4339       63039 :                                     value, it->GetReceiver(), language_mode);
    4340             : 
    4341             :       case LookupIterator::INTERCEPTOR: {
    4342      225664 :         if (it->HolderIsReceiverOrHiddenPrototype()) {
    4343             :           Maybe<bool> result =
    4344      225382 :               JSObject::SetPropertyWithInterceptor(it, should_throw, value);
    4345      450764 :           if (result.IsNothing() || result.FromJust()) return result;
    4346             :         } else {
    4347             :           Maybe<PropertyAttributes> maybe_attributes =
    4348         282 :               JSObject::GetPropertyAttributesWithInterceptor(it);
    4349         449 :           if (!maybe_attributes.IsJust()) return Nothing<bool>();
    4350         282 :           if ((maybe_attributes.FromJust() & READ_ONLY) != 0) {
    4351           0 :             return WriteToReadOnlyProperty(it, value, should_throw);
    4352             :           }
    4353         282 :           if (maybe_attributes.FromJust() == ABSENT) break;
    4354         167 :           *found = false;
    4355             :           return Nothing<bool>();
    4356             :         }
    4357             :         break;
    4358             :       }
    4359             : 
    4360             :       case LookupIterator::ACCESSOR: {
    4361      411341 :         if (it->IsReadOnly()) {
    4362        2651 :           return WriteToReadOnlyProperty(it, value, should_throw);
    4363             :         }
    4364      408690 :         Handle<Object> accessors = it->GetAccessors();
    4365      619410 :         if (accessors->IsAccessorInfo() &&
    4366      549681 :             !it->HolderIsReceiverOrHiddenPrototype() &&
    4367             :             AccessorInfo::cast(*accessors)->is_special_data_property()) {
    4368         713 :           *found = false;
    4369             :           return Nothing<bool>();
    4370             :         }
    4371      407977 :         return SetPropertyWithAccessor(it, value, should_throw);
    4372             :       }
    4373             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    4374             :         // TODO(verwaest): We should throw an exception if holder is receiver.
    4375             :         return Just(true);
    4376             : 
    4377             :       case LookupIterator::DATA:
    4378    14689502 :         if (it->IsReadOnly()) {
    4379       44336 :           return WriteToReadOnlyProperty(it, value, should_throw);
    4380             :         }
    4381    14645166 :         if (it->HolderIsReceiverOrHiddenPrototype()) {
    4382    14499107 :           return SetDataProperty(it, value);
    4383             :         }
    4384             :       // Fall through.
    4385             :       case LookupIterator::TRANSITION:
    4386     1588699 :         *found = false;
    4387             :         return Nothing<bool>();
    4388             :     }
    4389      312981 :     it->Next();
    4390             :   } while (it->IsFound());
    4391             : 
    4392      154972 :   *found = false;
    4393             :   return Nothing<bool>();
    4394             : }
    4395             : 
    4396             : 
    4397    35797626 : Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
    4398             :                                 LanguageMode language_mode,
    4399             :                                 StoreFromKeyed store_mode) {
    4400    35795776 :   if (it->IsFound()) {
    4401    16697310 :     bool found = true;
    4402             :     Maybe<bool> result =
    4403    16697310 :         SetPropertyInternal(it, value, language_mode, store_mode, &found);
    4404    16697310 :     if (found) return result;
    4405             :   }
    4406             : 
    4407             :   // If the receiver is the JSGlobalObject, the store was contextual. In case
    4408             :   // the property did not exist yet on the global object itself, we have to
    4409             :   // throw a reference error in strict mode.  In sloppy mode, we continue.
    4410    35888256 :   if (is_strict(language_mode) && it->GetReceiver()->IsJSGlobalObject()) {
    4411             :     it->isolate()->Throw(*it->isolate()->factory()->NewReferenceError(
    4412        1850 :         MessageTemplate::kNotDefined, it->name()));
    4413             :     return Nothing<bool>();
    4414             :   }
    4415             : 
    4416             :   ShouldThrow should_throw =
    4417    20838756 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    4418    20838756 :   return AddDataProperty(it, value, NONE, should_throw, store_mode);
    4419             : }
    4420             : 
    4421             : 
    4422       81956 : Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
    4423             :                                      LanguageMode language_mode,
    4424             :                                      StoreFromKeyed store_mode) {
    4425             :   Isolate* isolate = it->isolate();
    4426             : 
    4427       73680 :   if (it->IsFound()) {
    4428       67606 :     bool found = true;
    4429             :     Maybe<bool> result =
    4430       67606 :         SetPropertyInternal(it, value, language_mode, store_mode, &found);
    4431       67606 :     if (found) return result;
    4432             :   }
    4433             : 
    4434        9410 :   it->UpdateProtector();
    4435             : 
    4436             :   // The property either doesn't exist on the holder or exists there as a data
    4437             :   // property.
    4438             : 
    4439             :   ShouldThrow should_throw =
    4440        9410 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    4441             : 
    4442        9410 :   if (!it->GetReceiver()->IsJSReceiver()) {
    4443        1134 :     return WriteToReadOnlyProperty(it, value, should_throw);
    4444             :   }
    4445             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    4446             : 
    4447             :   LookupIterator::Configuration c = LookupIterator::OWN;
    4448             :   LookupIterator own_lookup =
    4449             :       it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
    4450       16552 :                       : LookupIterator(receiver, it->name(), c);
    4451             : 
    4452          28 :   for (; own_lookup.IsFound(); own_lookup.Next()) {
    4453        6162 :     switch (own_lookup.state()) {
    4454             :       case LookupIterator::ACCESS_CHECK:
    4455          34 :         if (!own_lookup.HasAccess()) {
    4456             :           return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value,
    4457           6 :                                                             should_throw);
    4458             :         }
    4459             :         break;
    4460             : 
    4461             :       case LookupIterator::ACCESSOR:
    4462        3052 :         if (own_lookup.GetAccessors()->IsAccessorInfo()) {
    4463          14 :           if (own_lookup.IsReadOnly()) {
    4464           0 :             return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
    4465             :           }
    4466             :           return JSObject::SetPropertyWithAccessor(&own_lookup, value,
    4467          14 :                                                    should_throw);
    4468             :         }
    4469             :       // Fall through.
    4470             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    4471             :         return RedefineIncompatibleProperty(isolate, it->GetName(), value,
    4472        3024 :                                             should_throw);
    4473             : 
    4474             :       case LookupIterator::DATA: {
    4475        1526 :         if (own_lookup.IsReadOnly()) {
    4476         462 :           return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
    4477             :         }
    4478        1064 :         return SetDataProperty(&own_lookup, value);
    4479             :       }
    4480             : 
    4481             :       case LookupIterator::INTERCEPTOR:
    4482             :       case LookupIterator::JSPROXY: {
    4483             :         PropertyDescriptor desc;
    4484             :         Maybe<bool> owned =
    4485        3076 :             JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc);
    4486        3076 :         MAYBE_RETURN(owned, Nothing<bool>());
    4487        2376 :         if (!owned.FromJust()) {
    4488             :           return JSReceiver::CreateDataProperty(&own_lookup, value,
    4489        1057 :                                                 should_throw);
    4490             :         }
    4491        2638 :         if (PropertyDescriptor::IsAccessorDescriptor(&desc) ||
    4492             :             !desc.writable()) {
    4493             :           return RedefineIncompatibleProperty(isolate, it->GetName(), value,
    4494           0 :                                               should_throw);
    4495             :         }
    4496             : 
    4497             :         PropertyDescriptor value_desc;
    4498             :         value_desc.set_value(value);
    4499             :         return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
    4500        2638 :                                              &value_desc, should_throw);
    4501             :       }
    4502             : 
    4503             :       case LookupIterator::NOT_FOUND:
    4504             :       case LookupIterator::TRANSITION:
    4505           0 :         UNREACHABLE();
    4506             :     }
    4507             :   }
    4508             : 
    4509        2142 :   return AddDataProperty(&own_lookup, value, NONE, should_throw, store_mode);
    4510             : }
    4511             : 
    4512        9541 : Maybe<bool> Object::CannotCreateProperty(Isolate* isolate,
    4513             :                                          Handle<Object> receiver,
    4514             :                                          Handle<Object> name,
    4515             :                                          Handle<Object> value,
    4516             :                                          ShouldThrow should_throw) {
    4517        9917 :   RETURN_FAILURE(
    4518             :       isolate, should_throw,
    4519             :       NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name,
    4520             :                    Object::TypeOf(isolate, receiver), receiver));
    4521             : }
    4522             : 
    4523             : 
    4524       97166 : Maybe<bool> Object::WriteToReadOnlyProperty(LookupIterator* it,
    4525             :                                             Handle<Object> value,
    4526             :                                             ShouldThrow should_throw) {
    4527             :   return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
    4528       97166 :                                  it->GetName(), value, should_throw);
    4529             : }
    4530             : 
    4531             : 
    4532       48583 : Maybe<bool> Object::WriteToReadOnlyProperty(Isolate* isolate,
    4533             :                                             Handle<Object> receiver,
    4534             :                                             Handle<Object> name,
    4535             :                                             Handle<Object> value,
    4536             :                                             ShouldThrow should_throw) {
    4537       79245 :   RETURN_FAILURE(isolate, should_throw,
    4538             :                  NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
    4539             :                               Object::TypeOf(isolate, receiver), receiver));
    4540             : }
    4541             : 
    4542             : 
    4543        1527 : Maybe<bool> Object::RedefineIncompatibleProperty(Isolate* isolate,
    4544             :                                                  Handle<Object> name,
    4545             :                                                  Handle<Object> value,
    4546             :                                                  ShouldThrow should_throw) {
    4547        1893 :   RETURN_FAILURE(isolate, should_throw,
    4548             :                  NewTypeError(MessageTemplate::kRedefineDisallowed, name));
    4549             : }
    4550             : 
    4551             : 
    4552    31008692 : Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) {
    4553             :   // Proxies are handled elsewhere. Other non-JSObjects cannot have own
    4554             :   // properties.
    4555             :   Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
    4556             : 
    4557             :   // Store on the holder which may be hidden behind the receiver.
    4558             :   DCHECK(it->HolderIsReceiverOrHiddenPrototype());
    4559             : 
    4560    15500616 :   Handle<Object> to_assign = value;
    4561             :   // Convert the incoming value to a number for storing into typed arrays.
    4562    16844465 :   if (it->IsElement() && receiver->HasFixedTypedArrayElements()) {
    4563     1170047 :     if (!value->IsNumber() && !value->IsUndefined(it->isolate())) {
    4564        5292 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    4565             :           it->isolate(), to_assign, Object::ToNumber(value), Nothing<bool>());
    4566             :       // We have to recheck the length. However, it can only change if the
    4567             :       // underlying buffer was neutered, so just check that.
    4568        2646 :       if (Handle<JSArrayBufferView>::cast(receiver)->WasNeutered()) {
    4569             :         return Just(true);
    4570             :         // TODO(neis): According to the spec, this should throw a TypeError.
    4571             :       }
    4572             :     }
    4573             :   }
    4574             : 
    4575             :   // Possibly migrate to the most up-to-date map that will be able to store
    4576             :   // |value| under it->name().
    4577    15500616 :   it->PrepareForDataProperty(to_assign);
    4578             : 
    4579             :   // Write the property value.
    4580    15500616 :   it->WriteDataValue(to_assign, false);
    4581             : 
    4582             : #if VERIFY_HEAP
    4583             :   if (FLAG_verify_heap) {
    4584             :     receiver->JSObjectVerify();
    4585             :   }
    4586             : #endif
    4587             :   return Just(true);
    4588             : }
    4589             : 
    4590             : 
    4591   173082748 : Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
    4592             :                                     PropertyAttributes attributes,
    4593             :                                     ShouldThrow should_throw,
    4594             :                                     StoreFromKeyed store_mode) {
    4595    56016474 :   if (!it->GetReceiver()->IsJSObject()) {
    4596        9625 :     if (it->GetReceiver()->IsJSProxy() && it->GetName()->IsPrivate()) {
    4597          70 :       RETURN_FAILURE(it->isolate(), should_throw,
    4598             :                      NewTypeError(MessageTemplate::kProxyPrivate));
    4599             :     }
    4600             :     return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
    4601       19082 :                                 value, should_throw);
    4602             :   }
    4603             : 
    4604             :   DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
    4605             : 
    4606    56006891 :   Handle<JSObject> receiver = it->GetStoreTarget();
    4607             : 
    4608             :   // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
    4609             :   // instead. If the prototype is Null, the proxy is detached.
    4610    56006844 :   if (receiver->IsJSGlobalProxy()) return Just(true);
    4611             : 
    4612             :   Isolate* isolate = it->isolate();
    4613             : 
    4614    56006844 :   if (it->ExtendingNonExtensible(receiver)) {
    4615      607516 :     RETURN_FAILURE(
    4616             :         isolate, should_throw,
    4617             :         NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName()));
    4618             :   }
    4619             : 
    4620    55851604 :   if (it->IsElement()) {
    4621     3679372 :     if (receiver->IsJSArray()) {
    4622             :       Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    4623     1519342 :       if (JSArray::WouldChangeReadOnlyLength(array, it->index())) {
    4624        1719 :         RETURN_FAILURE(array->GetIsolate(), should_throw,
    4625             :                        NewTypeError(MessageTemplate::kStrictReadOnlyProperty,
    4626             :                                     isolate->factory()->length_string(),
    4627             :                                     Object::TypeOf(isolate, array), array));
    4628             :       }
    4629             : 
    4630     1518880 :       if (FLAG_trace_external_array_abuse &&
    4631           0 :           array->HasFixedTypedArrayElements()) {
    4632           0 :         CheckArrayAbuse(array, "typed elements write", it->index(), true);
    4633             :       }
    4634             : 
    4635     1518880 :       if (FLAG_trace_js_array_abuse && !array->HasFixedTypedArrayElements()) {
    4636           0 :         CheckArrayAbuse(array, "elements write", it->index(), false);
    4637             :       }
    4638             :     }
    4639             : 
    4640             :     Maybe<bool> result = JSObject::AddDataElement(receiver, it->index(), value,
    4641     3678910 :                                                   attributes, should_throw);
    4642             :     JSObject::ValidateElements(receiver);
    4643     3678910 :     return result;
    4644             :   } else {
    4645    52172232 :     it->UpdateProtector();
    4646             :     // Migrate to the most up-to-date map that will be able to store |value|
    4647             :     // under it->name() with |attributes|.
    4648             :     it->PrepareTransitionToDataProperty(receiver, value, attributes,
    4649    52172236 :                                         store_mode);
    4650             :     DCHECK_EQ(LookupIterator::TRANSITION, it->state());
    4651    52172277 :     it->ApplyTransitionToDataProperty(receiver);
    4652             : 
    4653             :     // Write the property value.
    4654    52172261 :     it->WriteDataValue(value, true);
    4655             : 
    4656             : #if VERIFY_HEAP
    4657             :     if (FLAG_verify_heap) {
    4658             :       receiver->JSObjectVerify();
    4659             :     }
    4660             : #endif
    4661             :   }
    4662             : 
    4663             :   return Just(true);
    4664             : }
    4665             : 
    4666             : 
    4667     5831580 : void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
    4668             :   // Only supports adding slack to owned descriptors.
    4669             :   DCHECK(map->owns_descriptors());
    4670             : 
    4671             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    4672             :   int old_size = map->NumberOfOwnDescriptors();
    4673     5831580 :   if (slack <= descriptors->NumberOfSlackDescriptors()) return;
    4674             : 
    4675             :   Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
    4676             :       descriptors, old_size, slack);
    4677             : 
    4678             :   DisallowHeapAllocation no_allocation;
    4679             :   // The descriptors are still the same, so keep the layout descriptor.
    4680             :   LayoutDescriptor* layout_descriptor = map->GetLayoutDescriptor();
    4681             : 
    4682     5831581 :   if (old_size == 0) {
    4683        2669 :     map->UpdateDescriptors(*new_descriptors, layout_descriptor);
    4684        2669 :     return;
    4685             :   }
    4686             : 
    4687             :   // If the source descriptors had an enum cache we copy it. This ensures
    4688             :   // that the maps to which we push the new descriptor array back can rely
    4689             :   // on a cache always being available once it is set. If the map has more
    4690             :   // enumerated descriptors than available in the original cache, the cache
    4691             :   // will be lazily replaced by the extended cache when needed.
    4692     5828912 :   if (descriptors->HasEnumCache()) {
    4693       36845 :     new_descriptors->CopyEnumCacheFrom(*descriptors);
    4694             :   }
    4695             : 
    4696             :   Isolate* isolate = map->GetIsolate();
    4697             :   // Replace descriptors by new_descriptors in all maps that share it.
    4698     5828911 :   isolate->heap()->incremental_marking()->IterateBlackObject(*descriptors);
    4699             : 
    4700             :   Map* current = *map;
    4701    49684512 :   while (current->instance_descriptors() == *descriptors) {
    4702    38027269 :     Object* next = current->GetBackPointer();
    4703    38027274 :     if (next->IsUndefined(isolate)) break;  // Stop overwriting at initial map.
    4704    38026698 :     current->UpdateDescriptors(*new_descriptors, layout_descriptor);
    4705             :     current = Map::cast(next);
    4706             :   }
    4707     5828908 :   map->UpdateDescriptors(*new_descriptors, layout_descriptor);
    4708             : }
    4709             : 
    4710             : // static
    4711      189312 : Handle<Map> Map::GetObjectCreateMap(Handle<HeapObject> prototype) {
    4712             :   Isolate* isolate = prototype->GetIsolate();
    4713             :   Handle<Map> map(isolate->native_context()->object_function()->initial_map(),
    4714      378624 :                   isolate);
    4715      189312 :   if (map->prototype() == *prototype) return map;
    4716      189283 :   if (prototype->IsNull(isolate)) {
    4717         559 :     return isolate->slow_object_with_null_prototype_map();
    4718             :   }
    4719      188724 :   if (prototype->IsJSObject()) {
    4720             :     Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype);
    4721      187616 :     if (!js_prototype->map()->is_prototype_map()) {
    4722      183690 :       JSObject::OptimizeAsPrototype(js_prototype, FAST_PROTOTYPE);
    4723             :     }
    4724             :     Handle<PrototypeInfo> info =
    4725      187616 :         Map::GetOrCreatePrototypeInfo(js_prototype, isolate);
    4726             :     // TODO(verwaest): Use inobject slack tracking for this map.
    4727      187616 :     if (info->HasObjectCreateMap()) {
    4728             :       map = handle(info->ObjectCreateMap(), isolate);
    4729             :     } else {
    4730      187555 :       map = Map::CopyInitialMap(map);
    4731      187555 :       Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
    4732      187555 :       PrototypeInfo::SetObjectCreateMap(info, map);
    4733             :     }
    4734      187616 :     return map;
    4735             :   }
    4736             : 
    4737        1108 :   return Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE);
    4738             : }
    4739             : 
    4740             : template <class T>
    4741       63307 : static int AppendUniqueCallbacks(Handle<TemplateList> callbacks,
    4742             :                                  Handle<typename T::Array> array,
    4743             :                                  int valid_descriptors) {
    4744             :   int nof_callbacks = callbacks->length();
    4745             : 
    4746             :   Isolate* isolate = array->GetIsolate();
    4747             :   // Ensure the keys are unique names before writing them into the
    4748             :   // instance descriptor. Since it may cause a GC, it has to be done before we
    4749             :   // temporarily put the heap in an invalid state while appending descriptors.
    4750      190250 :   for (int i = 0; i < nof_callbacks; ++i) {
    4751             :     Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)));
    4752       64211 :     if (entry->name()->IsUniqueName()) continue;
    4753             :     Handle<String> key =
    4754             :         isolate->factory()->InternalizeString(
    4755       63061 :             Handle<String>(String::cast(entry->name())));
    4756       63061 :     entry->set_name(*key);
    4757             :   }
    4758             : 
    4759             :   // Fill in new callback descriptors.  Process the callbacks from
    4760             :   // back to front so that the last callback with a given name takes
    4761             :   // precedence over previously added callbacks with that name.
    4762      126943 :   for (int i = nof_callbacks - 1; i >= 0; i--) {
    4763             :     Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)));
    4764             :     Handle<Name> key(Name::cast(entry->name()));
    4765             :     // Check if a descriptor with this name already exists before writing.
    4766       63636 :     if (!T::Contains(key, entry, valid_descriptors, array)) {
    4767           0 :       T::Insert(key, entry, valid_descriptors, array);
    4768       63622 :       valid_descriptors++;
    4769             :     }
    4770             :   }
    4771             : 
    4772       63307 :   return valid_descriptors;
    4773             : }
    4774             : 
    4775             : struct DescriptorArrayAppender {
    4776             :   typedef DescriptorArray Array;
    4777             :   static bool Contains(Handle<Name> key,
    4778             :                        Handle<AccessorInfo> entry,
    4779             :                        int valid_descriptors,
    4780             :                        Handle<DescriptorArray> array) {
    4781             :     DisallowHeapAllocation no_gc;
    4782             :     return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound;
    4783             :   }
    4784           0 :   static void Insert(Handle<Name> key,
    4785             :                      Handle<AccessorInfo> entry,
    4786             :                      int valid_descriptors,
    4787             :                      Handle<DescriptorArray> array) {
    4788             :     DisallowHeapAllocation no_gc;
    4789             :     Descriptor d =
    4790             :         Descriptor::AccessorConstant(key, entry, entry->property_attributes());
    4791           0 :     array->Append(&d);
    4792           0 :   }
    4793             : };
    4794             : 
    4795             : 
    4796             : struct FixedArrayAppender {
    4797             :   typedef FixedArray Array;
    4798       63636 :   static bool Contains(Handle<Name> key,
    4799             :                        Handle<AccessorInfo> entry,
    4800             :                        int valid_descriptors,
    4801             :                        Handle<FixedArray> array) {
    4802         609 :     for (int i = 0; i < valid_descriptors; i++) {
    4803         623 :       if (*key == AccessorInfo::cast(array->get(i))->name()) return true;
    4804             :     }
    4805             :     return false;
    4806             :   }
    4807             :   static void Insert(Handle<Name> key,
    4808             :                      Handle<AccessorInfo> entry,
    4809             :                      int valid_descriptors,
    4810             :                      Handle<FixedArray> array) {
    4811             :     DisallowHeapAllocation no_gc;
    4812       63622 :     array->set(valid_descriptors, *entry);
    4813             :   }
    4814             : };
    4815             : 
    4816             : 
    4817           0 : void Map::AppendCallbackDescriptors(Handle<Map> map,
    4818             :                                     Handle<Object> descriptors) {
    4819             :   int nof = map->NumberOfOwnDescriptors();
    4820             :   Handle<DescriptorArray> array(map->instance_descriptors());
    4821           0 :   Handle<TemplateList> callbacks = Handle<TemplateList>::cast(descriptors);
    4822             :   DCHECK_GE(array->NumberOfSlackDescriptors(), callbacks->length());
    4823           0 :   nof = AppendUniqueCallbacks<DescriptorArrayAppender>(callbacks, array, nof);
    4824             :   map->SetNumberOfOwnDescriptors(nof);
    4825           0 : }
    4826             : 
    4827             : 
    4828       63307 : int AccessorInfo::AppendUnique(Handle<Object> descriptors,
    4829             :                                Handle<FixedArray> array,
    4830             :                                int valid_descriptors) {
    4831       63307 :   Handle<TemplateList> callbacks = Handle<TemplateList>::cast(descriptors);
    4832             :   DCHECK_GE(array->length(), callbacks->length() + valid_descriptors);
    4833             :   return AppendUniqueCallbacks<FixedArrayAppender>(callbacks, array,
    4834       63307 :                                                    valid_descriptors);
    4835             : }
    4836             : 
    4837             : 
    4838      317859 : static bool ContainsMap(MapHandleList* maps, Map* map) {
    4839             :   DCHECK_NOT_NULL(map);
    4840      488624 :   for (int i = 0; i < maps->length(); ++i) {
    4841      393930 :     if (!maps->at(i).is_null() && *maps->at(i) == map) return true;
    4842             :   }
    4843             :   return false;
    4844             : }
    4845             : 
    4846       98675 : Map* Map::FindElementsKindTransitionedMap(MapHandleList* candidates) {
    4847             :   DisallowHeapAllocation no_allocation;
    4848             :   DisallowDeoptimization no_deoptimization(GetIsolate());
    4849             : 
    4850             :   ElementsKind kind = elements_kind();
    4851             :   bool packed = IsFastPackedElementsKind(kind);
    4852             : 
    4853             :   Map* transition = nullptr;
    4854       98675 :   if (IsTransitionableFastElementsKind(kind)) {
    4855             :     // Check the state of the root map.
    4856       48921 :     Map* root_map = FindRootMap();
    4857       48921 :     if (!EquivalentToForTransition(root_map)) return nullptr;
    4858             :     root_map = root_map->LookupElementsTransitionMap(kind);
    4859             :     DCHECK_NOT_NULL(root_map);
    4860             :     // Starting from the next existing elements kind transition try to
    4861             :     // replay the property transitions that does not involve instance rewriting
    4862             :     // (ElementsTransitionAndStoreStub does not support that).
    4863      249489 :     for (root_map = root_map->ElementsTransitionMap();
    4864      355119 :          root_map != nullptr && root_map->has_fast_elements();
    4865             :          root_map = root_map->ElementsTransitionMap()) {
    4866      151647 :       Map* current = root_map->TryReplayPropertyTransitions(this);
    4867      151647 :       if (current == nullptr) continue;
    4868      147124 :       if (InstancesNeedRewriting(current)) continue;
    4869             : 
    4870      294188 :       if (ContainsMap(candidates, current) &&
    4871        5018 :           (packed || !IsFastPackedElementsKind(current->elements_kind()))) {
    4872             :         transition = current;
    4873       46969 :         packed = packed && IsFastPackedElementsKind(current->elements_kind());
    4874             :       }
    4875             :     }
    4876             :   }
    4877       98675 :   return transition;
    4878             : }
    4879             : 
    4880             : 
    4881     1577782 : static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
    4882             :   // Ensure we are requested to search elements kind transition "near the root".
    4883             :   DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(),
    4884             :             map->NumberOfOwnDescriptors());
    4885             :   Map* current_map = map;
    4886             : 
    4887             :   ElementsKind kind = map->elements_kind();
    4888     5515597 :   while (kind != to_kind) {
    4889             :     Map* next_map = current_map->ElementsTransitionMap();
    4890     2622239 :     if (next_map == nullptr) return current_map;
    4891             :     kind = next_map->elements_kind();
    4892             :     current_map = next_map;
    4893             :   }
    4894             : 
    4895             :   DCHECK_EQ(to_kind, current_map->elements_kind());
    4896             :   return current_map;
    4897             : }
    4898             : 
    4899             : 
    4900           0 : Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) {
    4901       48939 :   Map* to_map = FindClosestElementsTransition(this, to_kind);
    4902       48939 :   if (to_map->elements_kind() == to_kind) return to_map;
    4903             :   return nullptr;
    4904             : }
    4905             : 
    4906             : 
    4907      416927 : bool Map::IsMapInArrayPrototypeChain() {
    4908             :   Isolate* isolate = GetIsolate();
    4909      833854 :   if (isolate->initial_array_prototype()->map() == this) {
    4910             :     return true;
    4911             :   }
    4912             : 
    4913      832164 :   if (isolate->initial_object_prototype()->map() == this) {
    4914             :     return true;
    4915             :   }
    4916             : 
    4917      415838 :   return false;
    4918             : }
    4919             : 
    4920             : 
    4921    20640027 : Handle<WeakCell> Map::WeakCellForMap(Handle<Map> map) {
    4922             :   Isolate* isolate = map->GetIsolate();
    4923    20640026 :   if (map->weak_cell_cache()->IsWeakCell()) {
    4924     8420738 :     return Handle<WeakCell>(WeakCell::cast(map->weak_cell_cache()));
    4925             :   }
    4926    12219288 :   Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(map);
    4927    12219290 :   map->set_weak_cell_cache(*weak_cell);
    4928    12219291 :   return weak_cell;
    4929             : }
    4930             : 
    4931             : 
    4932      262206 : static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
    4933             :                                                  ElementsKind to_kind) {
    4934             :   DCHECK(IsTransitionElementsKind(map->elements_kind()));
    4935             : 
    4936             :   Handle<Map> current_map = map;
    4937             : 
    4938             :   ElementsKind kind = map->elements_kind();
    4939             :   TransitionFlag flag;
    4940      262206 :   if (map->is_prototype_map()) {
    4941             :     flag = OMIT_TRANSITION;
    4942             :   } else {
    4943             :     flag = INSERT_TRANSITION;
    4944      259852 :     if (IsFastElementsKind(kind)) {
    4945      537558 :       while (kind != to_kind && !IsTerminalElementsKind(kind)) {
    4946       10459 :         kind = GetNextTransitionElementsKind(kind);
    4947       10459 :         current_map = Map::CopyAsElementsKind(current_map, kind, flag);
    4948             :       }
    4949             :     }
    4950             :   }
    4951             : 
    4952             :   // In case we are exiting the fast elements kind system, just add the map in
    4953             :   // the end.
    4954      262206 :   if (kind != to_kind) {
    4955      259420 :     current_map = Map::CopyAsElementsKind(current_map, to_kind, flag);
    4956             :   }
    4957             : 
    4958             :   DCHECK(current_map->elements_kind() == to_kind);
    4959      262206 :   return current_map;
    4960             : }
    4961             : 
    4962             : 
    4963     2600915 : Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
    4964             :                                       ElementsKind to_kind) {
    4965             :   ElementsKind from_kind = map->elements_kind();
    4966     2600915 :   if (from_kind == to_kind) return map;
    4967             : 
    4968     1505623 :   Isolate* isolate = map->GetIsolate();
    4969             :   Context* native_context = isolate->context()->native_context();
    4970     1505623 :   if (from_kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
    4971         532 :     if (*map == native_context->fast_aliased_arguments_map()) {
    4972             :       DCHECK_EQ(SLOW_SLOPPY_ARGUMENTS_ELEMENTS, to_kind);
    4973             :       return handle(native_context->slow_aliased_arguments_map());
    4974             :     }
    4975     1505091 :   } else if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
    4976          30 :     if (*map == native_context->slow_aliased_arguments_map()) {
    4977             :       DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, to_kind);
    4978             :       return handle(native_context->fast_aliased_arguments_map());
    4979             :     }
    4980     3006889 :   } else if (IsFastElementsKind(from_kind) && IsFastElementsKind(to_kind)) {
    4981             :     // Reuse map transitions for JSArrays.
    4982             :     DisallowHeapAllocation no_gc;
    4983     1038715 :     if (native_context->get(Context::ArrayMapIndex(from_kind)) == *map) {
    4984             :       Object* maybe_transitioned_map =
    4985             :           native_context->get(Context::ArrayMapIndex(to_kind));
    4986      849262 :       if (maybe_transitioned_map->IsMap()) {
    4987             :         return handle(Map::cast(maybe_transitioned_map), isolate);
    4988             :       }
    4989             :     }
    4990             :   }
    4991             : 
    4992             :   DCHECK(!map->IsUndefined(isolate));
    4993             :   // Check if we can go back in the elements kind transition chain.
    4994     1282592 :   if (IsHoleyElementsKind(from_kind) &&
    4995           0 :       to_kind == GetPackedElementsKind(from_kind) &&
    4996      655889 :       map->GetBackPointer()->IsMap() &&
    4997           0 :       Map::cast(map->GetBackPointer())->elements_kind() == to_kind) {
    4998           0 :     return handle(Map::cast(map->GetBackPointer()));
    4999             :   }
    5000             : 
    5001             :   bool allow_store_transition = IsTransitionElementsKind(from_kind);
    5002             :   // Only store fast element maps in ascending generality.
    5003      655889 :   if (IsFastElementsKind(to_kind)) {
    5004             :     allow_store_transition =
    5005      571379 :         allow_store_transition && IsTransitionableFastElementsKind(from_kind) &&
    5006      189453 :         IsMoreGeneralElementsKindTransition(from_kind, to_kind);
    5007             :   }
    5008             : 
    5009      655889 :   if (!allow_store_transition) {
    5010        3035 :     return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION);
    5011             :   }
    5012             : 
    5013      652854 :   return Map::ReconfigureElementsKind(map, to_kind);
    5014             : }
    5015             : 
    5016             : 
    5017             : // static
    5018     1528843 : Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) {
    5019     1528843 :   Handle<Map> closest_map(FindClosestElementsTransition(*map, kind));
    5020             : 
    5021     1528843 :   if (closest_map->elements_kind() == kind) {
    5022     1266637 :     return closest_map;
    5023             :   }
    5024             : 
    5025      262206 :   return AddMissingElementsTransitions(closest_map, kind);
    5026             : }
    5027             : 
    5028             : 
    5029     2523439 : Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
    5030             :                                                ElementsKind to_kind) {
    5031             :   Handle<Map> map(object->map());
    5032     2523439 :   return Map::TransitionElementsTo(map, to_kind);
    5033             : }
    5034             : 
    5035             : 
    5036         188 : void JSProxy::Revoke(Handle<JSProxy> proxy) {
    5037             :   Isolate* isolate = proxy->GetIsolate();
    5038         362 :   if (!proxy->IsRevoked()) proxy->set_handler(isolate->heap()->null_value());
    5039             :   DCHECK(proxy->IsRevoked());
    5040         188 : }
    5041             : 
    5042             : 
    5043       68199 : Maybe<bool> JSProxy::HasProperty(Isolate* isolate, Handle<JSProxy> proxy,
    5044             :                                  Handle<Name> name) {
    5045             :   DCHECK(!name->IsPrivate());
    5046       68199 :   STACK_CHECK(isolate, Nothing<bool>());
    5047             :   // 1. (Assert)
    5048             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    5049             :   Handle<Object> handler(proxy->handler(), isolate);
    5050             :   // 3. If handler is null, throw a TypeError exception.
    5051             :   // 4. Assert: Type(handler) is Object.
    5052       68185 :   if (proxy->IsRevoked()) {
    5053             :     isolate->Throw(*isolate->factory()->NewTypeError(
    5054          56 :         MessageTemplate::kProxyRevoked, isolate->factory()->has_string()));
    5055             :     return Nothing<bool>();
    5056             :   }
    5057             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    5058             :   Handle<JSReceiver> target(proxy->target(), isolate);
    5059             :   // 6. Let trap be ? GetMethod(handler, "has").
    5060             :   Handle<Object> trap;
    5061      136314 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5062             :       isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler),
    5063             :                                        isolate->factory()->has_string()),
    5064             :       Nothing<bool>());
    5065             :   // 7. If trap is undefined, then
    5066       67947 :   if (trap->IsUndefined(isolate)) {
    5067             :     // 7a. Return target.[[HasProperty]](P).
    5068       53258 :     return JSReceiver::HasProperty(target, name);
    5069             :   }
    5070             :   // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, P»)).
    5071             :   Handle<Object> trap_result_obj;
    5072             :   Handle<Object> args[] = {target, name};
    5073       29378 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5074             :       isolate, trap_result_obj,
    5075             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    5076             :       Nothing<bool>());
    5077       14045 :   bool boolean_trap_result = trap_result_obj->BooleanValue();
    5078             :   // 9. If booleanTrapResult is false, then:
    5079       14045 :   if (!boolean_trap_result) {
    5080             :     // 9a. Let targetDesc be ? target.[[GetOwnProperty]](P).
    5081             :     PropertyDescriptor target_desc;
    5082             :     Maybe<bool> target_found = JSReceiver::GetOwnPropertyDescriptor(
    5083        8990 :         isolate, target, name, &target_desc);
    5084        9032 :     MAYBE_RETURN(target_found, Nothing<bool>());
    5085             :     // 9b. If targetDesc is not undefined, then:
    5086        8990 :     if (target_found.FromJust()) {
    5087             :       // 9b i. If targetDesc.[[Configurable]] is false, throw a TypeError
    5088             :       //       exception.
    5089          72 :       if (!target_desc.configurable()) {
    5090             :         isolate->Throw(*isolate->factory()->NewTypeError(
    5091          56 :             MessageTemplate::kProxyHasNonConfigurable, name));
    5092          42 :         return Nothing<bool>();
    5093             :       }
    5094             :       // 9b ii. Let extensibleTarget be ? IsExtensible(target).
    5095          44 :       Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    5096          44 :       MAYBE_RETURN(extensible_target, Nothing<bool>());
    5097             :       // 9b iii. If extensibleTarget is false, throw a TypeError exception.
    5098          44 :       if (!extensible_target.FromJust()) {
    5099             :         isolate->Throw(*isolate->factory()->NewTypeError(
    5100          28 :             MessageTemplate::kProxyHasNonExtensible, name));
    5101             :         return Nothing<bool>();
    5102             :       }
    5103             :     }
    5104             :   }
    5105             :   // 10. Return booleanTrapResult.
    5106             :   return Just(boolean_trap_result);
    5107             : }
    5108             : 
    5109             : 
    5110       63039 : Maybe<bool> JSProxy::SetProperty(Handle<JSProxy> proxy, Handle<Name> name,
    5111             :                                  Handle<Object> value, Handle<Object> receiver,
    5112             :                                  LanguageMode language_mode) {
    5113             :   DCHECK(!name->IsPrivate());
    5114             :   Isolate* isolate = proxy->GetIsolate();
    5115       63039 :   STACK_CHECK(isolate, Nothing<bool>());
    5116             :   Factory* factory = isolate->factory();
    5117             :   Handle<String> trap_name = factory->set_string();
    5118             :   ShouldThrow should_throw =
    5119       63011 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    5120             : 
    5121       63011 :   if (proxy->IsRevoked()) {
    5122             :     isolate->Throw(
    5123          56 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    5124             :     return Nothing<bool>();
    5125             :   }
    5126             :   Handle<JSReceiver> target(proxy->target(), isolate);
    5127             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    5128             : 
    5129             :   Handle<Object> trap;
    5130      125966 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5131             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    5132       62507 :   if (trap->IsUndefined(isolate)) {
    5133             :     LookupIterator it =
    5134       57942 :         LookupIterator::PropertyOrElement(isolate, receiver, name, target);
    5135             :     return Object::SetSuperProperty(&it, value, language_mode,
    5136       57942 :                                     Object::MAY_BE_STORE_FROM_KEYED);
    5137             :   }
    5138             : 
    5139             :   Handle<Object> trap_result;
    5140        4565 :   Handle<Object> args[] = {target, name, value, receiver};
    5141        9130 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5142             :       isolate, trap_result,
    5143             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    5144             :       Nothing<bool>());
    5145        4061 :   if (!trap_result->BooleanValue()) {
    5146         869 :     RETURN_FAILURE(isolate, should_throw,
    5147             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    5148             :                                 trap_name, name));
    5149             :   }
    5150             : 
    5151             :   // Enforce the invariant.
    5152             :   PropertyDescriptor target_desc;
    5153             :   Maybe<bool> owned =
    5154        3332 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    5155        3332 :   MAYBE_RETURN(owned, Nothing<bool>());
    5156        3332 :   if (owned.FromJust()) {
    5157        1526 :     bool inconsistent = PropertyDescriptor::IsDataDescriptor(&target_desc) &&
    5158         840 :                         !target_desc.configurable() &&
    5159        2646 :                         !target_desc.writable() &&
    5160         560 :                         !value->SameValue(*target_desc.value());
    5161        2086 :     if (inconsistent) {
    5162             :       isolate->Throw(*isolate->factory()->NewTypeError(
    5163         560 :           MessageTemplate::kProxySetFrozenData, name));
    5164             :       return Nothing<bool>();
    5165             :     }
    5166         560 :     inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
    5167        2086 :                    !target_desc.configurable() &&
    5168             :                    target_desc.set()->IsUndefined(isolate);
    5169        1806 :     if (inconsistent) {
    5170             :       isolate->Throw(*isolate->factory()->NewTypeError(
    5171         560 :           MessageTemplate::kProxySetFrozenAccessor, name));
    5172             :       return Nothing<bool>();
    5173             :     }
    5174             :   }
    5175             :   return Just(true);
    5176             : }
    5177             : 
    5178             : 
    5179        4817 : Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy,
    5180             :                                              Handle<Name> name,
    5181             :                                              LanguageMode language_mode) {
    5182             :   DCHECK(!name->IsPrivate());
    5183             :   ShouldThrow should_throw =
    5184        4817 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    5185             :   Isolate* isolate = proxy->GetIsolate();
    5186        4817 :   STACK_CHECK(isolate, Nothing<bool>());
    5187             :   Factory* factory = isolate->factory();
    5188             :   Handle<String> trap_name = factory->deleteProperty_string();
    5189             : 
    5190        4817 :   if (proxy->IsRevoked()) {
    5191             :     isolate->Throw(
    5192          56 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    5193             :     return Nothing<bool>();
    5194             :   }
    5195             :   Handle<JSReceiver> target(proxy->target(), isolate);
    5196             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    5197             : 
    5198             :   Handle<Object> trap;
    5199        9578 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5200             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    5201        4579 :   if (trap->IsUndefined(isolate)) {
    5202        1261 :     return JSReceiver::DeletePropertyOrElement(target, name, language_mode);
    5203             :   }
    5204             : 
    5205             :   Handle<Object> trap_result;
    5206             :   Handle<Object> args[] = {target, name};
    5207        6636 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5208             :       isolate, trap_result,
    5209             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    5210             :       Nothing<bool>());
    5211        2814 :   if (!trap_result->BooleanValue()) {
    5212        1932 :     RETURN_FAILURE(isolate, should_throw,
    5213             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    5214             :                                 trap_name, name));
    5215             :   }
    5216             : 
    5217             :   // Enforce the invariant.
    5218             :   PropertyDescriptor target_desc;
    5219             :   Maybe<bool> owned =
    5220        1638 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    5221        1638 :   MAYBE_RETURN(owned, Nothing<bool>());
    5222        2478 :   if (owned.FromJust() && !target_desc.configurable()) {
    5223             :     isolate->Throw(*factory->NewTypeError(
    5224        1120 :         MessageTemplate::kProxyDeletePropertyNonConfigurable, name));
    5225             :     return Nothing<bool>();
    5226             :   }
    5227             :   return Just(true);
    5228             : }
    5229             : 
    5230             : 
    5231             : // static
    5232       45334 : MaybeHandle<JSProxy> JSProxy::New(Isolate* isolate, Handle<Object> target,
    5233             :                                   Handle<Object> handler) {
    5234       45334 :   if (!target->IsJSReceiver()) {
    5235          30 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject),
    5236             :                     JSProxy);
    5237             :   }
    5238       50361 :   if (target->IsJSProxy() && JSProxy::cast(*target)->IsRevoked()) {
    5239           0 :     THROW_NEW_ERROR(isolate,
    5240             :                     NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
    5241             :                     JSProxy);
    5242             :   }
    5243       45319 :   if (!handler->IsJSReceiver()) {
    5244           0 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject),
    5245             :                     JSProxy);
    5246             :   }
    5247       52739 :   if (handler->IsJSProxy() && JSProxy::cast(*handler)->IsRevoked()) {
    5248           0 :     THROW_NEW_ERROR(isolate,
    5249             :                     NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
    5250             :                     JSProxy);
    5251             :   }
    5252             :   return isolate->factory()->NewJSProxy(Handle<JSReceiver>::cast(target),
    5253       45319 :                                         Handle<JSReceiver>::cast(handler));
    5254             : }
    5255             : 
    5256             : 
    5257             : // static
    5258          29 : MaybeHandle<Context> JSProxy::GetFunctionRealm(Handle<JSProxy> proxy) {
    5259             :   DCHECK(proxy->map()->is_constructor());
    5260          29 :   if (proxy->IsRevoked()) {
    5261           0 :     THROW_NEW_ERROR(proxy->GetIsolate(),
    5262             :                     NewTypeError(MessageTemplate::kProxyRevoked), Context);
    5263             :   }
    5264             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()));
    5265          29 :   return JSReceiver::GetFunctionRealm(target);
    5266             : }
    5267             : 
    5268             : 
    5269             : // static
    5270           0 : MaybeHandle<Context> JSBoundFunction::GetFunctionRealm(
    5271             :     Handle<JSBoundFunction> function) {
    5272             :   DCHECK(function->map()->is_constructor());
    5273             :   return JSReceiver::GetFunctionRealm(
    5274           0 :       handle(function->bound_target_function()));
    5275             : }
    5276             : 
    5277             : // static
    5278         341 : MaybeHandle<String> JSBoundFunction::GetName(Isolate* isolate,
    5279             :                                              Handle<JSBoundFunction> function) {
    5280             :   Handle<String> prefix = isolate->factory()->bound__string();
    5281         341 :   if (!function->bound_target_function()->IsJSFunction()) return prefix;
    5282             :   Handle<JSFunction> target(JSFunction::cast(function->bound_target_function()),
    5283             :                             isolate);
    5284         341 :   Handle<Object> target_name = JSFunction::GetName(isolate, target);
    5285         341 :   if (!target_name->IsString()) return prefix;
    5286             :   Factory* factory = isolate->factory();
    5287         341 :   return factory->NewConsString(prefix, Handle<String>::cast(target_name));
    5288             : }
    5289             : 
    5290             : // static
    5291      145679 : Handle<Object> JSFunction::GetName(Isolate* isolate,
    5292             :                                    Handle<JSFunction> function) {
    5293      145679 :   if (function->shared()->name_should_print_as_anonymous()) {
    5294           0 :     return isolate->factory()->anonymous_string();
    5295             :   }
    5296             :   return handle(function->shared()->name(), isolate);
    5297             : }
    5298             : 
    5299             : // static
    5300       24391 : MaybeHandle<Smi> JSFunction::GetLength(Isolate* isolate,
    5301             :                                        Handle<JSFunction> function) {
    5302             :   int length = 0;
    5303       24391 :   if (function->shared()->is_compiled()) {
    5304             :     length = function->shared()->GetLength();
    5305             :   } else {
    5306             :     // If the function isn't compiled yet, the length is not computed
    5307             :     // correctly yet. Compile it now and return the right length.
    5308        2141 :     if (Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) {
    5309             :       length = function->shared()->GetLength();
    5310             :     }
    5311        2141 :     if (isolate->has_pending_exception()) return MaybeHandle<Smi>();
    5312             :   }
    5313             :   DCHECK_GE(length, 0);
    5314             :   return handle(Smi::FromInt(length), isolate);
    5315             : }
    5316             : 
    5317             : // static
    5318        4331 : Handle<Context> JSFunction::GetFunctionRealm(Handle<JSFunction> function) {
    5319             :   DCHECK(function->map()->is_constructor());
    5320        4331 :   return handle(function->context()->native_context());
    5321             : }
    5322             : 
    5323             : 
    5324             : // static
    5325           0 : MaybeHandle<Context> JSObject::GetFunctionRealm(Handle<JSObject> object) {
    5326             :   DCHECK(object->map()->is_constructor());
    5327             :   DCHECK(!object->IsJSFunction());
    5328           0 :   return object->GetCreationContext();
    5329             : }
    5330             : 
    5331             : 
    5332             : // static
    5333        4360 : MaybeHandle<Context> JSReceiver::GetFunctionRealm(Handle<JSReceiver> receiver) {
    5334        4360 :   if (receiver->IsJSProxy()) {
    5335          29 :     return JSProxy::GetFunctionRealm(Handle<JSProxy>::cast(receiver));
    5336             :   }
    5337             : 
    5338        4331 :   if (receiver->IsJSFunction()) {
    5339        4331 :     return JSFunction::GetFunctionRealm(Handle<JSFunction>::cast(receiver));
    5340             :   }
    5341             : 
    5342           0 :   if (receiver->IsJSBoundFunction()) {
    5343             :     return JSBoundFunction::GetFunctionRealm(
    5344           0 :         Handle<JSBoundFunction>::cast(receiver));
    5345             :   }
    5346             : 
    5347             :   return JSObject::GetFunctionRealm(Handle<JSObject>::cast(receiver));
    5348             : }
    5349             : 
    5350             : 
    5351        4940 : Maybe<PropertyAttributes> JSProxy::GetPropertyAttributes(LookupIterator* it) {
    5352             :   PropertyDescriptor desc;
    5353             :   Maybe<bool> found = JSProxy::GetOwnPropertyDescriptor(
    5354        4940 :       it->isolate(), it->GetHolder<JSProxy>(), it->GetName(), &desc);
    5355        2470 :   MAYBE_RETURN(found, Nothing<PropertyAttributes>());
    5356        2005 :   if (!found.FromJust()) return Just(ABSENT);
    5357        1766 :   return Just(desc.ToAttributes());
    5358             : }
    5359             : 
    5360             : 
    5361     9945195 : void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
    5362             :   DCHECK(object->map()->GetInObjectProperties() ==
    5363             :          map->GetInObjectProperties());
    5364             :   ElementsKind obj_kind = object->map()->elements_kind();
    5365             :   ElementsKind map_kind = map->elements_kind();
    5366     9945195 :   if (map_kind != obj_kind) {
    5367             :     ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind);
    5368          60 :     if (IsDictionaryElementsKind(obj_kind)) {
    5369             :       to_kind = obj_kind;
    5370             :     }
    5371          60 :     if (IsDictionaryElementsKind(to_kind)) {
    5372          45 :       NormalizeElements(object);
    5373             :     } else {
    5374          15 :       TransitionElementsKind(object, to_kind);
    5375             :     }
    5376          60 :     map = Map::ReconfigureElementsKind(map, to_kind);
    5377             :   }
    5378     9945195 :   JSObject::MigrateToMap(object, map);
    5379     9945195 : }
    5380             : 
    5381             : 
    5382        9782 : void JSObject::MigrateInstance(Handle<JSObject> object) {
    5383             :   Handle<Map> original_map(object->map());
    5384        9782 :   Handle<Map> map = Map::Update(original_map);
    5385             :   map->set_migration_target(true);
    5386        9782 :   MigrateToMap(object, map);
    5387        9782 :   if (FLAG_trace_migration) {
    5388           0 :     object->PrintInstanceMigration(stdout, *original_map, *map);
    5389             :   }
    5390             : #if VERIFY_HEAP
    5391             :   if (FLAG_verify_heap) {
    5392             :     object->JSObjectVerify();
    5393             :   }
    5394             : #endif
    5395        9782 : }
    5396             : 
    5397             : 
    5398             : // static
    5399        8185 : bool JSObject::TryMigrateInstance(Handle<JSObject> object) {
    5400             :   Isolate* isolate = object->GetIsolate();
    5401             :   DisallowDeoptimization no_deoptimization(isolate);
    5402             :   Handle<Map> original_map(object->map(), isolate);
    5403             :   Handle<Map> new_map;
    5404       16370 :   if (!Map::TryUpdate(original_map).ToHandle(&new_map)) {
    5405             :     return false;
    5406             :   }
    5407        8157 :   JSObject::MigrateToMap(object, new_map);
    5408        8157 :   if (FLAG_trace_migration && *original_map != object->map()) {
    5409           0 :     object->PrintInstanceMigration(stdout, *original_map, object->map());
    5410             :   }
    5411             : #if VERIFY_HEAP
    5412             :   if (FLAG_verify_heap) {
    5413             :     object->JSObjectVerify();
    5414             :   }
    5415             : #endif
    5416             :   return true;
    5417             : }
    5418             : 
    5419             : 
    5420    17984358 : void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name,
    5421             :                            Handle<Object> value,
    5422             :                            PropertyAttributes attributes) {
    5423    17984358 :   LookupIterator it(object, name, object, LookupIterator::OWN_SKIP_INTERCEPTOR);
    5424    17984366 :   CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
    5425             : #ifdef DEBUG
    5426             :   uint32_t index;
    5427             :   DCHECK(!object->IsJSProxy());
    5428             :   DCHECK(!name->AsArrayIndex(&index));
    5429             :   Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
    5430             :   DCHECK(maybe.IsJust());
    5431             :   DCHECK(!it.IsFound());
    5432             :   DCHECK(object->map()->is_extensible() || name->IsPrivate());
    5433             : #endif
    5434    17984366 :   CHECK(AddDataProperty(&it, value, attributes, THROW_ON_ERROR,
    5435             :                         CERTAINLY_NOT_STORE_FROM_KEYED)
    5436             :             .IsJust());
    5437    17984360 : }
    5438             : 
    5439             : 
    5440             : // Reconfigures a property to a data property with attributes, even if it is not
    5441             : // reconfigurable.
    5442             : // Requires a LookupIterator that does not look at the prototype chain beyond
    5443             : // hidden prototypes.
    5444     2307104 : MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
    5445             :     LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
    5446             :     AccessorInfoHandling handling) {
    5447    16424432 :   MAYBE_RETURN_NULL(DefineOwnPropertyIgnoreAttributes(
    5448             :       it, value, attributes, THROW_ON_ERROR, handling));
    5449             :   return value;
    5450             : }
    5451             : 
    5452             : 
    5453    16758648 : Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
    5454    16794773 :     LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
    5455             :     ShouldThrow should_throw, AccessorInfoHandling handling) {
    5456    16758648 :   it->UpdateProtector();
    5457             :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    5458             : 
    5459    33519342 :   for (; it->IsFound(); it->Next()) {
    5460     2610278 :     switch (it->state()) {
    5461             :       case LookupIterator::JSPROXY:
    5462             :       case LookupIterator::NOT_FOUND:
    5463             :       case LookupIterator::TRANSITION:
    5464           0 :         UNREACHABLE();
    5465             : 
    5466             :       case LookupIterator::ACCESS_CHECK:
    5467         771 :         if (!it->HasAccess()) {
    5468           6 :           it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    5469           6 :           RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    5470             :           return Just(true);
    5471             :         }
    5472             :         break;
    5473             : 
    5474             :       // If there's an interceptor, try to store the property with the
    5475             :       // interceptor.
    5476             :       // In case of success, the attributes will have been reset to the default
    5477             :       // attributes of the interceptor, rather than the incoming attributes.
    5478             :       //
    5479             :       // TODO(verwaest): JSProxy afterwards verify the attributes that the
    5480             :       // JSProxy claims it has, and verifies that they are compatible. If not,
    5481             :       // they throw. Here we should do the same.
    5482             :       case LookupIterator::INTERCEPTOR:
    5483         259 :         if (handling == DONT_FORCE_FIELD) {
    5484             :           Maybe<bool> result =
    5485         259 :               JSObject::SetPropertyWithInterceptor(it, should_throw, value);
    5486         518 :           if (result.IsNothing() || result.FromJust()) return result;
    5487             :         }
    5488             :         break;
    5489             : 
    5490             :       case LookupIterator::ACCESSOR: {
    5491     1573711 :         Handle<Object> accessors = it->GetAccessors();
    5492             : 
    5493             :         // Special handling for AccessorInfo, which behaves like a data
    5494             :         // property.
    5495     1573713 :         if (accessors->IsAccessorInfo() && handling == DONT_FORCE_FIELD) {
    5496             :           PropertyAttributes current_attributes = it->property_attributes();
    5497             :           // Ensure the context isn't changed after calling into accessors.
    5498             :           AssertNoContextChange ncc(it->isolate());
    5499             : 
    5500             :           // Update the attributes before calling the setter. The setter may
    5501             :           // later change the shape of the property.
    5502     1572947 :           if (current_attributes != attributes) {
    5503       78896 :             it->TransitionToAccessorPair(accessors, attributes);
    5504             :           }
    5505             : 
    5506     1572947 :           return JSObject::SetPropertyWithAccessor(it, value, should_throw);
    5507             :         }
    5508             : 
    5509         766 :         it->ReconfigureDataProperty(value, attributes);
    5510             :         return Just(true);
    5511             :       }
    5512             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    5513             :         return RedefineIncompatibleProperty(it->isolate(), it->GetName(), value,
    5514          30 :                                             should_throw);
    5515             : 
    5516             :       case LookupIterator::DATA: {
    5517             :         // Regular property update if the attributes match.
    5518     1035520 :         if (it->property_attributes() == attributes) {
    5519     1000445 :           return SetDataProperty(it, value);
    5520             :         }
    5521             : 
    5522             :         // Special case: properties of typed arrays cannot be reconfigured to
    5523             :         // non-writable nor to non-enumerable.
    5524       67243 :         if (it->IsElement() && object->HasFixedTypedArrayElements()) {
    5525             :           return RedefineIncompatibleProperty(it->isolate(), it->GetName(),
    5526           0 :                                               value, should_throw);
    5527             :         }
    5528             : 
    5529             :         // Reconfigure the data property if the attributes mismatch.
    5530       35075 :         it->ReconfigureDataProperty(value, attributes);
    5531             : 
    5532             :         return Just(true);
    5533             :       }
    5534             :     }
    5535             :   }
    5536             : 
    5537             :   return AddDataProperty(it, value, attributes, should_throw,
    5538    14149393 :                          CERTAINLY_NOT_STORE_FROM_KEYED);
    5539             : }
    5540             : 
    5541    10953707 : MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
    5542             :     Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
    5543             :     PropertyAttributes attributes) {
    5544             :   DCHECK(!value->IsTheHole(object->GetIsolate()));
    5545    10953707 :   LookupIterator it(object, name, object, LookupIterator::OWN);
    5546    10953708 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    5547             : }
    5548             : 
    5549      295176 : MaybeHandle<Object> JSObject::SetOwnElementIgnoreAttributes(
    5550             :     Handle<JSObject> object, uint32_t index, Handle<Object> value,
    5551             :     PropertyAttributes attributes) {
    5552             :   Isolate* isolate = object->GetIsolate();
    5553             :   LookupIterator it(isolate, object, index, object, LookupIterator::OWN);
    5554      295176 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    5555             : }
    5556             : 
    5557     2017759 : MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes(
    5558             :     Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
    5559             :     PropertyAttributes attributes) {
    5560             :   Isolate* isolate = object->GetIsolate();
    5561             :   LookupIterator it = LookupIterator::PropertyOrElement(
    5562     2017759 :       isolate, object, name, object, LookupIterator::OWN);
    5563     2017757 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    5564             : }
    5565             : 
    5566      281223 : Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
    5567             :     LookupIterator* it) {
    5568      281223 :   return GetPropertyAttributesWithInterceptorInternal(it, it->GetInterceptor());
    5569             : }
    5570             : 
    5571    10835943 : Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
    5572    13998897 :     LookupIterator* it) {
    5573    27997794 :   for (; it->IsFound(); it->Next()) {
    5574    10149097 :     switch (it->state()) {
    5575             :       case LookupIterator::NOT_FOUND:
    5576             :       case LookupIterator::TRANSITION:
    5577           0 :         UNREACHABLE();
    5578             :       case LookupIterator::JSPROXY:
    5579        1304 :         return JSProxy::GetPropertyAttributes(it);
    5580             :       case LookupIterator::INTERCEPTOR: {
    5581             :         Maybe<PropertyAttributes> result =
    5582         411 :             JSObject::GetPropertyAttributesWithInterceptor(it);
    5583         466 :         if (!result.IsJust()) return result;
    5584         411 :         if (result.FromJust() != ABSENT) return result;
    5585         356 :         break;
    5586             :       }
    5587             :       case LookupIterator::ACCESS_CHECK:
    5588     3162695 :         if (it->HasAccess()) break;
    5589          97 :         return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
    5590             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    5591             :         return Just(ABSENT);
    5592             :       case LookupIterator::ACCESSOR:
    5593             :       case LookupIterator::DATA:
    5594             :         return Just(it->property_attributes());
    5595             :     }
    5596             :   }
    5597             :   return Just(ABSENT);
    5598             : }
    5599             : 
    5600             : 
    5601          79 : Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) {
    5602             :   Handle<FixedArray> array(
    5603          79 :       isolate->factory()->NewFixedArray(kEntries, TENURED));
    5604          79 :   return Handle<NormalizedMapCache>::cast(array);
    5605             : }
    5606             : 
    5607             : 
    5608     1083329 : MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
    5609             :                                          PropertyNormalizationMode mode) {
    5610             :   DisallowHeapAllocation no_gc;
    5611             :   Object* value = FixedArray::get(GetIndex(fast_map));
    5612     2050871 :   if (!value->IsMap() ||
    5613      967542 :       !Map::cast(value)->EquivalentToForNormalization(*fast_map, mode)) {
    5614             :     return MaybeHandle<Map>();
    5615             :   }
    5616             :   return handle(Map::cast(value));
    5617             : }
    5618             : 
    5619             : 
    5620      329942 : void NormalizedMapCache::Set(Handle<Map> fast_map,
    5621             :                              Handle<Map> normalized_map) {
    5622             :   DisallowHeapAllocation no_gc;
    5623             :   DCHECK(normalized_map->is_dictionary_map());
    5624      329942 :   FixedArray::set(GetIndex(fast_map), *normalized_map);
    5625      329942 : }
    5626             : 
    5627             : 
    5628       76477 : void NormalizedMapCache::Clear() {
    5629             :   int entries = length();
    5630     4971005 :   for (int i = 0; i != entries; i++) {
    5631     4894528 :     set_undefined(i);
    5632             :   }
    5633       76477 : }
    5634             : 
    5635             : 
    5636           0 : void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object,
    5637             :                                     Handle<Name> name,
    5638             :                                     Handle<Code> code) {
    5639             :   Handle<Map> map(object->map());
    5640           0 :   Map::UpdateCodeCache(map, name, code);
    5641           0 : }
    5642             : 
    5643             : 
    5644     1308059 : void JSObject::NormalizeProperties(Handle<JSObject> object,
    5645             :                                    PropertyNormalizationMode mode,
    5646             :                                    int expected_additional_properties,
    5647             :                                    const char* reason) {
    5648     1574423 :   if (!object->HasFastProperties()) return;
    5649             : 
    5650             :   Handle<Map> map(object->map());
    5651     1041695 :   Handle<Map> new_map = Map::Normalize(map, mode, reason);
    5652             : 
    5653     1041695 :   MigrateToMap(object, new_map, expected_additional_properties);
    5654             : }
    5655             : 
    5656             : 
    5657      792179 : void JSObject::MigrateSlowToFast(Handle<JSObject> object,
    5658             :                                  int unused_property_fields,
    5659             :                                  const char* reason) {
    5660     1190307 :   if (object->HasFastProperties()) return;
    5661             :   DCHECK(!object->IsJSGlobalObject());
    5662             :   Isolate* isolate = object->GetIsolate();
    5663             :   Factory* factory = isolate->factory();
    5664             :   Handle<NameDictionary> dictionary(object->property_dictionary());
    5665             : 
    5666             :   // Make sure we preserve dictionary representation if there are too many
    5667             :   // descriptors.
    5668             :   int number_of_elements = dictionary->NumberOfElements();
    5669      523637 :   if (number_of_elements > kMaxNumberOfDescriptors) return;
    5670             : 
    5671             :   Handle<FixedArray> iteration_order =
    5672      523054 :       NameDictionary::IterationIndices(dictionary);
    5673             : 
    5674             :   int instance_descriptor_length = iteration_order->length();
    5675             :   int number_of_fields = 0;
    5676             : 
    5677             :   // Compute the length of the instance descriptor.
    5678     3723248 :   for (int i = 0; i < instance_descriptor_length; i++) {
    5679             :     int index = Smi::cast(iteration_order->get(i))->value();
    5680             :     DCHECK(dictionary->IsKey(isolate, dictionary->KeyAt(index)));
    5681             : 
    5682             :     PropertyKind kind = dictionary->DetailsAt(index).kind();
    5683     3200194 :     if (kind == kData) {
    5684             :       if (FLAG_track_constant_fields) {
    5685             :         number_of_fields += 1;
    5686             :       } else {
    5687     2747990 :         Object* value = dictionary->ValueAt(index);
    5688     2747990 :         if (!value->IsJSFunction()) {
    5689      905026 :           number_of_fields += 1;
    5690             :         }
    5691             :       }
    5692             :     }
    5693             :   }
    5694             : 
    5695             :   Handle<Map> old_map(object->map(), isolate);
    5696             : 
    5697             :   int inobject_props = old_map->GetInObjectProperties();
    5698             : 
    5699             :   // Allocate new map.
    5700      523054 :   Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
    5701             :   new_map->set_dictionary_map(false);
    5702             : 
    5703      523054 :   NotifyMapChange(old_map, new_map, isolate);
    5704             : 
    5705             : #if TRACE_MAPS
    5706             :   if (FLAG_trace_maps) {
    5707             :     PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n",
    5708             :            reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map),
    5709             :            reason);
    5710             :   }
    5711             : #endif
    5712             : 
    5713      523054 :   if (instance_descriptor_length == 0) {
    5714             :     DisallowHeapAllocation no_gc;
    5715             :     DCHECK_LE(unused_property_fields, inobject_props);
    5716             :     // Transform the object.
    5717             :     new_map->set_unused_property_fields(inobject_props);
    5718      129003 :     object->synchronized_set_map(*new_map);
    5719      258006 :     object->set_properties(isolate->heap()->empty_fixed_array());
    5720             :     // Check that it really works.
    5721             :     DCHECK(object->HasFastProperties());
    5722             :     return;
    5723             :   }
    5724             : 
    5725             :   // Allocate the instance descriptor.
    5726             :   Handle<DescriptorArray> descriptors = DescriptorArray::Allocate(
    5727      394051 :       isolate, instance_descriptor_length, 0, TENURED);
    5728             : 
    5729             :   int number_of_allocated_fields =
    5730      394051 :       number_of_fields + unused_property_fields - inobject_props;
    5731      394051 :   if (number_of_allocated_fields < 0) {
    5732             :     // There is enough inobject space for all fields (including unused).
    5733             :     number_of_allocated_fields = 0;
    5734      121867 :     unused_property_fields = inobject_props - number_of_fields;
    5735             :   }
    5736             : 
    5737             :   // Allocate the fixed array for the fields.
    5738             :   Handle<FixedArray> fields = factory->NewFixedArray(
    5739      394051 :       number_of_allocated_fields);
    5740             : 
    5741             :   // Fill in the instance descriptor and the fields.
    5742             :   int current_offset = 0;
    5743     3594245 :   for (int i = 0; i < instance_descriptor_length; i++) {
    5744             :     int index = Smi::cast(iteration_order->get(i))->value();
    5745             :     Object* k = dictionary->KeyAt(index);
    5746             :     DCHECK(dictionary->IsKey(isolate, k));
    5747             :     // Dictionary keys are internalized upon insertion.
    5748             :     // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild.
    5749     3200194 :     CHECK(k->IsUniqueName());
    5750             :     Handle<Name> key(Name::cast(k), isolate);
    5751             : 
    5752     3200194 :     Object* value = dictionary->ValueAt(index);
    5753             : 
    5754             :     PropertyDetails details = dictionary->DetailsAt(index);
    5755             :     DCHECK_EQ(kField, details.location());
    5756             :     DCHECK_EQ(kMutable, details.constness());
    5757             : 
    5758             :     Descriptor d;
    5759     3200194 :     if (details.kind() == kData) {
    5760     2747990 :       if (!FLAG_track_constant_fields && value->IsJSFunction()) {
    5761             :         d = Descriptor::DataConstant(key, handle(value, isolate),
    5762     1842964 :                                      details.attributes());
    5763             :       } else {
    5764             :         d = Descriptor::DataField(
    5765             :             key, current_offset, details.attributes(), kDefaultFieldConstness,
    5766             :             // TODO(verwaest): value->OptimalRepresentation();
    5767     1810052 :             Representation::Tagged(), FieldType::Any(isolate));
    5768             :       }
    5769             :     } else {
    5770             :       DCHECK_EQ(kAccessor, details.kind());
    5771             :       d = Descriptor::AccessorConstant(key, handle(value, isolate),
    5772      452204 :                                        details.attributes());
    5773             :     }
    5774             :     details = d.GetDetails();
    5775     3200194 :     if (details.location() == kField) {
    5776      905026 :       if (current_offset < inobject_props) {
    5777             :         object->InObjectPropertyAtPut(current_offset, value,
    5778      494032 :                                       UPDATE_WRITE_BARRIER);
    5779             :       } else {
    5780      410994 :         int offset = current_offset - inobject_props;
    5781      410994 :         fields->set(offset, value);
    5782             :       }
    5783      905026 :       current_offset += details.field_width_in_words();
    5784             :     }
    5785     3200194 :     descriptors->Set(i, &d);
    5786             :   }
    5787             :   DCHECK(current_offset == number_of_fields);
    5788             : 
    5789      394051 :   descriptors->Sort();
    5790             : 
    5791             :   Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New(
    5792      394051 :       new_map, descriptors, descriptors->number_of_descriptors());
    5793             : 
    5794             :   DisallowHeapAllocation no_gc;
    5795      394051 :   new_map->InitializeDescriptors(*descriptors, *layout_descriptor);
    5796             :   new_map->set_unused_property_fields(unused_property_fields);
    5797             : 
    5798             :   // Transform the object.
    5799      394051 :   object->synchronized_set_map(*new_map);
    5800             : 
    5801      394051 :   object->set_properties(*fields);
    5802             :   DCHECK(object->IsJSObject());
    5803             : 
    5804             :   // Check that it really works.
    5805             :   DCHECK(object->HasFastProperties());
    5806             : }
    5807             : 
    5808             : 
    5809        5432 : void JSObject::ResetElements(Handle<JSObject> object) {
    5810             :   Isolate* isolate = object->GetIsolate();
    5811        5432 :   CHECK(object->map() != isolate->heap()->sloppy_arguments_elements_map());
    5812        5432 :   if (object->map()->has_dictionary_elements()) {
    5813             :     Handle<SeededNumberDictionary> new_elements =
    5814        3444 :         SeededNumberDictionary::New(isolate, 0);
    5815        3444 :     object->set_elements(*new_elements);
    5816             :   } else {
    5817        3976 :     object->set_elements(object->map()->GetInitialElements());
    5818             :   }
    5819        5432 : }
    5820             : 
    5821             : 
    5822      126651 : void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) {
    5823      253302 :   if (dictionary->requires_slow_elements()) return;
    5824             :   dictionary->set_requires_slow_elements();
    5825       75500 :   if (map()->is_prototype_map()) {
    5826             :     // If this object is a prototype (the callee will check), invalidate any
    5827             :     // prototype chains involving it.
    5828             :     InvalidatePrototypeChains(map());
    5829             :   }
    5830             : }
    5831             : 
    5832             : 
    5833      466580 : Handle<SeededNumberDictionary> JSObject::NormalizeElements(
    5834             :     Handle<JSObject> object) {
    5835             :   DCHECK(!object->HasFixedTypedArrayElements());
    5836      458683 :   Isolate* isolate = object->GetIsolate();
    5837      466580 :   bool is_arguments = object->HasSloppyArgumentsElements();
    5838             :   {
    5839             :     DisallowHeapAllocation no_gc;
    5840             :     FixedArrayBase* elements = object->elements();
    5841             : 
    5842      466580 :     if (is_arguments) {
    5843             :       FixedArray* parameter_map = FixedArray::cast(elements);
    5844             :       elements = FixedArrayBase::cast(parameter_map->get(1));
    5845             :     }
    5846             : 
    5847      466580 :     if (elements->IsDictionary()) {
    5848             :       return handle(SeededNumberDictionary::cast(elements), isolate);
    5849             :     }
    5850             :   }
    5851             : 
    5852             :   DCHECK(object->HasFastSmiOrObjectElements() ||
    5853             :          object->HasFastDoubleElements() ||
    5854             :          object->HasFastArgumentsElements() ||
    5855             :          object->HasFastStringWrapperElements());
    5856             : 
    5857             :   Handle<SeededNumberDictionary> dictionary =
    5858      458683 :       object->GetElementsAccessor()->Normalize(object);
    5859             : 
    5860             :   // Switch to using the dictionary as the backing storage for elements.
    5861             :   ElementsKind target_kind = is_arguments
    5862             :                                  ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS
    5863      458151 :                                  : object->HasFastStringWrapperElements()
    5864             :                                        ? SLOW_STRING_WRAPPER_ELEMENTS
    5865      916834 :                                        : DICTIONARY_ELEMENTS;
    5866      458683 :   Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind);
    5867             :   // Set the new map first to satify the elements type assert in set_elements().
    5868      458683 :   JSObject::MigrateToMap(object, new_map);
    5869             : 
    5870      458683 :   if (is_arguments) {
    5871         532 :     FixedArray::cast(object->elements())->set(1, *dictionary);
    5872             :   } else {
    5873      458151 :     object->set_elements(*dictionary);
    5874             :   }
    5875             : 
    5876      458683 :   isolate->counters()->elements_to_dictionary()->Increment();
    5877             : 
    5878             : #ifdef DEBUG
    5879             :   if (FLAG_trace_normalization) {
    5880             :     OFStream os(stdout);
    5881             :     os << "Object elements have been normalized:\n";
    5882             :     object->Print(os);
    5883             :   }
    5884             : #endif
    5885             : 
    5886             :   DCHECK(object->HasDictionaryElements() ||
    5887             :          object->HasSlowArgumentsElements() ||
    5888             :          object->HasSlowStringWrapperElements());
    5889      458683 :   return dictionary;
    5890             : }
    5891             : 
    5892             : 
    5893             : template <typename ProxyType>
    5894        3181 : static Smi* GetOrCreateIdentityHashHelper(Isolate* isolate,
    5895             :                                           Handle<ProxyType> proxy) {
    5896             :   Object* maybe_hash = proxy->hash();
    5897        3181 :   if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash);
    5898             : 
    5899         687 :   Smi* hash = Smi::FromInt(isolate->GenerateIdentityHash(Smi::kMaxValue));
    5900         687 :   proxy->set_hash(hash);
    5901         687 :   return hash;
    5902             : }
    5903             : 
    5904             : // static
    5905       20925 : Object* JSObject::GetIdentityHash(Isolate* isolate, Handle<JSObject> object) {
    5906       20925 :   if (object->IsJSGlobalProxy()) {
    5907          82 :     return JSGlobalProxy::cast(*object)->hash();
    5908             :   }
    5909             :   Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol();
    5910       41686 :   return *JSReceiver::GetDataProperty(object, hash_code_symbol);
    5911             : }
    5912             : 
    5913             : // static
    5914        3952 : Smi* JSObject::GetOrCreateIdentityHash(Isolate* isolate,
    5915             :                                        Handle<JSObject> object) {
    5916        3952 :   if (object->IsJSGlobalProxy()) {
    5917             :     return GetOrCreateIdentityHashHelper(isolate,
    5918          87 :                                          Handle<JSGlobalProxy>::cast(object));
    5919             :   }
    5920             : 
    5921             :   Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol();
    5922        3865 :   LookupIterator it(object, hash_code_symbol, object, LookupIterator::OWN);
    5923        3865 :   if (it.IsFound()) {
    5924             :     DCHECK_EQ(LookupIterator::DATA, it.state());
    5925         962 :     Object* maybe_hash = *it.GetDataValue();
    5926         481 :     if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash);
    5927             :   }
    5928             : 
    5929        3384 :   Smi* hash = Smi::FromInt(isolate->GenerateIdentityHash(Smi::kMaxValue));
    5930        3384 :   CHECK(AddDataProperty(&it, handle(hash, isolate), NONE, THROW_ON_ERROR,
    5931             :                         CERTAINLY_NOT_STORE_FROM_KEYED)
    5932             :             .IsJust());
    5933             :   return hash;
    5934             : }
    5935             : 
    5936             : // static
    5937           0 : Object* JSProxy::GetIdentityHash(Handle<JSProxy> proxy) {
    5938           0 :   return proxy->hash();
    5939             : }
    5940             : 
    5941           0 : Smi* JSProxy::GetOrCreateIdentityHash(Isolate* isolate, Handle<JSProxy> proxy) {
    5942        3094 :   return GetOrCreateIdentityHashHelper(isolate, proxy);
    5943             : }
    5944             : 
    5945             : 
    5946         185 : Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
    5947             :                                                     ShouldThrow should_throw) {
    5948             :   Isolate* isolate = it->isolate();
    5949             :   // Make sure that the top context does not change when doing callbacks or
    5950             :   // interceptor calls.
    5951             :   AssertNoContextChange ncc(isolate);
    5952             : 
    5953             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    5954         117 :   Handle<InterceptorInfo> interceptor(it->GetInterceptor());
    5955         117 :   if (interceptor->deleter()->IsUndefined(isolate)) return Nothing<bool>();
    5956             : 
    5957             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    5958             :   Handle<Object> receiver = it->GetReceiver();
    5959          68 :   if (!receiver->IsJSReceiver()) {
    5960           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    5961             :                                      Object::ConvertReceiver(isolate, receiver),
    5962             :                                      Nothing<bool>());
    5963             :   }
    5964             : 
    5965             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    5966             :                                  *holder, should_throw);
    5967             :   Handle<Object> result;
    5968          68 :   if (it->IsElement()) {
    5969             :     uint32_t index = it->index();
    5970             :     v8::IndexedPropertyDeleterCallback deleter =
    5971             :         v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
    5972          27 :     result = args.Call(deleter, index);
    5973             :   } else {
    5974             :     DCHECK_IMPLIES(it->name()->IsSymbol(),
    5975             :                    interceptor->can_intercept_symbols());
    5976          41 :     Handle<Name> name = it->name();
    5977             :     DCHECK(!name->IsPrivate());
    5978             :     v8::GenericNamedPropertyDeleterCallback deleter =
    5979             :         v8::ToCData<v8::GenericNamedPropertyDeleterCallback>(
    5980             :             interceptor->deleter());
    5981          41 :     result = args.Call(deleter, name);
    5982             :   }
    5983             : 
    5984          68 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    5985          68 :   if (result.is_null()) return Nothing<bool>();
    5986             : 
    5987             :   DCHECK(result->IsBoolean());
    5988             :   // Rebox CustomArguments::kReturnValueOffset before returning.
    5989             :   return Just(result->IsTrue(isolate));
    5990             : }
    5991             : 
    5992             : 
    5993     6177375 : void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object,
    5994             :                                           Handle<Name> name, int entry) {
    5995             :   DCHECK(!object->HasFastProperties());
    5996             :   Isolate* isolate = object->GetIsolate();
    5997             : 
    5998     6177375 :   if (object->IsJSGlobalObject()) {
    5999             :     // If we have a global object, invalidate the cell and swap in a new one.
    6000             :     Handle<GlobalDictionary> dictionary(
    6001             :         JSObject::cast(*object)->global_dictionary());
    6002             :     DCHECK_NE(GlobalDictionary::kNotFound, entry);
    6003             : 
    6004       12243 :     auto cell = PropertyCell::InvalidateEntry(dictionary, entry);
    6005       24486 :     cell->set_value(isolate->heap()->the_hole_value());
    6006             :     cell->set_property_details(
    6007             :         PropertyDetails::Empty(PropertyCellType::kUninitialized));
    6008             :   } else {
    6009             :     Handle<NameDictionary> dictionary(object->property_dictionary());
    6010             :     DCHECK_NE(NameDictionary::kNotFound, entry);
    6011             : 
    6012     6165132 :     NameDictionary::DeleteProperty(dictionary, entry);
    6013             :     Handle<NameDictionary> new_properties =
    6014             :         NameDictionary::Shrink(dictionary, name);
    6015     6165132 :     object->set_properties(*new_properties);
    6016             :   }
    6017     6177375 : }
    6018             : 
    6019             : 
    6020    27147935 : Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it,
    6021             :                                        LanguageMode language_mode) {
    6022     9045871 :   it->UpdateProtector();
    6023             : 
    6024             :   Isolate* isolate = it->isolate();
    6025             : 
    6026     9045871 :   if (it->state() == LookupIterator::JSPROXY) {
    6027             :     return JSProxy::DeletePropertyOrElement(it->GetHolder<JSProxy>(),
    6028        4817 :                                             it->GetName(), language_mode);
    6029             :   }
    6030             : 
    6031     9041054 :   if (it->GetReceiver()->IsJSProxy()) {
    6032          56 :     if (it->state() != LookupIterator::NOT_FOUND) {
    6033             :       DCHECK_EQ(LookupIterator::DATA, it->state());
    6034             :       DCHECK(it->name()->IsPrivate());
    6035           7 :       it->Delete();
    6036             :     }
    6037             :     return Just(true);
    6038             :   }
    6039             :   Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
    6040             : 
    6041    18112274 :   for (; it->IsFound(); it->Next()) {
    6042     6360279 :     switch (it->state()) {
    6043             :       case LookupIterator::JSPROXY:
    6044             :       case LookupIterator::NOT_FOUND:
    6045             :       case LookupIterator::TRANSITION:
    6046           0 :         UNREACHABLE();
    6047             :       case LookupIterator::ACCESS_CHECK:
    6048       15093 :         if (it->HasAccess()) break;
    6049          43 :         isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    6050          43 :         RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    6051             :         return Just(false);
    6052             :       case LookupIterator::INTERCEPTOR: {
    6053             :         ShouldThrow should_throw =
    6054         117 :             is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    6055             :         Maybe<bool> result =
    6056         117 :             JSObject::DeletePropertyWithInterceptor(it, should_throw);
    6057             :         // An exception was thrown in the interceptor. Propagate.
    6058         145 :         if (isolate->has_pending_exception()) return Nothing<bool>();
    6059             :         // Delete with interceptor succeeded. Return result.
    6060             :         // TODO(neis): In strict mode, we should probably throw if the
    6061             :         // interceptor returns false.
    6062         117 :         if (result.IsJust()) return result;
    6063          89 :         break;
    6064             :       }
    6065             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    6066             :         return Just(true);
    6067             :       case LookupIterator::DATA:
    6068             :       case LookupIterator::ACCESSOR: {
    6069     6344999 :         if (!it->IsConfigurable()) {
    6070             :           // Fail if the property is not configurable.
    6071        3502 :           if (is_strict(language_mode)) {
    6072             :             isolate->Throw(*isolate->factory()->NewTypeError(
    6073             :                 MessageTemplate::kStrictDeleteProperty, it->GetName(),
    6074        2517 :                 receiver));
    6075             :             return Nothing<bool>();
    6076             :           }
    6077             :           return Just(false);
    6078             :         }
    6079             : 
    6080     6341497 :         it->Delete();
    6081             : 
    6082             :         return Just(true);
    6083             :       }
    6084             :     }
    6085             :   }
    6086             : 
    6087             :   return Just(true);
    6088             : }
    6089             : 
    6090             : 
    6091          12 : Maybe<bool> JSReceiver::DeleteElement(Handle<JSReceiver> object, uint32_t index,
    6092             :                                       LanguageMode language_mode) {
    6093             :   LookupIterator it(object->GetIsolate(), object, index, object,
    6094             :                     LookupIterator::OWN);
    6095          12 :   return DeleteProperty(&it, language_mode);
    6096             : }
    6097             : 
    6098             : 
    6099         468 : Maybe<bool> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
    6100             :                                        Handle<Name> name,
    6101             :                                        LanguageMode language_mode) {
    6102         468 :   LookupIterator it(object, name, object, LookupIterator::OWN);
    6103         468 :   return DeleteProperty(&it, language_mode);
    6104             : }
    6105             : 
    6106             : 
    6107        5843 : Maybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object,
    6108             :                                                 Handle<Name> name,
    6109             :                                                 LanguageMode language_mode) {
    6110             :   LookupIterator it = LookupIterator::PropertyOrElement(
    6111        5843 :       name->GetIsolate(), object, name, object, LookupIterator::OWN);
    6112        5843 :   return DeleteProperty(&it, language_mode);
    6113             : }
    6114             : 
    6115             : // ES6 19.1.2.4
    6116             : // static
    6117      285954 : Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object,
    6118             :                                    Handle<Object> key,
    6119             :                                    Handle<Object> attributes) {
    6120             :   // 1. If Type(O) is not Object, throw a TypeError exception.
    6121      285954 :   if (!object->IsJSReceiver()) {
    6122             :     Handle<String> fun_name =
    6123         102 :         isolate->factory()->InternalizeUtf8String("Object.defineProperty");
    6124         204 :     THROW_NEW_ERROR_RETURN_FAILURE(
    6125             :         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name));
    6126             :   }
    6127             :   // 2. Let key be ToPropertyKey(P).
    6128             :   // 3. ReturnIfAbrupt(key).
    6129      571704 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, ToPropertyKey(isolate, key));
    6130             :   // 4. Let desc be ToPropertyDescriptor(Attributes).
    6131             :   // 5. ReturnIfAbrupt(desc).
    6132             :   PropertyDescriptor desc;
    6133      285852 :   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
    6134         215 :     return isolate->heap()->exception();
    6135             :   }
    6136             :   // 6. Let success be DefinePropertyOrThrow(O,key, desc).
    6137             :   Maybe<bool> success = DefineOwnProperty(
    6138      285637 :       isolate, Handle<JSReceiver>::cast(object), key, &desc, THROW_ON_ERROR);
    6139             :   // 7. ReturnIfAbrupt(success).
    6140      285637 :   MAYBE_RETURN(success, isolate->heap()->exception());
    6141      283962 :   CHECK(success.FromJust());
    6142             :   // 8. Return O.
    6143      283962 :   return *object;
    6144             : }
    6145             : 
    6146             : 
    6147             : // ES6 19.1.2.3.1
    6148             : // static
    6149       19975 : MaybeHandle<Object> JSReceiver::DefineProperties(Isolate* isolate,
    6150             :                                                  Handle<Object> object,
    6151             :                                                  Handle<Object> properties) {
    6152             :   // 1. If Type(O) is not Object, throw a TypeError exception.
    6153       19975 :   if (!object->IsJSReceiver()) {
    6154             :     Handle<String> fun_name =
    6155          43 :         isolate->factory()->InternalizeUtf8String("Object.defineProperties");
    6156          86 :     THROW_NEW_ERROR(isolate,
    6157             :                     NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name),
    6158             :                     Object);
    6159             :   }
    6160             :   // 2. Let props be ToObject(Properties).
    6161             :   // 3. ReturnIfAbrupt(props).
    6162             :   Handle<JSReceiver> props;
    6163       39864 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, props,
    6164             :                              Object::ToObject(isolate, properties), Object);
    6165             : 
    6166             :   // 4. Let keys be props.[[OwnPropertyKeys]]().
    6167             :   // 5. ReturnIfAbrupt(keys).
    6168             :   Handle<FixedArray> keys;
    6169       39834 :   ASSIGN_RETURN_ON_EXCEPTION(
    6170             :       isolate, keys, KeyAccumulator::GetKeys(props, KeyCollectionMode::kOwnOnly,
    6171             :                                              ALL_PROPERTIES),
    6172             :       Object);
    6173             :   // 6. Let descriptors be an empty List.
    6174             :   int capacity = keys->length();
    6175       19917 :   std::vector<PropertyDescriptor> descriptors(capacity);
    6176             :   size_t descriptors_index = 0;
    6177             :   // 7. Repeat for each element nextKey of keys in List order,
    6178      379204 :   for (int i = 0; i < keys->length(); ++i) {
    6179             :     Handle<Object> next_key(keys->get(i), isolate);
    6180             :     // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey).
    6181             :     // 7b. ReturnIfAbrupt(propDesc).
    6182      170044 :     bool success = false;
    6183             :     LookupIterator it = LookupIterator::PropertyOrElement(
    6184      170044 :         isolate, props, next_key, &success, LookupIterator::OWN);
    6185             :     DCHECK(success);
    6186      170044 :     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
    6187      170403 :     if (!maybe.IsJust()) return MaybeHandle<Object>();
    6188             :     PropertyAttributes attrs = maybe.FromJust();
    6189             :     // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true:
    6190      171765 :     if (attrs == ABSENT) continue;
    6191      170044 :     if (attrs & DONT_ENUM) continue;
    6192             :     // 7c i. Let descObj be Get(props, nextKey).
    6193             :     // 7c ii. ReturnIfAbrupt(descObj).
    6194             :     Handle<Object> desc_obj;
    6195      336646 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, desc_obj, Object::GetProperty(&it),
    6196             :                                Object);
    6197             :     // 7c iii. Let desc be ToPropertyDescriptor(descObj).
    6198             :     success = PropertyDescriptor::ToPropertyDescriptor(
    6199      336646 :         isolate, desc_obj, &descriptors[descriptors_index]);
    6200             :     // 7c iv. ReturnIfAbrupt(desc).
    6201      168323 :     if (!success) return MaybeHandle<Object>();
    6202             :     // 7c v. Append the pair (a two element List) consisting of nextKey and
    6203             :     //       desc to the end of descriptors.
    6204      167964 :     descriptors[descriptors_index].set_name(next_key);
    6205      167964 :     descriptors_index++;
    6206             :   }
    6207             :   // 8. For each pair from descriptors in list order,
    6208      167290 :   for (size_t i = 0; i < descriptors_index; ++i) {
    6209      167290 :     PropertyDescriptor* desc = &descriptors[i];
    6210             :     // 8a. Let P be the first element of pair.
    6211             :     // 8b. Let desc be the second element of pair.
    6212             :     // 8c. Let status be DefinePropertyOrThrow(O, P, desc).
    6213             :     Maybe<bool> status =
    6214             :         DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object),
    6215      167290 :                           desc->name(), desc, THROW_ON_ERROR);
    6216             :     // 8d. ReturnIfAbrupt(status).
    6217      167290 :     if (!status.IsJust()) return MaybeHandle<Object>();
    6218      167290 :     CHECK(status.FromJust());
    6219             :   }
    6220             :   // 9. Return o.
    6221             :   return object;
    6222             : }
    6223             : 
    6224             : 
    6225             : // static
    6226      647894 : Maybe<bool> JSReceiver::DefineOwnProperty(Isolate* isolate,
    6227             :                                           Handle<JSReceiver> object,
    6228             :                                           Handle<Object> key,
    6229             :                                           PropertyDescriptor* desc,
    6230             :                                           ShouldThrow should_throw) {
    6231      647894 :   if (object->IsJSArray()) {
    6232             :     return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object),
    6233       80669 :                                       key, desc, should_throw);
    6234             :   }
    6235      567225 :   if (object->IsJSProxy()) {
    6236             :     return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object),
    6237        5822 :                                       key, desc, should_throw);
    6238             :   }
    6239      561403 :   if (object->IsJSTypedArray()) {
    6240             :     return JSTypedArray::DefineOwnProperty(
    6241        4786 :         isolate, Handle<JSTypedArray>::cast(object), key, desc, should_throw);
    6242             :   }
    6243             :   // TODO(neis): Special case for JSModuleNamespace?
    6244             : 
    6245             :   // OrdinaryDefineOwnProperty, by virtue of calling
    6246             :   // DefineOwnPropertyIgnoreAttributes, can handle arguments
    6247             :   // (ES#sec-arguments-exotic-objects-defineownproperty-p-desc).
    6248             :   return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key,
    6249      556617 :                                    desc, should_throw);
    6250             : }
    6251             : 
    6252             : 
    6253             : // static
    6254      662258 : Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate,
    6255             :                                                   Handle<JSObject> object,
    6256             :                                                   Handle<Object> key,
    6257             :                                                   PropertyDescriptor* desc,
    6258             :                                                   ShouldThrow should_throw) {
    6259      662258 :   bool success = false;
    6260             :   DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey...
    6261             :   LookupIterator it = LookupIterator::PropertyOrElement(
    6262      662258 :       isolate, object, key, &success, LookupIterator::OWN);
    6263             :   DCHECK(success);  // ...so creating a LookupIterator can't fail.
    6264             : 
    6265             :   // Deal with access checks first.
    6266      662258 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    6267        3716 :     if (!it.HasAccess()) {
    6268          36 :       isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
    6269          36 :       RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    6270             :       return Just(true);
    6271             :     }
    6272        3680 :     it.Next();
    6273             :   }
    6274             : 
    6275             :   // Handle interceptor
    6276      662222 :   if (it.state() == LookupIterator::INTERCEPTOR) {
    6277         208 :     if (it.HolderIsReceiverOrHiddenPrototype()) {
    6278             :       Maybe<bool> result = DefinePropertyWithInterceptorInternal(
    6279         208 :           &it, it.GetInterceptor(), should_throw, *desc);
    6280         416 :       if (result.IsNothing() || result.FromJust()) {
    6281          63 :         return result;
    6282             :       }
    6283             :     }
    6284             :   }
    6285             : 
    6286      662159 :   return OrdinaryDefineOwnProperty(&it, desc, should_throw);
    6287             : }
    6288             : 
    6289             : 
    6290             : // ES6 9.1.6.1
    6291             : // static
    6292      662159 : Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it,
    6293             :                                                   PropertyDescriptor* desc,
    6294             :                                                   ShouldThrow should_throw) {
    6295             :   Isolate* isolate = it->isolate();
    6296             :   // 1. Let current be O.[[GetOwnProperty]](P).
    6297             :   // 2. ReturnIfAbrupt(current).
    6298             :   PropertyDescriptor current;
    6299      662159 :   MAYBE_RETURN(GetOwnPropertyDescriptor(it, &current), Nothing<bool>());
    6300             : 
    6301             :   // TODO(jkummerow/verwaest): It would be nice if we didn't have to reset
    6302             :   // the iterator every time. Currently, the reasons why we need it are:
    6303             :   // - handle interceptors correctly
    6304             :   // - handle accessors correctly (which might change the holder's map)
    6305      662159 :   it->Restart();
    6306             :   // 3. Let extensible be the value of the [[Extensible]] internal slot of O.
    6307      662159 :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    6308      662159 :   bool extensible = JSObject::IsExtensible(object);
    6309             : 
    6310             :   return ValidateAndApplyPropertyDescriptor(isolate, it, extensible, desc,
    6311      662159 :                                             &current, should_throw);
    6312             : }
    6313             : 
    6314             : 
    6315             : // ES6 9.1.6.2
    6316             : // static
    6317           0 : Maybe<bool> JSReceiver::IsCompatiblePropertyDescriptor(
    6318             :     Isolate* isolate, bool extensible, PropertyDescriptor* desc,
    6319             :     PropertyDescriptor* current, Handle<Name> property_name,
    6320             :     ShouldThrow should_throw) {
    6321             :   // 1. Return ValidateAndApplyPropertyDescriptor(undefined, undefined,
    6322             :   //    Extensible, Desc, Current).
    6323             :   return ValidateAndApplyPropertyDescriptor(
    6324        6987 :       isolate, NULL, extensible, desc, current, should_throw, property_name);
    6325             : }
    6326             : 
    6327             : 
    6328             : // ES6 9.1.6.3
    6329             : // static
    6330      669146 : Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
    6331             :     Isolate* isolate, LookupIterator* it, bool extensible,
    6332             :     PropertyDescriptor* desc, PropertyDescriptor* current,
    6333             :     ShouldThrow should_throw, Handle<Name> property_name) {
    6334             :   // We either need a LookupIterator, or a property name.
    6335             :   DCHECK((it == NULL) != property_name.is_null());
    6336             :   Handle<JSObject> object;
    6337             :   if (it != NULL) object = Handle<JSObject>::cast(it->GetReceiver());
    6338             :   bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc);
    6339             :   bool desc_is_accessor_descriptor =
    6340             :       PropertyDescriptor::IsAccessorDescriptor(desc);
    6341             :   bool desc_is_generic_descriptor =
    6342             :       PropertyDescriptor::IsGenericDescriptor(desc);
    6343             :   // 1. (Assert)
    6344             :   // 2. If current is undefined, then
    6345      669146 :   if (current->is_empty()) {
    6346             :     // 2a. If extensible is false, return false.
    6347      522769 :     if (!extensible) {
    6348         667 :       RETURN_FAILURE(isolate, should_throw,
    6349             :                      NewTypeError(MessageTemplate::kDefineDisallowed,
    6350             :                                   it != NULL ? it->GetName() : property_name));
    6351             :     }
    6352             :     // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then:
    6353             :     // (This is equivalent to !IsAccessorDescriptor(desc).)
    6354             :     DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) ==
    6355             :            !desc_is_accessor_descriptor);
    6356      522549 :     if (!desc_is_accessor_descriptor) {
    6357             :       // 2c i. If O is not undefined, create an own data property named P of
    6358             :       // object O whose [[Value]], [[Writable]], [[Enumerable]] and
    6359             :       // [[Configurable]] attribute values are described by Desc. If the value
    6360             :       // of an attribute field of Desc is absent, the attribute of the newly
    6361             :       // created property is set to its default value.
    6362      420612 :       if (it != NULL) {
    6363      416720 :         if (!desc->has_writable()) desc->set_writable(false);
    6364      416720 :         if (!desc->has_enumerable()) desc->set_enumerable(false);
    6365      416720 :         if (!desc->has_configurable()) desc->set_configurable(false);
    6366             :         Handle<Object> value(
    6367             :             desc->has_value()
    6368             :                 ? desc->value()
    6369      416720 :                 : Handle<Object>::cast(isolate->factory()->undefined_value()));
    6370             :         MaybeHandle<Object> result =
    6371             :             JSObject::DefineOwnPropertyIgnoreAttributes(it, value,
    6372      416720 :                                                         desc->ToAttributes());
    6373      416720 :         if (result.is_null()) return Nothing<bool>();
    6374             :       }
    6375             :     } else {
    6376             :       // 2d. Else Desc must be an accessor Property Descriptor,
    6377             :       DCHECK(desc_is_accessor_descriptor);
    6378             :       // 2d i. If O is not undefined, create an own accessor property named P
    6379             :       // of object O whose [[Get]], [[Set]], [[Enumerable]] and
    6380             :       // [[Configurable]] attribute values are described by Desc. If the value
    6381             :       // of an attribute field of Desc is absent, the attribute of the newly
    6382             :       // created property is set to its default value.
    6383      101937 :       if (it != NULL) {
    6384      101713 :         if (!desc->has_enumerable()) desc->set_enumerable(false);
    6385      101713 :         if (!desc->has_configurable()) desc->set_configurable(false);
    6386             :         Handle<Object> getter(
    6387             :             desc->has_get()
    6388             :                 ? desc->get()
    6389      120469 :                 : Handle<Object>::cast(isolate->factory()->null_value()));
    6390             :         Handle<Object> setter(
    6391             :             desc->has_set()
    6392             :                 ? desc->set()
    6393      165985 :                 : Handle<Object>::cast(isolate->factory()->null_value()));
    6394             :         MaybeHandle<Object> result =
    6395      101713 :             JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes());
    6396      101713 :         if (result.is_null()) return Nothing<bool>();
    6397             :       }
    6398             :     }
    6399             :     // 2e. Return true.
    6400             :     return Just(true);
    6401             :   }
    6402             :   // 3. Return true, if every field in Desc is absent.
    6403             :   // 4. Return true, if every field in Desc also occurs in current and the
    6404             :   // value of every field in Desc is the same value as the corresponding field
    6405             :   // in current when compared using the SameValue algorithm.
    6406      209179 :   if ((!desc->has_enumerable() ||
    6407      144914 :        desc->enumerable() == current->enumerable()) &&
    6408       90228 :       (!desc->has_configurable() ||
    6409      141164 :        desc->configurable() == current->configurable()) &&
    6410      114821 :       (!desc->has_value() ||
    6411      216819 :        (current->has_value() && current->value()->SameValue(*desc->value()))) &&
    6412       77568 :       (!desc->has_writable() ||
    6413      160725 :        (current->has_writable() && current->writable() == desc->writable())) &&
    6414        8350 :       (!desc->has_get() ||
    6415      227636 :        (current->has_get() && current->get()->SameValue(*desc->get()))) &&
    6416       11182 :       (!desc->has_set() ||
    6417       10889 :        (current->has_set() && current->set()->SameValue(*desc->set())))) {
    6418             :     return Just(true);
    6419             :   }
    6420             :   // 5. If the [[Configurable]] field of current is false, then
    6421       82274 :   if (!current->configurable()) {
    6422             :     // 5a. Return false, if the [[Configurable]] field of Desc is true.
    6423       28431 :     if (desc->has_configurable() && desc->configurable()) {
    6424         809 :       RETURN_FAILURE(isolate, should_throw,
    6425             :                      NewTypeError(MessageTemplate::kRedefineDisallowed,
    6426             :                                   it != NULL ? it->GetName() : property_name));
    6427             :     }
    6428             :     // 5b. Return false, if the [[Enumerable]] field of Desc is present and the
    6429             :     // [[Enumerable]] fields of current and Desc are the Boolean negation of
    6430             :     // each other.
    6431       27434 :     if (desc->has_enumerable() && desc->enumerable() != current->enumerable()) {
    6432         452 :       RETURN_FAILURE(isolate, should_throw,
    6433             :                      NewTypeError(MessageTemplate::kRedefineDisallowed,
    6434             :                                   it != NULL ? it->GetName() : property_name));
    6435             :     }
    6436             :   }
    6437             : 
    6438             :   bool current_is_data_descriptor =
    6439             :       PropertyDescriptor::IsDataDescriptor(current);
    6440             :   // 6. If IsGenericDescriptor(Desc) is true, no further validation is required.
    6441       81796 :   if (desc_is_generic_descriptor) {
    6442             :     // Nothing to see here.
    6443             : 
    6444             :     // 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) have
    6445             :     // different results, then:
    6446       80377 :   } else if (current_is_data_descriptor != desc_is_data_descriptor) {
    6447             :     // 7a. Return false, if the [[Configurable]] field of current is false.
    6448        3678 :     if (!current->configurable()) {
    6449         671 :       RETURN_FAILURE(isolate, should_throw,
    6450             :                      NewTypeError(MessageTemplate::kRedefineDisallowed,
    6451             :                                   it != NULL ? it->GetName() : property_name));
    6452             :     }
    6453             :     // 7b. If IsDataDescriptor(current) is true, then:
    6454             :     if (current_is_data_descriptor) {
    6455             :       // 7b i. If O is not undefined, convert the property named P of object O
    6456             :       // from a data property to an accessor property. Preserve the existing
    6457             :       // values of the converted property's [[Configurable]] and [[Enumerable]]
    6458             :       // attributes and set the rest of the property's attributes to their
    6459             :       // default values.
    6460             :       // --> Folded into step 10.
    6461             :     } else {
    6462             :       // 7c i. If O is not undefined, convert the property named P of object O
    6463             :       // from an accessor property to a data property. Preserve the existing
    6464             :       // values of the converted property’s [[Configurable]] and [[Enumerable]]
    6465             :       // attributes and set the rest of the property’s attributes to their
    6466             :       // default values.
    6467             :       // --> Folded into step 10.
    6468             :     }
    6469             : 
    6470             :     // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both
    6471             :     // true, then:
    6472       76699 :   } else if (current_is_data_descriptor && desc_is_data_descriptor) {
    6473             :     // 8a. If the [[Configurable]] field of current is false, then:
    6474       59633 :     if (!current->configurable()) {
    6475             :       // 8a i. Return false, if the [[Writable]] field of current is false and
    6476             :       // the [[Writable]] field of Desc is true.
    6477       23582 :       if (!current->writable() && desc->has_writable() && desc->writable()) {
    6478         298 :         RETURN_FAILURE(
    6479             :             isolate, should_throw,
    6480             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    6481             :                          it != NULL ? it->GetName() : property_name));
    6482             :       }
    6483             :       // 8a ii. If the [[Writable]] field of current is false, then:
    6484       22941 :       if (!current->writable()) {
    6485             :         // 8a ii 1. Return false, if the [[Value]] field of Desc is present and
    6486             :         // SameValue(Desc.[[Value]], current.[[Value]]) is false.
    6487         714 :         if (desc->has_value() && !desc->value()->SameValue(*current->value())) {
    6488        1224 :           RETURN_FAILURE(
    6489             :               isolate, should_throw,
    6490             :               NewTypeError(MessageTemplate::kRedefineDisallowed,
    6491             :                            it != NULL ? it->GetName() : property_name));
    6492             :         }
    6493             :       }
    6494             :     }
    6495             :   } else {
    6496             :     // 9. Else IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc)
    6497             :     // are both true,
    6498             :     DCHECK(PropertyDescriptor::IsAccessorDescriptor(current) &&
    6499             :            desc_is_accessor_descriptor);
    6500             :     // 9a. If the [[Configurable]] field of current is false, then:
    6501       17066 :     if (!current->configurable()) {
    6502             :       // 9a i. Return false, if the [[Set]] field of Desc is present and
    6503             :       // SameValue(Desc.[[Set]], current.[[Set]]) is false.
    6504         220 :       if (desc->has_set() && !desc->set()->SameValue(*current->set())) {
    6505         186 :         RETURN_FAILURE(
    6506             :             isolate, should_throw,
    6507             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    6508             :                          it != NULL ? it->GetName() : property_name));
    6509             :       }
    6510             :       // 9a ii. Return false, if the [[Get]] field of Desc is present and
    6511             :       // SameValue(Desc.[[Get]], current.[[Get]]) is false.
    6512         154 :       if (desc->has_get() && !desc->get()->SameValue(*current->get())) {
    6513         248 :         RETURN_FAILURE(
    6514             :             isolate, should_throw,
    6515             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    6516             :                          it != NULL ? it->GetName() : property_name));
    6517             :       }
    6518             :     }
    6519             :   }
    6520             : 
    6521             :   // 10. If O is not undefined, then:
    6522       81020 :   if (it != NULL) {
    6523             :     // 10a. For each field of Desc that is present, set the corresponding
    6524             :     // attribute of the property named P of object O to the value of the field.
    6525             :     PropertyAttributes attrs = NONE;
    6526             : 
    6527       80656 :     if (desc->has_enumerable()) {
    6528             :       attrs = static_cast<PropertyAttributes>(
    6529        8755 :           attrs | (desc->enumerable() ? NONE : DONT_ENUM));
    6530             :     } else {
    6531             :       attrs = static_cast<PropertyAttributes>(
    6532       71901 :           attrs | (current->enumerable() ? NONE : DONT_ENUM));
    6533             :     }
    6534       80656 :     if (desc->has_configurable()) {
    6535             :       attrs = static_cast<PropertyAttributes>(
    6536       27238 :           attrs | (desc->configurable() ? NONE : DONT_DELETE));
    6537             :     } else {
    6538             :       attrs = static_cast<PropertyAttributes>(
    6539       53418 :           attrs | (current->configurable() ? NONE : DONT_DELETE));
    6540             :     }
    6541      101809 :     if (desc_is_data_descriptor ||
    6542       21153 :         (desc_is_generic_descriptor && current_is_data_descriptor)) {
    6543       60762 :       if (desc->has_writable()) {
    6544             :         attrs = static_cast<PropertyAttributes>(
    6545       56382 :             attrs | (desc->writable() ? NONE : READ_ONLY));
    6546             :       } else {
    6547             :         attrs = static_cast<PropertyAttributes>(
    6548        4380 :             attrs | (current->writable() ? NONE : READ_ONLY));
    6549             :       }
    6550             :       Handle<Object> value(
    6551             :           desc->has_value() ? desc->value()
    6552             :                             : current->has_value()
    6553             :                                   ? current->value()
    6554             :                                   : Handle<Object>::cast(
    6555       64925 :                                         isolate->factory()->undefined_value()));
    6556             :       MaybeHandle<Object> result =
    6557             :           JSObject::DefineOwnPropertyIgnoreAttributes(it, value, attrs);
    6558       60762 :       if (result.is_null()) return Nothing<bool>();
    6559             :     } else {
    6560             :       DCHECK(desc_is_accessor_descriptor ||
    6561             :              (desc_is_generic_descriptor &&
    6562             :               PropertyDescriptor::IsAccessorDescriptor(current)));
    6563             :       Handle<Object> getter(
    6564             :           desc->has_get()
    6565             :               ? desc->get()
    6566             :               : current->has_get()
    6567             :                     ? current->get()
    6568       31570 :                     : Handle<Object>::cast(isolate->factory()->null_value()));
    6569             :       Handle<Object> setter(
    6570             :           desc->has_set()
    6571             :               ? desc->set()
    6572             :               : current->has_set()
    6573             :                     ? current->set()
    6574       29738 :                     : Handle<Object>::cast(isolate->factory()->null_value()));
    6575             :       MaybeHandle<Object> result =
    6576       19894 :           JSObject::DefineAccessor(it, getter, setter, attrs);
    6577       19894 :       if (result.is_null()) return Nothing<bool>();
    6578             :     }
    6579             :   }
    6580             : 
    6581             :   // 11. Return true.
    6582             :   return Just(true);
    6583             : }
    6584             : 
    6585             : 
    6586             : // static
    6587      371016 : Maybe<bool> JSReceiver::CreateDataProperty(LookupIterator* it,
    6588             :                                            Handle<Object> value,
    6589             :                                            ShouldThrow should_throw) {
    6590             :   DCHECK(!it->check_prototype_chain());
    6591             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    6592             :   Isolate* isolate = receiver->GetIsolate();
    6593             : 
    6594      371016 :   if (receiver->IsJSObject()) {
    6595      369929 :     return JSObject::CreateDataProperty(it, value, should_throw);  // Shortcut.
    6596             :   }
    6597             : 
    6598             :   PropertyDescriptor new_desc;
    6599             :   new_desc.set_value(value);
    6600             :   new_desc.set_writable(true);
    6601             :   new_desc.set_enumerable(true);
    6602             :   new_desc.set_configurable(true);
    6603             : 
    6604             :   return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
    6605        2174 :                                        &new_desc, should_throw);
    6606             : }
    6607             : 
    6608      746712 : Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
    6609             :                                          Handle<Object> value,
    6610             :                                          ShouldThrow should_throw) {
    6611             :   DCHECK(it->GetReceiver()->IsJSObject());
    6612      373359 :   MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
    6613             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    6614             :   Isolate* isolate = receiver->GetIsolate();
    6615             : 
    6616      373353 :   if (it->IsFound()) {
    6617      200496 :     Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
    6618      200551 :     MAYBE_RETURN(attributes, Nothing<bool>());
    6619      200496 :     if ((attributes.FromJust() & DONT_DELETE) != 0) {
    6620         184 :       RETURN_FAILURE(
    6621             :           isolate, should_throw,
    6622             :           NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
    6623             :     }
    6624             :   } else {
    6625      172857 :     if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) {
    6626         350 :       RETURN_FAILURE(
    6627             :           isolate, should_throw,
    6628             :           NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
    6629             :     }
    6630             :   }
    6631             : 
    6632      373206 :   RETURN_ON_EXCEPTION_VALUE(it->isolate(),
    6633             :                             DefineOwnPropertyIgnoreAttributes(it, value, NONE),
    6634             :                             Nothing<bool>());
    6635             : 
    6636             :   return Just(true);
    6637             : }
    6638             : 
    6639             : 
    6640             : // TODO(jkummerow): Consider unification with FastAsArrayLength() in
    6641             : // accessors.cc.
    6642       62431 : bool PropertyKeyToArrayLength(Handle<Object> value, uint32_t* length) {
    6643             :   DCHECK(value->IsNumber() || value->IsName());
    6644       62431 :   if (value->ToArrayLength(length)) return true;
    6645       83510 :   if (value->IsString()) return String::cast(*value)->AsArrayIndex(length);
    6646             :   return false;
    6647             : }
    6648             : 
    6649           0 : bool PropertyKeyToArrayIndex(Handle<Object> index_obj, uint32_t* output) {
    6650       62431 :   return PropertyKeyToArrayLength(index_obj, output) && *output != kMaxUInt32;
    6651             : }
    6652             : 
    6653             : 
    6654             : // ES6 9.4.2.1
    6655             : // static
    6656       80669 : Maybe<bool> JSArray::DefineOwnProperty(Isolate* isolate, Handle<JSArray> o,
    6657             :                                        Handle<Object> name,
    6658             :                                        PropertyDescriptor* desc,
    6659             :                                        ShouldThrow should_throw) {
    6660             :   // 1. Assert: IsPropertyKey(P) is true. ("P" is |name|.)
    6661             :   // 2. If P is "length", then:
    6662             :   // TODO(jkummerow): Check if we need slow string comparison.
    6663       80669 :   if (*name == isolate->heap()->length_string()) {
    6664             :     // 2a. Return ArraySetLength(A, Desc).
    6665       18238 :     return ArraySetLength(isolate, o, desc, should_throw);
    6666             :   }
    6667             :   // 3. Else if P is an array index, then:
    6668       62431 :   uint32_t index = 0;
    6669       62431 :   if (PropertyKeyToArrayIndex(name, &index)) {
    6670             :     // 3a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    6671             :     PropertyDescriptor old_len_desc;
    6672             :     Maybe<bool> success = GetOwnPropertyDescriptor(
    6673       59292 :         isolate, o, isolate->factory()->length_string(), &old_len_desc);
    6674             :     // 3b. (Assert)
    6675             :     DCHECK(success.FromJust());
    6676             :     USE(success);
    6677             :     // 3c. Let oldLen be oldLenDesc.[[Value]].
    6678       59292 :     uint32_t old_len = 0;
    6679       59292 :     CHECK(old_len_desc.value()->ToArrayLength(&old_len));
    6680             :     // 3d. Let index be ToUint32(P).
    6681             :     // (Already done above.)
    6682             :     // 3e. (Assert)
    6683             :     // 3f. If index >= oldLen and oldLenDesc.[[Writable]] is false,
    6684             :     //     return false.
    6685      100272 :     if (index >= old_len && old_len_desc.has_writable() &&
    6686             :         !old_len_desc.writable()) {
    6687           0 :       RETURN_FAILURE(isolate, should_throw,
    6688             :                      NewTypeError(MessageTemplate::kDefineDisallowed, name));
    6689             :     }
    6690             :     // 3g. Let succeeded be OrdinaryDefineOwnProperty(A, P, Desc).
    6691             :     Maybe<bool> succeeded =
    6692       59292 :         OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
    6693             :     // 3h. Assert: succeeded is not an abrupt completion.
    6694             :     //     In our case, if should_throw == THROW_ON_ERROR, it can be!
    6695             :     // 3i. If succeeded is false, return false.
    6696      118457 :     if (succeeded.IsNothing() || !succeeded.FromJust()) return succeeded;
    6697             :     // 3j. If index >= oldLen, then:
    6698       59151 :     if (index >= old_len) {
    6699             :       // 3j i. Set oldLenDesc.[[Value]] to index + 1.
    6700       20490 :       old_len_desc.set_value(isolate->factory()->NewNumberFromUint(index + 1));
    6701             :       // 3j ii. Let succeeded be
    6702             :       //        OrdinaryDefineOwnProperty(A, "length", oldLenDesc).
    6703             :       succeeded = OrdinaryDefineOwnProperty(isolate, o,
    6704             :                                             isolate->factory()->length_string(),
    6705       20490 :                                             &old_len_desc, should_throw);
    6706             :       // 3j iii. Assert: succeeded is true.
    6707             :       DCHECK(succeeded.FromJust());
    6708             :       USE(succeeded);
    6709             :     }
    6710             :     // 3k. Return true.
    6711             :     return Just(true);
    6712             :   }
    6713             : 
    6714             :   // 4. Return OrdinaryDefineOwnProperty(A, P, Desc).
    6715        3139 :   return OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
    6716             : }
    6717             : 
    6718             : 
    6719             : // Part of ES6 9.4.2.4 ArraySetLength.
    6720             : // static
    6721     1021233 : bool JSArray::AnythingToArrayLength(Isolate* isolate,
    6722             :                                     Handle<Object> length_object,
    6723             :                                     uint32_t* output) {
    6724             :   // Fast path: check numbers and strings that can be converted directly
    6725             :   // and unobservably.
    6726     1021233 :   if (length_object->ToArrayLength(output)) return true;
    6727      533158 :   if (length_object->IsString() &&
    6728          30 :       Handle<String>::cast(length_object)->AsArrayIndex(output)) {
    6729             :     return true;
    6730             :   }
    6731             :   // Slow path: follow steps in ES6 9.4.2.4 "ArraySetLength".
    6732             :   // 3. Let newLen be ToUint32(Desc.[[Value]]).
    6733             :   Handle<Object> uint32_v;
    6734     1066226 :   if (!Object::ToUint32(isolate, length_object).ToHandle(&uint32_v)) {
    6735             :     // 4. ReturnIfAbrupt(newLen).
    6736             :     return false;
    6737             :   }
    6738             :   // 5. Let numberLen be ToNumber(Desc.[[Value]]).
    6739             :   Handle<Object> number_v;
    6740     1066196 :   if (!Object::ToNumber(length_object).ToHandle(&number_v)) {
    6741             :     // 6. ReturnIfAbrupt(newLen).
    6742             :     return false;
    6743             :   }
    6744             :   // 7. If newLen != numberLen, throw a RangeError exception.
    6745      533098 :   if (uint32_v->Number() != number_v->Number()) {
    6746             :     Handle<Object> exception =
    6747         386 :         isolate->factory()->NewRangeError(MessageTemplate::kInvalidArrayLength);
    6748         386 :     isolate->Throw(*exception);
    6749             :     return false;
    6750             :   }
    6751      532712 :   CHECK(uint32_v->ToArrayLength(output));
    6752             :   return true;
    6753             : }
    6754             : 
    6755             : 
    6756             : // ES6 9.4.2.4
    6757             : // static
    6758       18238 : Maybe<bool> JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a,
    6759             :                                     PropertyDescriptor* desc,
    6760             :                                     ShouldThrow should_throw) {
    6761             :   // 1. If the [[Value]] field of Desc is absent, then
    6762       18238 :   if (!desc->has_value()) {
    6763             :     // 1a. Return OrdinaryDefineOwnProperty(A, "length", Desc).
    6764             :     return OrdinaryDefineOwnProperty(
    6765         400 :         isolate, a, isolate->factory()->length_string(), desc, should_throw);
    6766             :   }
    6767             :   // 2. Let newLenDesc be a copy of Desc.
    6768             :   // (Actual copying is not necessary.)
    6769             :   PropertyDescriptor* new_len_desc = desc;
    6770             :   // 3. - 7. Convert Desc.[[Value]] to newLen.
    6771       17838 :   uint32_t new_len = 0;
    6772       17838 :   if (!AnythingToArrayLength(isolate, desc->value(), &new_len)) {
    6773             :     DCHECK(isolate->has_pending_exception());
    6774             :     return Nothing<bool>();
    6775             :   }
    6776             :   // 8. Set newLenDesc.[[Value]] to newLen.
    6777             :   // (Done below, if needed.)
    6778             :   // 9. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    6779             :   PropertyDescriptor old_len_desc;
    6780             :   Maybe<bool> success = GetOwnPropertyDescriptor(
    6781       17823 :       isolate, a, isolate->factory()->length_string(), &old_len_desc);
    6782             :   // 10. (Assert)
    6783             :   DCHECK(success.FromJust());
    6784             :   USE(success);
    6785             :   // 11. Let oldLen be oldLenDesc.[[Value]].
    6786       17823 :   uint32_t old_len = 0;
    6787       17823 :   CHECK(old_len_desc.value()->ToArrayLength(&old_len));
    6788             :   // 12. If newLen >= oldLen, then
    6789       17823 :   if (new_len >= old_len) {
    6790             :     // 8. Set newLenDesc.[[Value]] to newLen.
    6791             :     // 12a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc).
    6792       17809 :     new_len_desc->set_value(isolate->factory()->NewNumberFromUint(new_len));
    6793             :     return OrdinaryDefineOwnProperty(isolate, a,
    6794             :                                      isolate->factory()->length_string(),
    6795       17809 :                                      new_len_desc, should_throw);
    6796             :   }
    6797             :   // 13. If oldLenDesc.[[Writable]] is false, return false.
    6798          14 :   if (!old_len_desc.writable()) {
    6799           0 :     RETURN_FAILURE(isolate, should_throw,
    6800             :                    NewTypeError(MessageTemplate::kRedefineDisallowed,
    6801             :                                 isolate->factory()->length_string()));
    6802             :   }
    6803             :   // 14. If newLenDesc.[[Writable]] is absent or has the value true,
    6804             :   // let newWritable be true.
    6805             :   bool new_writable = false;
    6806          14 :   if (!new_len_desc->has_writable() || new_len_desc->writable()) {
    6807             :     new_writable = true;
    6808             :   } else {
    6809             :     // 15. Else,
    6810             :     // 15a. Need to defer setting the [[Writable]] attribute to false in case
    6811             :     //      any elements cannot be deleted.
    6812             :     // 15b. Let newWritable be false. (It's initialized as "false" anyway.)
    6813             :     // 15c. Set newLenDesc.[[Writable]] to true.
    6814             :     // (Not needed.)
    6815             :   }
    6816             :   // Most of steps 16 through 19 is implemented by JSArray::SetLength.
    6817          14 :   JSArray::SetLength(a, new_len);
    6818             :   // Steps 19d-ii, 20.
    6819          14 :   if (!new_writable) {
    6820             :     PropertyDescriptor readonly;
    6821             :     readonly.set_writable(false);
    6822             :     Maybe<bool> success = OrdinaryDefineOwnProperty(
    6823             :         isolate, a, isolate->factory()->length_string(), &readonly,
    6824           0 :         should_throw);
    6825             :     DCHECK(success.FromJust());
    6826             :     USE(success);
    6827             :   }
    6828          14 :   uint32_t actual_new_len = 0;
    6829          14 :   CHECK(a->length()->ToArrayLength(&actual_new_len));
    6830             :   // Steps 19d-v, 21. Return false if there were non-deletable elements.
    6831          14 :   bool result = actual_new_len == new_len;
    6832          14 :   if (!result) {
    6833          14 :     RETURN_FAILURE(
    6834             :         isolate, should_throw,
    6835             :         NewTypeError(MessageTemplate::kStrictDeleteProperty,
    6836             :                      isolate->factory()->NewNumberFromUint(actual_new_len - 1),
    6837             :                      a));
    6838             :   }
    6839             :   return Just(result);
    6840             : }
    6841             : 
    6842             : 
    6843             : // ES6 9.5.6
    6844             : // static
    6845        5822 : Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy,
    6846             :                                        Handle<Object> key,
    6847             :                                        PropertyDescriptor* desc,
    6848             :                                        ShouldThrow should_throw) {
    6849        5822 :   STACK_CHECK(isolate, Nothing<bool>());
    6850        6214 :   if (key->IsSymbol() && Handle<Symbol>::cast(key)->IsPrivate()) {
    6851             :     return SetPrivateProperty(isolate, proxy, Handle<Symbol>::cast(key), desc,
    6852          28 :                               should_throw);
    6853             :   }
    6854             :   Handle<String> trap_name = isolate->factory()->defineProperty_string();
    6855             :   // 1. Assert: IsPropertyKey(P) is true.
    6856             :   DCHECK(key->IsName() || key->IsNumber());
    6857             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    6858             :   Handle<Object> handler(proxy->handler(), isolate);
    6859             :   // 3. If handler is null, throw a TypeError exception.
    6860             :   // 4. Assert: Type(handler) is Object.
    6861        5794 :   if (proxy->IsRevoked()) {
    6862             :     isolate->Throw(*isolate->factory()->NewTypeError(
    6863          28 :         MessageTemplate::kProxyRevoked, trap_name));
    6864             :     return Nothing<bool>();
    6865             :   }
    6866             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    6867             :   Handle<JSReceiver> target(proxy->target(), isolate);
    6868             :   // 6. Let trap be ? GetMethod(handler, "defineProperty").
    6869             :   Handle<Object> trap;
    6870       11560 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    6871             :       isolate, trap,
    6872             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    6873             :       Nothing<bool>());
    6874             :   // 7. If trap is undefined, then:
    6875        5640 :   if (trap->IsUndefined(isolate)) {
    6876             :     // 7a. Return target.[[DefineOwnProperty]](P, Desc).
    6877             :     return JSReceiver::DefineOwnProperty(isolate, target, key, desc,
    6878        2810 :                                          should_throw);
    6879             :   }
    6880             :   // 8. Let descObj be FromPropertyDescriptor(Desc).
    6881        2830 :   Handle<Object> desc_obj = desc->ToObject(isolate);
    6882             :   // 9. Let booleanTrapResult be
    6883             :   //    ToBoolean(? Call(trap, handler, «target, P, descObj»)).
    6884             :   Handle<Name> property_name =
    6885             :       key->IsName()
    6886             :           ? Handle<Name>::cast(key)
    6887        2830 :           : Handle<Name>::cast(isolate->factory()->NumberToString(key));
    6888             :   // Do not leak private property names.
    6889             :   DCHECK(!property_name->IsPrivate());
    6890             :   Handle<Object> trap_result_obj;
    6891        2830 :   Handle<Object> args[] = {target, property_name, desc_obj};
    6892        5660 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    6893             :       isolate, trap_result_obj,
    6894             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    6895             :       Nothing<bool>());
    6896             :   // 10. If booleanTrapResult is false, return false.
    6897        2017 :   if (!trap_result_obj->BooleanValue()) {
    6898         154 :     RETURN_FAILURE(isolate, should_throw,
    6899             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    6900             :                                 trap_name, property_name));
    6901             :   }
    6902             :   // 11. Let targetDesc be ? target.[[GetOwnProperty]](P).
    6903             :   PropertyDescriptor target_desc;
    6904             :   Maybe<bool> target_found =
    6905        1891 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, key, &target_desc);
    6906        1891 :   MAYBE_RETURN(target_found, Nothing<bool>());
    6907             :   // 12. Let extensibleTarget be ? IsExtensible(target).
    6908        1891 :   Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target);
    6909        1891 :   MAYBE_RETURN(maybe_extensible, Nothing<bool>());
    6910             :   bool extensible_target = maybe_extensible.FromJust();
    6911             :   // 13. If Desc has a [[Configurable]] field and if Desc.[[Configurable]]
    6912             :   //     is false, then:
    6913             :   // 13a. Let settingConfigFalse be true.
    6914             :   // 14. Else let settingConfigFalse be false.
    6915        2956 :   bool setting_config_false = desc->has_configurable() && !desc->configurable();
    6916             :   // 15. If targetDesc is undefined, then
    6917        1891 :   if (!target_found.FromJust()) {
    6918             :     // 15a. If extensibleTarget is false, throw a TypeError exception.
    6919         966 :     if (!extensible_target) {
    6920             :       isolate->Throw(*isolate->factory()->NewTypeError(
    6921          28 :           MessageTemplate::kProxyDefinePropertyNonExtensible, property_name));
    6922             :       return Nothing<bool>();
    6923             :     }
    6924             :     // 15b. If settingConfigFalse is true, throw a TypeError exception.
    6925         952 :     if (setting_config_false) {
    6926             :       isolate->Throw(*isolate->factory()->NewTypeError(
    6927          28 :           MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
    6928             :       return Nothing<bool>();
    6929             :     }
    6930             :   } else {
    6931             :     // 16. Else targetDesc is not undefined,
    6932             :     // 16a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc,
    6933             :     //      targetDesc) is false, throw a TypeError exception.
    6934             :     Maybe<bool> valid =
    6935             :         IsCompatiblePropertyDescriptor(isolate, extensible_target, desc,
    6936             :                                        &target_desc, property_name, DONT_THROW);
    6937         925 :     MAYBE_RETURN(valid, Nothing<bool>());
    6938         925 :     if (!valid.FromJust()) {
    6939             :       isolate->Throw(*isolate->factory()->NewTypeError(
    6940          28 :           MessageTemplate::kProxyDefinePropertyIncompatible, property_name));
    6941             :       return Nothing<bool>();
    6942             :     }
    6943             :     // 16b. If settingConfigFalse is true and targetDesc.[[Configurable]] is
    6944             :     //      true, throw a TypeError exception.
    6945        1051 :     if (setting_config_false && target_desc.configurable()) {
    6946             :       isolate->Throw(*isolate->factory()->NewTypeError(
    6947          28 :           MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
    6948             :       return Nothing<bool>();
    6949             :     }
    6950             :   }
    6951             :   // 17. Return true.
    6952             :   return Just(true);
    6953             : }
    6954             : 
    6955             : 
    6956             : // static
    6957          49 : Maybe<bool> JSProxy::SetPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy,
    6958             :                                         Handle<Symbol> private_name,
    6959             :                                         PropertyDescriptor* desc,
    6960             :                                         ShouldThrow should_throw) {
    6961             :   // Despite the generic name, this can only add private data properties.
    6962          70 :   if (!PropertyDescriptor::IsDataDescriptor(desc) ||
    6963          21 :       desc->ToAttributes() != DONT_ENUM) {
    6964          56 :     RETURN_FAILURE(isolate, should_throw,
    6965             :                    NewTypeError(MessageTemplate::kProxyPrivate));
    6966             :   }
    6967             :   DCHECK(proxy->map()->is_dictionary_map());
    6968             :   Handle<Object> value =
    6969             :       desc->has_value()
    6970             :           ? desc->value()
    6971          21 :           : Handle<Object>::cast(isolate->factory()->undefined_value());
    6972             : 
    6973          21 :   LookupIterator it(proxy, private_name, proxy);
    6974             : 
    6975          21 :   if (it.IsFound()) {
    6976             :     DCHECK_EQ(LookupIterator::DATA, it.state());
    6977             :     DCHECK_EQ(DONT_ENUM, it.property_attributes());
    6978           7 :     it.WriteDataValue(value, false);
    6979             :     return Just(true);
    6980             :   }
    6981             : 
    6982             :   Handle<NameDictionary> dict(proxy->property_dictionary());
    6983             :   PropertyDetails details(kData, DONT_ENUM, 0, PropertyCellType::kNoCell);
    6984             :   Handle<NameDictionary> result =
    6985          14 :       NameDictionary::Add(dict, private_name, value, details);
    6986          21 :   if (!dict.is_identical_to(result)) proxy->set_properties(*result);
    6987             :   return Just(true);
    6988             : }
    6989             : 
    6990             : 
    6991             : // static
    6992     3691025 : Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate,
    6993             :                                                  Handle<JSReceiver> object,
    6994             :                                                  Handle<Object> key,
    6995             :                                                  PropertyDescriptor* desc) {
    6996     3691025 :   bool success = false;
    6997             :   DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey...
    6998             :   LookupIterator it = LookupIterator::PropertyOrElement(
    6999     3691025 :       isolate, object, key, &success, LookupIterator::OWN);
    7000             :   DCHECK(success);  // ...so creating a LookupIterator can't fail.
    7001     3691025 :   return GetOwnPropertyDescriptor(&it, desc);
    7002             : }
    7003             : 
    7004             : namespace {
    7005             : 
    7006     8694658 : Maybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
    7007             :                                                  PropertyDescriptor* desc) {
    7008             :   bool has_access = true;
    7009     4347220 :   if (it->state() == LookupIterator::ACCESS_CHECK) {
    7010     3156992 :     has_access = it->HasAccess() || JSObject::AllCanRead(it);
    7011     3156992 :     it->Next();
    7012             :   }
    7013             : 
    7014     8694386 :   if (has_access && it->state() == LookupIterator::INTERCEPTOR) {
    7015             :     Isolate* isolate = it->isolate();
    7016         213 :     Handle<InterceptorInfo> interceptor = it->GetInterceptor();
    7017         213 :     if (!interceptor->descriptor()->IsUndefined(isolate)) {
    7018             :       Handle<Object> result;
    7019             :       Handle<JSObject> holder = it->GetHolder<JSObject>();
    7020             : 
    7021             :       Handle<Object> receiver = it->GetReceiver();
    7022          45 :       if (!receiver->IsJSReceiver()) {
    7023          14 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7024             :             isolate, receiver, Object::ConvertReceiver(isolate, receiver),
    7025             :             Nothing<bool>());
    7026             :       }
    7027             : 
    7028             :       PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    7029             :                                      *holder, Object::DONT_THROW);
    7030          45 :       if (it->IsElement()) {
    7031             :         uint32_t index = it->index();
    7032             :         v8::IndexedPropertyDescriptorCallback descriptorCallback =
    7033             :             v8::ToCData<v8::IndexedPropertyDescriptorCallback>(
    7034             :                 interceptor->descriptor());
    7035             : 
    7036          12 :         result = args.Call(descriptorCallback, index);
    7037             :       } else {
    7038          33 :         Handle<Name> name = it->name();
    7039             :         DCHECK(!name->IsPrivate());
    7040             :         v8::GenericNamedPropertyDescriptorCallback descriptorCallback =
    7041             :             v8::ToCData<v8::GenericNamedPropertyDescriptorCallback>(
    7042             :                 interceptor->descriptor());
    7043          33 :         result = args.Call(descriptorCallback, name);
    7044             :       }
    7045          45 :       if (!result.is_null()) {
    7046             :         // Request successfully intercepted, try to set the property
    7047             :         // descriptor.
    7048             :         Utils::ApiCheck(
    7049          14 :             PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
    7050             :             it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
    7051             :                             : "v8::NamedPropertyDescriptorCallback",
    7052          14 :             "Invalid property descriptor.");
    7053             : 
    7054             :         return Just(true);
    7055             :       }
    7056             :     }
    7057             :   }
    7058     4347206 :   it->Restart();
    7059             :   return Just(false);
    7060             : }
    7061             : }  // namespace
    7062             : 
    7063             : // ES6 9.1.5.1
    7064             : // Returns true on success, false if the property didn't exist, nothing if
    7065             : // an exception was thrown.
    7066             : // static
    7067     8089344 : Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it,
    7068             :                                                  PropertyDescriptor* desc) {
    7069             :   Isolate* isolate = it->isolate();
    7070             :   // "Virtual" dispatch.
    7071     8098960 :   if (it->IsFound() && it->GetHolder<JSReceiver>()->IsJSProxy()) {
    7072             :     return JSProxy::GetOwnPropertyDescriptor(isolate, it->GetHolder<JSProxy>(),
    7073        9040 :                                              it->GetName(), desc);
    7074             :   }
    7075             : 
    7076     4347220 :   Maybe<bool> intercepted = GetPropertyDescriptorWithInterceptor(it, desc);
    7077     4347220 :   MAYBE_RETURN(intercepted, Nothing<bool>());
    7078     4347220 :   if (intercepted.FromJust()) {
    7079             :     return Just(true);
    7080             :   }
    7081             : 
    7082             :   // Request was not intercepted, continue as normal.
    7083             :   // 1. (Assert)
    7084             :   // 2. If O does not have an own property with key P, return undefined.
    7085     4347206 :   Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it);
    7086     4347206 :   MAYBE_RETURN(maybe, Nothing<bool>());
    7087             :   PropertyAttributes attrs = maybe.FromJust();
    7088     4347152 :   if (attrs == ABSENT) return Just(false);
    7089             :   DCHECK(!isolate->has_pending_exception());
    7090             : 
    7091             :   // 3. Let D be a newly created Property Descriptor with no fields.
    7092             :   DCHECK(desc->is_empty());
    7093             :   // 4. Let X be O's own property whose key is P.
    7094             :   // 5. If X is a data property, then
    7095     3901307 :   bool is_accessor_pair = it->state() == LookupIterator::ACCESSOR &&
    7096     3901307 :                           it->GetAccessors()->IsAccessorPair();
    7097     3733084 :   if (!is_accessor_pair) {
    7098             :     // 5a. Set D.[[Value]] to the value of X's [[Value]] attribute.
    7099             :     Handle<Object> value;
    7100     7394938 :     if (!Object::GetProperty(it).ToHandle(&value)) {
    7101             :       DCHECK(isolate->has_pending_exception());
    7102             :       return Nothing<bool>();
    7103             :     }
    7104             :     desc->set_value(value);
    7105             :     // 5b. Set D.[[Writable]] to the value of X's [[Writable]] attribute
    7106     3697469 :     desc->set_writable((attrs & READ_ONLY) == 0);
    7107             :   } else {
    7108             :     // 6. Else X is an accessor property, so
    7109             :     Handle<AccessorPair> accessors =
    7110       35615 :         Handle<AccessorPair>::cast(it->GetAccessors());
    7111             :     // 6a. Set D.[[Get]] to the value of X's [[Get]] attribute.
    7112       35615 :     desc->set_get(AccessorPair::GetComponent(accessors, ACCESSOR_GETTER));
    7113             :     // 6b. Set D.[[Set]] to the value of X's [[Set]] attribute.
    7114       35615 :     desc->set_set(AccessorPair::GetComponent(accessors, ACCESSOR_SETTER));
    7115             :   }
    7116             : 
    7117             :   // 7. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
    7118     3733084 :   desc->set_enumerable((attrs & DONT_ENUM) == 0);
    7119             :   // 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
    7120     3733084 :   desc->set_configurable((attrs & DONT_DELETE) == 0);
    7121             :   // 9. Return D.
    7122             :   DCHECK(PropertyDescriptor::IsAccessorDescriptor(desc) !=
    7123             :          PropertyDescriptor::IsDataDescriptor(desc));
    7124             :   return Just(true);
    7125             : }
    7126             : 
    7127             : 
    7128             : // ES6 9.5.5
    7129             : // static
    7130       13932 : Maybe<bool> JSProxy::GetOwnPropertyDescriptor(Isolate* isolate,
    7131             :                                               Handle<JSProxy> proxy,
    7132             :                                               Handle<Name> name,
    7133             :                                               PropertyDescriptor* desc) {
    7134             :   DCHECK(!name->IsPrivate());
    7135       13932 :   STACK_CHECK(isolate, Nothing<bool>());
    7136             : 
    7137             :   Handle<String> trap_name =
    7138             :       isolate->factory()->getOwnPropertyDescriptor_string();
    7139             :   // 1. (Assert)
    7140             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    7141             :   Handle<Object> handler(proxy->handler(), isolate);
    7142             :   // 3. If handler is null, throw a TypeError exception.
    7143             :   // 4. Assert: Type(handler) is Object.
    7144       13932 :   if (proxy->IsRevoked()) {
    7145             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7146          56 :         MessageTemplate::kProxyRevoked, trap_name));
    7147             :     return Nothing<bool>();
    7148             :   }
    7149             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    7150             :   Handle<JSReceiver> target(proxy->target(), isolate);
    7151             :   // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor").
    7152             :   Handle<Object> trap;
    7153       27808 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7154             :       isolate, trap,
    7155             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    7156             :       Nothing<bool>());
    7157             :   // 7. If trap is undefined, then
    7158       13820 :   if (trap->IsUndefined(isolate)) {
    7159             :     // 7a. Return target.[[GetOwnProperty]](P).
    7160        4983 :     return JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, desc);
    7161             :   }
    7162             :   // 8. Let trapResultObj be ? Call(trap, handler, «target, P»).
    7163             :   Handle<Object> trap_result_obj;
    7164             :   Handle<Object> args[] = {target, name};
    7165       17674 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7166             :       isolate, trap_result_obj,
    7167             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    7168             :       Nothing<bool>());
    7169             :   // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a
    7170             :   //    TypeError exception.
    7171        8694 :   if (!trap_result_obj->IsJSReceiver() &&
    7172             :       !trap_result_obj->IsUndefined(isolate)) {
    7173             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7174          56 :         MessageTemplate::kProxyGetOwnPropertyDescriptorInvalid, name));
    7175             :     return Nothing<bool>();
    7176             :   }
    7177             :   // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
    7178             :   PropertyDescriptor target_desc;
    7179             :   Maybe<bool> found =
    7180        7406 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    7181        7406 :   MAYBE_RETURN(found, Nothing<bool>());
    7182             :   // 11. If trapResultObj is undefined, then
    7183        7406 :   if (trap_result_obj->IsUndefined(isolate)) {
    7184             :     // 11a. If targetDesc is undefined, return undefined.
    7185        1232 :     if (!found.FromJust()) return Just(false);
    7186             :     // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError
    7187             :     //      exception.
    7188          70 :     if (!target_desc.configurable()) {
    7189             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7190          84 :           MessageTemplate::kProxyGetOwnPropertyDescriptorUndefined, name));
    7191             :       return Nothing<bool>();
    7192             :     }
    7193             :     // 11c. Let extensibleTarget be ? IsExtensible(target).
    7194          28 :     Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    7195          28 :     MAYBE_RETURN(extensible_target, Nothing<bool>());
    7196             :     // 11d. (Assert)
    7197             :     // 11e. If extensibleTarget is false, throw a TypeError exception.
    7198          28 :     if (!extensible_target.FromJust()) {
    7199             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7200           0 :           MessageTemplate::kProxyGetOwnPropertyDescriptorNonExtensible, name));
    7201             :       return Nothing<bool>();
    7202             :     }
    7203             :     // 11f. Return undefined.
    7204             :     return Just(false);
    7205             :   }
    7206             :   // 12. Let extensibleTarget be ? IsExtensible(target).
    7207        6174 :   Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    7208        6174 :   MAYBE_RETURN(extensible_target, Nothing<bool>());
    7209             :   // 13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj).
    7210        6174 :   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj,
    7211        6174 :                                                 desc)) {
    7212             :     DCHECK(isolate->has_pending_exception());
    7213             :     return Nothing<bool>();
    7214             :   }
    7215             :   // 14. Call CompletePropertyDescriptor(resultDesc).
    7216        6062 :   PropertyDescriptor::CompletePropertyDescriptor(isolate, desc);
    7217             :   // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget,
    7218             :   //     resultDesc, targetDesc).
    7219             :   Maybe<bool> valid =
    7220             :       IsCompatiblePropertyDescriptor(isolate, extensible_target.FromJust(),
    7221             :                                      desc, &target_desc, name, DONT_THROW);
    7222        6062 :   MAYBE_RETURN(valid, Nothing<bool>());
    7223             :   // 16. If valid is false, throw a TypeError exception.
    7224        6062 :   if (!valid.FromJust()) {
    7225             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7226          56 :         MessageTemplate::kProxyGetOwnPropertyDescriptorIncompatible, name));
    7227             :     return Nothing<bool>();
    7228             :   }
    7229             :   // 17. If resultDesc.[[Configurable]] is false, then
    7230        6034 :   if (!desc->configurable()) {
    7231             :     // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true:
    7232         742 :     if (target_desc.is_empty() || target_desc.configurable()) {
    7233             :       // 17a i. Throw a TypeError exception.
    7234             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7235             :           MessageTemplate::kProxyGetOwnPropertyDescriptorNonConfigurable,
    7236          56 :           name));
    7237             :       return Nothing<bool>();
    7238             :     }
    7239             :   }
    7240             :   // 18. Return resultDesc.
    7241             :   return Just(true);
    7242             : }
    7243             : 
    7244             : 
    7245           0 : bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
    7246             :                                             ElementsKind kind,
    7247             :                                             Object* object) {
    7248             :   Isolate* isolate = elements->GetIsolate();
    7249           0 :   if (IsFastObjectElementsKind(kind) || kind == FAST_STRING_WRAPPER_ELEMENTS) {
    7250             :     int length = IsJSArray()
    7251             :         ? Smi::cast(JSArray::cast(this)->length())->value()
    7252           0 :         : elements->length();
    7253           0 :     for (int i = 0; i < length; ++i) {
    7254             :       Object* element = elements->get(i);
    7255           0 :       if (!element->IsTheHole(isolate) && element == object) return true;
    7256             :     }
    7257             :   } else {
    7258             :     DCHECK(kind == DICTIONARY_ELEMENTS || kind == SLOW_STRING_WRAPPER_ELEMENTS);
    7259             :     Object* key =
    7260           0 :         SeededNumberDictionary::cast(elements)->SlowReverseLookup(object);
    7261           0 :     if (!key->IsUndefined(isolate)) return true;
    7262             :   }
    7263             :   return false;
    7264             : }
    7265             : 
    7266             : 
    7267             : // Check whether this object references another object.
    7268           0 : bool JSObject::ReferencesObject(Object* obj) {
    7269             :   Map* map_of_this = map();
    7270             :   Heap* heap = GetHeap();
    7271             :   DisallowHeapAllocation no_allocation;
    7272             : 
    7273             :   // Is the object the constructor for this object?
    7274           0 :   if (map_of_this->GetConstructor() == obj) {
    7275             :     return true;
    7276             :   }
    7277             : 
    7278             :   // Is the object the prototype for this object?
    7279           0 :   if (map_of_this->prototype() == obj) {
    7280             :     return true;
    7281             :   }
    7282             : 
    7283             :   // Check if the object is among the named properties.
    7284           0 :   Object* key = SlowReverseLookup(obj);
    7285           0 :   if (!key->IsUndefined(heap->isolate())) {
    7286             :     return true;
    7287             :   }
    7288             : 
    7289             :   // Check if the object is among the indexed properties.
    7290             :   ElementsKind kind = GetElementsKind();
    7291           0 :   switch (kind) {
    7292             :     // Raw pixels and external arrays do not reference other
    7293             :     // objects.
    7294             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
    7295             :     case TYPE##_ELEMENTS:                                                      \
    7296             :       break;
    7297             : 
    7298             :     TYPED_ARRAYS(TYPED_ARRAY_CASE)
    7299             : #undef TYPED_ARRAY_CASE
    7300             : 
    7301             :     case FAST_DOUBLE_ELEMENTS:
    7302             :     case FAST_HOLEY_DOUBLE_ELEMENTS:
    7303             :       break;
    7304             :     case FAST_SMI_ELEMENTS:
    7305             :     case FAST_HOLEY_SMI_ELEMENTS:
    7306             :       break;
    7307             :     case FAST_ELEMENTS:
    7308             :     case FAST_HOLEY_ELEMENTS:
    7309             :     case DICTIONARY_ELEMENTS:
    7310             :     case FAST_STRING_WRAPPER_ELEMENTS:
    7311             :     case SLOW_STRING_WRAPPER_ELEMENTS: {
    7312             :       FixedArray* elements = FixedArray::cast(this->elements());
    7313           0 :       if (ReferencesObjectFromElements(elements, kind, obj)) return true;
    7314             :       break;
    7315             :     }
    7316             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    7317             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
    7318             :       SloppyArgumentsElements* elements =
    7319             :           SloppyArgumentsElements::cast(this->elements());
    7320             :       // Check the mapped parameters.
    7321           0 :       for (uint32_t i = 0; i < elements->parameter_map_length(); ++i) {
    7322             :         Object* value = elements->get_mapped_entry(i);
    7323           0 :         if (!value->IsTheHole(heap->isolate()) && value == obj) return true;
    7324             :       }
    7325             :       // Check the arguments.
    7326             :       FixedArray* arguments = elements->arguments();
    7327             :       kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS :
    7328           0 :           FAST_HOLEY_ELEMENTS;
    7329           0 :       if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
    7330             :       break;
    7331             :     }
    7332             :     case NO_ELEMENTS:
    7333             :       break;
    7334             :   }
    7335             : 
    7336             :   // For functions check the context.
    7337           0 :   if (IsJSFunction()) {
    7338             :     // Get the constructor function for arguments array.
    7339             :     Map* arguments_map =
    7340           0 :         heap->isolate()->context()->native_context()->sloppy_arguments_map();
    7341             :     JSFunction* arguments_function =
    7342           0 :         JSFunction::cast(arguments_map->GetConstructor());
    7343             : 
    7344             :     // Get the context and don't check if it is the native context.
    7345             :     JSFunction* f = JSFunction::cast(this);
    7346             :     Context* context = f->context();
    7347           0 :     if (context->IsNativeContext()) {
    7348             :       return false;
    7349             :     }
    7350             : 
    7351             :     // Check the non-special context slots.
    7352           0 :     for (int i = Context::MIN_CONTEXT_SLOTS; i < context->length(); i++) {
    7353             :       // Only check JS objects.
    7354           0 :       if (context->get(i)->IsJSObject()) {
    7355             :         JSObject* ctxobj = JSObject::cast(context->get(i));
    7356             :         // If it is an arguments array check the content.
    7357           0 :         if (ctxobj->map()->GetConstructor() == arguments_function) {
    7358           0 :           if (ctxobj->ReferencesObject(obj)) {
    7359             :             return true;
    7360             :           }
    7361           0 :         } else if (ctxobj == obj) {
    7362             :           return true;
    7363             :         }
    7364             :       }
    7365             :     }
    7366             : 
    7367             :     // Check the context extension (if any) if it can have references.
    7368           0 :     if (context->has_extension() && !context->IsCatchContext()) {
    7369             :       // With harmony scoping, a JSFunction may have a script context.
    7370             :       // TODO(mvstanton): walk into the ScopeInfo.
    7371           0 :       if (context->IsScriptContext()) {
    7372             :         return false;
    7373             :       }
    7374             : 
    7375           0 :       return context->extension_object()->ReferencesObject(obj);
    7376             :     }
    7377             :   }
    7378             : 
    7379             :   // No references to object.
    7380             :   return false;
    7381             : }
    7382             : 
    7383             : 
    7384      206214 : Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver,
    7385             :                                           IntegrityLevel level,
    7386             :                                           ShouldThrow should_throw) {
    7387             :   DCHECK(level == SEALED || level == FROZEN);
    7388             : 
    7389      206214 :   if (receiver->IsJSObject()) {
    7390             :     Handle<JSObject> object = Handle<JSObject>::cast(receiver);
    7391      205570 :     if (!object->HasSloppyArgumentsElements()) {  // Fast path.
    7392      205496 :       if (level == SEALED) {
    7393             :         return JSObject::PreventExtensionsWithTransition<SEALED>(object,
    7394         409 :                                                                  should_throw);
    7395             :       } else {
    7396             :         return JSObject::PreventExtensionsWithTransition<FROZEN>(object,
    7397      205087 :                                                                  should_throw);
    7398             :       }
    7399             :     }
    7400             :   }
    7401             : 
    7402             :   Isolate* isolate = receiver->GetIsolate();
    7403             : 
    7404         718 :   MAYBE_RETURN(JSReceiver::PreventExtensions(receiver, should_throw),
    7405             :                Nothing<bool>());
    7406             : 
    7407             :   Handle<FixedArray> keys;
    7408         718 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7409             :       isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
    7410             : 
    7411             :   PropertyDescriptor no_conf;
    7412             :   no_conf.set_configurable(false);
    7413             : 
    7414             :   PropertyDescriptor no_conf_no_write;
    7415             :   no_conf_no_write.set_configurable(false);
    7416             :   no_conf_no_write.set_writable(false);
    7417             : 
    7418         718 :   if (level == SEALED) {
    7419         406 :     for (int i = 0; i < keys->length(); ++i) {
    7420             :       Handle<Object> key(keys->get(i), isolate);
    7421         126 :       MAYBE_RETURN(
    7422             :           DefineOwnProperty(isolate, receiver, key, &no_conf, THROW_ON_ERROR),
    7423             :           Nothing<bool>());
    7424             :     }
    7425             :     return Just(true);
    7426             :   }
    7427             : 
    7428        4498 :   for (int i = 0; i < keys->length(); ++i) {
    7429             :     Handle<Object> key(keys->get(i), isolate);
    7430             :     PropertyDescriptor current_desc;
    7431             :     Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
    7432        1967 :         isolate, receiver, key, &current_desc);
    7433        1967 :     MAYBE_RETURN(owned, Nothing<bool>());
    7434        1967 :     if (owned.FromJust()) {
    7435             :       PropertyDescriptor desc =
    7436             :           PropertyDescriptor::IsAccessorDescriptor(&current_desc)
    7437             :               ? no_conf
    7438        1967 :               : no_conf_no_write;
    7439        1967 :       MAYBE_RETURN(
    7440             :           DefineOwnProperty(isolate, receiver, key, &desc, THROW_ON_ERROR),
    7441             :           Nothing<bool>());
    7442             :     }
    7443             :   }
    7444             :   return Just(true);
    7445             : }
    7446             : 
    7447             : 
    7448        7712 : Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> object,
    7449             :                                            IntegrityLevel level) {
    7450             :   DCHECK(level == SEALED || level == FROZEN);
    7451             :   Isolate* isolate = object->GetIsolate();
    7452             : 
    7453        7712 :   Maybe<bool> extensible = JSReceiver::IsExtensible(object);
    7454        7712 :   MAYBE_RETURN(extensible, Nothing<bool>());
    7455        7712 :   if (extensible.FromJust()) return Just(false);
    7456             : 
    7457             :   Handle<FixedArray> keys;
    7458        1585 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7459             :       isolate, keys, JSReceiver::OwnPropertyKeys(object), Nothing<bool>());
    7460             : 
    7461       19213 :   for (int i = 0; i < keys->length(); ++i) {
    7462             :     Handle<Object> key(keys->get(i), isolate);
    7463             :     PropertyDescriptor current_desc;
    7464             :     Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
    7465        9314 :         isolate, object, key, &current_desc);
    7466        9814 :     MAYBE_RETURN(owned, Nothing<bool>());
    7467        9314 :     if (owned.FromJust()) {
    7468        9314 :       if (current_desc.configurable()) return Just(false);
    7469       14809 :       if (level == FROZEN &&
    7470       14699 :           PropertyDescriptor::IsDataDescriptor(&current_desc) &&
    7471             :           current_desc.writable()) {
    7472             :         return Just(false);
    7473             :       }
    7474             :     }
    7475             :   }
    7476             :   return Just(true);
    7477             : }
    7478             : 
    7479             : 
    7480        7126 : Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object,
    7481             :                                           ShouldThrow should_throw) {
    7482        7126 :   if (object->IsJSProxy()) {
    7483             :     return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object),
    7484         952 :                                       should_throw);
    7485             :   }
    7486             :   DCHECK(object->IsJSObject());
    7487             :   return JSObject::PreventExtensions(Handle<JSObject>::cast(object),
    7488        6174 :                                      should_throw);
    7489             : }
    7490             : 
    7491             : 
    7492         952 : Maybe<bool> JSProxy::PreventExtensions(Handle<JSProxy> proxy,
    7493             :                                        ShouldThrow should_throw) {
    7494             :   Isolate* isolate = proxy->GetIsolate();
    7495         952 :   STACK_CHECK(isolate, Nothing<bool>());
    7496             :   Factory* factory = isolate->factory();
    7497             :   Handle<String> trap_name = factory->preventExtensions_string();
    7498             : 
    7499         952 :   if (proxy->IsRevoked()) {
    7500             :     isolate->Throw(
    7501          56 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    7502             :     return Nothing<bool>();
    7503             :   }
    7504             :   Handle<JSReceiver> target(proxy->target(), isolate);
    7505             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    7506             : 
    7507             :   Handle<Object> trap;
    7508        1848 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7509             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    7510         896 :   if (trap->IsUndefined(isolate)) {
    7511         812 :     return JSReceiver::PreventExtensions(target, should_throw);
    7512             :   }
    7513             : 
    7514             :   Handle<Object> trap_result;
    7515             :   Handle<Object> args[] = {target};
    7516         168 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7517             :       isolate, trap_result,
    7518             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    7519             :       Nothing<bool>());
    7520          84 :   if (!trap_result->BooleanValue()) {
    7521          28 :     RETURN_FAILURE(
    7522             :         isolate, should_throw,
    7523             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
    7524             :   }
    7525             : 
    7526             :   // Enforce the invariant.
    7527          56 :   Maybe<bool> target_result = JSReceiver::IsExtensible(target);
    7528          56 :   MAYBE_RETURN(target_result, Nothing<bool>());
    7529          56 :   if (target_result.FromJust()) {
    7530             :     isolate->Throw(*factory->NewTypeError(
    7531          28 :         MessageTemplate::kProxyPreventExtensionsExtensible));
    7532             :     return Nothing<bool>();
    7533             :   }
    7534             :   return Just(true);
    7535             : }
    7536             : 
    7537             : 
    7538        6632 : Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
    7539             :                                         ShouldThrow should_throw) {
    7540           0 :   Isolate* isolate = object->GetIsolate();
    7541             : 
    7542        6632 :   if (!object->HasSloppyArgumentsElements()) {
    7543        6543 :     return PreventExtensionsWithTransition<NONE>(object, should_throw);
    7544             :   }
    7545             : 
    7546          89 :   if (object->IsAccessCheckNeeded() &&
    7547           0 :       !isolate->MayAccess(handle(isolate->context()), object)) {
    7548           0 :     isolate->ReportFailedAccessCheck(object);
    7549           0 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    7550           0 :     RETURN_FAILURE(isolate, should_throw,
    7551             :                    NewTypeError(MessageTemplate::kNoAccess));
    7552             :   }
    7553             : 
    7554          89 :   if (!object->map()->is_extensible()) return Just(true);
    7555             : 
    7556          89 :   if (object->IsJSGlobalProxy()) {
    7557           0 :     PrototypeIterator iter(isolate, object);
    7558           0 :     if (iter.IsAtEnd()) return Just(true);
    7559             :     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
    7560             :     return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter),
    7561           0 :                              should_throw);
    7562             :   }
    7563             : 
    7564         178 :   if (object->map()->has_named_interceptor() ||
    7565             :       object->map()->has_indexed_interceptor()) {
    7566           0 :     RETURN_FAILURE(isolate, should_throw,
    7567             :                    NewTypeError(MessageTemplate::kCannotPreventExt));
    7568             :   }
    7569             : 
    7570          89 :   if (!object->HasFixedTypedArrayElements()) {
    7571             :     // If there are fast elements we normalize.
    7572          89 :     Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
    7573             :     DCHECK(object->HasDictionaryElements() ||
    7574             :            object->HasSlowArgumentsElements());
    7575             : 
    7576             :     // Make sure that we never go back to fast case.
    7577          89 :     object->RequireSlowElements(*dictionary);
    7578             :   }
    7579             : 
    7580             :   // Do a map transition, other objects with this map may still
    7581             :   // be extensible.
    7582             :   // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
    7583          89 :   Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions");
    7584             : 
    7585             :   new_map->set_is_extensible(false);
    7586          89 :   JSObject::MigrateToMap(object, new_map);
    7587             :   DCHECK(!object->map()->is_extensible());
    7588             : 
    7589             :   return Just(true);
    7590             : }
    7591             : 
    7592             : 
    7593     1520952 : Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) {
    7594     1520952 :   if (object->IsJSProxy()) {
    7595         910 :     return JSProxy::IsExtensible(Handle<JSProxy>::cast(object));
    7596             :   }
    7597     1520042 :   return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object)));
    7598             : }
    7599             : 
    7600             : 
    7601         910 : Maybe<bool> JSProxy::IsExtensible(Handle<JSProxy> proxy) {
    7602             :   Isolate* isolate = proxy->GetIsolate();
    7603         910 :   STACK_CHECK(isolate, Nothing<bool>());
    7604             :   Factory* factory = isolate->factory();
    7605             :   Handle<String> trap_name = factory->isExtensible_string();
    7606             : 
    7607         910 :   if (proxy->IsRevoked()) {
    7608             :     isolate->Throw(
    7609          56 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    7610             :     return Nothing<bool>();
    7611             :   }
    7612             :   Handle<JSReceiver> target(proxy->target(), isolate);
    7613             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    7614             : 
    7615             :   Handle<Object> trap;
    7616        1764 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7617             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    7618         854 :   if (trap->IsUndefined(isolate)) {
    7619         196 :     return JSReceiver::IsExtensible(target);
    7620             :   }
    7621             : 
    7622             :   Handle<Object> trap_result;
    7623             :   Handle<Object> args[] = {target};
    7624        1316 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7625             :       isolate, trap_result,
    7626             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    7627             :       Nothing<bool>());
    7628             : 
    7629             :   // Enforce the invariant.
    7630         658 :   Maybe<bool> target_result = JSReceiver::IsExtensible(target);
    7631         658 :   MAYBE_RETURN(target_result, Nothing<bool>());
    7632         658 :   if (target_result.FromJust() != trap_result->BooleanValue()) {
    7633             :     isolate->Throw(
    7634             :         *factory->NewTypeError(MessageTemplate::kProxyIsExtensibleInconsistent,
    7635          84 :                                factory->ToBoolean(target_result.FromJust())));
    7636             :     return Nothing<bool>();
    7637             :   }
    7638         616 :   return target_result;
    7639             : }
    7640             : 
    7641             : 
    7642     2355058 : bool JSObject::IsExtensible(Handle<JSObject> object) {
    7643          36 :   Isolate* isolate = object->GetIsolate();
    7644     2355094 :   if (object->IsAccessCheckNeeded() &&
    7645          36 :       !isolate->MayAccess(handle(isolate->context()), object)) {
    7646             :     return true;
    7647             :   }
    7648     2355034 :   if (object->IsJSGlobalProxy()) {
    7649             :     PrototypeIterator iter(isolate, *object);
    7650        3969 :     if (iter.IsAtEnd()) return false;
    7651             :     DCHECK(iter.GetCurrent()->IsJSGlobalObject());
    7652        7938 :     return iter.GetCurrent<JSObject>()->map()->is_extensible();
    7653             :   }
    7654     2351065 :   return object->map()->is_extensible();
    7655             : }
    7656             : 
    7657             : namespace {
    7658             : 
    7659             : template <typename Dictionary>
    7660             : void DictionaryDetailsAtPut(Isolate* isolate, Handle<Dictionary> dictionary,
    7661             :                             int entry, PropertyDetails details) {
    7662             :   dictionary->DetailsAtPut(entry, details);
    7663             : }
    7664             : 
    7665             : template <>
    7666       13229 : void DictionaryDetailsAtPut<GlobalDictionary>(
    7667             :     Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry,
    7668             :     PropertyDetails details) {
    7669       13229 :   Object* value = dictionary->ValueAt(entry);
    7670             :   DCHECK(value->IsPropertyCell());
    7671             :   value = PropertyCell::cast(value)->value();
    7672       26458 :   if (value->IsTheHole(isolate)) return;
    7673             :   PropertyCell::PrepareForValue(dictionary, entry, handle(value, isolate),
    7674       13214 :                                 details);
    7675             : }
    7676             : 
    7677             : template <typename Dictionary>
    7678        5991 : void ApplyAttributesToDictionary(Isolate* isolate,
    7679             :                                  Handle<Dictionary> dictionary,
    7680             :                                  const PropertyAttributes attributes) {
    7681             :   int capacity = dictionary->Capacity();
    7682       70583 :   for (int i = 0; i < capacity; i++) {
    7683             :     Object* k = dictionary->KeyAt(i);
    7684       90851 :     if (dictionary->IsKey(isolate, k) &&
    7685             :         !(k->IsSymbol() && Symbol::cast(k)->is_private())) {
    7686             :       PropertyDetails details = dictionary->DetailsAt(i);
    7687       26125 :       int attrs = attributes;
    7688             :       // READ_ONLY is an invalid attribute for JS setters/getters.
    7689       49718 :       if ((attributes & READ_ONLY) && details.kind() == kAccessor) {
    7690          44 :         Object* v = dictionary->ValueAt(i);
    7691          44 :         if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value();
    7692          44 :         if (v->IsAccessorPair()) attrs &= ~READ_ONLY;
    7693             :       }
    7694             :       details = details.CopyAddAttributes(
    7695             :           static_cast<PropertyAttributes>(attrs));
    7696       13229 :       DictionaryDetailsAtPut<Dictionary>(isolate, dictionary, i, details);
    7697             :     }
    7698             :   }
    7699        5991 : }
    7700             : 
    7701             : }  // namespace
    7702             : 
    7703             : template <PropertyAttributes attrs>
    7704      212187 : Maybe<bool> JSObject::PreventExtensionsWithTransition(
    7705             :     Handle<JSObject> object, ShouldThrow should_throw) {
    7706             :   STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN);
    7707             : 
    7708             :   // Sealing/freezing sloppy arguments should be handled elsewhere.
    7709             :   DCHECK(!object->HasSloppyArgumentsElements());
    7710             : 
    7711          30 :   Isolate* isolate = object->GetIsolate();
    7712      212217 :   if (object->IsAccessCheckNeeded() &&
    7713          30 :       !isolate->MayAccess(handle(isolate->context()), object)) {
    7714          24 :     isolate->ReportFailedAccessCheck(object);
    7715          24 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    7716           0 :     RETURN_FAILURE(isolate, should_throw,
    7717             :                    NewTypeError(MessageTemplate::kNoAccess));
    7718             :   }
    7719             : 
    7720        6545 :   if (attrs == NONE && !object->map()->is_extensible()) return Just(true);
    7721             : 
    7722      212148 :   if (object->IsJSGlobalProxy()) {
    7723         148 :     PrototypeIterator iter(isolate, object);
    7724         148 :     if (iter.IsAtEnd()) return Just(true);
    7725             :     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
    7726             :     return PreventExtensionsWithTransition<attrs>(
    7727         148 :         PrototypeIterator::GetCurrent<JSObject>(iter), should_throw);
    7728             :   }
    7729             : 
    7730      423999 :   if (object->map()->has_named_interceptor() ||
    7731             :       object->map()->has_indexed_interceptor()) {
    7732             :     MessageTemplate::Template message = MessageTemplate::kNone;
    7733             :     switch (attrs) {
    7734             :       case NONE:
    7735             :         message = MessageTemplate::kCannotPreventExt;
    7736             :         break;
    7737             : 
    7738             :       case SEALED:
    7739             :         message = MessageTemplate::kCannotSeal;
    7740             :         break;
    7741             : 
    7742             :       case FROZEN:
    7743             :         message = MessageTemplate::kCannotFreeze;
    7744             :         break;
    7745             :     }
    7746           3 :     RETURN_FAILURE(isolate, should_throw, NewTypeError(message));
    7747             :   }
    7748             : 
    7749             :   Handle<SeededNumberDictionary> new_element_dictionary;
    7750      635500 :   if (!object->HasFixedTypedArrayElements() &&
    7751      211910 :       !object->HasDictionaryElements() &&
    7752      211591 :       !object->HasSlowStringWrapperElements()) {
    7753             :     int length =
    7754             :         object->IsJSArray()
    7755             :             ? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
    7756      211591 :             : object->elements()->length();
    7757      217870 :     new_element_dictionary =
    7758             :         length == 0 ? isolate->factory()->empty_slow_element_dictionary()
    7759        6279 :                     : object->GetElementsAccessor()->Normalize(object);
    7760             :   }
    7761             : 
    7762             :   Handle<Symbol> transition_marker;
    7763             :   if (attrs == NONE) {
    7764             :     transition_marker = isolate->factory()->nonextensible_symbol();
    7765             :   } else if (attrs == SEALED) {
    7766             :     transition_marker = isolate->factory()->sealed_symbol();
    7767             :   } else {
    7768             :     DCHECK(attrs == FROZEN);
    7769             :     transition_marker = isolate->factory()->frozen_symbol();
    7770             :   }
    7771             : 
    7772             :   Handle<Map> old_map(object->map(), isolate);
    7773             :   Map* transition =
    7774      211999 :       TransitionArray::SearchSpecial(*old_map, *transition_marker);
    7775      211999 :   if (transition != NULL) {
    7776             :     Handle<Map> transition_map(transition, isolate);
    7777             :     DCHECK(transition_map->has_dictionary_elements() ||
    7778             :            transition_map->has_fixed_typed_array_elements() ||
    7779             :            transition_map->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
    7780             :     DCHECK(!transition_map->is_extensible());
    7781      159859 :     JSObject::MigrateToMap(object, transition_map);
    7782       52140 :   } else if (TransitionArray::CanHaveMoreTransitions(old_map)) {
    7783             :     // Create a new descriptor array with the appropriate property attributes
    7784             :     Handle<Map> new_map = Map::CopyForPreventExtensions(
    7785       51203 :         old_map, attrs, transition_marker, "CopyForPreventExtensions");
    7786       51203 :     JSObject::MigrateToMap(object, new_map);
    7787             :   } else {
    7788             :     DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map());
    7789             :     // Slow path: need to normalize properties for safety
    7790         937 :     NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0,
    7791             :                         "SlowPreventExtensions");
    7792             : 
    7793             :     // Create a new map, since other objects with this map may be extensible.
    7794             :     // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
    7795             :     Handle<Map> new_map =
    7796         937 :         Map::Copy(handle(object->map()), "SlowCopyForPreventExtensions");
    7797             :     new_map->set_is_extensible(false);
    7798         937 :     if (!new_element_dictionary.is_null()) {
    7799             :       ElementsKind new_kind =
    7800             :           IsStringWrapperElementsKind(old_map->elements_kind())
    7801             :               ? SLOW_STRING_WRAPPER_ELEMENTS
    7802         937 :               : DICTIONARY_ELEMENTS;
    7803             :       new_map->set_elements_kind(new_kind);
    7804             :     }
    7805         937 :     JSObject::MigrateToMap(object, new_map);
    7806             : 
    7807             :     if (attrs != NONE) {
    7808         213 :       if (object->IsJSGlobalObject()) {
    7809             :         Handle<GlobalDictionary> dictionary(object->global_dictionary(),
    7810             :                                             isolate);
    7811         134 :         ApplyAttributesToDictionary(isolate, dictionary, attrs);
    7812             :       } else {
    7813             :         Handle<NameDictionary> dictionary(object->property_dictionary(),
    7814             :                                           isolate);
    7815          79 :         ApplyAttributesToDictionary(isolate, dictionary, attrs);
    7816             :       }
    7817             :     }
    7818             :   }
    7819             : 
    7820             :   // Both seal and preventExtensions always go through without modifications to
    7821             :   // typed array elements. Freeze works only if there are no actual elements.
    7822      211999 :   if (object->HasFixedTypedArrayElements()) {
    7823          59 :     if (attrs == FROZEN &&
    7824             :         JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) {
    7825          44 :       isolate->Throw(*isolate->factory()->NewTypeError(
    7826          88 :           MessageTemplate::kCannotFreezeArrayBufferView));
    7827             :       return Nothing<bool>();
    7828             :     }
    7829             :     return Just(true);
    7830             :   }
    7831             : 
    7832             :   DCHECK(object->map()->has_dictionary_elements() ||
    7833             :          object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
    7834      211910 :   if (!new_element_dictionary.is_null()) {
    7835      211591 :     object->set_elements(*new_element_dictionary);
    7836             :   }
    7837             : 
    7838      211910 :   if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
    7839             :     Handle<SeededNumberDictionary> dictionary(object->element_dictionary(),
    7840             :                                               isolate);
    7841             :     // Make sure we never go back to the fast case
    7842        6510 :     object->RequireSlowElements(*dictionary);
    7843             :     if (attrs != NONE) {
    7844        5778 :       ApplyAttributesToDictionary(isolate, dictionary, attrs);
    7845             :     }
    7846             :   }
    7847             : 
    7848             :   return Just(true);
    7849             : }
    7850             : 
    7851             : 
    7852    58226998 : Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
    7853             :                                         Representation representation,
    7854             :                                         FieldIndex index) {
    7855             :   Isolate* isolate = object->GetIsolate();
    7856    58226998 :   if (object->IsUnboxedDoubleField(index)) {
    7857             :     double value = object->RawFastDoublePropertyAt(index);
    7858       78602 :     return isolate->factory()->NewHeapNumber(value);
    7859             :   }
    7860    58148396 :   Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
    7861    58148397 :   return Object::WrapForRead(isolate, raw_value, representation);
    7862             : }
    7863             : 
    7864             : template <class ContextObject>
    7865             : class JSObjectWalkVisitor {
    7866             :  public:
    7867             :   JSObjectWalkVisitor(ContextObject* site_context, bool copying,
    7868             :                       JSObject::DeepCopyHints hints)
    7869             :     : site_context_(site_context),
    7870             :       copying_(copying),
    7871     8266444 :       hints_(hints) {}
    7872             : 
    7873             :   MUST_USE_RESULT MaybeHandle<JSObject> StructureWalk(Handle<JSObject> object);
    7874             : 
    7875             :  protected:
    7876     1900263 :   MUST_USE_RESULT inline MaybeHandle<JSObject> VisitElementOrProperty(
    7877             :       Handle<JSObject> object,
    7878     2205317 :       Handle<JSObject> value) {
    7879     1900263 :     Handle<AllocationSite> current_site = site_context()->EnterNewScope();
    7880     1900263 :     MaybeHandle<JSObject> copy_of_value = StructureWalk(value);
    7881      305054 :     site_context()->ExitScope(current_site, value);
    7882     1900263 :     return copy_of_value;
    7883             :   }
    7884             : 
    7885             :   inline ContextObject* site_context() { return site_context_; }
    7886    10166706 :   inline Isolate* isolate() { return site_context()->isolate(); }
    7887             : 
    7888             :   inline bool copying() const { return copying_; }
    7889             : 
    7890             :  private:
    7891             :   ContextObject* site_context_;
    7892             :   const bool copying_;
    7893             :   const JSObject::DeepCopyHints hints_;
    7894             : };
    7895             : 
    7896             : template <class ContextObject>
    7897    10166706 : MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
    7898    26230673 :     Handle<JSObject> object) {
    7899      641994 :   Isolate* isolate = this->isolate();
    7900             :   bool copying = this->copying();
    7901    10166706 :   bool shallow = hints_ == JSObject::kObjectIsShallow;
    7902             : 
    7903    10166706 :   if (!shallow) {
    7904             :     StackLimitCheck check(isolate);
    7905             : 
    7906     8816476 :     if (check.HasOverflowed()) {
    7907         165 :       isolate->StackOverflow();
    7908             :       return MaybeHandle<JSObject>();
    7909             :     }
    7910             :   }
    7911             : 
    7912    10166541 :   if (object->map()->is_deprecated()) {
    7913        2317 :     JSObject::MigrateInstance(object);
    7914             :   }
    7915             : 
    7916             :   Handle<JSObject> copy;
    7917    10166543 :   if (copying) {
    7918             :     // JSFunction objects are not allowed to be in normal boilerplates at all.
    7919             :     DCHECK(!object->IsJSFunction());
    7920             :     Handle<AllocationSite> site_to_pass;
    7921     8940784 :     if (site_context()->ShouldCreateMemento(object)) {
    7922     7123183 :       site_to_pass = site_context()->current();
    7923             :     }
    7924     8940785 :     copy = isolate->factory()->CopyJSObjectWithAllocationSite(
    7925             :         object, site_to_pass);
    7926             :   } else {
    7927             :     copy = object;
    7928             :   }
    7929             : 
    7930             :   DCHECK(copying || copy.is_identical_to(object));
    7931             : 
    7932             :   ElementsKind kind = copy->GetElementsKind();
    7933    18796869 :   if (copying && IsFastSmiOrObjectElementsKind(kind) &&
    7934             :       FixedArray::cast(copy->elements())->map() ==
    7935     8630330 :         isolate->heap()->fixed_cow_array_map()) {
    7936      641994 :     isolate->counters()->cow_arrays_created_runtime()->Increment();
    7937             :   }
    7938             : 
    7939    10166539 :   if (!shallow) {
    7940             :     HandleScope scope(isolate);
    7941             : 
    7942             :     // Deep copy own properties.
    7943     8816307 :     if (copy->HasFastProperties()) {
    7944             :       Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
    7945             :       int limit = copy->map()->NumberOfOwnDescriptors();
    7946    29997254 :       for (int i = 0; i < limit; i++) {
    7947    21181137 :         PropertyDetails details = descriptors->GetDetails(i);
    7948    23151788 :         if (details.location() != kField) continue;
    7949             :         DCHECK_EQ(kData, details.kind());
    7950    19210488 :         FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i);
    7951    19210483 :         if (object->IsUnboxedDoubleField(index)) {
    7952      161042 :           if (copying) {
    7953             :             // Ensure that all bits of the double value are preserved.
    7954             :             uint64_t value = object->RawFastDoublePropertyAsBitsAt(index);
    7955             :             copy->RawFastDoublePropertyAsBitsAtPut(index, value);
    7956             :           }
    7957             :         } else {
    7958    19049441 :           Handle<Object> value(object->RawFastPropertyAt(index), isolate);
    7959    19049449 :           if (value->IsJSObject()) {
    7960     1698378 :             ASSIGN_RETURN_ON_EXCEPTION(
    7961             :                 isolate, value,
    7962             :                 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
    7963             :                 JSObject);
    7964      849174 :             if (copying) {
    7965      646404 :               copy->FastPropertyAtPut(index, *value);
    7966             :             }
    7967             :           } else {
    7968    18200260 :             if (copying) {
    7969    15778022 :               Representation representation = details.representation();
    7970    15778022 :               value = Object::NewStorageFor(isolate, value, representation);
    7971    15778022 :               copy->FastPropertyAtPut(index, *value);
    7972             :             }
    7973             :           }
    7974             :         }
    7975             :       }
    7976             :     } else {
    7977             :       // Only deep copy fields from the object literal expression.
    7978             :       // In particular, don't try to copy the length attribute of
    7979             :       // an array.
    7980             :       PropertyFilter filter = static_cast<PropertyFilter>(
    7981             :           ONLY_WRITABLE | ONLY_ENUMERABLE | ONLY_CONFIGURABLE);
    7982             :       KeyAccumulator accumulator(isolate, KeyCollectionMode::kOwnOnly, filter);
    7983         182 :       accumulator.CollectOwnPropertyNames(copy, copy);
    7984         182 :       Handle<FixedArray> names = accumulator.GetKeys();
    7985      593688 :       for (int i = 0; i < names->length(); i++) {
    7986             :         DCHECK(names->get(i)->IsName());
    7987             :         Handle<Name> name(Name::cast(names->get(i)));
    7988             :         Handle<Object> value =
    7989      593324 :             JSObject::GetProperty(copy, name).ToHandleChecked();
    7990      296662 :         if (value->IsJSObject()) {
    7991             :           Handle<JSObject> result;
    7992           0 :           ASSIGN_RETURN_ON_EXCEPTION(
    7993             :               isolate, result,
    7994             :               VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
    7995             :               JSObject);
    7996           0 :           if (copying) {
    7997             :             // Creating object copy for literals. No strict mode needed.
    7998           0 :             JSObject::SetProperty(copy, name, result, SLOPPY).Assert();
    7999             :           }
    8000             :         }
    8001         182 :       }
    8002             :     }
    8003             : 
    8004             :     // Deep copy own elements.
    8005     8816299 :     switch (kind) {
    8006             :       case FAST_ELEMENTS:
    8007             :       case FAST_HOLEY_ELEMENTS: {
    8008             :         Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
    8009     7735331 :         if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
    8010             : #ifdef DEBUG
    8011             :           for (int i = 0; i < elements->length(); i++) {
    8012             :             DCHECK(!elements->get(i)->IsJSObject());
    8013             :           }
    8014             : #endif
    8015             :         } else {
    8016    14179808 :           for (int i = 0; i < elements->length(); i++) {
    8017             :             Handle<Object> value(elements->get(i), isolate);
    8018     3268967 :             if (value->IsJSObject()) {
    8019             :               Handle<JSObject> result;
    8020     2101408 :               ASSIGN_RETURN_ON_EXCEPTION(
    8021             :                   isolate, result,
    8022             :                   VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
    8023             :                   JSObject);
    8024     1050674 :               if (copying) {
    8025      948560 :                 elements->set(i, *result);
    8026             :               }
    8027             :             }
    8028             :           }
    8029             :         }
    8030             :         break;
    8031             :       }
    8032             :       case DICTIONARY_ELEMENTS: {
    8033             :         Handle<SeededNumberDictionary> element_dictionary(
    8034             :             copy->element_dictionary());
    8035             :         int capacity = element_dictionary->Capacity();
    8036       28179 :         for (int i = 0; i < capacity; i++) {
    8037             :           Object* k = element_dictionary->KeyAt(i);
    8038       26276 :           if (element_dictionary->IsKey(isolate, k)) {
    8039        9826 :             Handle<Object> value(element_dictionary->ValueAt(i), isolate);
    8040        9826 :             if (value->IsJSObject()) {
    8041             :               Handle<JSObject> result;
    8042         740 :               ASSIGN_RETURN_ON_EXCEPTION(
    8043             :                   isolate, result,
    8044             :                   VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
    8045             :                   JSObject);
    8046         370 :               if (copying) {
    8047             :                 element_dictionary->ValueAtPut(i, *result);
    8048             :               }
    8049             :             }
    8050             :           }
    8051             :         }
    8052             :         break;
    8053             :       }
    8054             :       case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    8055             :       case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    8056           0 :         UNIMPLEMENTED();
    8057             :         break;
    8058             :       case FAST_STRING_WRAPPER_ELEMENTS:
    8059             :       case SLOW_STRING_WRAPPER_ELEMENTS:
    8060           0 :         UNREACHABLE();
    8061             :         break;
    8062             : 
    8063             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
    8064             :       case TYPE##_ELEMENTS:                                                    \
    8065             : 
    8066             :       TYPED_ARRAYS(TYPED_ARRAY_CASE)
    8067             : #undef TYPED_ARRAY_CASE
    8068             :       // Typed elements cannot be created using an object literal.
    8069           0 :       UNREACHABLE();
    8070             :       break;
    8071             : 
    8072             :       case FAST_SMI_ELEMENTS:
    8073             :       case FAST_HOLEY_SMI_ELEMENTS:
    8074             :       case FAST_DOUBLE_ELEMENTS:
    8075             :       case FAST_HOLEY_DOUBLE_ELEMENTS:
    8076             :       case NO_ELEMENTS:
    8077             :         // No contained objects, nothing to do.
    8078             :         break;
    8079             :     }
    8080             :   }
    8081             : 
    8082             :   return copy;
    8083             : }
    8084             : 
    8085             : 
    8086      920835 : MaybeHandle<JSObject> JSObject::DeepWalk(
    8087             :     Handle<JSObject> object,
    8088             :     AllocationSiteCreationContext* site_context) {
    8089             :   JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, false,
    8090             :                                                        kNoHints);
    8091      920835 :   MaybeHandle<JSObject> result = v.StructureWalk(object);
    8092             :   Handle<JSObject> for_assert;
    8093             :   DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object));
    8094      920835 :   return result;
    8095             : }
    8096             : 
    8097             : 
    8098     7345609 : MaybeHandle<JSObject> JSObject::DeepCopy(
    8099             :     Handle<JSObject> object,
    8100             :     AllocationSiteUsageContext* site_context,
    8101             :     DeepCopyHints hints) {
    8102             :   JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints);
    8103     7345609 :   MaybeHandle<JSObject> copy = v.StructureWalk(object);
    8104             :   Handle<JSObject> for_assert;
    8105             :   DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object));
    8106     7345609 :   return copy;
    8107             : }
    8108             : 
    8109             : // static
    8110    10352699 : MaybeHandle<Object> JSReceiver::ToPrimitive(Handle<JSReceiver> receiver,
    8111             :                                             ToPrimitiveHint hint) {
    8112             :   Isolate* const isolate = receiver->GetIsolate();
    8113             :   Handle<Object> exotic_to_prim;
    8114    20705398 :   ASSIGN_RETURN_ON_EXCEPTION(
    8115             :       isolate, exotic_to_prim,
    8116             :       GetMethod(receiver, isolate->factory()->to_primitive_symbol()), Object);
    8117    10352693 :   if (!exotic_to_prim->IsUndefined(isolate)) {
    8118             :     Handle<Object> hint_string =
    8119        6539 :         isolate->factory()->ToPrimitiveHintString(hint);
    8120             :     Handle<Object> result;
    8121       13078 :     ASSIGN_RETURN_ON_EXCEPTION(
    8122             :         isolate, result,
    8123             :         Execution::Call(isolate, exotic_to_prim, receiver, 1, &hint_string),
    8124             :         Object);
    8125        6410 :     if (result->IsPrimitive()) return result;
    8126           0 :     THROW_NEW_ERROR(isolate,
    8127             :                     NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
    8128             :                     Object);
    8129             :   }
    8130             :   return OrdinaryToPrimitive(receiver, (hint == ToPrimitiveHint::kString)
    8131             :                                            ? OrdinaryToPrimitiveHint::kString
    8132    10346154 :                                            : OrdinaryToPrimitiveHint::kNumber);
    8133             : }
    8134             : 
    8135             : 
    8136             : // static
    8137    10346154 : MaybeHandle<Object> JSReceiver::OrdinaryToPrimitive(
    8138             :     Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint) {
    8139             :   Isolate* const isolate = receiver->GetIsolate();
    8140    31038462 :   Handle<String> method_names[2];
    8141    10346154 :   switch (hint) {
    8142             :     case OrdinaryToPrimitiveHint::kNumber:
    8143       12382 :       method_names[0] = isolate->factory()->valueOf_string();
    8144       12382 :       method_names[1] = isolate->factory()->toString_string();
    8145       12382 :       break;
    8146             :     case OrdinaryToPrimitiveHint::kString:
    8147    10333772 :       method_names[0] = isolate->factory()->toString_string();
    8148    10333772 :       method_names[1] = isolate->factory()->valueOf_string();
    8149    10333772 :       break;
    8150             :   }
    8151    10362949 :   for (Handle<String> name : method_names) {
    8152             :     Handle<Object> method;
    8153    20708884 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, method,
    8154             :                                JSReceiver::GetProperty(receiver, name), Object);
    8155    10354414 :     if (method->IsCallable()) {
    8156             :       Handle<Object> result;
    8157    20707314 :       ASSIGN_RETURN_ON_EXCEPTION(
    8158             :           isolate, result, Execution::Call(isolate, method, receiver, 0, NULL),
    8159             :           Object);
    8160    10332865 :       if (result->IsPrimitive()) return result;
    8161             :     }
    8162             :   }
    8163         438 :   THROW_NEW_ERROR(isolate,
    8164             :                   NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
    8165             :                   Object);
    8166             : }
    8167             : 
    8168             : 
    8169             : // TODO(cbruni/jkummerow): Consider moving this into elements.cc.
    8170      222954 : bool JSObject::HasEnumerableElements() {
    8171             :   // TODO(cbruni): cleanup
    8172             :   JSObject* object = this;
    8173      222954 :   switch (object->GetElementsKind()) {
    8174             :     case FAST_SMI_ELEMENTS:
    8175             :     case FAST_ELEMENTS:
    8176             :     case FAST_DOUBLE_ELEMENTS: {
    8177             :       int length = object->IsJSArray()
    8178             :                        ? Smi::cast(JSArray::cast(object)->length())->value()
    8179       89170 :                        : object->elements()->length();
    8180       89170 :       return length > 0;
    8181             :     }
    8182             :     case FAST_HOLEY_SMI_ELEMENTS:
    8183             :     case FAST_HOLEY_ELEMENTS: {
    8184             :       FixedArray* elements = FixedArray::cast(object->elements());
    8185             :       int length = object->IsJSArray()
    8186             :                        ? Smi::cast(JSArray::cast(object)->length())->value()
    8187      133339 :                        : elements->length();
    8188             :       Isolate* isolate = GetIsolate();
    8189     4028504 :       for (int i = 0; i < length; i++) {
    8190     3934375 :         if (!elements->is_the_hole(isolate, i)) return true;
    8191             :       }
    8192             :       return false;
    8193             :     }
    8194             :     case FAST_HOLEY_DOUBLE_ELEMENTS: {
    8195             :       int length = object->IsJSArray()
    8196             :                        ? Smi::cast(JSArray::cast(object)->length())->value()
    8197          75 :                        : object->elements()->length();
    8198             :       // Zero-length arrays would use the empty FixedArray...
    8199          75 :       if (length == 0) return false;
    8200             :       // ...so only cast to FixedDoubleArray otherwise.
    8201             :       FixedDoubleArray* elements = FixedDoubleArray::cast(object->elements());
    8202          75 :       for (int i = 0; i < length; i++) {
    8203          75 :         if (!elements->is_the_hole(i)) return true;
    8204             :       }
    8205             :       return false;
    8206             :     }
    8207             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
    8208             :     case TYPE##_ELEMENTS:
    8209             : 
    8210             :       TYPED_ARRAYS(TYPED_ARRAY_CASE)
    8211             : #undef TYPED_ARRAY_CASE
    8212             :       {
    8213             :         int length = object->elements()->length();
    8214           0 :         return length > 0;
    8215             :       }
    8216             :     case DICTIONARY_ELEMENTS: {
    8217             :       SeededNumberDictionary* elements =
    8218             :           SeededNumberDictionary::cast(object->elements());
    8219         280 :       return elements->NumberOfElementsFilterAttributes(ONLY_ENUMERABLE) > 0;
    8220             :     }
    8221             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    8222             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    8223             :       // We're approximating non-empty arguments objects here.
    8224             :       return true;
    8225             :     case FAST_STRING_WRAPPER_ELEMENTS:
    8226             :     case SLOW_STRING_WRAPPER_ELEMENTS:
    8227           0 :       if (String::cast(JSValue::cast(object)->value())->length() > 0) {
    8228             :         return true;
    8229             :       }
    8230           0 :       return object->elements()->length() > 0;
    8231             :     case NO_ELEMENTS:
    8232           0 :       return false;
    8233             :   }
    8234           0 :   UNREACHABLE();
    8235             :   return true;
    8236             : }
    8237             : 
    8238             : 
    8239      175387 : int Map::NumberOfDescribedProperties(DescriptorFlag which,
    8240             :                                      PropertyFilter filter) {
    8241             :   int result = 0;
    8242             :   DescriptorArray* descs = instance_descriptors();
    8243             :   int limit = which == ALL_DESCRIPTORS
    8244             :       ? descs->number_of_descriptors()
    8245      175387 :       : NumberOfOwnDescriptors();
    8246     1120658 :   for (int i = 0; i < limit; i++) {
    8247     2605272 :     if ((descs->GetDetails(i).attributes() & filter) == 0 &&
    8248      714730 :         !descs->GetKey(i)->FilterKey(filter)) {
    8249      712003 :       result++;
    8250             :     }
    8251             :   }
    8252      175387 :   return result;
    8253             : }
    8254             : 
    8255             : 
    8256     8783405 : int Map::NextFreePropertyIndex() {
    8257             :   int free_index = 0;
    8258             :   int number_of_own_descriptors = NumberOfOwnDescriptors();
    8259             :   DescriptorArray* descs = instance_descriptors();
    8260   289323401 :   for (int i = 0; i < number_of_own_descriptors; i++) {
    8261   280540009 :     PropertyDetails details = descs->GetDetails(i);
    8262   280539996 :     if (details.location() == kField) {
    8263   271074062 :       int candidate = details.field_index() + details.field_width_in_words();
    8264   271074062 :       if (candidate > free_index) free_index = candidate;
    8265             :     }
    8266             :   }
    8267     8783392 :   return free_index;
    8268             : }
    8269             : 
    8270             : 
    8271    16083027 : bool Map::OnlyHasSimpleProperties() {
    8272             :   // Wrapped string elements aren't explicitly stored in the elements backing
    8273             :   // store, but are loaded indirectly from the underlying string.
    8274    16078518 :   return !IsStringWrapperElementsKind(elements_kind()) &&
    8275    48181067 :          !IsSpecialReceiverMap() && !has_hidden_prototype() &&
    8276    16083027 :          !is_dictionary_map();
    8277             : }
    8278             : 
    8279        1064 : MUST_USE_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
    8280             :     Isolate* isolate, Handle<JSReceiver> receiver, bool get_entries,
    8281             :     Handle<FixedArray>* result) {
    8282             :   Handle<Map> map(JSReceiver::cast(*receiver)->map(), isolate);
    8283             : 
    8284        1064 :   if (!map->IsJSObjectMap()) return Just(false);
    8285         616 :   if (!map->OnlyHasSimpleProperties()) return Just(false);
    8286             : 
    8287             :   Handle<JSObject> object(JSObject::cast(*receiver));
    8288             : 
    8289             :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    8290             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    8291             :   int number_of_own_elements =
    8292         952 :       object->GetElementsAccessor()->GetCapacity(*object, object->elements());
    8293             :   Handle<FixedArray> values_or_entries = isolate->factory()->NewFixedArray(
    8294         476 :       number_of_own_descriptors + number_of_own_elements);
    8295         476 :   int count = 0;
    8296             : 
    8297         476 :   if (object->elements() != isolate->heap()->empty_fixed_array()) {
    8298         336 :     MAYBE_RETURN(object->GetElementsAccessor()->CollectValuesOrEntries(
    8299             :                      isolate, object, values_or_entries, get_entries, &count,
    8300             :                      ENUMERABLE_STRINGS),
    8301             :                  Nothing<bool>());
    8302             :   }
    8303             : 
    8304         476 :   bool stable = object->map() == *map;
    8305             : 
    8306        1792 :   for (int index = 0; index < number_of_own_descriptors; index++) {
    8307             :     Handle<Name> next_key(descriptors->GetKey(index), isolate);
    8308        1316 :     if (!next_key->IsString()) continue;
    8309             :     Handle<Object> prop_value;
    8310             : 
    8311             :     // Directly decode from the descriptor array if |from| did not change shape.
    8312        1176 :     if (stable) {
    8313        1148 :       PropertyDetails details = descriptors->GetDetails(index);
    8314        1148 :       if (!details.IsEnumerable()) continue;
    8315         784 :       if (details.kind() == kData) {
    8316         728 :         if (details.location() == kDescriptor) {
    8317             :           prop_value = handle(descriptors->GetValue(index), isolate);
    8318             :         } else {
    8319         728 :           Representation representation = details.representation();
    8320         728 :           FieldIndex field_index = FieldIndex::ForDescriptor(*map, index);
    8321             :           prop_value =
    8322         728 :               JSObject::FastPropertyAt(object, representation, field_index);
    8323             :         }
    8324             :       } else {
    8325         112 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8326             :             isolate, prop_value, JSReceiver::GetProperty(object, next_key),
    8327             :             Nothing<bool>());
    8328          56 :         stable = object->map() == *map;
    8329             :       }
    8330             :     } else {
    8331             :       // If the map did change, do a slower lookup. We are still guaranteed that
    8332             :       // the object has a simple shape, and that the key is a name.
    8333          28 :       LookupIterator it(object, next_key, LookupIterator::OWN_SKIP_INTERCEPTOR);
    8334          28 :       if (!it.IsFound()) continue;
    8335             :       DCHECK(it.state() == LookupIterator::DATA ||
    8336             :              it.state() == LookupIterator::ACCESSOR);
    8337          28 :       if (!it.IsEnumerable()) continue;
    8338          56 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8339             :           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
    8340             :     }
    8341             : 
    8342         812 :     if (get_entries) {
    8343         560 :       prop_value = MakeEntryPair(isolate, next_key, prop_value);
    8344             :     }
    8345             : 
    8346        1624 :     values_or_entries->set(count, *prop_value);
    8347         812 :     count++;
    8348             :   }
    8349             : 
    8350         476 :   if (count < values_or_entries->length()) values_or_entries->Shrink(count);
    8351         476 :   *result = values_or_entries;
    8352             :   return Just(true);
    8353             : }
    8354             : 
    8355        1064 : MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
    8356             :                                               Handle<JSReceiver> object,
    8357             :                                               PropertyFilter filter,
    8358             :                                               bool get_entries) {
    8359             :   Handle<FixedArray> values_or_entries;
    8360        1064 :   if (filter == ENUMERABLE_STRINGS) {
    8361             :     Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries(
    8362        1064 :         isolate, object, get_entries, &values_or_entries);
    8363        1540 :     if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>();
    8364        1064 :     if (fast_values_or_entries.FromJust()) return values_or_entries;
    8365             :   }
    8366             : 
    8367             :   PropertyFilter key_filter =
    8368         588 :       static_cast<PropertyFilter>(filter & ~ONLY_ENUMERABLE);
    8369             : 
    8370             :   Handle<FixedArray> keys;
    8371        1176 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8372             :       isolate, keys,
    8373             :       KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, key_filter,
    8374             :                               GetKeysConversion::kConvertToString),
    8375             :       MaybeHandle<FixedArray>());
    8376             : 
    8377         588 :   values_or_entries = isolate->factory()->NewFixedArray(keys->length());
    8378             :   int length = 0;
    8379             : 
    8380        5152 :   for (int i = 0; i < keys->length(); ++i) {
    8381             :     Handle<Name> key = Handle<Name>::cast(handle(keys->get(i), isolate));
    8382             : 
    8383        1988 :     if (filter & ONLY_ENUMERABLE) {
    8384             :       PropertyDescriptor descriptor;
    8385             :       Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
    8386        1988 :           isolate, object, key, &descriptor);
    8387        1988 :       MAYBE_RETURN(did_get_descriptor, MaybeHandle<FixedArray>());
    8388        3948 :       if (!did_get_descriptor.FromJust() || !descriptor.enumerable()) continue;
    8389             :     }
    8390             : 
    8391             :     Handle<Object> value;
    8392        2744 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8393             :         isolate, value, JSReceiver::GetPropertyOrElement(object, key),
    8394             :         MaybeHandle<FixedArray>());
    8395             : 
    8396        1372 :     if (get_entries) {
    8397             :       Handle<FixedArray> entry_storage =
    8398         686 :           isolate->factory()->NewUninitializedFixedArray(2);
    8399         686 :       entry_storage->set(0, *key);
    8400         686 :       entry_storage->set(1, *value);
    8401             :       value = isolate->factory()->NewJSArrayWithElements(entry_storage,
    8402         686 :                                                          FAST_ELEMENTS, 2);
    8403             :     }
    8404             : 
    8405        1372 :     values_or_entries->set(length, *value);
    8406        1372 :     length++;
    8407             :   }
    8408         588 :   if (length < values_or_entries->length()) values_or_entries->Shrink(length);
    8409             :   return values_or_entries;
    8410             : }
    8411             : 
    8412         518 : MaybeHandle<FixedArray> JSReceiver::GetOwnValues(Handle<JSReceiver> object,
    8413             :                                                  PropertyFilter filter) {
    8414         518 :   return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, false);
    8415             : }
    8416             : 
    8417         546 : MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object,
    8418             :                                                   PropertyFilter filter) {
    8419         546 :   return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, true);
    8420             : }
    8421             : 
    8422      303091 : bool Map::DictionaryElementsInPrototypeChainOnly() {
    8423      303091 :   if (IsDictionaryElementsKind(elements_kind())) {
    8424             :     return false;
    8425             :   }
    8426             : 
    8427      891548 :   for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) {
    8428             :     // Be conservative, don't walk into proxies.
    8429     1205650 :     if (iter.GetCurrent()->IsJSProxy()) return true;
    8430             :     // String wrappers have non-configurable, non-writable elements.
    8431     1205650 :     if (iter.GetCurrent()->IsStringWrapper()) return true;
    8432      602780 :     JSObject* current = iter.GetCurrent<JSObject>();
    8433             : 
    8434      613997 :     if (current->HasDictionaryElements() &&
    8435       11217 :         current->element_dictionary()->requires_slow_elements()) {
    8436             :       return true;
    8437             :     }
    8438             : 
    8439      591882 :     if (current->HasSlowArgumentsElements()) {
    8440             :       FixedArray* parameter_map = FixedArray::cast(current->elements());
    8441             :       Object* arguments = parameter_map->get(1);
    8442           0 :       if (SeededNumberDictionary::cast(arguments)->requires_slow_elements()) {
    8443             :         return true;
    8444             :       }
    8445             :     }
    8446             :   }
    8447             : 
    8448      288723 :   return false;
    8449             : }
    8450             : 
    8451             : 
    8452      386592 : MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
    8453             :                                              Handle<Name> name,
    8454             :                                              Handle<Object> getter,
    8455             :                                              Handle<Object> setter,
    8456             :                                              PropertyAttributes attributes) {
    8457             :   Isolate* isolate = object->GetIsolate();
    8458             : 
    8459             :   LookupIterator it = LookupIterator::PropertyOrElement(
    8460      386592 :       isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    8461      386593 :   return DefineAccessor(&it, getter, setter, attributes);
    8462             : }
    8463             : 
    8464             : 
    8465     1524592 : MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
    8466             :                                              Handle<Object> getter,
    8467             :                                              Handle<Object> setter,
    8468             :                                              PropertyAttributes attributes) {
    8469             :   Isolate* isolate = it->isolate();
    8470             : 
    8471      508199 :   it->UpdateProtector();
    8472             : 
    8473      508200 :   if (it->state() == LookupIterator::ACCESS_CHECK) {
    8474        2657 :     if (!it->HasAccess()) {
    8475           6 :       isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    8476           6 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    8477             :       return isolate->factory()->undefined_value();
    8478             :     }
    8479        2651 :     it->Next();
    8480             :   }
    8481             : 
    8482             :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    8483             :   // Ignore accessors on typed arrays.
    8484      547507 :   if (it->IsElement() && object->HasFixedTypedArrayElements()) {
    8485             :     return it->factory()->undefined_value();
    8486             :   }
    8487             : 
    8488             :   DCHECK(getter->IsCallable() || getter->IsUndefined(isolate) ||
    8489             :          getter->IsNull(isolate) || getter->IsFunctionTemplateInfo());
    8490             :   DCHECK(setter->IsCallable() || setter->IsUndefined(isolate) ||
    8491             :          setter->IsNull(isolate) || setter->IsFunctionTemplateInfo());
    8492      508193 :   it->TransitionToAccessorProperty(getter, setter, attributes);
    8493             : 
    8494             :   return isolate->factory()->undefined_value();
    8495             : }
    8496             : 
    8497             : 
    8498      118446 : MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
    8499             :                                           Handle<AccessorInfo> info) {
    8500             :   Isolate* isolate = object->GetIsolate();
    8501             :   Handle<Name> name(Name::cast(info->name()), isolate);
    8502             : 
    8503             :   LookupIterator it = LookupIterator::PropertyOrElement(
    8504      118446 :       isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    8505             : 
    8506             :   // Duplicate ACCESS_CHECK outside of GetPropertyAttributes for the case that
    8507             :   // the FailedAccessCheckCallbackFunction doesn't throw an exception.
    8508             :   //
    8509             :   // TODO(verwaest): Force throw an exception if the callback doesn't, so we can
    8510             :   // remove reliance on default return values.
    8511      118446 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    8512        6955 :     if (!it.HasAccess()) {
    8513           6 :       isolate->ReportFailedAccessCheck(object);
    8514           6 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    8515           0 :       return it.factory()->undefined_value();
    8516             :     }
    8517        6949 :     it.Next();
    8518             :   }
    8519             : 
    8520             :   // Ignore accessors on typed arrays.
    8521      118454 :   if (it.IsElement() && object->HasFixedTypedArrayElements()) {
    8522           0 :     return it.factory()->undefined_value();
    8523             :   }
    8524             : 
    8525      118440 :   CHECK(GetPropertyAttributes(&it).IsJust());
    8526             : 
    8527             :   // ES5 forbids turning a property into an accessor if it's not
    8528             :   // configurable. See 8.6.1 (Table 5).
    8529      118483 :   if (it.IsFound() && !it.IsConfigurable()) {
    8530          29 :     return it.factory()->undefined_value();
    8531             :   }
    8532             : 
    8533      118411 :   it.TransitionToAccessorPair(info, info->property_attributes());
    8534             : 
    8535             :   return object;
    8536             : }
    8537             : 
    8538          84 : Object* JSObject::SlowReverseLookup(Object* value) {
    8539          84 :   if (HasFastProperties()) {
    8540             :     int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
    8541             :     DescriptorArray* descs = map()->instance_descriptors();
    8542             :     bool value_is_number = value->IsNumber();
    8543         252 :     for (int i = 0; i < number_of_own_descriptors; i++) {
    8544         210 :       PropertyDetails details = descs->GetDetails(i);
    8545         210 :       if (details.location() == kField) {
    8546             :         DCHECK_EQ(kData, details.kind());
    8547          28 :         FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
    8548          28 :         if (IsUnboxedDoubleField(field_index)) {
    8549           0 :           if (value_is_number) {
    8550             :             double property = RawFastDoublePropertyAt(field_index);
    8551           0 :             if (property == value->Number()) {
    8552          28 :               return descs->GetKey(i);
    8553             :             }
    8554             :           }
    8555             :         } else {
    8556          28 :           Object* property = RawFastPropertyAt(field_index);
    8557          28 :           if (field_index.is_double()) {
    8558             :             DCHECK(property->IsMutableHeapNumber());
    8559           0 :             if (value_is_number && property->Number() == value->Number()) {
    8560           0 :               return descs->GetKey(i);
    8561             :             }
    8562          28 :           } else if (property == value) {
    8563          28 :             return descs->GetKey(i);
    8564             :           }
    8565             :         }
    8566             :       } else {
    8567             :         DCHECK_EQ(kDescriptor, details.location());
    8568         182 :         if (details.kind() == kData) {
    8569         168 :           if (descs->GetValue(i) == value) {
    8570           0 :             return descs->GetKey(i);
    8571             :           }
    8572             :         }
    8573             :       }
    8574             :     }
    8575          42 :     return GetHeap()->undefined_value();
    8576          14 :   } else if (IsJSGlobalObject()) {
    8577          14 :     return global_dictionary()->SlowReverseLookup(value);
    8578             :   } else {
    8579           0 :     return property_dictionary()->SlowReverseLookup(value);
    8580             :   }
    8581             : }
    8582             : 
    8583             : 
    8584    25922194 : Handle<Map> Map::RawCopy(Handle<Map> map, int instance_size) {
    8585             :   Isolate* isolate = map->GetIsolate();
    8586             :   Handle<Map> result =
    8587    25922194 :       isolate->factory()->NewMap(map->instance_type(), instance_size);
    8588             :   Handle<Object> prototype(map->prototype(), isolate);
    8589    25922198 :   Map::SetPrototype(result, prototype);
    8590    51844417 :   result->set_constructor_or_backpointer(map->GetConstructor());
    8591             :   result->set_bit_field(map->bit_field());
    8592             :   result->set_bit_field2(map->bit_field2());
    8593             :   int new_bit_field3 = map->bit_field3();
    8594             :   new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
    8595             :   new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
    8596             :   new_bit_field3 = EnumLengthBits::update(new_bit_field3,
    8597             :                                           kInvalidEnumCacheSentinel);
    8598    25922212 :   new_bit_field3 = Deprecated::update(new_bit_field3, false);
    8599    25922212 :   if (!map->is_dictionary_map()) {
    8600    24640893 :     new_bit_field3 = IsUnstable::update(new_bit_field3, false);
    8601             :   }
    8602    25922212 :   result->set_bit_field3(new_bit_field3);
    8603    25922212 :   return result;
    8604             : }
    8605             : 
    8606             : 
    8607     1318662 : Handle<Map> Map::Normalize(Handle<Map> fast_map, PropertyNormalizationMode mode,
    8608             :                            const char* reason) {
    8609             :   DCHECK(!fast_map->is_dictionary_map());
    8610             : 
    8611      329942 :   Isolate* isolate = fast_map->GetIsolate();
    8612             :   Handle<Object> maybe_cache(isolate->native_context()->normalized_map_cache(),
    8613     2637324 :                              isolate);
    8614             :   bool use_cache =
    8615     2402465 :       !fast_map->is_prototype_map() && !maybe_cache->IsUndefined(isolate);
    8616             :   Handle<NormalizedMapCache> cache;
    8617     1318662 :   if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache);
    8618             : 
    8619             :   Handle<Map> new_map;
    8620     3485320 :   if (use_cache && cache->Get(fast_map, mode).ToHandle(&new_map)) {
    8621             : #ifdef VERIFY_HEAP
    8622             :     if (FLAG_verify_heap) new_map->DictionaryMapVerify();
    8623             : #endif
    8624             : #ifdef ENABLE_SLOW_DCHECKS
    8625             :     if (FLAG_enable_slow_asserts) {
    8626             :       // The cached map should match newly created normalized map bit-by-bit,
    8627             :       // except for the code cache, which can contain some ics which can be
    8628             :       // applied to the shared map, dependent code and weak cell cache.
    8629             :       Handle<Map> fresh = Map::CopyNormalized(fast_map, mode);
    8630             : 
    8631             :       if (new_map->is_prototype_map()) {
    8632             :         // For prototype maps, the PrototypeInfo is not copied.
    8633             :         DCHECK(memcmp(fresh->address(), new_map->address(),
    8634             :                       kTransitionsOrPrototypeInfoOffset) == 0);
    8635             :         DCHECK(fresh->raw_transitions() == Smi::kZero);
    8636             :         STATIC_ASSERT(kDescriptorsOffset ==
    8637             :                       kTransitionsOrPrototypeInfoOffset + kPointerSize);
    8638             :         DCHECK(memcmp(HeapObject::RawField(*fresh, kDescriptorsOffset),
    8639             :                       HeapObject::RawField(*new_map, kDescriptorsOffset),
    8640             :                       kCodeCacheOffset - kDescriptorsOffset) == 0);
    8641             :       } else {
    8642             :         DCHECK(memcmp(fresh->address(), new_map->address(),
    8643             :                       Map::kCodeCacheOffset) == 0);
    8644             :       }
    8645             :       STATIC_ASSERT(Map::kDependentCodeOffset ==
    8646             :                     Map::kCodeCacheOffset + kPointerSize);
    8647             :       STATIC_ASSERT(Map::kWeakCellCacheOffset ==
    8648             :                     Map::kDependentCodeOffset + kPointerSize);
    8649             :       int offset = Map::kWeakCellCacheOffset + kPointerSize;
    8650             :       DCHECK(memcmp(fresh->address() + offset,
    8651             :                     new_map->address() + offset,
    8652             :                     Map::kSize - offset) == 0);
    8653             :     }
    8654             : #endif
    8655             :   } else {
    8656      565275 :     new_map = Map::CopyNormalized(fast_map, mode);
    8657      565275 :     if (use_cache) {
    8658      329942 :       cache->Set(fast_map, new_map);
    8659      329942 :       isolate->counters()->maps_normalized()->Increment();
    8660             :     }
    8661             : #if TRACE_MAPS
    8662             :     if (FLAG_trace_maps) {
    8663             :       PrintF("[TraceMaps: Normalize from= %p to= %p reason= %s ]\n",
    8664             :              reinterpret_cast<void*>(*fast_map),
    8665             :              reinterpret_cast<void*>(*new_map), reason);
    8666             :     }
    8667             : #endif
    8668             :   }
    8669     1318662 :   fast_map->NotifyLeafMapLayoutChange();
    8670     1318662 :   return new_map;
    8671             : }
    8672             : 
    8673             : 
    8674      565275 : Handle<Map> Map::CopyNormalized(Handle<Map> map,
    8675             :                                 PropertyNormalizationMode mode) {
    8676             :   int new_instance_size = map->instance_size();
    8677      565275 :   if (mode == CLEAR_INOBJECT_PROPERTIES) {
    8678      110251 :     new_instance_size -= map->GetInObjectProperties() * kPointerSize;
    8679             :   }
    8680             : 
    8681      565275 :   Handle<Map> result = RawCopy(map, new_instance_size);
    8682             : 
    8683      565275 :   if (mode != CLEAR_INOBJECT_PROPERTIES) {
    8684             :     result->SetInObjectProperties(map->GetInObjectProperties());
    8685             :   }
    8686             : 
    8687             :   result->set_dictionary_map(true);
    8688             :   result->set_migration_target(false);
    8689             :   result->set_construction_counter(kNoSlackTracking);
    8690             : 
    8691             : #ifdef VERIFY_HEAP
    8692             :   if (FLAG_verify_heap) result->DictionaryMapVerify();
    8693             : #endif
    8694             : 
    8695      565275 :   return result;
    8696             : }
    8697             : 
    8698             : // Return an immutable prototype exotic object version of the input map.
    8699             : // Never even try to cache it in the transition tree, as it is intended
    8700             : // for the global object and its prototype chain, and excluding it saves
    8701             : // memory on the map transition tree.
    8702             : 
    8703             : // static
    8704           7 : Handle<Map> Map::TransitionToImmutableProto(Handle<Map> map) {
    8705           7 :   Handle<Map> new_map = Map::Copy(map, "ImmutablePrototype");
    8706             :   new_map->set_immutable_proto(true);
    8707           7 :   return new_map;
    8708             : }
    8709             : 
    8710      410519 : Handle<Map> Map::CopyInitialMap(Handle<Map> map, int instance_size,
    8711             :                                 int in_object_properties,
    8712             :                                 int unused_property_fields) {
    8713             : #ifdef DEBUG
    8714             :   Isolate* isolate = map->GetIsolate();
    8715             :   // Strict function maps have Function as a constructor but the
    8716             :   // Function's initial map is a sloppy function map. Same holds for
    8717             :   // GeneratorFunction / AsyncFunction and its initial map.
    8718             :   Object* constructor = map->GetConstructor();
    8719             :   DCHECK(constructor->IsJSFunction());
    8720             :   DCHECK(*map == JSFunction::cast(constructor)->initial_map() ||
    8721             :          *map == *isolate->strict_function_map() ||
    8722             :          *map == *isolate->generator_function_map() ||
    8723             :          *map == *isolate->async_function_map());
    8724             : #endif
    8725             :   // Initial maps must always own their descriptors and it's descriptor array
    8726             :   // does not contain descriptors that do not belong to the map.
    8727             :   DCHECK(map->owns_descriptors());
    8728             :   DCHECK_EQ(map->NumberOfOwnDescriptors(),
    8729             :             map->instance_descriptors()->number_of_descriptors());
    8730             : 
    8731      410519 :   Handle<Map> result = RawCopy(map, instance_size);
    8732             : 
    8733             :   // Please note instance_type and instance_size are set when allocated.
    8734             :   result->SetInObjectProperties(in_object_properties);
    8735             :   result->set_unused_property_fields(unused_property_fields);
    8736             : 
    8737             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    8738      410521 :   if (number_of_own_descriptors > 0) {
    8739             :     // The copy will use the same descriptors array.
    8740             :     result->UpdateDescriptors(map->instance_descriptors(),
    8741      214379 :                               map->GetLayoutDescriptor());
    8742             :     result->SetNumberOfOwnDescriptors(number_of_own_descriptors);
    8743             : 
    8744             :     DCHECK_EQ(result->NumberOfFields(),
    8745             :               in_object_properties - unused_property_fields);
    8746             :   }
    8747             : 
    8748      410521 :   return result;
    8749             : }
    8750             : 
    8751             : 
    8752    24946405 : Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) {
    8753    24946405 :   Handle<Map> result = RawCopy(map, map->instance_size());
    8754             : 
    8755             :   // Please note instance_type and instance_size are set when allocated.
    8756    24946418 :   if (map->IsJSObjectMap()) {
    8757             :     result->SetInObjectProperties(map->GetInObjectProperties());
    8758             :     result->set_unused_property_fields(map->unused_property_fields());
    8759             :   }
    8760             :   result->ClearCodeCache(map->GetHeap());
    8761    24946418 :   map->NotifyLeafMapLayoutChange();
    8762    24946414 :   return result;
    8763             : }
    8764             : 
    8765             : 
    8766     9529929 : Handle<Map> Map::ShareDescriptor(Handle<Map> map,
    8767             :                                  Handle<DescriptorArray> descriptors,
    8768             :                                  Descriptor* descriptor) {
    8769             :   // Sanity check. This path is only to be taken if the map owns its descriptor
    8770             :   // array, implying that its NumberOfOwnDescriptors equals the number of
    8771             :   // descriptors in the descriptor array.
    8772             :   DCHECK_EQ(map->NumberOfOwnDescriptors(),
    8773             :             map->instance_descriptors()->number_of_descriptors());
    8774             : 
    8775     9529929 :   Handle<Map> result = CopyDropDescriptors(map);
    8776     9529934 :   Handle<Name> name = descriptor->GetKey();
    8777             : 
    8778             :   // Ensure there's space for the new descriptor in the shared descriptor array.
    8779     9529934 :   if (descriptors->NumberOfSlackDescriptors() == 0) {
    8780     5829126 :     int old_size = descriptors->number_of_descriptors();
    8781     5829126 :     if (old_size == 0) {
    8782         531 :       descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1);
    8783             :     } else {
    8784     5828595 :       int slack = SlackForArraySize(old_size, kMaxNumberOfDescriptors);
    8785     5828595 :       EnsureDescriptorSlack(map, slack);
    8786             :       descriptors = handle(map->instance_descriptors());
    8787             :     }
    8788             :   }
    8789             : 
    8790             :   Handle<LayoutDescriptor> layout_descriptor =
    8791             :       FLAG_unbox_double_fields
    8792             :           ? LayoutDescriptor::ShareAppend(map, descriptor->GetDetails())
    8793     9529932 :           : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate());
    8794             : 
    8795             :   {
    8796             :     DisallowHeapAllocation no_gc;
    8797     9529930 :     descriptors->Append(descriptor);
    8798     9529933 :     result->InitializeDescriptors(*descriptors, *layout_descriptor);
    8799             :   }
    8800             : 
    8801             :   DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
    8802     9529931 :   ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION);
    8803             : 
    8804     9529934 :   return result;
    8805             : }
    8806             : 
    8807             : 
    8808             : #if TRACE_MAPS
    8809             : 
    8810             : // static
    8811             : void Map::TraceTransition(const char* what, Map* from, Map* to, Name* name) {
    8812             :   if (FLAG_trace_maps) {
    8813             :     PrintF("[TraceMaps: %s from= %p to= %p name= ", what,
    8814             :            reinterpret_cast<void*>(from), reinterpret_cast<void*>(to));
    8815             :     name->NameShortPrint();
    8816             :     PrintF(" ]\n");
    8817             :   }
    8818             : }
    8819             : 
    8820             : 
    8821             : // static
    8822             : void Map::TraceAllTransitions(Map* map) {
    8823             :   Object* transitions = map->raw_transitions();
    8824             :   int num_transitions = TransitionArray::NumberOfTransitions(transitions);
    8825             :   for (int i = -0; i < num_transitions; ++i) {
    8826             :     Map* target = TransitionArray::GetTarget(transitions, i);
    8827             :     Name* key = TransitionArray::GetKey(transitions, i);
    8828             :     Map::TraceTransition("Transition", map, target, key);
    8829             :     Map::TraceAllTransitions(target);
    8830             :   }
    8831             : }
    8832             : 
    8833             : #endif  // TRACE_MAPS
    8834             : 
    8835             : 
    8836    11753241 : void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child,
    8837             :                             Handle<Name> name, SimpleTransitionFlag flag) {
    8838    23506487 :   if (!parent->GetBackPointer()->IsUndefined(parent->GetIsolate())) {
    8839             :     parent->set_owns_descriptors(false);
    8840             :   } else {
    8841             :     // |parent| is initial map and it must keep the ownership, there must be no
    8842             :     // descriptors in the descriptors array that do not belong to the map.
    8843             :     DCHECK(parent->owns_descriptors());
    8844             :     DCHECK_EQ(parent->NumberOfOwnDescriptors(),
    8845             :               parent->instance_descriptors()->number_of_descriptors());
    8846             :   }
    8847    11753246 :   if (parent->is_prototype_map()) {
    8848             :     DCHECK(child->is_prototype_map());
    8849             : #if TRACE_MAPS
    8850             :     Map::TraceTransition("NoTransition", *parent, *child, *name);
    8851             : #endif
    8852             :   } else {
    8853    11753246 :     TransitionArray::Insert(parent, name, child, flag);
    8854             : #if TRACE_MAPS
    8855             :     Map::TraceTransition("Transition", *parent, *child, *name);
    8856             : #endif
    8857             :   }
    8858    11753246 : }
    8859             : 
    8860             : 
    8861    14395438 : Handle<Map> Map::CopyReplaceDescriptors(
    8862             :     Handle<Map> map, Handle<DescriptorArray> descriptors,
    8863             :     Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
    8864             :     MaybeHandle<Name> maybe_name, const char* reason,
    8865             :     SimpleTransitionFlag simple_flag) {
    8866             :   DCHECK(descriptors->IsSortedNoDuplicates());
    8867             : 
    8868    14395438 :   Handle<Map> result = CopyDropDescriptors(map);
    8869             : 
    8870    14395444 :   if (!map->is_prototype_map()) {
    8871    11255359 :     if (flag == INSERT_TRANSITION &&
    8872     1832059 :         TransitionArray::CanHaveMoreTransitions(map)) {
    8873     1832059 :       result->InitializeDescriptors(*descriptors, *layout_descriptor);
    8874             : 
    8875             :       Handle<Name> name;
    8876     1832060 :       CHECK(maybe_name.ToHandle(&name));
    8877     1832060 :       ConnectTransition(map, result, name, simple_flag);
    8878             :     } else {
    8879     7591241 :       descriptors->GeneralizeAllFields();
    8880             :       result->InitializeDescriptors(*descriptors,
    8881     7591243 :                                     LayoutDescriptor::FastPointerLayout());
    8882             :     }
    8883             :   } else {
    8884     4972144 :     result->InitializeDescriptors(*descriptors, *layout_descriptor);
    8885             :   }
    8886             : #if TRACE_MAPS
    8887             :   if (FLAG_trace_maps &&
    8888             :       // Mirror conditions above that did not call ConnectTransition().
    8889             :       (map->is_prototype_map() ||
    8890             :        !(flag == INSERT_TRANSITION &&
    8891             :          TransitionArray::CanHaveMoreTransitions(map)))) {
    8892             :     PrintF("[TraceMaps: ReplaceDescriptors from= %p to= %p reason= %s ]\n",
    8893             :            reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*result),
    8894             :            reason);
    8895             :   }
    8896             : #endif
    8897             : 
    8898    14395443 :   return result;
    8899             : }
    8900             : 
    8901             : 
    8902             : // Creates transition tree starting from |split_map| and adding all descriptors
    8903             : // starting from descriptor with index |split_map|.NumberOfOwnDescriptors().
    8904             : // The way how it is done is tricky because of GC and special descriptors
    8905             : // marking logic.
    8906      167598 : Handle<Map> Map::AddMissingTransitions(
    8907             :     Handle<Map> split_map, Handle<DescriptorArray> descriptors,
    8908             :     Handle<LayoutDescriptor> full_layout_descriptor) {
    8909             :   DCHECK(descriptors->IsSortedNoDuplicates());
    8910             :   int split_nof = split_map->NumberOfOwnDescriptors();
    8911      167598 :   int nof_descriptors = descriptors->number_of_descriptors();
    8912             :   DCHECK_LT(split_nof, nof_descriptors);
    8913             : 
    8914             :   // Start with creating last map which will own full descriptors array.
    8915             :   // This is necessary to guarantee that GC will mark the whole descriptor
    8916             :   // array if any of the allocations happening below fail.
    8917             :   // Number of unused properties is temporarily incorrect and the layout
    8918             :   // descriptor could unnecessarily be in slow mode but we will fix after
    8919             :   // all the other intermediate maps are created.
    8920      167598 :   Handle<Map> last_map = CopyDropDescriptors(split_map);
    8921      167598 :   last_map->InitializeDescriptors(*descriptors, *full_layout_descriptor);
    8922             :   last_map->set_unused_property_fields(0);
    8923             : 
    8924             :   // During creation of intermediate maps we violate descriptors sharing
    8925             :   // invariant since the last map is not yet connected to the transition tree
    8926             :   // we create here. But it is safe because GC never trims map's descriptors
    8927             :   // if there are no dead transitions from that map and this is exactly the
    8928             :   // case for all the intermediate maps we create here.
    8929             :   Handle<Map> map = split_map;
    8930      248953 :   for (int i = split_nof; i < nof_descriptors - 1; ++i) {
    8931       81355 :     Handle<Map> new_map = CopyDropDescriptors(map);
    8932       81355 :     InstallDescriptors(map, new_map, i, descriptors, full_layout_descriptor);
    8933       81355 :     map = new_map;
    8934             :   }
    8935      167598 :   map->NotifyLeafMapLayoutChange();
    8936             :   InstallDescriptors(map, last_map, nof_descriptors - 1, descriptors,
    8937      167598 :                      full_layout_descriptor);
    8938      167598 :   return last_map;
    8939             : }
    8940             : 
    8941             : 
    8942             : // Since this method is used to rewrite an existing transition tree, it can
    8943             : // always insert transitions without checking.
    8944      248953 : void Map::InstallDescriptors(Handle<Map> parent, Handle<Map> child,
    8945             :                              int new_descriptor,
    8946             :                              Handle<DescriptorArray> descriptors,
    8947             :                              Handle<LayoutDescriptor> full_layout_descriptor) {
    8948             :   DCHECK(descriptors->IsSortedNoDuplicates());
    8949             : 
    8950      248953 :   child->set_instance_descriptors(*descriptors);
    8951      248953 :   child->SetNumberOfOwnDescriptors(new_descriptor + 1);
    8952             : 
    8953             :   int unused_property_fields = parent->unused_property_fields();
    8954      248953 :   PropertyDetails details = descriptors->GetDetails(new_descriptor);
    8955      248953 :   if (details.location() == kField) {
    8956      231522 :     unused_property_fields = parent->unused_property_fields() - 1;
    8957      231522 :     if (unused_property_fields < 0) {
    8958       21521 :       unused_property_fields += JSObject::kFieldsAdded;
    8959             :     }
    8960             :   }
    8961             :   child->set_unused_property_fields(unused_property_fields);
    8962             : 
    8963             :   if (FLAG_unbox_double_fields) {
    8964             :     Handle<LayoutDescriptor> layout_descriptor =
    8965             :         LayoutDescriptor::AppendIfFastOrUseFull(parent, details,
    8966      248953 :                                                 full_layout_descriptor);
    8967      248953 :     child->set_layout_descriptor(*layout_descriptor);
    8968             : #ifdef VERIFY_HEAP
    8969             :     // TODO(ishell): remove these checks from VERIFY_HEAP mode.
    8970             :     if (FLAG_verify_heap) {
    8971             :       CHECK(child->layout_descriptor()->IsConsistentWithMap(*child));
    8972             :     }
    8973             : #else
    8974             :     SLOW_DCHECK(child->layout_descriptor()->IsConsistentWithMap(*child));
    8975             : #endif
    8976      248953 :     child->set_visitor_id(Heap::GetStaticVisitorIdForMap(*child));
    8977             :   }
    8978             : 
    8979      248953 :   Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
    8980      248953 :   ConnectTransition(parent, child, name, SIMPLE_PROPERTY_TRANSITION);
    8981      248953 : }
    8982             : 
    8983             : 
    8984      273704 : Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
    8985             :                                     TransitionFlag flag) {
    8986             :   Map* maybe_elements_transition_map = NULL;
    8987      273704 :   if (flag == INSERT_TRANSITION) {
    8988             :     // Ensure we are requested to add elements kind transition "near the root".
    8989             :     DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(),
    8990             :               map->NumberOfOwnDescriptors());
    8991             : 
    8992             :     maybe_elements_transition_map = map->ElementsTransitionMap();
    8993             :     DCHECK(maybe_elements_transition_map == NULL ||
    8994             :            (maybe_elements_transition_map->elements_kind() ==
    8995             :                 DICTIONARY_ELEMENTS &&
    8996             :             kind == DICTIONARY_ELEMENTS));
    8997             :     DCHECK(!IsFastElementsKind(kind) ||
    8998             :            IsMoreGeneralElementsKindTransition(map->elements_kind(), kind));
    8999             :     DCHECK(kind != map->elements_kind());
    9000             :   }
    9001             : 
    9002      268315 :   bool insert_transition = flag == INSERT_TRANSITION &&
    9003      415835 :                            TransitionArray::CanHaveMoreTransitions(map) &&
    9004             :                            maybe_elements_transition_map == NULL;
    9005             : 
    9006      273704 :   if (insert_transition) {
    9007      142131 :     Handle<Map> new_map = CopyForTransition(map, "CopyAsElementsKind");
    9008             :     new_map->set_elements_kind(kind);
    9009             : 
    9010             :     Isolate* isolate = map->GetIsolate();
    9011             :     Handle<Name> name = isolate->factory()->elements_transition_symbol();
    9012      142131 :     ConnectTransition(map, new_map, name, SPECIAL_TRANSITION);
    9013      142131 :     return new_map;
    9014             :   }
    9015             : 
    9016             :   // Create a new free-floating map only if we are not allowed to store it.
    9017      131573 :   Handle<Map> new_map = Copy(map, "CopyAsElementsKind");
    9018             :   new_map->set_elements_kind(kind);
    9019      131573 :   return new_map;
    9020             : }
    9021             : 
    9022             : 
    9023         731 : Handle<Map> Map::AsLanguageMode(Handle<Map> initial_map,
    9024             :                                 LanguageMode language_mode, FunctionKind kind) {
    9025             :   DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
    9026             :   // Initial map for sloppy mode function is stored in the function
    9027             :   // constructor. Initial maps for strict mode are cached as special transitions
    9028             :   // using |strict_function_transition_symbol| as a key.
    9029         731 :   if (language_mode == SLOPPY) return initial_map;
    9030             :   Isolate* isolate = initial_map->GetIsolate();
    9031             : 
    9032         226 :   int map_index = Context::FunctionMapIndex(language_mode, kind);
    9033             :   Handle<Map> function_map(
    9034         452 :       Map::cast(isolate->native_context()->get(map_index)));
    9035             : 
    9036             :   STATIC_ASSERT(LANGUAGE_END == 2);
    9037             :   DCHECK_EQ(STRICT, language_mode);
    9038             :   Handle<Symbol> transition_symbol =
    9039             :       isolate->factory()->strict_function_transition_symbol();
    9040             :   Map* maybe_transition =
    9041         226 :       TransitionArray::SearchSpecial(*initial_map, *transition_symbol);
    9042         226 :   if (maybe_transition != NULL) {
    9043             :     return handle(maybe_transition, isolate);
    9044             :   }
    9045         170 :   initial_map->NotifyLeafMapLayoutChange();
    9046             : 
    9047             :   // Create new map taking descriptors from the |function_map| and all
    9048             :   // the other details from the |initial_map|.
    9049             :   Handle<Map> map =
    9050             :       Map::CopyInitialMap(function_map, initial_map->instance_size(),
    9051             :                           initial_map->GetInObjectProperties(),
    9052         170 :                           initial_map->unused_property_fields());
    9053         170 :   map->SetConstructor(initial_map->GetConstructor());
    9054         170 :   map->set_prototype(initial_map->prototype());
    9055             : 
    9056         170 :   if (TransitionArray::CanHaveMoreTransitions(initial_map)) {
    9057             :     Map::ConnectTransition(initial_map, map, transition_symbol,
    9058         170 :                            SPECIAL_TRANSITION);
    9059             :   }
    9060         170 :   return map;
    9061             : }
    9062             : 
    9063             : 
    9064      142131 : Handle<Map> Map::CopyForTransition(Handle<Map> map, const char* reason) {
    9065             :   DCHECK(!map->is_prototype_map());
    9066      142131 :   Handle<Map> new_map = CopyDropDescriptors(map);
    9067             : 
    9068      142131 :   if (map->owns_descriptors()) {
    9069             :     // In case the map owned its own descriptors, share the descriptors and
    9070             :     // transfer ownership to the new map.
    9071             :     // The properties did not change, so reuse descriptors.
    9072             :     new_map->InitializeDescriptors(map->instance_descriptors(),
    9073      142129 :                                    map->GetLayoutDescriptor());
    9074             :   } else {
    9075             :     // In case the map did not own its own descriptors, a split is forced by
    9076             :     // copying the map; creating a new descriptor array cell.
    9077             :     Handle<DescriptorArray> descriptors(map->instance_descriptors());
    9078             :     int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9079             :     Handle<DescriptorArray> new_descriptors =
    9080             :         DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
    9081             :     Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9082             :                                                    map->GetIsolate());
    9083           2 :     new_map->InitializeDescriptors(*new_descriptors, *new_layout_descriptor);
    9084             :   }
    9085             : 
    9086             : #if TRACE_MAPS
    9087             :   if (FLAG_trace_maps) {
    9088             :     PrintF("[TraceMaps: CopyForTransition from= %p to= %p reason= %s ]\n",
    9089             :            reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*new_map),
    9090             :            reason);
    9091             :   }
    9092             : #endif
    9093             : 
    9094      142131 :   return new_map;
    9095             : }
    9096             : 
    9097             : 
    9098     6162719 : Handle<Map> Map::Copy(Handle<Map> map, const char* reason) {
    9099             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    9100             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9101             :   Handle<DescriptorArray> new_descriptors =
    9102     6162721 :       DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
    9103             :   Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9104             :                                                  map->GetIsolate());
    9105             :   return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
    9106             :                                 OMIT_TRANSITION, MaybeHandle<Name>(), reason,
    9107     6162721 :                                 SPECIAL_TRANSITION);
    9108             : }
    9109             : 
    9110             : 
    9111      250729 : Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
    9112             :   Handle<Map> copy =
    9113      501458 :       Copy(handle(isolate->object_function()->initial_map()), "MapCreate");
    9114             : 
    9115             :   // Check that we do not overflow the instance size when adding the extra
    9116             :   // inobject properties. If the instance size overflows, we allocate as many
    9117             :   // properties as we can as inobject properties.
    9118             :   int max_extra_properties =
    9119             :       (JSObject::kMaxInstanceSize - JSObject::kHeaderSize) >> kPointerSizeLog2;
    9120             : 
    9121      250729 :   if (inobject_properties > max_extra_properties) {
    9122             :     inobject_properties = max_extra_properties;
    9123             :   }
    9124             : 
    9125             :   int new_instance_size =
    9126      250729 :       JSObject::kHeaderSize + kPointerSize * inobject_properties;
    9127             : 
    9128             :   // Adjust the map with the extra inobject properties.
    9129             :   copy->SetInObjectProperties(inobject_properties);
    9130             :   copy->set_unused_property_fields(inobject_properties);
    9131             :   copy->set_instance_size(new_instance_size);
    9132      250729 :   copy->set_visitor_id(Heap::GetStaticVisitorIdForMap(*copy));
    9133      250729 :   return copy;
    9134             : }
    9135             : 
    9136             : 
    9137       51215 : Handle<Map> Map::CopyForPreventExtensions(Handle<Map> map,
    9138             :                                           PropertyAttributes attrs_to_add,
    9139             :                                           Handle<Symbol> transition_marker,
    9140             :                                           const char* reason) {
    9141             :   int num_descriptors = map->NumberOfOwnDescriptors();
    9142             :   Isolate* isolate = map->GetIsolate();
    9143             :   Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
    9144             :       handle(map->instance_descriptors(), isolate), num_descriptors,
    9145       51215 :       attrs_to_add);
    9146             :   Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9147             :                                                  isolate);
    9148             :   Handle<Map> new_map = CopyReplaceDescriptors(
    9149             :       map, new_desc, new_layout_descriptor, INSERT_TRANSITION,
    9150       51215 :       transition_marker, reason, SPECIAL_TRANSITION);
    9151             :   new_map->set_is_extensible(false);
    9152       51215 :   if (!IsFixedTypedArrayElementsKind(map->elements_kind())) {
    9153             :     ElementsKind new_kind = IsStringWrapperElementsKind(map->elements_kind())
    9154             :                                 ? SLOW_STRING_WRAPPER_ELEMENTS
    9155       51141 :                                 : DICTIONARY_ELEMENTS;
    9156             :     new_map->set_elements_kind(new_kind);
    9157             :   }
    9158       51215 :   return new_map;
    9159             : }
    9160             : 
    9161             : namespace {
    9162             : 
    9163    25271041 : bool CanHoldValue(DescriptorArray* descriptors, int descriptor,
    9164             :                   PropertyConstness constness, Object* value) {
    9165    25271041 :   PropertyDetails details = descriptors->GetDetails(descriptor);
    9166    25271043 :   if (details.location() == kField) {
    9167    24695253 :     if (details.kind() == kData) {
    9168    24695251 :       return IsGeneralizableTo(constness, details.constness()) &&
    9169    73630093 :              value->FitsRepresentation(details.representation()) &&
    9170    48934838 :              descriptors->GetFieldType(descriptor)->NowContains(value);
    9171             :     } else {
    9172             :       DCHECK_EQ(kAccessor, details.kind());
    9173             :       return false;
    9174             :     }
    9175             : 
    9176             :   } else {
    9177             :     DCHECK_EQ(kDescriptor, details.location());
    9178             :     DCHECK_EQ(kConst, details.constness());
    9179      575790 :     if (details.kind() == kData) {
    9180             :       DCHECK(!FLAG_track_constant_fields);
    9181             :       DCHECK(descriptors->GetValue(descriptor) != value ||
    9182             :              value->FitsRepresentation(details.representation()));
    9183      575790 :       return descriptors->GetValue(descriptor) == value;
    9184             :     } else {
    9185             :       DCHECK_EQ(kAccessor, details.kind());
    9186             :       return false;
    9187             :     }
    9188             :   }
    9189             :   UNREACHABLE();
    9190             :   return false;
    9191             : }
    9192             : 
    9193    25271041 : Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor,
    9194             :                                      PropertyConstness constness,
    9195             :                                      Handle<Object> value) {
    9196    25271041 :   if (CanHoldValue(map->instance_descriptors(), descriptor, constness,
    9197             :                    *value)) {
    9198    24114477 :     return map;
    9199             :   }
    9200             : 
    9201             :   Isolate* isolate = map->GetIsolate();
    9202             :   PropertyAttributes attributes =
    9203     2313132 :       map->instance_descriptors()->GetDetails(descriptor).attributes();
    9204     1156566 :   Representation representation = value->OptimalRepresentation();
    9205     1156566 :   Handle<FieldType> type = value->OptimalType(isolate, representation);
    9206             : 
    9207     1156566 :   MapUpdater mu(isolate, map);
    9208             :   return mu.ReconfigureToDataField(descriptor, attributes, constness,
    9209     1156566 :                                    representation, type);
    9210             : }
    9211             : 
    9212             : }  // namespace
    9213             : 
    9214             : // static
    9215    10661007 : Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor,
    9216             :                                         PropertyConstness constness,
    9217             :                                         Handle<Object> value) {
    9218             :   // Dictionaries can store any property value.
    9219             :   DCHECK(!map->is_dictionary_map());
    9220             :   // Update to the newest map before storing the property.
    9221    10661007 :   return UpdateDescriptorForValue(Update(map), descriptor, constness, value);
    9222             : }
    9223             : 
    9224    30201648 : Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
    9225             :                                           Handle<Object> value,
    9226             :                                           PropertyAttributes attributes,
    9227             :                                           PropertyConstness constness,
    9228             :                                           StoreFromKeyed store_mode) {
    9229             :   RuntimeCallTimerScope stats_scope(
    9230             :       *map, map->is_prototype_map()
    9231             :                 ? &RuntimeCallStats::PrototypeMap_TransitionToDataProperty
    9232    30201648 :                 : &RuntimeCallStats::Map_TransitionToDataProperty);
    9233             : 
    9234             :   DCHECK(name->IsUniqueName());
    9235             :   DCHECK(!map->is_dictionary_map());
    9236             : 
    9237             :   // Migrate to the newest map before storing the property.
    9238    30201664 :   map = Update(map);
    9239             : 
    9240             :   Map* maybe_transition =
    9241    30201663 :       TransitionArray::SearchTransition(*map, kData, *name, attributes);
    9242    30201661 :   if (maybe_transition != NULL) {
    9243             :     Handle<Map> transition(maybe_transition);
    9244             :     int descriptor = transition->LastAdded();
    9245             : 
    9246             :     DCHECK_EQ(attributes, transition->instance_descriptors()
    9247             :                               ->GetDetails(descriptor)
    9248             :                               .attributes());
    9249             : 
    9250    14610033 :     return UpdateDescriptorForValue(transition, descriptor, constness, value);
    9251             :   }
    9252             : 
    9253             :   TransitionFlag flag = INSERT_TRANSITION;
    9254             :   MaybeHandle<Map> maybe_map;
    9255    15591629 :   if (!FLAG_track_constant_fields && value->IsJSFunction()) {
    9256     6722361 :     maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag);
    9257     8869268 :   } else if (!map->TooManyFastProperties(store_mode)) {
    9258             :     Isolate* isolate = name->GetIsolate();
    9259     8768176 :     Representation representation = value->OptimalRepresentation();
    9260     8768176 :     Handle<FieldType> type = value->OptimalType(isolate, representation);
    9261             :     maybe_map = Map::CopyWithField(map, name, type, attributes, constness,
    9262     8768176 :                                    representation, flag);
    9263             :   }
    9264             : 
    9265             :   Handle<Map> result;
    9266    15591626 :   if (!maybe_map.ToHandle(&result)) {
    9267             :     Isolate* isolate = name->GetIsolate();
    9268             :     const char* reason = "TooManyFastProperties";
    9269             : #if TRACE_MAPS
    9270             :     std::unique_ptr<ScopedVector<char>> buffer;
    9271             :     if (FLAG_trace_maps) {
    9272             :       ScopedVector<char> name_buffer(100);
    9273             :       name->NameShortPrint(name_buffer);
    9274             :       buffer.reset(new ScopedVector<char>(128));
    9275             :       SNPrintF(*buffer, "TooManyFastProperties %s", name_buffer.start());
    9276             :       reason = buffer->start();
    9277             :     }
    9278             : #endif
    9279      101209 :     Handle<Object> maybe_constructor(map->GetConstructor(), isolate);
    9280      101209 :     if (FLAG_feedback_normalization && map->new_target_is_base() &&
    9281      101209 :         maybe_constructor->IsJSFunction() &&
    9282             :         !JSFunction::cast(*maybe_constructor)->shared()->native()) {
    9283             :       Handle<JSFunction> constructor =
    9284             :           Handle<JSFunction>::cast(maybe_constructor);
    9285             :       DCHECK_NE(*constructor,
    9286             :                 constructor->context()->native_context()->object_function());
    9287             :       Handle<Map> initial_map(constructor->initial_map(), isolate);
    9288           0 :       result = Map::Normalize(initial_map, CLEAR_INOBJECT_PROPERTIES, reason);
    9289           0 :       initial_map->DeprecateTransitionTree();
    9290             :       Handle<Object> prototype(result->prototype(), isolate);
    9291           0 :       JSFunction::SetInitialMap(constructor, result, prototype);
    9292             : 
    9293             :       // Deoptimize all code that embeds the previous initial map.
    9294             :       initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
    9295           0 :           isolate, DependentCode::kInitialMapChangedGroup);
    9296           0 :       if (!result->EquivalentToForNormalization(*map,
    9297           0 :                                                 CLEAR_INOBJECT_PROPERTIES)) {
    9298           0 :         result = Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, reason);
    9299             :       }
    9300             :     } else {
    9301      101209 :       result = Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, reason);
    9302             :     }
    9303             :   }
    9304             : 
    9305    15591626 :   return result;
    9306             : }
    9307             : 
    9308             : 
    9309     1515963 : Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor,
    9310             :                                              PropertyKind kind,
    9311             :                                              PropertyAttributes attributes) {
    9312             :   // Dictionaries have to be reconfigured in-place.
    9313             :   DCHECK(!map->is_dictionary_map());
    9314             : 
    9315     3031927 :   if (!map->GetBackPointer()->IsMap()) {
    9316             :     // There is no benefit from reconstructing transition tree for maps without
    9317             :     // back pointers.
    9318             :     return CopyGeneralizeAllFields(map, map->elements_kind(), descriptor, kind,
    9319             :                                    attributes,
    9320     1490691 :                                    "GenAll_AttributesMismatchProtoMap");
    9321             :   }
    9322             : 
    9323       25273 :   if (FLAG_trace_generalization) {
    9324           0 :     map->PrintReconfiguration(stdout, descriptor, kind, attributes);
    9325             :   }
    9326             : 
    9327             :   Isolate* isolate = map->GetIsolate();
    9328             : 
    9329       25273 :   MapUpdater mu(isolate, map);
    9330             :   DCHECK_EQ(kData, kind);  // Only kData case is supported so far.
    9331             :   Handle<Map> new_map = mu.ReconfigureToDataField(
    9332             :       descriptor, attributes, kDefaultFieldConstness, Representation::None(),
    9333       25273 :       FieldType::None(isolate));
    9334       25273 :   return new_map;
    9335             : }
    9336             : 
    9337      434921 : Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
    9338             :                                               Handle<Name> name, int descriptor,
    9339             :                                               Handle<Object> getter,
    9340             :                                               Handle<Object> setter,
    9341             :                                               PropertyAttributes attributes) {
    9342             :   RuntimeCallTimerScope stats_scope(
    9343             :       isolate,
    9344             :       map->is_prototype_map()
    9345             :           ? &RuntimeCallStats::PrototypeMap_TransitionToAccessorProperty
    9346      434921 :           : &RuntimeCallStats::Map_TransitionToAccessorProperty);
    9347             : 
    9348             :   // At least one of the accessors needs to be a new value.
    9349             :   DCHECK(!getter->IsNull(isolate) || !setter->IsNull(isolate));
    9350             :   DCHECK(name->IsUniqueName());
    9351             : 
    9352             :   // Dictionary maps can always have additional data properties.
    9353      434921 :   if (map->is_dictionary_map()) return map;
    9354             : 
    9355             :   // Migrate to the newest map before transitioning to the new property.
    9356      434921 :   map = Update(map);
    9357             : 
    9358             :   PropertyNormalizationMode mode = map->is_prototype_map()
    9359             :                                        ? KEEP_INOBJECT_PROPERTIES
    9360      434921 :                                        : CLEAR_INOBJECT_PROPERTIES;
    9361             : 
    9362             :   Map* maybe_transition =
    9363      434921 :       TransitionArray::SearchTransition(*map, kAccessor, *name, attributes);
    9364      434921 :   if (maybe_transition != NULL) {
    9365             :     Handle<Map> transition(maybe_transition, isolate);
    9366             :     DescriptorArray* descriptors = transition->instance_descriptors();
    9367             :     int descriptor = transition->LastAdded();
    9368             :     DCHECK(descriptors->GetKey(descriptor)->Equals(*name));
    9369             : 
    9370             :     DCHECK_EQ(kAccessor, descriptors->GetDetails(descriptor).kind());
    9371             :     DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes());
    9372             : 
    9373             :     Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
    9374       18809 :     if (!maybe_pair->IsAccessorPair()) {
    9375           0 :       return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair");
    9376             :     }
    9377             : 
    9378             :     Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair);
    9379       18809 :     if (!pair->Equals(*getter, *setter)) {
    9380       17908 :       return Map::Normalize(map, mode, "TransitionToDifferentAccessor");
    9381             :     }
    9382             : 
    9383         901 :     return transition;
    9384             :   }
    9385             : 
    9386             :   Handle<AccessorPair> pair;
    9387             :   DescriptorArray* old_descriptors = map->instance_descriptors();
    9388      416112 :   if (descriptor != DescriptorArray::kNotFound) {
    9389      158119 :     if (descriptor != map->LastAdded()) {
    9390        3251 :       return Map::Normalize(map, mode, "AccessorsOverwritingNonLast");
    9391             :     }
    9392      154868 :     PropertyDetails old_details = old_descriptors->GetDetails(descriptor);
    9393      154868 :     if (old_details.kind() != kAccessor) {
    9394      152339 :       return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors");
    9395             :     }
    9396             : 
    9397        2529 :     if (old_details.attributes() != attributes) {
    9398         131 :       return Map::Normalize(map, mode, "AccessorsWithAttributes");
    9399             :     }
    9400             : 
    9401             :     Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate);
    9402        2398 :     if (!maybe_pair->IsAccessorPair()) {
    9403          28 :       return Map::Normalize(map, mode, "AccessorsOverwritingNonPair");
    9404             :     }
    9405             : 
    9406             :     Handle<AccessorPair> current_pair = Handle<AccessorPair>::cast(maybe_pair);
    9407        2370 :     if (current_pair->Equals(*getter, *setter)) return map;
    9408             : 
    9409             :     bool overwriting_accessor = false;
    9410        4733 :     if (!getter->IsNull(isolate) &&
    9411        4589 :         !current_pair->get(ACCESSOR_GETTER)->IsNull(isolate) &&
    9412             :         current_pair->get(ACCESSOR_GETTER) != *getter) {
    9413             :       overwriting_accessor = true;
    9414             :     }
    9415        4726 :     if (!setter->IsNull(isolate) &&
    9416        4185 :         !current_pair->get(ACCESSOR_SETTER)->IsNull(isolate) &&
    9417             :         current_pair->get(ACCESSOR_SETTER) != *setter) {
    9418             :       overwriting_accessor = true;
    9419             :     }
    9420        2370 :     if (overwriting_accessor) {
    9421        2094 :       return Map::Normalize(map, mode, "AccessorsOverwritingAccessors");
    9422             :     }
    9423             : 
    9424         276 :     pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair));
    9425      515987 :   } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors ||
    9426      257993 :              map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) {
    9427           0 :     return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors");
    9428             :   } else {
    9429      257994 :     pair = isolate->factory()->NewAccessorPair();
    9430             :   }
    9431             : 
    9432      258270 :   pair->SetComponents(*getter, *setter);
    9433             : 
    9434             :   TransitionFlag flag = INSERT_TRANSITION;
    9435             :   Descriptor d = Descriptor::AccessorConstant(name, pair, attributes);
    9436      258270 :   return Map::CopyInsertDescriptor(map, &d, flag);
    9437             : }
    9438             : 
    9439             : 
    9440    15763576 : Handle<Map> Map::CopyAddDescriptor(Handle<Map> map,
    9441             :                                    Descriptor* descriptor,
    9442             :                                    TransitionFlag flag) {
    9443             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    9444             : 
    9445             :   // Share descriptors only if map owns descriptors and it not an initial map.
    9446    47205515 :   if (flag == INSERT_TRANSITION && map->owns_descriptors() &&
    9447    40972154 :       !map->GetBackPointer()->IsUndefined(map->GetIsolate()) &&
    9448     9529932 :       TransitionArray::CanHaveMoreTransitions(map)) {
    9449     9529932 :     return ShareDescriptor(map, descriptors, descriptor);
    9450             :   }
    9451             : 
    9452             :   int nof = map->NumberOfOwnDescriptors();
    9453             :   Handle<DescriptorArray> new_descriptors =
    9454             :       DescriptorArray::CopyUpTo(descriptors, nof, 1);
    9455     6233650 :   new_descriptors->Append(descriptor);
    9456             : 
    9457             :   Handle<LayoutDescriptor> new_layout_descriptor =
    9458             :       FLAG_unbox_double_fields
    9459     6233649 :           ? LayoutDescriptor::New(map, new_descriptors, nof + 1)
    9460     6233649 :           : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate());
    9461             : 
    9462             :   return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
    9463             :                                 flag, descriptor->GetKey(), "CopyAddDescriptor",
    9464     6233649 :                                 SIMPLE_PROPERTY_TRANSITION);
    9465             : }
    9466             : 
    9467             : 
    9468      258318 : Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map,
    9469             :                                       Descriptor* descriptor,
    9470             :                                       TransitionFlag flag) {
    9471             :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors());
    9472             : 
    9473             :   // We replace the key if it is already present.
    9474             :   int index = old_descriptors->SearchWithCache(map->GetIsolate(),
    9475             :                                                *descriptor->GetKey(), *map);
    9476      258318 :   if (index != DescriptorArray::kNotFound) {
    9477         276 :     return CopyReplaceDescriptor(map, old_descriptors, descriptor, index, flag);
    9478             :   }
    9479      258042 :   return CopyAddDescriptor(map, descriptor, flag);
    9480             : }
    9481             : 
    9482             : 
    9483           0 : Handle<DescriptorArray> DescriptorArray::CopyUpTo(
    9484             :     Handle<DescriptorArray> desc,
    9485             :     int enumeration_index,
    9486             :     int slack) {
    9487             :   return DescriptorArray::CopyUpToAddAttributes(
    9488    20175803 :       desc, enumeration_index, NONE, slack);
    9489             : }
    9490             : 
    9491             : 
    9492    20227008 : Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
    9493             :     Handle<DescriptorArray> desc,
    9494             :     int enumeration_index,
    9495             :     PropertyAttributes attributes,
    9496             :     int slack) {
    9497    20227008 :   if (enumeration_index + slack == 0) {
    9498             :     return desc->GetIsolate()->factory()->empty_descriptor_array();
    9499             :   }
    9500             : 
    9501             :   int size = enumeration_index;
    9502             : 
    9503             :   Handle<DescriptorArray> descriptors =
    9504    18027552 :       DescriptorArray::Allocate(desc->GetIsolate(), size, slack);
    9505             : 
    9506    18027559 :   if (attributes != NONE) {
    9507       78469 :     for (int i = 0; i < size; ++i) {
    9508             :       Object* value = desc->GetValue(i);
    9509             :       Name* key = desc->GetKey(i);
    9510       78469 :       PropertyDetails details = desc->GetDetails(i);
    9511             :       // Bulk attribute changes never affect private properties.
    9512       78469 :       if (!key->IsPrivate()) {
    9513             :         int mask = DONT_DELETE | DONT_ENUM;
    9514             :         // READ_ONLY is an invalid attribute for JS setters/getters.
    9515       79854 :         if (details.kind() != kAccessor || !value->IsAccessorPair()) {
    9516             :           mask |= READ_ONLY;
    9517             :         }
    9518             :         details = details.CopyAddAttributes(
    9519       78413 :             static_cast<PropertyAttributes>(attributes & mask));
    9520             :       }
    9521       78469 :       descriptors->Set(i, key, value, details);
    9522             :     }
    9523             :   } else {
    9524   154745882 :     for (int i = 0; i < size; ++i) {
    9525   154745871 :       descriptors->CopyFrom(i, *desc);
    9526             :     }
    9527             :   }
    9528             : 
    9529    18125364 :   if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort();
    9530             : 
    9531    18027570 :   return descriptors;
    9532             : }
    9533             : 
    9534             : 
    9535        8613 : bool DescriptorArray::IsEqualUpTo(DescriptorArray* desc, int nof_descriptors) {
    9536       56593 :   for (int i = 0; i < nof_descriptors; i++) {
    9537       95960 :     if (GetKey(i) != desc->GetKey(i) || GetValue(i) != desc->GetValue(i)) {
    9538             :       return false;
    9539             :     }
    9540       47980 :     PropertyDetails details = GetDetails(i);
    9541       47980 :     PropertyDetails other_details = desc->GetDetails(i);
    9542       95960 :     if (details.kind() != other_details.kind() ||
    9543       95960 :         details.location() != other_details.location() ||
    9544             :         !details.representation().Equals(other_details.representation())) {
    9545             :       return false;
    9546             :     }
    9547             :   }
    9548             :   return true;
    9549             : }
    9550             : 
    9551             : 
    9552         276 : Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map,
    9553             :                                        Handle<DescriptorArray> descriptors,
    9554             :                                        Descriptor* descriptor,
    9555             :                                        int insertion_index,
    9556             :                                        TransitionFlag flag) {
    9557             :   Handle<Name> key = descriptor->GetKey();
    9558             :   DCHECK(*key == descriptors->GetKey(insertion_index));
    9559             : 
    9560             :   Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
    9561             :       descriptors, map->NumberOfOwnDescriptors());
    9562             : 
    9563         276 :   new_descriptors->Replace(insertion_index, descriptor);
    9564             :   Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New(
    9565         276 :       map, new_descriptors, new_descriptors->number_of_descriptors());
    9566             : 
    9567             :   SimpleTransitionFlag simple_flag =
    9568         276 :       (insertion_index == descriptors->number_of_descriptors() - 1)
    9569             :           ? SIMPLE_PROPERTY_TRANSITION
    9570         276 :           : PROPERTY_TRANSITION;
    9571             :   return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
    9572             :                                 flag, key, "CopyReplaceDescriptor",
    9573         276 :                                 simple_flag);
    9574             : }
    9575             : 
    9576             : // Helper class to manage a Map's code cache. The layout depends on the number
    9577             : // of entries; this is worthwhile because most code caches are very small,
    9578             : // but some are huge (thousands of entries).
    9579             : // For zero entries, the EmptyFixedArray is used.
    9580             : // For one entry, we use a 2-element FixedArray containing [name, code].
    9581             : // For 2..100 entries, we use a FixedArray with linear lookups, the layout is:
    9582             : //   [0] - number of slots that are currently in use
    9583             : //   [1] - first name
    9584             : //   [2] - first code
    9585             : //   [3] - second name
    9586             : //   [4] - second code
    9587             : //   etc.
    9588             : // For more than 128 entries, we use a CodeCacheHashTable.
    9589             : class CodeCache : public AllStatic {
    9590             :  public:
    9591             :   // Returns the new cache, to be stored on the map.
    9592       39748 :   static Handle<FixedArray> Put(Isolate* isolate, Handle<FixedArray> cache,
    9593             :                                 Handle<Name> name, Handle<Code> code) {
    9594             :     int length = cache->length();
    9595       39748 :     if (length == 0) return PutFirstElement(isolate, name, code);
    9596        2387 :     if (length == kEntrySize) {
    9597         577 :       return PutSecondElement(isolate, cache, name, code);
    9598             :     }
    9599        1810 :     if (length <= kLinearMaxSize) {
    9600        1663 :       Handle<FixedArray> result = PutLinearElement(isolate, cache, name, code);
    9601        1663 :       if (!result.is_null()) return result;
    9602             :       // Fall through if linear storage is getting too large.
    9603             :     }
    9604         154 :     return PutHashTableElement(isolate, cache, name, code);
    9605             :   }
    9606             : 
    9607       43599 :   static Code* Lookup(FixedArray* cache, Name* name, Code::Flags flags) {
    9608             :     int length = cache->length();
    9609       43599 :     if (length == 0) return nullptr;
    9610        6245 :     if (length == kEntrySize) return OneElementLookup(cache, name, flags);
    9611        3701 :     if (!cache->IsCodeCacheHashTable()) {
    9612        2490 :       return LinearLookup(cache, name, flags);
    9613             :     } else {
    9614        1211 :       return CodeCacheHashTable::cast(cache)->Lookup(name, flags);
    9615             :     }
    9616             :   }
    9617             : 
    9618             :  private:
    9619             :   static const int kNameIndex = 0;
    9620             :   static const int kCodeIndex = 1;
    9621             :   static const int kEntrySize = 2;
    9622             : 
    9623             :   static const int kLinearUsageIndex = 0;
    9624             :   static const int kLinearReservedSlots = 1;
    9625             :   static const int kLinearInitialCapacity = 2;
    9626             :   static const int kLinearMaxSize = 257;  // == LinearSizeFor(128);
    9627             : 
    9628             :   static const int kHashTableInitialCapacity = 200;  // Number of entries.
    9629             : 
    9630             :   static int LinearSizeFor(int entries) {
    9631         164 :     return kLinearReservedSlots + kEntrySize * entries;
    9632             :   }
    9633             : 
    9634             :   static int LinearNewSize(int old_size) {
    9635         164 :     int old_entries = (old_size - kLinearReservedSlots) / kEntrySize;
    9636         164 :     return LinearSizeFor(old_entries * 2);
    9637             :   }
    9638             : 
    9639        2544 :   static Code* OneElementLookup(FixedArray* cache, Name* name,
    9640             :                                 Code::Flags flags) {
    9641             :     DCHECK_EQ(cache->length(), kEntrySize);
    9642        2544 :     if (cache->get(kNameIndex) != name) return nullptr;
    9643             :     Code* maybe_code = Code::cast(cache->get(kCodeIndex));
    9644        2241 :     if (maybe_code->flags() != flags) return nullptr;
    9645        2194 :     return maybe_code;
    9646             :   }
    9647             : 
    9648        2490 :   static Code* LinearLookup(FixedArray* cache, Name* name, Code::Flags flags) {
    9649             :     DCHECK_GE(cache->length(), kEntrySize);
    9650             :     DCHECK(!cache->IsCodeCacheHashTable());
    9651             :     int usage = GetLinearUsage(cache);
    9652       59584 :     for (int i = kLinearReservedSlots; i < usage; i += kEntrySize) {
    9653       59544 :       if (cache->get(i + kNameIndex) != name) continue;
    9654        2501 :       Code* code = Code::cast(cache->get(i + kCodeIndex));
    9655        2501 :       if (code->flags() == flags) return code;
    9656             :     }
    9657             :     return nullptr;
    9658             :   }
    9659             : 
    9660       37361 :   static Handle<FixedArray> PutFirstElement(Isolate* isolate, Handle<Name> name,
    9661             :                                             Handle<Code> code) {
    9662       37361 :     Handle<FixedArray> cache = isolate->factory()->NewFixedArray(kEntrySize);
    9663       37361 :     cache->set(kNameIndex, *name);
    9664       37361 :     cache->set(kCodeIndex, *code);
    9665       37361 :     return cache;
    9666             :   }
    9667             : 
    9668         577 :   static Handle<FixedArray> PutSecondElement(Isolate* isolate,
    9669             :                                              Handle<FixedArray> cache,
    9670             :                                              Handle<Name> name,
    9671             :                                              Handle<Code> code) {
    9672             :     DCHECK_EQ(cache->length(), kEntrySize);
    9673             :     Handle<FixedArray> new_cache = isolate->factory()->NewFixedArray(
    9674         577 :         LinearSizeFor(kLinearInitialCapacity));
    9675         577 :     new_cache->set(kLinearReservedSlots + kNameIndex, cache->get(kNameIndex));
    9676         577 :     new_cache->set(kLinearReservedSlots + kCodeIndex, cache->get(kCodeIndex));
    9677         577 :     new_cache->set(LinearSizeFor(1) + kNameIndex, *name);
    9678         577 :     new_cache->set(LinearSizeFor(1) + kCodeIndex, *code);
    9679             :     new_cache->set(kLinearUsageIndex, Smi::FromInt(LinearSizeFor(2)));
    9680         577 :     return new_cache;
    9681             :   }
    9682             : 
    9683        1663 :   static Handle<FixedArray> PutLinearElement(Isolate* isolate,
    9684             :                                              Handle<FixedArray> cache,
    9685             :                                              Handle<Name> name,
    9686             :                                              Handle<Code> code) {
    9687             :     int length = cache->length();
    9688             :     int usage = GetLinearUsage(*cache);
    9689             :     DCHECK_LE(usage, length);
    9690             :     // Check if we need to grow.
    9691        1663 :     if (usage == length) {
    9692             :       int new_length = LinearNewSize(length);
    9693         164 :       if (new_length > kLinearMaxSize) return Handle<FixedArray>::null();
    9694             :       Handle<FixedArray> new_cache =
    9695         157 :           isolate->factory()->NewFixedArray(new_length);
    9696        3841 :       for (int i = kLinearReservedSlots; i < length; i++) {
    9697        3684 :         new_cache->set(i, cache->get(i));
    9698             :       }
    9699         157 :       cache = new_cache;
    9700             :     }
    9701             :     // Store new entry.
    9702             :     DCHECK_GE(cache->length(), usage + kEntrySize);
    9703        1656 :     cache->set(usage + kNameIndex, *name);
    9704        3312 :     cache->set(usage + kCodeIndex, *code);
    9705        1656 :     cache->set(kLinearUsageIndex, Smi::FromInt(usage + kEntrySize));
    9706        1656 :     return cache;
    9707             :   }
    9708             : 
    9709         154 :   static Handle<FixedArray> PutHashTableElement(Isolate* isolate,
    9710             :                                                 Handle<FixedArray> cache,
    9711             :                                                 Handle<Name> name,
    9712             :                                                 Handle<Code> code) {
    9713             :     // Check if we need to transition from linear to hash table storage.
    9714         154 :     if (!cache->IsCodeCacheHashTable()) {
    9715             :       // Check that the initial hash table capacity is large enough.
    9716             :       DCHECK_EQ(kLinearMaxSize, LinearSizeFor(128));
    9717             :       STATIC_ASSERT(kHashTableInitialCapacity > 128);
    9718             : 
    9719             :       int length = cache->length();
    9720             :       // Only migrate from linear storage when it's full.
    9721             :       DCHECK_EQ(length, GetLinearUsage(*cache));
    9722             :       DCHECK_EQ(length, kLinearMaxSize);
    9723             :       Handle<CodeCacheHashTable> table =
    9724           7 :           CodeCacheHashTable::New(isolate, kHashTableInitialCapacity);
    9725             :       HandleScope scope(isolate);
    9726         903 :       for (int i = kLinearReservedSlots; i < length; i += kEntrySize) {
    9727             :         Handle<Name> old_name(Name::cast(cache->get(i + kNameIndex)), isolate);
    9728         896 :         Handle<Code> old_code(Code::cast(cache->get(i + kCodeIndex)), isolate);
    9729         896 :         CodeCacheHashTable::Put(table, old_name, old_code);
    9730             :       }
    9731             :       cache = table;
    9732             :     }
    9733             :     // Store new entry.
    9734             :     DCHECK(cache->IsCodeCacheHashTable());
    9735             :     return CodeCacheHashTable::Put(Handle<CodeCacheHashTable>::cast(cache),
    9736         154 :                                    name, code);
    9737             :   }
    9738             : 
    9739             :   static inline int GetLinearUsage(FixedArray* linear_cache) {
    9740             :     DCHECK_GT(linear_cache->length(), kEntrySize);
    9741             :     return Smi::cast(linear_cache->get(kLinearUsageIndex))->value();
    9742             :   }
    9743             : };
    9744             : 
    9745       39748 : void Map::UpdateCodeCache(Handle<Map> map,
    9746             :                           Handle<Name> name,
    9747             :                           Handle<Code> code) {
    9748             :   Isolate* isolate = map->GetIsolate();
    9749             :   Handle<FixedArray> cache(map->code_cache(), isolate);
    9750       39748 :   Handle<FixedArray> new_cache = CodeCache::Put(isolate, cache, name, code);
    9751       39748 :   map->set_code_cache(*new_cache);
    9752       39748 : }
    9753             : 
    9754       43599 : Code* Map::LookupInCodeCache(Name* name, Code::Flags flags) {
    9755       43599 :   return CodeCache::Lookup(code_cache(), name, flags);
    9756             : }
    9757             : 
    9758             : 
    9759             : // The key in the code cache hash table consists of the property name and the
    9760             : // code object. The actual match is on the name and the code flags. If a key
    9761             : // is created using the flags and not a code object it can only be used for
    9762             : // lookup not to create a new entry.
    9763           0 : class CodeCacheHashTableKey : public HashTableKey {
    9764             :  public:
    9765             :   CodeCacheHashTableKey(Handle<Name> name, Code::Flags flags)
    9766        1211 :       : name_(name), flags_(flags), code_() {
    9767             :     DCHECK(name_->IsUniqueName());
    9768             :   }
    9769             : 
    9770             :   CodeCacheHashTableKey(Handle<Name> name, Handle<Code> code)
    9771        2100 :       : name_(name), flags_(code->flags()), code_(code) {
    9772             :     DCHECK(name_->IsUniqueName());
    9773             :   }
    9774             : 
    9775        1673 :   bool IsMatch(Object* other) override {
    9776             :     DCHECK(other->IsFixedArray());
    9777             :     FixedArray* pair = FixedArray::cast(other);
    9778             :     Name* name = Name::cast(pair->get(0));
    9779             :     Code::Flags flags = Code::cast(pair->get(1))->flags();
    9780        1673 :     if (flags != flags_) return false;
    9781             :     DCHECK(name->IsUniqueName());
    9782        1673 :     return *name_ == name;
    9783             :   }
    9784             : 
    9785             :   static uint32_t NameFlagsHashHelper(Name* name, Code::Flags flags) {
    9786        2261 :     return name->Hash() ^ flags;
    9787             :   }
    9788             : 
    9789        4522 :   uint32_t Hash() override { return NameFlagsHashHelper(*name_, flags_); }
    9790             : 
    9791           0 :   uint32_t HashForObject(Object* obj) override {
    9792             :     FixedArray* pair = FixedArray::cast(obj);
    9793             :     Name* name = Name::cast(pair->get(0));
    9794             :     Code* code = Code::cast(pair->get(1));
    9795           0 :     return NameFlagsHashHelper(name, code->flags());
    9796             :   }
    9797             : 
    9798        1050 :   MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) override {
    9799             :     Handle<Code> code = code_.ToHandleChecked();
    9800        1050 :     Handle<FixedArray> pair = isolate->factory()->NewFixedArray(2);
    9801        1050 :     pair->set(0, *name_);
    9802        1050 :     pair->set(1, *code);
    9803        1050 :     return pair;
    9804             :   }
    9805             : 
    9806             :  private:
    9807             :   Handle<Name> name_;
    9808             :   Code::Flags flags_;
    9809             :   // TODO(jkummerow): We should be able to get by without this.
    9810             :   MaybeHandle<Code> code_;
    9811             : };
    9812             : 
    9813             : 
    9814        1050 : Handle<CodeCacheHashTable> CodeCacheHashTable::Put(
    9815             :     Handle<CodeCacheHashTable> cache, Handle<Name> name, Handle<Code> code) {
    9816             :   CodeCacheHashTableKey key(name, code);
    9817             : 
    9818        1050 :   Handle<CodeCacheHashTable> new_cache = EnsureCapacity(cache, 1, &key);
    9819             : 
    9820        2100 :   int entry = new_cache->FindInsertionEntry(key.Hash());
    9821        1050 :   Handle<Object> k = key.AsHandle(cache->GetIsolate());
    9822             : 
    9823        1050 :   new_cache->set(EntryToIndex(entry), *k);
    9824        1050 :   new_cache->ElementAdded();
    9825        1050 :   return new_cache;
    9826             : }
    9827             : 
    9828        1211 : Code* CodeCacheHashTable::Lookup(Name* name, Code::Flags flags) {
    9829             :   DisallowHeapAllocation no_alloc;
    9830             :   CodeCacheHashTableKey key(handle(name), flags);
    9831             :   int entry = FindEntry(&key);
    9832        1211 :   if (entry == kNotFound) return nullptr;
    9833        1204 :   return Code::cast(FixedArray::cast(get(EntryToIndex(entry)))->get(1));
    9834             : }
    9835             : 
    9836    10508796 : Handle<FixedArray> FixedArray::SetAndGrow(Handle<FixedArray> array, int index,
    9837             :                                           Handle<Object> value) {
    9838    10508796 :   if (index < array->length()) {
    9839     9939006 :     array->set(index, *value);
    9840     9939011 :     return array;
    9841             :   }
    9842             :   int capacity = array->length();
    9843      569790 :   do {
    9844     1139580 :     capacity = JSObject::NewElementsCapacity(capacity);
    9845             :   } while (capacity <= index);
    9846             :   Handle<FixedArray> new_array =
    9847      569790 :       array->GetIsolate()->factory()->NewUninitializedFixedArray(capacity);
    9848      569790 :   array->CopyTo(0, *new_array, 0, array->length());
    9849      569790 :   new_array->FillWithHoles(array->length(), new_array->length());
    9850      569790 :   new_array->set(index, *value);
    9851      569790 :   return new_array;
    9852             : }
    9853             : 
    9854    12882925 : void FixedArray::Shrink(int new_length) {
    9855             :   DCHECK(0 <= new_length && new_length <= length());
    9856    12882925 :   if (new_length < length()) {
    9857    21161162 :     GetHeap()->RightTrimFixedArray(this, length() - new_length);
    9858             :   }
    9859    12882925 : }
    9860             : 
    9861      619376 : void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos,
    9862             :                         int len) const {
    9863             :   DisallowHeapAllocation no_gc;
    9864      619376 :   WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
    9865    27222669 :   for (int index = 0; index < len; index++) {
    9866    53206564 :     dest->set(dest_pos+index, get(pos+index), mode);
    9867             :   }
    9868      619387 : }
    9869             : 
    9870             : #ifdef DEBUG
    9871             : bool FixedArray::IsEqualTo(FixedArray* other) {
    9872             :   if (length() != other->length()) return false;
    9873             :   for (int i = 0 ; i < length(); ++i) {
    9874             :     if (get(i) != other->get(i)) return false;
    9875             :   }
    9876             :   return true;
    9877             : }
    9878             : #endif
    9879             : 
    9880             : 
    9881             : // static
    9882    13257250 : void WeakFixedArray::Set(Handle<WeakFixedArray> array, int index,
    9883             :                          Handle<HeapObject> value) {
    9884             :   DCHECK(array->IsEmptySlot(index));  // Don't overwrite anything.
    9885             :   Handle<WeakCell> cell =
    9886             :       value->IsMap() ? Map::WeakCellForMap(Handle<Map>::cast(value))
    9887    26015352 :                      : array->GetIsolate()->factory()->NewWeakCell(value);
    9888    26514496 :   Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell);
    9889    13257244 :   if (FLAG_trace_weak_arrays) {
    9890           0 :     PrintF("[WeakFixedArray: storing at index %d ]\n", index);
    9891             :   }
    9892             :   array->set_last_used_index(index);
    9893    13257244 : }
    9894             : 
    9895             : 
    9896             : // static
    9897    13257234 : Handle<WeakFixedArray> WeakFixedArray::Add(Handle<Object> maybe_array,
    9898             :                                            Handle<HeapObject> value,
    9899             :                                            int* assigned_index) {
    9900             :   Handle<WeakFixedArray> array =
    9901    13257243 :       (maybe_array.is_null() || !maybe_array->IsWeakFixedArray())
    9902             :           ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null())
    9903    13353593 :           : Handle<WeakFixedArray>::cast(maybe_array);
    9904             :   // Try to store the new entry if there's room. Optimize for consecutive
    9905             :   // accesses.
    9906             :   int first_index = array->last_used_index();
    9907             :   int length = array->Length();
    9908    13257253 :   if (length > 0) {
    9909             :     for (int i = first_index;;) {
    9910    57574811 :       if (array->IsEmptySlot((i))) {
    9911    13069700 :         WeakFixedArray::Set(array, i, value);
    9912    13069696 :         if (assigned_index != NULL) *assigned_index = i;
    9913    13069696 :         return array;
    9914             :       }
    9915    44505111 :       if (FLAG_trace_weak_arrays) {
    9916           0 :         PrintF("[WeakFixedArray: searching for free slot]\n");
    9917             :       }
    9918    44505110 :       i = (i + 1) % length;
    9919    44505110 :       if (i == first_index) break;
    9920             :     }
    9921             :   }
    9922             : 
    9923             :   // No usable slot found, grow the array.
    9924      187550 :   int new_length = length == 0 ? 1 : length + (length >> 1) + 4;
    9925             :   Handle<WeakFixedArray> new_array =
    9926      187550 :       Allocate(array->GetIsolate(), new_length, array);
    9927      187550 :   if (FLAG_trace_weak_arrays) {
    9928           0 :     PrintF("[WeakFixedArray: growing to size %d ]\n", new_length);
    9929             :   }
    9930      187550 :   WeakFixedArray::Set(new_array, length, value);
    9931      187550 :   if (assigned_index != NULL) *assigned_index = length;
    9932      187550 :   return new_array;
    9933             : }
    9934             : 
    9935             : 
    9936             : template <class CompactionCallback>
    9937         321 : void WeakFixedArray::Compact() {
    9938             :   FixedArray* array = FixedArray::cast(this);
    9939             :   int new_length = kFirstIndex;
    9940      139936 :   for (int i = kFirstIndex; i < array->length(); i++) {
    9941             :     Object* element = array->get(i);
    9942       69647 :     if (element->IsSmi()) continue;
    9943       46681 :     if (WeakCell::cast(element)->cleared()) continue;
    9944             :     Object* value = WeakCell::cast(element)->value();
    9945             :     CompactionCallback::Callback(value, i - kFirstIndex,
    9946         242 :                                  new_length - kFirstIndex);
    9947       46562 :     array->set(new_length++, element);
    9948             :   }
    9949         321 :   array->Shrink(new_length);
    9950             :   set_last_used_index(0);
    9951         321 : }
    9952             : 
    9953             : 
    9954     1068873 : void WeakFixedArray::Iterator::Reset(Object* maybe_array) {
    9955     1068873 :   if (maybe_array->IsWeakFixedArray()) {
    9956      425603 :     list_ = WeakFixedArray::cast(maybe_array);
    9957      425603 :     index_ = 0;
    9958             : #ifdef DEBUG
    9959             :     last_used_index_ = list_->last_used_index();
    9960             : #endif  // DEBUG
    9961             :   }
    9962     1068873 : }
    9963             : 
    9964             : 
    9965           0 : void JSObject::PrototypeRegistryCompactionCallback::Callback(Object* value,
    9966             :                                                              int old_index,
    9967             :                                                              int new_index) {
    9968             :   DCHECK(value->IsMap() && Map::cast(value)->is_prototype_map());
    9969             :   Map* map = Map::cast(value);
    9970             :   DCHECK(map->prototype_info()->IsPrototypeInfo());
    9971             :   PrototypeInfo* proto_info = PrototypeInfo::cast(map->prototype_info());
    9972             :   DCHECK_EQ(old_index, proto_info->registry_slot());
    9973             :   proto_info->set_registry_slot(new_index);
    9974           0 : }
    9975             : 
    9976             : 
    9977             : template void WeakFixedArray::Compact<WeakFixedArray::NullCallback>();
    9978             : template void
    9979             : WeakFixedArray::Compact<JSObject::PrototypeRegistryCompactionCallback>();
    9980             : 
    9981             : 
    9982     6239198 : bool WeakFixedArray::Remove(Handle<HeapObject> value) {
    9983     6239198 :   if (Length() == 0) return false;
    9984             :   // Optimize for the most recently added element to be removed again.
    9985             :   int first_index = last_used_index();
    9986             :   for (int i = first_index;;) {
    9987    13671188 :     if (Get(i) == *value) {
    9988             :       Clear(i);
    9989             :       // Users of WeakFixedArray should make sure that there are no duplicates.
    9990     6239198 :       return true;
    9991             :     }
    9992     1192792 :     i = (i + 1) % Length();
    9993      596396 :     if (i == first_index) return false;
    9994             :   }
    9995             :   UNREACHABLE();
    9996             : }
    9997             : 
    9998             : 
    9999             : // static
   10000      283923 : Handle<WeakFixedArray> WeakFixedArray::Allocate(
   10001             :     Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from) {
   10002             :   DCHECK(0 <= size);
   10003             :   Handle<FixedArray> result =
   10004      283923 :       isolate->factory()->NewUninitializedFixedArray(size + kFirstIndex);
   10005             :   int index = 0;
   10006      283923 :   if (!initialize_from.is_null()) {
   10007             :     DCHECK(initialize_from->Length() <= size);
   10008             :     Handle<FixedArray> raw_source = Handle<FixedArray>::cast(initialize_from);
   10009             :     // Copy the entries without compacting, since the PrototypeInfo relies on
   10010             :     // the index of the entries not to change.
   10011    37626613 :     while (index < raw_source->length()) {
   10012    37439063 :       result->set(index, raw_source->get(index));
   10013    37439063 :       index++;
   10014             :     }
   10015             :   }
   10016    19836103 :   while (index < result->length()) {
   10017             :     result->set(index, Smi::kZero);
   10018    19552180 :     index++;
   10019             :   }
   10020      283923 :   return Handle<WeakFixedArray>::cast(result);
   10021             : }
   10022             : 
   10023             : // static
   10024        2215 : Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj,
   10025             :                                  AddMode mode) {
   10026        2215 :   int length = array->Length();
   10027        2215 :   array = EnsureSpace(array, length + 1);
   10028        2215 :   if (mode == kReloadLengthAfterAllocation) {
   10029             :     DCHECK(array->Length() <= length);
   10030           0 :     length = array->Length();
   10031             :   }
   10032             :   array->Set(length, *obj);
   10033             :   array->SetLength(length + 1);
   10034        2215 :   return array;
   10035             : }
   10036             : 
   10037             : // static
   10038      964240 : Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj1,
   10039             :                                  Handle<Object> obj2, AddMode mode) {
   10040      964240 :   int length = array->Length();
   10041      964240 :   array = EnsureSpace(array, length + 2);
   10042      964240 :   if (mode == kReloadLengthAfterAllocation) {
   10043       38231 :     length = array->Length();
   10044             :   }
   10045             :   array->Set(length, *obj1);
   10046             :   array->Set(length + 1, *obj2);
   10047             :   array->SetLength(length + 2);
   10048      964240 :   return array;
   10049             : }
   10050             : 
   10051             : // static
   10052         472 : Handle<ArrayList> ArrayList::New(Isolate* isolate, int size) {
   10053             :   Handle<ArrayList> result = Handle<ArrayList>::cast(
   10054         472 :       isolate->factory()->NewFixedArray(size + kFirstIndex));
   10055             :   result->SetLength(0);
   10056         472 :   return result;
   10057             : }
   10058             : 
   10059         210 : Handle<FixedArray> ArrayList::Elements() const {
   10060         420 :   Handle<FixedArray> result = GetIsolate()->factory()->NewFixedArray(Length());
   10061             :   // Do not copy the first entry, i.e., the length.
   10062         420 :   CopyTo(kFirstIndex, *result, 0, Length());
   10063         210 :   return result;
   10064             : }
   10065             : 
   10066       38231 : bool ArrayList::IsFull() {
   10067             :   int capacity = length();
   10068       38231 :   return kFirstIndex + Length() == capacity;
   10069             : }
   10070             : 
   10071             : namespace {
   10072             : 
   10073     5994834 : Handle<FixedArray> EnsureSpaceInFixedArray(Handle<FixedArray> array,
   10074             :                                            int length) {
   10075             :   int capacity = array->length();
   10076     5994834 :   if (capacity < length) {
   10077             :     Isolate* isolate = array->GetIsolate();
   10078             :     int new_capacity = length;
   10079       97978 :     new_capacity = new_capacity + Max(new_capacity / 2, 2);
   10080       48989 :     int grow_by = new_capacity - capacity;
   10081       48989 :     array = isolate->factory()->CopyFixedArrayAndGrow(array, grow_by);
   10082             :   }
   10083     5994834 :   return array;
   10084             : }
   10085             : 
   10086             : }  // namespace
   10087             : 
   10088             : // static
   10089      966455 : Handle<ArrayList> ArrayList::EnsureSpace(Handle<ArrayList> array, int length) {
   10090             :   const bool empty = (array->length() == 0);
   10091             :   auto ret = Handle<ArrayList>::cast(
   10092     1932910 :       EnsureSpaceInFixedArray(array, kFirstIndex + length));
   10093      966455 :   if (empty) ret->SetLength(0);
   10094      966455 :   return ret;
   10095             : }
   10096             : 
   10097      259838 : Handle<RegExpMatchInfo> RegExpMatchInfo::ReserveCaptures(
   10098             :     Handle<RegExpMatchInfo> match_info, int capture_count) {
   10099             :   DCHECK_GE(match_info->length(), kLastMatchOverhead);
   10100      259838 :   const int required_length = kFirstCaptureIndex + capture_count;
   10101             :   Handle<FixedArray> result =
   10102      259838 :       EnsureSpaceInFixedArray(match_info, required_length);
   10103      259838 :   return Handle<RegExpMatchInfo>::cast(result);
   10104             : }
   10105             : 
   10106             : // static
   10107     4730461 : Handle<FrameArray> FrameArray::AppendJSFrame(Handle<FrameArray> in,
   10108             :                                              Handle<Object> receiver,
   10109             :                                              Handle<JSFunction> function,
   10110             :                                              Handle<AbstractCode> code,
   10111             :                                              int offset, int flags) {
   10112             :   const int frame_count = in->FrameCount();
   10113     4730461 :   const int new_length = LengthFor(frame_count + 1);
   10114             :   Handle<FrameArray> array = EnsureSpace(in, new_length);
   10115             :   array->SetReceiver(frame_count, *receiver);
   10116             :   array->SetFunction(frame_count, *function);
   10117             :   array->SetCode(frame_count, *code);
   10118             :   array->SetOffset(frame_count, Smi::FromInt(offset));
   10119     4730461 :   array->SetFlags(frame_count, Smi::FromInt(flags));
   10120             :   array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1));
   10121     4730461 :   return array;
   10122             : }
   10123             : 
   10124             : // static
   10125       38080 : Handle<FrameArray> FrameArray::AppendWasmFrame(Handle<FrameArray> in,
   10126             :                                                Handle<Object> wasm_instance,
   10127             :                                                int wasm_function_index,
   10128             :                                                Handle<AbstractCode> code,
   10129             :                                                int offset, int flags) {
   10130             :   const int frame_count = in->FrameCount();
   10131       38080 :   const int new_length = LengthFor(frame_count + 1);
   10132             :   Handle<FrameArray> array = EnsureSpace(in, new_length);
   10133             :   array->SetWasmInstance(frame_count, *wasm_instance);
   10134             :   array->SetWasmFunctionIndex(frame_count, Smi::FromInt(wasm_function_index));
   10135             :   // code will be a null handle for interpreted wasm frames.
   10136       38080 :   if (!code.is_null()) array->SetCode(frame_count, *code);
   10137             :   array->SetOffset(frame_count, Smi::FromInt(offset));
   10138       38080 :   array->SetFlags(frame_count, Smi::FromInt(flags));
   10139             :   array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1));
   10140       38080 :   return array;
   10141             : }
   10142             : 
   10143     2420150 : void FrameArray::ShrinkToFit() { Shrink(LengthFor(FrameCount())); }
   10144             : 
   10145             : // static
   10146           0 : Handle<FrameArray> FrameArray::EnsureSpace(Handle<FrameArray> array,
   10147             :                                            int length) {
   10148     4768541 :   return Handle<FrameArray>::cast(EnsureSpaceInFixedArray(array, length));
   10149             : }
   10150             : 
   10151    18589809 : Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
   10152             :                                                   int number_of_descriptors,
   10153             :                                                   int slack,
   10154             :                                                   PretenureFlag pretenure) {
   10155             :   DCHECK(0 <= number_of_descriptors);
   10156             :   Factory* factory = isolate->factory();
   10157             :   // Do not use DescriptorArray::cast on incomplete object.
   10158    18589809 :   int size = number_of_descriptors + slack;
   10159    18589809 :   if (size == 0) return factory->empty_descriptor_array();
   10160             :   // Allocate the array of keys.
   10161             :   Handle<FixedArray> result =
   10162    18589809 :       factory->NewFixedArray(LengthFor(size), pretenure);
   10163             : 
   10164             :   result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
   10165             :   result->set(kEnumCacheIndex, Smi::kZero);
   10166             :   return Handle<DescriptorArray>::cast(result);
   10167             : }
   10168             : 
   10169          12 : void DescriptorArray::ClearEnumCache() { set(kEnumCacheIndex, Smi::kZero); }
   10170             : 
   10171     2497941 : void DescriptorArray::Replace(int index, Descriptor* descriptor) {
   10172             :   descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index));
   10173     2497941 :   Set(index, descriptor);
   10174     2497941 : }
   10175             : 
   10176             : 
   10177             : // static
   10178      114947 : void DescriptorArray::SetEnumCache(Handle<DescriptorArray> descriptors,
   10179             :                                    Isolate* isolate,
   10180             :                                    Handle<FixedArray> new_cache,
   10181             :                                    Handle<FixedArray> new_index_cache) {
   10182             :   DCHECK(!descriptors->IsEmpty());
   10183             :   FixedArray* bridge_storage;
   10184      114947 :   bool needs_new_enum_cache = !descriptors->HasEnumCache();
   10185      114947 :   if (needs_new_enum_cache) {
   10186             :     bridge_storage = *isolate->factory()->NewFixedArray(
   10187      189884 :         DescriptorArray::kEnumCacheBridgeLength);
   10188             :   } else {
   10189             :     bridge_storage = FixedArray::cast(descriptors->get(kEnumCacheIndex));
   10190             :   }
   10191      114947 :   bridge_storage->set(kEnumCacheBridgeCacheIndex, *new_cache);
   10192             :   bridge_storage->set(
   10193             :       kEnumCacheBridgeIndicesCacheIndex,
   10194      229894 :       new_index_cache.is_null() ? Object::cast(Smi::kZero) : *new_index_cache);
   10195      114947 :   if (needs_new_enum_cache) {
   10196       94942 :     descriptors->set(kEnumCacheIndex, bridge_storage);
   10197             :   }
   10198      114947 : }
   10199             : 
   10200   154745872 : void DescriptorArray::CopyFrom(int index, DescriptorArray* src) {
   10201   154745872 :   PropertyDetails details = src->GetDetails(index);
   10202   154745879 :   Set(index, src->GetKey(index), src->GetValue(index), details);
   10203   154745884 : }
   10204             : 
   10205      673949 : void DescriptorArray::Sort() {
   10206             :   // In-place heap sort.
   10207      673949 :   int len = number_of_descriptors();
   10208             :   // Reset sorting since the descriptor array might contain invalid pointers.
   10209      673949 :   for (int i = 0; i < len; ++i) SetSortedKey(i, i);
   10210             :   // Bottom-up max-heap construction.
   10211             :   // Index of the last node with children
   10212      673949 :   const int max_parent_index = (len / 2) - 1;
   10213     2379558 :   for (int i = max_parent_index; i >= 0; --i) {
   10214             :     int parent_index = i;
   10215     1705609 :     const uint32_t parent_hash = GetSortedKey(i)->Hash();
   10216     5025342 :     while (parent_index <= max_parent_index) {
   10217     2443304 :       int child_index = 2 * parent_index + 1;
   10218     2443304 :       uint32_t child_hash = GetSortedKey(child_index)->Hash();
   10219     2443304 :       if (child_index + 1 < len) {
   10220     2075621 :         uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
   10221     2075621 :         if (right_child_hash > child_hash) {
   10222             :           child_index++;
   10223             :           child_hash = right_child_hash;
   10224             :         }
   10225             :       }
   10226     2443304 :       if (child_hash <= parent_hash) break;
   10227     1614124 :       SwapSortedKeys(parent_index, child_index);
   10228             :       // Now element at child_index could be < its children.
   10229             :       parent_index = child_index;  // parent_hash remains correct.
   10230             :     }
   10231             :   }
   10232             : 
   10233             :   // Extract elements and create sorted array.
   10234     3827504 :   for (int i = len - 1; i > 0; --i) {
   10235             :     // Put max element at the back of the array.
   10236     3153555 :     SwapSortedKeys(0, i);
   10237             :     // Shift down the new top element.
   10238             :     int parent_index = 0;
   10239     3153555 :     const uint32_t parent_hash = GetSortedKey(parent_index)->Hash();
   10240     3153555 :     const int max_parent_index = (i / 2) - 1;
   10241    12648488 :     while (parent_index <= max_parent_index) {
   10242     6813984 :       int child_index = parent_index * 2 + 1;
   10243     6813984 :       uint32_t child_hash = GetSortedKey(child_index)->Hash();
   10244     6813984 :       if (child_index + 1 < i) {
   10245     6150540 :         uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
   10246     6150540 :         if (right_child_hash > child_hash) {
   10247             :           child_index++;
   10248             :           child_hash = right_child_hash;
   10249             :         }
   10250             :       }
   10251     6813984 :       if (child_hash <= parent_hash) break;
   10252     6341378 :       SwapSortedKeys(parent_index, child_index);
   10253             :       parent_index = child_index;
   10254             :     }
   10255             :   }
   10256             :   DCHECK(IsSortedNoDuplicates());
   10257      673949 : }
   10258             : 
   10259             : 
   10260       17523 : Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) {
   10261       17523 :   Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair();
   10262       17523 :   copy->set_getter(pair->getter());
   10263       17523 :   copy->set_setter(pair->setter());
   10264       17523 :   return copy;
   10265             : }
   10266             : 
   10267       71561 : Handle<Object> AccessorPair::GetComponent(Handle<AccessorPair> accessor_pair,
   10268             :                                           AccessorComponent component) {
   10269             :   Object* accessor = accessor_pair->get(component);
   10270       71561 :   if (accessor->IsFunctionTemplateInfo()) {
   10271             :     return ApiNatives::InstantiateFunction(
   10272             :                handle(FunctionTemplateInfo::cast(accessor)))
   10273         184 :         .ToHandleChecked();
   10274             :   }
   10275             :   Isolate* isolate = accessor_pair->GetIsolate();
   10276       71469 :   if (accessor->IsNull(isolate)) {
   10277        6815 :     return isolate->factory()->undefined_value();
   10278             :   }
   10279             :   return handle(accessor, isolate);
   10280             : }
   10281             : 
   10282      670855 : Handle<DeoptimizationInputData> DeoptimizationInputData::New(
   10283             :     Isolate* isolate, int deopt_entry_count, PretenureFlag pretenure) {
   10284             :   return Handle<DeoptimizationInputData>::cast(
   10285             :       isolate->factory()->NewFixedArray(LengthFor(deopt_entry_count),
   10286      670855 :                                         pretenure));
   10287             : }
   10288             : 
   10289             : 
   10290      236544 : Handle<DeoptimizationOutputData> DeoptimizationOutputData::New(
   10291             :     Isolate* isolate,
   10292             :     int number_of_deopt_points,
   10293             :     PretenureFlag pretenure) {
   10294             :   Handle<FixedArray> result;
   10295      236544 :   if (number_of_deopt_points == 0) {
   10296             :     result = isolate->factory()->empty_fixed_array();
   10297             :   } else {
   10298             :     result = isolate->factory()->NewFixedArray(
   10299      236544 :         LengthOfFixedArray(number_of_deopt_points), pretenure);
   10300             :   }
   10301      236544 :   return Handle<DeoptimizationOutputData>::cast(result);
   10302             : }
   10303             : 
   10304          48 : SharedFunctionInfo* DeoptimizationInputData::GetInlinedFunction(int index) {
   10305          48 :   if (index == -1) {
   10306           0 :     return SharedFunctionInfo::cast(SharedFunctionInfo());
   10307             :   } else {
   10308          48 :     return SharedFunctionInfo::cast(LiteralArray()->get(index));
   10309             :   }
   10310             : }
   10311             : 
   10312    10643918 : int HandlerTable::LookupRange(int pc_offset, int* data_out,
   10313             :                               CatchPrediction* prediction_out) {
   10314             :   int innermost_handler = -1;
   10315             : #ifdef DEBUG
   10316             :   // Assuming that ranges are well nested, we don't need to track the innermost
   10317             :   // offsets. This is just to verify that the table is actually well nested.
   10318             :   int innermost_start = std::numeric_limits<int>::min();
   10319             :   int innermost_end = std::numeric_limits<int>::max();
   10320             : #endif
   10321    50999312 :   for (int i = 0; i < length(); i += kRangeEntrySize) {
   10322             :     int start_offset = Smi::cast(get(i + kRangeStartIndex))->value();
   10323    14855738 :     int end_offset = Smi::cast(get(i + kRangeEndIndex))->value();
   10324    14855738 :     int handler_field = Smi::cast(get(i + kRangeHandlerIndex))->value();
   10325    14855738 :     int handler_offset = HandlerOffsetField::decode(handler_field);
   10326             :     CatchPrediction prediction = HandlerPredictionField::decode(handler_field);
   10327    14855738 :     int handler_data = Smi::cast(get(i + kRangeDataIndex))->value();
   10328    14855738 :     if (pc_offset >= start_offset && pc_offset < end_offset) {
   10329             :       DCHECK_GE(start_offset, innermost_start);
   10330             :       DCHECK_LT(end_offset, innermost_end);
   10331             :       innermost_handler = handler_offset;
   10332             : #ifdef DEBUG
   10333             :       innermost_start = start_offset;
   10334             :       innermost_end = end_offset;
   10335             : #endif
   10336     2167171 :       if (data_out) *data_out = handler_data;
   10337     2167171 :       if (prediction_out) *prediction_out = prediction;
   10338             :     }
   10339             :   }
   10340    10643918 :   return innermost_handler;
   10341             : }
   10342             : 
   10343             : 
   10344             : // TODO(turbofan): Make sure table is sorted and use binary search.
   10345     2090381 : int HandlerTable::LookupReturn(int pc_offset) {
   10346     6623362 :   for (int i = 0; i < length(); i += kReturnEntrySize) {
   10347             :     int return_offset = Smi::cast(get(i + kReturnOffsetIndex))->value();
   10348     1546535 :     int handler_field = Smi::cast(get(i + kReturnHandlerIndex))->value();
   10349     1546535 :     if (pc_offset == return_offset) {
   10350      650470 :       return HandlerOffsetField::decode(handler_field);
   10351             :     }
   10352             :   }
   10353             :   return -1;
   10354             : }
   10355             : 
   10356             : 
   10357             : #ifdef DEBUG
   10358             : bool DescriptorArray::IsEqualTo(DescriptorArray* other) {
   10359             :   if (IsEmpty()) return other->IsEmpty();
   10360             :   if (other->IsEmpty()) return false;
   10361             :   if (length() != other->length()) return false;
   10362             :   for (int i = 0; i < length(); ++i) {
   10363             :     if (get(i) != other->get(i)) return false;
   10364             :   }
   10365             :   return true;
   10366             : }
   10367             : #endif
   10368             : 
   10369             : // static
   10370     1838054 : Handle<String> String::Trim(Handle<String> string, TrimMode mode) {
   10371     1838054 :   Isolate* const isolate = string->GetIsolate();
   10372     1838054 :   string = String::Flatten(string);
   10373             :   int const length = string->length();
   10374             : 
   10375             :   // Perform left trimming if requested.
   10376             :   int left = 0;
   10377             :   UnicodeCache* unicode_cache = isolate->unicode_cache();
   10378     1838054 :   if (mode == kTrim || mode == kTrimLeft) {
   10379     3693504 :     while (left < length &&
   10380     1846458 :            unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
   10381        9496 :       left++;
   10382             :     }
   10383             :   }
   10384             : 
   10385             :   // Perform right trimming if requested.
   10386             :   int right = length;
   10387     1838054 :   if (mode == kTrim || mode == kTrimRight) {
   10388     1838222 :     while (
   10389     3675856 :         right > left &&
   10390     3675268 :         unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(right - 1))) {
   10391        1050 :       right--;
   10392             :     }
   10393             :   }
   10394             : 
   10395     1838054 :   return isolate->factory()->NewSubString(string, left, right);
   10396             : }
   10397             : 
   10398     3124610 : bool String::LooksValid() { return GetIsolate()->heap()->Contains(this); }
   10399             : 
   10400             : // static
   10401     1533845 : MaybeHandle<String> Name::ToFunctionName(Handle<Name> name) {
   10402     1533850 :   if (name->IsString()) return Handle<String>::cast(name);
   10403             :   // ES6 section 9.2.11 SetFunctionName, step 4.
   10404             :   Isolate* const isolate = name->GetIsolate();
   10405             :   Handle<Object> description(Handle<Symbol>::cast(name)->name(), isolate);
   10406       11319 :   if (description->IsUndefined(isolate)) {
   10407             :     return isolate->factory()->empty_string();
   10408             :   }
   10409       11193 :   IncrementalStringBuilder builder(isolate);
   10410             :   builder.AppendCharacter('[');
   10411       11193 :   builder.AppendString(Handle<String>::cast(description));
   10412             :   builder.AppendCharacter(']');
   10413       11193 :   return builder.Finish();
   10414             : }
   10415             : 
   10416             : // static
   10417        6814 : MaybeHandle<String> Name::ToFunctionName(Handle<Name> name,
   10418             :                                          Handle<String> prefix) {
   10419             :   Handle<String> name_string;
   10420             :   Isolate* const isolate = name->GetIsolate();
   10421       13628 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, name_string, ToFunctionName(name),
   10422             :                              String);
   10423        6814 :   IncrementalStringBuilder builder(isolate);
   10424        6814 :   builder.AppendString(prefix);
   10425             :   builder.AppendCharacter(' ');
   10426        6814 :   builder.AppendString(name_string);
   10427        6814 :   return builder.Finish();
   10428             : }
   10429             : 
   10430             : namespace {
   10431             : 
   10432             : bool AreDigits(const uint8_t* s, int from, int to) {
   10433       46568 :   for (int i = from; i < to; i++) {
   10434      108361 :     if (s[i] < '0' || s[i] > '9') return false;
   10435             :   }
   10436             : 
   10437             :   return true;
   10438             : }
   10439             : 
   10440             : 
   10441             : int ParseDecimalInteger(const uint8_t* s, int from, int to) {
   10442             :   DCHECK(to - from < 10);  // Overflow is not possible.
   10443             :   DCHECK(from < to);
   10444        2619 :   int d = s[from] - '0';
   10445             : 
   10446        3198 :   for (int i = from + 1; i < to; i++) {
   10447         579 :     d = 10 * d + (s[i] - '0');
   10448             :   }
   10449             : 
   10450             :   return d;
   10451             : }
   10452             : 
   10453             : }  // namespace
   10454             : 
   10455             : 
   10456             : // static
   10457    12608721 : Handle<Object> String::ToNumber(Handle<String> subject) {
   10458     2719702 :   Isolate* const isolate = subject->GetIsolate();
   10459             : 
   10460             :   // Flatten {subject} string first.
   10461    12608721 :   subject = String::Flatten(subject);
   10462             : 
   10463             :   // Fast array index case.
   10464             :   uint32_t index;
   10465    12608721 :   if (subject->AsArrayIndex(&index)) {
   10466     6002725 :     return isolate->factory()->NewNumberFromUint(index);
   10467             :   }
   10468             : 
   10469             :   // Fast case: short integer or some sorts of junk values.
   10470     6605996 :   if (subject->IsSeqOneByteString()) {
   10471             :     int len = subject->length();
   10472     4158674 :     if (len == 0) return handle(Smi::kZero, isolate);
   10473             : 
   10474             :     DisallowHeapAllocation no_gc;
   10475     4092236 :     uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
   10476     4092236 :     bool minus = (data[0] == '-');
   10477     4092236 :     int start_pos = (minus ? 1 : 0);
   10478             : 
   10479     4092236 :     if (start_pos == len) {
   10480           0 :       return isolate->factory()->nan_value();
   10481     4092236 :     } else if (data[start_pos] > '9') {
   10482             :       // Fast check for a junk value. A valid string may start from a
   10483             :       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
   10484             :       // or the 'I' character ('Infinity'). All of that have codes not greater
   10485             :       // than '9' except 'I' and &nbsp;.
   10486     3859879 :       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
   10487     3850456 :         return isolate->factory()->nan_value();
   10488             :       }
   10489      296769 :     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
   10490             :       // The maximal/minimal smi has 10 digits. If the string has less digits
   10491             :       // we know it will fit into the smi-data type.
   10492             :       int d = ParseDecimalInteger(data, start_pos, len);
   10493        2619 :       if (minus) {
   10494        2933 :         if (d == 0) return isolate->factory()->minus_zero_value();
   10495        2125 :         d = -d;
   10496         180 :       } else if (!subject->HasHashCode() && len <= String::kMaxArrayIndexSize &&
   10497           0 :                  (len == 1 || data[0] != '0')) {
   10498             :         // String hash is not calculated yet but all the data are present.
   10499             :         // Update the hash field to speed up sequential convertions.
   10500           0 :         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
   10501             : #ifdef DEBUG
   10502             :         subject->Hash();  // Force hash calculation.
   10503             :         DCHECK_EQ(static_cast<int>(subject->hash_field()),
   10504             :                   static_cast<int>(hash));
   10505             : #endif
   10506             :         subject->set_hash_field(hash);
   10507             :       }
   10508        2215 :       return handle(Smi::FromInt(d), isolate);
   10509             :     }
   10510             :   }
   10511             : 
   10512             :   // Slower case.
   10513             :   int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
   10514             :   return isolate->factory()->NewNumber(
   10515     2719702 :       StringToDouble(isolate->unicode_cache(), subject, flags));
   10516             : }
   10517             : 
   10518             : 
   10519   125848762 : String::FlatContent String::GetFlatContent() {
   10520             :   DCHECK(!AllowHeapAllocation::IsAllowed());
   10521             :   int length = this->length();
   10522             :   StringShape shape(this);
   10523             :   String* string = this;
   10524             :   int offset = 0;
   10525   125848762 :   if (shape.representation_tag() == kConsStringTag) {
   10526             :     ConsString* cons = ConsString::cast(string);
   10527           0 :     if (cons->second()->length() != 0) {
   10528           0 :       return FlatContent();
   10529             :     }
   10530             :     string = cons->first();
   10531             :     shape = StringShape(string);
   10532   125848762 :   } else if (shape.representation_tag() == kSlicedStringTag) {
   10533             :     SlicedString* slice = SlicedString::cast(string);
   10534             :     offset = slice->offset();
   10535             :     string = slice->parent();
   10536             :     shape = StringShape(string);
   10537             :     DCHECK(shape.representation_tag() != kConsStringTag &&
   10538             :            shape.representation_tag() != kSlicedStringTag);
   10539             :   }
   10540   125848762 :   if (shape.representation_tag() == kThinStringTag) {
   10541             :     ThinString* thin = ThinString::cast(string);
   10542             :     string = thin->actual();
   10543             :     shape = StringShape(string);
   10544             :     DCHECK(!shape.IsCons());
   10545             :     DCHECK(!shape.IsSliced());
   10546             :   }
   10547   125848762 :   if (shape.encoding_tag() == kOneByteStringTag) {
   10548             :     const uint8_t* start;
   10549   113737003 :     if (shape.representation_tag() == kSeqStringTag) {
   10550   113733852 :       start = SeqOneByteString::cast(string)->GetChars();
   10551             :     } else {
   10552             :       start = ExternalOneByteString::cast(string)->GetChars();
   10553             :     }
   10554   113737004 :     return FlatContent(start + offset, length);
   10555             :   } else {
   10556             :     DCHECK(shape.encoding_tag() == kTwoByteStringTag);
   10557             :     const uc16* start;
   10558    12111759 :     if (shape.representation_tag() == kSeqStringTag) {
   10559    12108969 :       start = SeqTwoByteString::cast(string)->GetChars();
   10560             :     } else {
   10561             :       start = ExternalTwoByteString::cast(string)->GetChars();
   10562             :     }
   10563    12111759 :     return FlatContent(start + offset, length);
   10564             :   }
   10565             : }
   10566             : 
   10567     3735791 : std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls,
   10568             :                                           RobustnessFlag robust_flag,
   10569             :                                           int offset, int length,
   10570             :                                           int* length_return) {
   10571     6860293 :   if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
   10572             :     return std::unique_ptr<char[]>();
   10573             :   }
   10574             :   // Negative length means the to the end of the string.
   10575     3735791 :   if (length < 0) length = kMaxInt - offset;
   10576             : 
   10577             :   // Compute the size of the UTF-8 string. Start at the specified offset.
   10578             :   StringCharacterStream stream(this, offset);
   10579             :   int character_position = offset;
   10580             :   int utf8_bytes = 0;
   10581             :   int last = unibrow::Utf16::kNoPreviousCharacter;
   10582    42641389 :   while (stream.HasMore() && character_position++ < offset + length) {
   10583    35169807 :     uint16_t character = stream.GetNext();
   10584    35169807 :     utf8_bytes += unibrow::Utf8::Length(character, last);
   10585    35169807 :     last = character;
   10586             :   }
   10587             : 
   10588     3735791 :   if (length_return) {
   10589     3085192 :     *length_return = utf8_bytes;
   10590             :   }
   10591             : 
   10592     3735791 :   char* result = NewArray<char>(utf8_bytes + 1);
   10593             : 
   10594             :   // Convert the UTF-16 string to a UTF-8 buffer. Start at the specified offset.
   10595     3735792 :   stream.Reset(this, offset);
   10596             :   character_position = offset;
   10597             :   int utf8_byte_position = 0;
   10598             :   last = unibrow::Utf16::kNoPreviousCharacter;
   10599    42641391 :   while (stream.HasMore() && character_position++ < offset + length) {
   10600    35169807 :     uint16_t character = stream.GetNext();
   10601    35169807 :     if (allow_nulls == DISALLOW_NULLS && character == 0) {
   10602             :       character = ' ';
   10603             :     }
   10604             :     utf8_byte_position +=
   10605    35169807 :         unibrow::Utf8::Encode(result + utf8_byte_position, character, last);
   10606    35169807 :     last = character;
   10607             :   }
   10608     3735791 :   result[utf8_byte_position] = 0;
   10609             :   return std::unique_ptr<char[]>(result);
   10610             : }
   10611             : 
   10612      654987 : std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls,
   10613             :                                           RobustnessFlag robust_flag,
   10614             :                                           int* length_return) {
   10615      654987 :   return ToCString(allow_nulls, robust_flag, 0, -1, length_return);
   10616             : }
   10617             : 
   10618             : 
   10619          82 : const uc16* String::GetTwoByteData(unsigned start) {
   10620             :   DCHECK(!IsOneByteRepresentationUnderneath());
   10621          82 :   switch (StringShape(this).representation_tag()) {
   10622             :     case kSeqStringTag:
   10623           0 :       return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start);
   10624             :     case kExternalStringTag:
   10625             :       return ExternalTwoByteString::cast(this)->
   10626          82 :         ExternalTwoByteStringGetData(start);
   10627             :     case kSlicedStringTag: {
   10628             :       SlicedString* slice = SlicedString::cast(this);
   10629           0 :       return slice->parent()->GetTwoByteData(start + slice->offset());
   10630             :     }
   10631             :     case kConsStringTag:
   10632             :     case kThinStringTag:
   10633           0 :       UNREACHABLE();
   10634             :       return NULL;
   10635             :   }
   10636           0 :   UNREACHABLE();
   10637             :   return NULL;
   10638             : }
   10639             : 
   10640             : 
   10641           0 : const uc16* SeqTwoByteString::SeqTwoByteStringGetData(unsigned start) {
   10642             :   return reinterpret_cast<uc16*>(
   10643           0 :       reinterpret_cast<char*>(this) - kHeapObjectTag + kHeaderSize) + start;
   10644             : }
   10645             : 
   10646             : 
   10647      122535 : void Relocatable::PostGarbageCollectionProcessing(Isolate* isolate) {
   10648             :   Relocatable* current = isolate->relocatable_top();
   10649      266691 :   while (current != NULL) {
   10650       21621 :     current->PostGarbageCollection();
   10651       21621 :     current = current->prev_;
   10652             :   }
   10653      122535 : }
   10654             : 
   10655             : 
   10656             : // Reserve space for statics needing saving and restoring.
   10657        1280 : int Relocatable::ArchiveSpacePerThread() {
   10658        1280 :   return sizeof(Relocatable*);  // NOLINT
   10659             : }
   10660             : 
   10661             : 
   10662             : // Archive statics that are thread-local.
   10663       22574 : char* Relocatable::ArchiveState(Isolate* isolate, char* to) {
   10664       22574 :   *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top();
   10665             :   isolate->set_relocatable_top(NULL);
   10666       22574 :   return to + ArchiveSpacePerThread();
   10667             : }
   10668             : 
   10669             : 
   10670             : // Restore statics that are thread-local.
   10671       22574 : char* Relocatable::RestoreState(Isolate* isolate, char* from) {
   10672       22574 :   isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from));
   10673       22574 :   return from + ArchiveSpacePerThread();
   10674             : }
   10675             : 
   10676        4049 : char* Relocatable::Iterate(RootVisitor* v, char* thread_storage) {
   10677        4049 :   Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage);
   10678             :   Iterate(v, top);
   10679        4049 :   return thread_storage + ArchiveSpacePerThread();
   10680             : }
   10681             : 
   10682      241585 : void Relocatable::Iterate(Isolate* isolate, RootVisitor* v) {
   10683             :   Iterate(v, isolate->relocatable_top());
   10684      241585 : }
   10685             : 
   10686           0 : void Relocatable::Iterate(RootVisitor* v, Relocatable* top) {
   10687             :   Relocatable* current = top;
   10688      287607 :   while (current != NULL) {
   10689       41973 :     current->IterateInstance(v);
   10690       41973 :     current = current->prev_;
   10691             :   }
   10692           0 : }
   10693             : 
   10694             : 
   10695     1492125 : FlatStringReader::FlatStringReader(Isolate* isolate, Handle<String> str)
   10696             :     : Relocatable(isolate),
   10697             :       str_(str.location()),
   10698     4476375 :       length_(str->length()) {
   10699     1492125 :   PostGarbageCollection();
   10700     1492125 : }
   10701             : 
   10702             : 
   10703        3584 : FlatStringReader::FlatStringReader(Isolate* isolate, Vector<const char> input)
   10704             :     : Relocatable(isolate),
   10705             :       str_(0),
   10706             :       is_one_byte_(true),
   10707        3584 :       length_(input.length()),
   10708       10752 :       start_(input.start()) {}
   10709             : 
   10710             : 
   10711     1492210 : void FlatStringReader::PostGarbageCollection() {
   10712     1492210 :   if (str_ == NULL) return;
   10713             :   Handle<String> str(str_);
   10714             :   DCHECK(str->IsFlat());
   10715             :   DisallowHeapAllocation no_gc;
   10716             :   // This does not actually prevent the vector from being relocated later.
   10717     1492210 :   String::FlatContent content = str->GetFlatContent();
   10718             :   DCHECK(content.IsFlat());
   10719     2984420 :   is_one_byte_ = content.IsOneByte();
   10720     1492210 :   if (is_one_byte_) {
   10721     1352826 :     start_ = content.ToOneByteVector().start();
   10722             :   } else {
   10723      139384 :     start_ = content.ToUC16Vector().start();
   10724             :   }
   10725             : }
   10726             : 
   10727             : 
   10728       60578 : void ConsStringIterator::Initialize(ConsString* cons_string, int offset) {
   10729             :   DCHECK(cons_string != NULL);
   10730     6029272 :   root_ = cons_string;
   10731     6029272 :   consumed_ = offset;
   10732             :   // Force stack blown condition to trigger restart.
   10733     6029272 :   depth_ = 1;
   10734     6029272 :   maximum_depth_ = kStackSize + depth_;
   10735             :   DCHECK(StackBlown());
   10736       60578 : }
   10737             : 
   10738             : 
   10739    75773602 : String* ConsStringIterator::Continue(int* offset_out) {
   10740             :   DCHECK(depth_ != 0);
   10741             :   DCHECK_EQ(0, *offset_out);
   10742    75773602 :   bool blew_stack = StackBlown();
   10743             :   String* string = NULL;
   10744             :   // Get the next leaf if there is one.
   10745    75773602 :   if (!blew_stack) string = NextLeaf(&blew_stack);
   10746             :   // Restart search from root.
   10747    75773602 :   if (blew_stack) {
   10748             :     DCHECK(string == NULL);
   10749     6835546 :     string = Search(offset_out);
   10750             :   }
   10751             :   // Ensure future calls return null immediately.
   10752    75773602 :   if (string == NULL) Reset(NULL);
   10753    75773602 :   return string;
   10754             : }
   10755             : 
   10756             : 
   10757    13670918 : String* ConsStringIterator::Search(int* offset_out) {
   10758     6835546 :   ConsString* cons_string = root_;
   10759             :   // Reset the stack, pushing the root string.
   10760     6835546 :   depth_ = 1;
   10761     6835546 :   maximum_depth_ = 1;
   10762     6835546 :   frames_[0] = cons_string;
   10763     6835546 :   const int consumed = consumed_;
   10764             :   int offset = 0;
   10765             :   while (true) {
   10766             :     // Loop until the string is found which contains the target offset.
   10767             :     String* string = cons_string->first();
   10768             :     int length = string->length();
   10769             :     int32_t type;
   10770 23686754271 :     if (consumed < offset + length) {
   10771             :       // Target offset is in the left branch.
   10772             :       // Keep going if we're still in a ConString.
   10773             :       type = string->map()->instance_type();
   10774 23684379137 :       if ((type & kStringRepresentationMask) == kConsStringTag) {
   10775             :         cons_string = ConsString::cast(string);
   10776             :         PushLeft(cons_string);
   10777             :         continue;
   10778             :       }
   10779             :       // Tell the stack we're done descending.
   10780             :       AdjustMaximumDepth();
   10781             :     } else {
   10782             :       // Descend right.
   10783             :       // Update progress through the string.
   10784             :       offset += length;
   10785             :       // Keep going if we're still in a ConString.
   10786             :       string = cons_string->second();
   10787             :       type = string->map()->instance_type();
   10788     2375134 :       if ((type & kStringRepresentationMask) == kConsStringTag) {
   10789             :         cons_string = ConsString::cast(string);
   10790             :         PushRight(cons_string);
   10791             :         continue;
   10792             :       }
   10793             :       // Need this to be updated for the current string.
   10794             :       length = string->length();
   10795             :       // Account for the possibility of an empty right leaf.
   10796             :       // This happens only if we have asked for an offset outside the string.
   10797      770020 :       if (length == 0) {
   10798             :         // Reset so future operations will return null immediately.
   10799             :         Reset(NULL);
   10800         174 :         return NULL;
   10801             :       }
   10802             :       // Tell the stack we're done descending.
   10803             :       AdjustMaximumDepth();
   10804             :       // Pop stack so next iteration is in correct place.
   10805             :       Pop();
   10806             :     }
   10807             :     DCHECK(length != 0);
   10808             :     // Adjust return values and exit.
   10809     6835372 :     consumed_ = offset + length;
   10810     6835372 :     *offset_out = consumed - offset;
   10811     6835372 :     return string;
   10812             :   }
   10813             :   UNREACHABLE();
   10814             :   return NULL;
   10815             : }
   10816             : 
   10817             : 
   10818   152813306 : String* ConsStringIterator::NextLeaf(bool* blew_stack) {
   10819             :   while (true) {
   10820             :     // Tree traversal complete.
   10821    69531267 :     if (depth_ == 0) {
   10822        6995 :       *blew_stack = false;
   10823        6995 :       return NULL;
   10824             :     }
   10825             :     // We've lost track of higher nodes.
   10826    69524272 :     if (StackBlown()) {
   10827         834 :       *blew_stack = true;
   10828         834 :       return NULL;
   10829             :     }
   10830             :     // Go right.
   10831   139046876 :     ConsString* cons_string = frames_[OffsetForDepth(depth_ - 1)];
   10832             :     String* string = cons_string->second();
   10833             :     int32_t type = string->map()->instance_type();
   10834    69523438 :     if ((type & kStringRepresentationMask) != kConsStringTag) {
   10835             :       // Pop stack so next iteration is in correct place.
   10836             :       Pop();
   10837             :       int length = string->length();
   10838             :       // Could be a flattened ConsString.
   10839    55173294 :       if (length == 0) continue;
   10840    54580917 :       consumed_ += length;
   10841    54580917 :       return string;
   10842             :     }
   10843             :     cons_string = ConsString::cast(string);
   10844             :     PushRight(cons_string);
   10845             :     // Need to traverse all the way left.
   10846             :     while (true) {
   10847             :       // Continue left.
   10848             :       string = cons_string->first();
   10849             :       type = string->map()->instance_type();
   10850    23759740 :       if ((type & kStringRepresentationMask) != kConsStringTag) {
   10851             :         AdjustMaximumDepth();
   10852             :         int length = string->length();
   10853    14350144 :         if (length == 0) break;  // Skip empty left-hand sides of ConsStrings.
   10854    14350144 :         consumed_ += length;
   10855    14350144 :         return string;
   10856             :       }
   10857             :       cons_string = ConsString::cast(string);
   10858             :       PushLeft(cons_string);
   10859             :     }
   10860             :   }
   10861             :   UNREACHABLE();
   10862             :   return NULL;
   10863             : }
   10864             : 
   10865             : 
   10866     4314804 : uint16_t ConsString::ConsStringGet(int index) {
   10867             :   DCHECK(index >= 0 && index < this->length());
   10868             : 
   10869             :   // Check for a flattened cons string
   10870     4314804 :   if (second()->length() == 0) {
   10871             :     String* left = first();
   10872      368913 :     return left->Get(index);
   10873             :   }
   10874             : 
   10875             :   String* string = String::cast(this);
   10876             : 
   10877             :   while (true) {
   10878    42977412 :     if (StringShape(string).IsCons()) {
   10879             :       ConsString* cons_string = ConsString::cast(string);
   10880             :       String* left = cons_string->first();
   10881    39031521 :       if (left->length() > index) {
   10882             :         string = left;
   10883             :       } else {
   10884      488981 :         index -= left->length();
   10885             :         string = cons_string->second();
   10886             :       }
   10887             :     } else {
   10888     3945891 :       return string->Get(index);
   10889             :     }
   10890             :   }
   10891             : 
   10892             :   UNREACHABLE();
   10893             :   return 0;
   10894             : }
   10895             : 
   10896         516 : uint16_t ThinString::ThinStringGet(int index) { return actual()->Get(index); }
   10897             : 
   10898     1816876 : uint16_t SlicedString::SlicedStringGet(int index) {
   10899     3633752 :   return parent()->Get(offset() + index);
   10900             : }
   10901             : 
   10902             : 
   10903             : template <typename sinkchar>
   10904   277435848 : void String::WriteToFlat(String* src,
   10905             :                          sinkchar* sink,
   10906             :                          int f,
   10907             :                          int t) {
   10908             :   String* source = src;
   10909             :   int from = f;
   10910             :   int to = t;
   10911             :   while (true) {
   10912             :     DCHECK(0 <= from && from <= to && to <= source->length());
   10913   372472248 :     switch (StringShape(source).full_representation_tag()) {
   10914             :       case kOneByteStringTag | kExternalStringTag: {
   10915             :         CopyChars(sink, ExternalOneByteString::cast(source)->GetChars() + from,
   10916      996924 :                   to - from);
   10917             :         return;
   10918             :       }
   10919             :       case kTwoByteStringTag | kExternalStringTag: {
   10920             :         const uc16* data =
   10921             :             ExternalTwoByteString::cast(source)->GetChars();
   10922             :         CopyChars(sink,
   10923             :                   data + from,
   10924      340890 :                   to - from);
   10925             :         return;
   10926             :       }
   10927             :       case kOneByteStringTag | kSeqStringTag: {
   10928             :         CopyChars(sink,
   10929   244929479 :                   SeqOneByteString::cast(source)->GetChars() + from,
   10930   489858958 :                   to - from);
   10931             :         return;
   10932             :       }
   10933             :       case kTwoByteStringTag | kSeqStringTag: {
   10934             :         CopyChars(sink,
   10935    12055590 :                   SeqTwoByteString::cast(source)->GetChars() + from,
   10936    24111180 :                   to - from);
   10937             :         return;
   10938             :       }
   10939             :       case kOneByteStringTag | kConsStringTag:
   10940             :       case kTwoByteStringTag | kConsStringTag: {
   10941             :         ConsString* cons_string = ConsString::cast(source);
   10942             :         String* first = cons_string->first();
   10943             :         int boundary = first->length();
   10944   112535277 :         if (to - boundary >= boundary - from) {
   10945             :           // Right hand side is longer.  Recurse over left.
   10946    30928669 :           if (from < boundary) {
   10947    30928669 :             WriteToFlat(first, sink, from, boundary);
   10948    61857338 :             if (from == 0 && cons_string->second() == first) {
   10949    17531267 :               CopyChars(sink + boundary, sink, boundary);
   10950             :               return;
   10951             :             }
   10952    13397402 :             sink += boundary - from;
   10953             :             from = 0;
   10954             :           } else {
   10955           0 :             from -= boundary;
   10956             :           }
   10957             :           to -= boundary;
   10958             :           source = cons_string->second();
   10959             :         } else {
   10960             :           // Left hand side is longer.  Recurse over right.
   10961    81606608 :           if (to > boundary) {
   10962             :             String* second = cons_string->second();
   10963             :             // When repeatedly appending to a string, we get a cons string that
   10964             :             // is unbalanced to the left, a list, essentially.  We inline the
   10965             :             // common case of sequential one-byte right child.
   10966    81037951 :             if (to - boundary == 1) {
   10967    72452616 :               sink[boundary - from] = static_cast<sinkchar>(second->Get(0));
   10968    44811643 :             } else if (second->IsSeqOneByteString()) {
   10969    38380080 :               CopyChars(sink + boundary - from,
   10970    38380080 :                         SeqOneByteString::cast(second)->GetChars(),
   10971    76760160 :                         to - boundary);
   10972             :             } else {
   10973     6431563 :               WriteToFlat(second,
   10974     6431563 :                           sink + boundary - from,
   10975             :                           0,
   10976     6431563 :                           to - boundary);
   10977             :             }
   10978             :             to = boundary;
   10979             :           }
   10980             :           source = first;
   10981             :         }
   10982             :         break;
   10983             :       }
   10984             :       case kOneByteStringTag | kSlicedStringTag:
   10985             :       case kTwoByteStringTag | kSlicedStringTag: {
   10986             :         SlicedString* slice = SlicedString::cast(source);
   10987     2080159 :         unsigned offset = slice->offset();
   10988     4160318 :         WriteToFlat(slice->parent(), sink, from + offset, to + offset);
   10989     2080159 :         return;
   10990             :       }
   10991             :       case kOneByteStringTag | kThinStringTag:
   10992             :       case kTwoByteStringTag | kThinStringTag:
   10993             :         source = ThinString::cast(source)->actual();
   10994       32393 :         break;
   10995             :     }
   10996             :   }
   10997             : }
   10998             : 
   10999             : 
   11000             : 
   11001             : template <typename SourceChar>
   11002      129988 : static void CalculateLineEndsImpl(Isolate* isolate,
   11003             :                                   List<int>* line_ends,
   11004             :                                   Vector<const SourceChar> src,
   11005             :                                   bool include_ending_line) {
   11006       64994 :   const int src_len = src.length();
   11007             :   UnicodeCache* cache = isolate->unicode_cache();
   11008   330378325 :   for (int i = 0; i < src_len - 1; i++) {
   11009   330313331 :     SourceChar current = src[i];
   11010   660626662 :     SourceChar next = src[i + 1];
   11011   330313331 :     if (cache->IsLineTerminatorSequence(current, next)) line_ends->Add(i);
   11012             :   }
   11013             : 
   11014      129498 :   if (src_len > 0 && cache->IsLineTerminatorSequence(src[src_len - 1], 0)) {
   11015       23333 :     line_ends->Add(src_len - 1);
   11016             :   }
   11017       64994 :   if (include_ending_line) {
   11018             :     // Include one character beyond the end of script. The rewriter uses that
   11019             :     // position for the implicit return statement.
   11020       63154 :     line_ends->Add(src_len);
   11021             :   }
   11022       64994 : }
   11023             : 
   11024             : 
   11025       64994 : Handle<FixedArray> String::CalculateLineEnds(Handle<String> src,
   11026             :                                              bool include_ending_line) {
   11027       64994 :   src = Flatten(src);
   11028             :   // Rough estimate of line count based on a roughly estimated average
   11029             :   // length of (unpacked) code.
   11030       64994 :   int line_count_estimate = src->length() >> 4;
   11031             :   List<int> line_ends(line_count_estimate);
   11032             :   Isolate* isolate = src->GetIsolate();
   11033             :   { DisallowHeapAllocation no_allocation;  // ensure vectors stay valid.
   11034             :     // Dispatch on type of strings.
   11035       64994 :     String::FlatContent content = src->GetFlatContent();
   11036             :     DCHECK(content.IsFlat());
   11037       64994 :     if (content.IsOneByte()) {
   11038             :       CalculateLineEndsImpl(isolate,
   11039             :                             &line_ends,
   11040             :                             content.ToOneByteVector(),
   11041       64388 :                             include_ending_line);
   11042             :     } else {
   11043             :       CalculateLineEndsImpl(isolate,
   11044             :                             &line_ends,
   11045             :                             content.ToUC16Vector(),
   11046         606 :                             include_ending_line);
   11047             :     }
   11048             :   }
   11049       64994 :   int line_count = line_ends.length();
   11050       64994 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
   11051    14932606 :   for (int i = 0; i < line_count; i++) {
   11052    29735224 :     array->set(i, Smi::FromInt(line_ends[i]));
   11053             :   }
   11054      129988 :   return array;
   11055             : }
   11056             : 
   11057             : 
   11058             : // Compares the contents of two strings by reading and comparing
   11059             : // int-sized blocks of characters.
   11060             : template <typename Char>
   11061             : static inline bool CompareRawStringContents(const Char* const a,
   11062             :                                             const Char* const b,
   11063             :                                             int length) {
   11064   106067174 :   return CompareChars(a, b, length) == 0;
   11065             : }
   11066             : 
   11067             : 
   11068             : template<typename Chars1, typename Chars2>
   11069             : class RawStringComparator : public AllStatic {
   11070             :  public:
   11071             :   static inline bool compare(const Chars1* a, const Chars2* b, int len) {
   11072             :     DCHECK(sizeof(Chars1) != sizeof(Chars2));
   11073     1286580 :     for (int i = 0; i < len; i++) {
   11074     1286628 :       if (a[i] != b[i]) {
   11075             :         return false;
   11076             :       }
   11077             :     }
   11078             :     return true;
   11079             :   }
   11080             : };
   11081             : 
   11082             : 
   11083             : template<>
   11084             : class RawStringComparator<uint16_t, uint16_t> {
   11085             :  public:
   11086             :   static inline bool compare(const uint16_t* a, const uint16_t* b, int len) {
   11087             :     return CompareRawStringContents(a, b, len);
   11088             :   }
   11089             : };
   11090             : 
   11091             : 
   11092             : template<>
   11093             : class RawStringComparator<uint8_t, uint8_t> {
   11094             :  public:
   11095             :   static inline bool compare(const uint8_t* a, const uint8_t* b, int len) {
   11096             :     return CompareRawStringContents(a, b, len);
   11097             :   }
   11098             : };
   11099             : 
   11100             : 
   11101             : class StringComparator {
   11102             :   class State {
   11103             :    public:
   11104     6157423 :     State() : is_one_byte_(true), length_(0), buffer8_(NULL) {}
   11105             : 
   11106    12314846 :     void Init(String* string) {
   11107    12314846 :       ConsString* cons_string = String::VisitFlat(this, string);
   11108             :       iter_.Reset(cons_string);
   11109    12314846 :       if (cons_string != NULL) {
   11110             :         int offset;
   11111     3736066 :         string = iter_.Next(&offset);
   11112     3736066 :         String::VisitFlat(this, string, offset);
   11113             :       }
   11114    12314846 :     }
   11115             : 
   11116             :     inline void VisitOneByteString(const uint8_t* chars, int length) {
   11117    50963988 :       is_one_byte_ = true;
   11118    50963988 :       buffer8_ = chars;
   11119    50963988 :       length_ = length;
   11120             :     }
   11121             : 
   11122             :     inline void VisitTwoByteString(const uint16_t* chars, int length) {
   11123     7882395 :       is_one_byte_ = false;
   11124     7882395 :       buffer16_ = chars;
   11125     7882395 :       length_ = length;
   11126             :     }
   11127             : 
   11128    56474780 :     void Advance(int consumed) {
   11129             :       DCHECK(consumed <= length_);
   11130             :       // Still in buffer.
   11131    56474780 :       if (length_ != consumed) {
   11132     9943243 :         if (is_one_byte_) {
   11133     9849533 :           buffer8_ += consumed;
   11134             :         } else {
   11135       93710 :           buffer16_ += consumed;
   11136             :         }
   11137     9943243 :         length_ -= consumed;
   11138    66418023 :         return;
   11139             :       }
   11140             :       // Advance state.
   11141             :       int offset;
   11142    46531537 :       String* next = iter_.Next(&offset);
   11143             :       DCHECK_EQ(0, offset);
   11144             :       DCHECK(next != NULL);
   11145    46531537 :       String::VisitFlat(this, next);
   11146             :     }
   11147             : 
   11148             :     ConsStringIterator iter_;
   11149             :     bool is_one_byte_;
   11150             :     int length_;
   11151             :     union {
   11152             :       const uint8_t* buffer8_;
   11153             :       const uint16_t* buffer16_;
   11154             :     };
   11155             : 
   11156             :    private:
   11157             :     DISALLOW_COPY_AND_ASSIGN(State);
   11158             :   };
   11159             : 
   11160             :  public:
   11161             :   inline StringComparator() {}
   11162             : 
   11163             :   template<typename Chars1, typename Chars2>
   11164             :   static inline bool Equals(State* state_1, State* state_2, int to_check) {
   11165             :     const Chars1* a = reinterpret_cast<const Chars1*>(state_1->buffer8_);
   11166             :     const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_);
   11167             :     return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check);
   11168             :   }
   11169             : 
   11170     6157423 :   bool Equals(String* string_1, String* string_2) {
   11171             :     int length = string_1->length();
   11172    40552236 :     state_1_.Init(string_1);
   11173    40552236 :     state_2_.Init(string_2);
   11174             :     while (true) {
   11175    34394813 :       int to_check = Min(state_1_.length_, state_2_.length_);
   11176             :       DCHECK(to_check > 0 && to_check <= length);
   11177             :       bool is_equal;
   11178    34394813 :       if (state_1_.is_one_byte_) {
   11179    30354128 :         if (state_2_.is_one_byte_) {
   11180             :           is_equal = Equals<uint8_t, uint8_t>(&state_1_, &state_2_, to_check);
   11181             :         } else {
   11182             :           is_equal = Equals<uint8_t, uint16_t>(&state_1_, &state_2_, to_check);
   11183             :         }
   11184             :       } else {
   11185     4040685 :         if (state_2_.is_one_byte_) {
   11186             :           is_equal = Equals<uint16_t, uint8_t>(&state_1_, &state_2_, to_check);
   11187             :         } else {
   11188             :           is_equal = Equals<uint16_t, uint16_t>(&state_1_, &state_2_, to_check);
   11189             :         }
   11190             :       }
   11191             :       // Looping done.
   11192    34394813 :       if (!is_equal) return false;
   11193    34381984 :       length -= to_check;
   11194             :       // Exit condition. Strings are equal.
   11195    34381984 :       if (length == 0) return true;
   11196    28237390 :       state_1_.Advance(to_check);
   11197    28237390 :       state_2_.Advance(to_check);
   11198    28237390 :     }
   11199             :   }
   11200             : 
   11201             :  private:
   11202             :   State state_1_;
   11203             :   State state_2_;
   11204             : 
   11205             :   DISALLOW_COPY_AND_ASSIGN(StringComparator);
   11206             : };
   11207             : 
   11208             : 
   11209    35263083 : bool String::SlowEquals(String* other) {
   11210             :   DisallowHeapAllocation no_gc;
   11211             :   // Fast check: negative check with lengths.
   11212             :   int len = length();
   11213    35263083 :   if (len != other->length()) return false;
   11214    26100958 :   if (len == 0) return true;
   11215             : 
   11216             :   // Fast check: if at least one ThinString is involved, dereference it/them
   11217             :   // and restart.
   11218    52200660 :   if (this->IsThinString() || other->IsThinString()) {
   11219        4960 :     if (other->IsThinString()) other = ThinString::cast(other)->actual();
   11220        4960 :     if (this->IsThinString()) {
   11221        1252 :       return ThinString::cast(this)->actual()->Equals(other);
   11222             :     } else {
   11223        3708 :       return this->Equals(other);
   11224             :     }
   11225             :   }
   11226             : 
   11227             :   // Fast check: if hash code is computed for both strings
   11228             :   // a fast negative check can be performed.
   11229    51839502 :   if (HasHashCode() && other->HasHashCode()) {
   11230             : #ifdef ENABLE_SLOW_DCHECKS
   11231             :     if (FLAG_enable_slow_asserts) {
   11232             :       if (Hash() != other->Hash()) {
   11233             :         bool found_difference = false;
   11234             :         for (int i = 0; i < len; i++) {
   11235             :           if (Get(i) != other->Get(i)) {
   11236             :             found_difference = true;
   11237             :             break;
   11238             :           }
   11239             :         }
   11240             :         DCHECK(found_difference);
   11241             :       }
   11242             :     }
   11243             : #endif
   11244    25742399 :     if (Hash() != other->Hash()) return false;
   11245             :   }
   11246             : 
   11247             :   // We know the strings are both non-empty. Compare the first chars
   11248             :   // before we try to flatten the strings.
   11249    23611585 :   if (this->Get(0) != other->Get(0)) return false;
   11250             : 
   11251    41721061 :   if (IsSeqOneByteString() && other->IsSeqOneByteString()) {
   11252    17452655 :     const uint8_t* str1 = SeqOneByteString::cast(this)->GetChars();
   11253    17452655 :     const uint8_t* str2 = SeqOneByteString::cast(other)->GetChars();
   11254    17452655 :     return CompareRawStringContents(str1, str2, len);
   11255             :   }
   11256             : 
   11257             :   StringComparator comparator;
   11258     6157423 :   return comparator.Equals(this, other);
   11259             : }
   11260             : 
   11261             : 
   11262     6450995 : bool String::SlowEquals(Handle<String> one, Handle<String> two) {
   11263             :   // Fast check: negative check with lengths.
   11264             :   int one_length = one->length();
   11265     6450995 :   if (one_length != two->length()) return false;
   11266     6411118 :   if (one_length == 0) return true;
   11267             : 
   11268             :   // Fast check: if at least one ThinString is involved, dereference it/them
   11269             :   // and restart.
   11270    12822236 :   if (one->IsThinString() || two->IsThinString()) {
   11271          19 :     if (one->IsThinString()) one = handle(ThinString::cast(*one)->actual());
   11272          19 :     if (two->IsThinString()) two = handle(ThinString::cast(*two)->actual());
   11273          19 :     return String::Equals(one, two);
   11274             :   }
   11275             : 
   11276             :   // Fast check: if hash code is computed for both strings
   11277             :   // a fast negative check can be performed.
   11278     6427755 :   if (one->HasHashCode() && two->HasHashCode()) {
   11279             : #ifdef ENABLE_SLOW_DCHECKS
   11280             :     if (FLAG_enable_slow_asserts) {
   11281             :       if (one->Hash() != two->Hash()) {
   11282             :         bool found_difference = false;
   11283             :         for (int i = 0; i < one_length; i++) {
   11284             :           if (one->Get(i) != two->Get(i)) {
   11285             :             found_difference = true;
   11286             :             break;
   11287             :           }
   11288             :         }
   11289             :         DCHECK(found_difference);
   11290             :       }
   11291             :     }
   11292             : #endif
   11293        3656 :     if (one->Hash() != two->Hash()) return false;
   11294             :   }
   11295             : 
   11296             :   // We know the strings are both non-empty. Compare the first chars
   11297             :   // before we try to flatten the strings.
   11298     6411083 :   if (one->Get(0) != two->Get(0)) return false;
   11299             : 
   11300     4391400 :   one = String::Flatten(one);
   11301     4391400 :   two = String::Flatten(two);
   11302             : 
   11303             :   DisallowHeapAllocation no_gc;
   11304     4391400 :   String::FlatContent flat1 = one->GetFlatContent();
   11305     4391400 :   String::FlatContent flat2 = two->GetFlatContent();
   11306             : 
   11307     4391400 :   if (flat1.IsOneByte() && flat2.IsOneByte()) {
   11308             :       return CompareRawStringContents(flat1.ToOneByteVector().start(),
   11309             :                                       flat2.ToOneByteVector().start(),
   11310             :                                       one_length);
   11311             :   } else {
   11312    20597174 :     for (int i = 0; i < one_length; i++) {
   11313    20597174 :       if (flat1.Get(i) != flat2.Get(i)) return false;
   11314             :     }
   11315             :     return true;
   11316             :   }
   11317             : }
   11318             : 
   11319             : 
   11320             : // static
   11321     7363753 : ComparisonResult String::Compare(Handle<String> x, Handle<String> y) {
   11322             :   // A few fast case tests before we flatten.
   11323     7363753 :   if (x.is_identical_to(y)) {
   11324             :     return ComparisonResult::kEqual;
   11325     7363238 :   } else if (y->length() == 0) {
   11326             :     return x->length() == 0 ? ComparisonResult::kEqual
   11327           0 :                             : ComparisonResult::kGreaterThan;
   11328     7363238 :   } else if (x->length() == 0) {
   11329             :     return ComparisonResult::kLessThan;
   11330             :   }
   11331             : 
   11332    14726476 :   int const d = x->Get(0) - y->Get(0);
   11333     7363238 :   if (d < 0) {
   11334             :     return ComparisonResult::kLessThan;
   11335     5842647 :   } else if (d > 0) {
   11336             :     return ComparisonResult::kGreaterThan;
   11337             :   }
   11338             : 
   11339             :   // Slow case.
   11340       30338 :   x = String::Flatten(x);
   11341       30338 :   y = String::Flatten(y);
   11342             : 
   11343             :   DisallowHeapAllocation no_gc;
   11344             :   ComparisonResult result = ComparisonResult::kEqual;
   11345             :   int prefix_length = x->length();
   11346       30338 :   if (y->length() < prefix_length) {
   11347             :     prefix_length = y->length();
   11348             :     result = ComparisonResult::kGreaterThan;
   11349       30338 :   } else if (y->length() > prefix_length) {
   11350             :     result = ComparisonResult::kLessThan;
   11351             :   }
   11352             :   int r;
   11353       30338 :   String::FlatContent x_content = x->GetFlatContent();
   11354       30338 :   String::FlatContent y_content = y->GetFlatContent();
   11355       30338 :   if (x_content.IsOneByte()) {
   11356             :     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
   11357        3303 :     if (y_content.IsOneByte()) {
   11358             :       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   11359          55 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11360             :     } else {
   11361             :       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   11362        3248 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11363             :     }
   11364             :   } else {
   11365             :     Vector<const uc16> x_chars = x_content.ToUC16Vector();
   11366       27035 :     if (y_content.IsOneByte()) {
   11367             :       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   11368        1624 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11369             :     } else {
   11370             :       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   11371       25411 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11372             :     }
   11373             :   }
   11374       30338 :   if (r < 0) {
   11375             :     result = ComparisonResult::kLessThan;
   11376       18299 :   } else if (r > 0) {
   11377             :     result = ComparisonResult::kGreaterThan;
   11378             :   }
   11379       30338 :   return result;
   11380             : }
   11381             : 
   11382        3383 : Object* String::IndexOf(Isolate* isolate, Handle<Object> receiver,
   11383             :                         Handle<Object> search, Handle<Object> position) {
   11384        3383 :   if (receiver->IsNullOrUndefined(isolate)) {
   11385         900 :     THROW_NEW_ERROR_RETURN_FAILURE(
   11386             :         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
   11387             :                               isolate->factory()->NewStringFromAsciiChecked(
   11388             :                                   "String.prototype.indexOf")));
   11389             :   }
   11390             :   Handle<String> receiver_string;
   11391        6166 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_string,
   11392             :                                      Object::ToString(isolate, receiver));
   11393             : 
   11394             :   Handle<String> search_string;
   11395        6166 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, search_string,
   11396             :                                      Object::ToString(isolate, search));
   11397             : 
   11398        3083 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   11399             :                                      Object::ToInteger(isolate, position));
   11400             : 
   11401             :   uint32_t index = receiver_string->ToValidIndex(*position);
   11402             :   return Smi::FromInt(
   11403        6166 :       String::IndexOf(isolate, receiver_string, search_string, index));
   11404             : }
   11405             : 
   11406             : namespace {
   11407             : 
   11408             : template <typename T>
   11409      183161 : int SearchString(Isolate* isolate, String::FlatContent receiver_content,
   11410         240 :                  Vector<T> pat_vector, int start_index) {
   11411      183161 :   if (receiver_content.IsOneByte()) {
   11412             :     return SearchString(isolate, receiver_content.ToOneByteVector(), pat_vector,
   11413      182692 :                         start_index);
   11414             :   }
   11415             :   return SearchString(isolate, receiver_content.ToUC16Vector(), pat_vector,
   11416         469 :                       start_index);
   11417             : }
   11418             : 
   11419             : }  // namespace
   11420             : 
   11421      187350 : int String::IndexOf(Isolate* isolate, Handle<String> receiver,
   11422             :                     Handle<String> search, int start_index) {
   11423             :   DCHECK(0 <= start_index);
   11424             :   DCHECK(start_index <= receiver->length());
   11425             : 
   11426      187350 :   uint32_t search_length = search->length();
   11427      187350 :   if (search_length == 0) return start_index;
   11428             : 
   11429      187236 :   uint32_t receiver_length = receiver->length();
   11430      187236 :   if (start_index + search_length > receiver_length) return -1;
   11431             : 
   11432      183161 :   receiver = String::Flatten(receiver);
   11433      183161 :   search = String::Flatten(search);
   11434             : 
   11435             :   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   11436             :   // Extract flattened substrings of cons strings before getting encoding.
   11437      183161 :   String::FlatContent receiver_content = receiver->GetFlatContent();
   11438      183161 :   String::FlatContent search_content = search->GetFlatContent();
   11439             : 
   11440             :   // dispatch on type of strings
   11441      183161 :   if (search_content.IsOneByte()) {
   11442             :     Vector<const uint8_t> pat_vector = search_content.ToOneByteVector();
   11443             :     return SearchString<const uint8_t>(isolate, receiver_content, pat_vector,
   11444      180011 :                                        start_index);
   11445             :   }
   11446        3150 :   Vector<const uc16> pat_vector = search_content.ToUC16Vector();
   11447             :   return SearchString<const uc16>(isolate, receiver_content, pat_vector,
   11448        3150 :                                   start_index);
   11449             : }
   11450             : 
   11451        5600 : MaybeHandle<String> String::GetSubstitution(Isolate* isolate, Match* match,
   11452             :                                             Handle<String> replacement,
   11453             :                                             int start_index) {
   11454             :   DCHECK_IMPLIES(match->HasNamedCaptures(), FLAG_harmony_regexp_named_captures);
   11455             :   DCHECK_GE(start_index, 0);
   11456             : 
   11457             :   Factory* factory = isolate->factory();
   11458             : 
   11459             :   const int replacement_length = replacement->length();
   11460        5600 :   const int captures_length = match->CaptureCount();
   11461             : 
   11462        5600 :   replacement = String::Flatten(replacement);
   11463             : 
   11464             :   Handle<String> dollar_string =
   11465        5600 :       factory->LookupSingleCharacterStringFromCode('$');
   11466             :   int next_dollar_ix =
   11467        5600 :       String::IndexOf(isolate, replacement, dollar_string, start_index);
   11468        5600 :   if (next_dollar_ix < 0) {
   11469             :     return replacement;
   11470             :   }
   11471             : 
   11472        5525 :   IncrementalStringBuilder builder(isolate);
   11473             : 
   11474        5525 :   if (next_dollar_ix > 0) {
   11475         465 :     builder.AppendString(factory->NewSubString(replacement, 0, next_dollar_ix));
   11476             :   }
   11477             : 
   11478             :   while (true) {
   11479       12473 :     const int peek_ix = next_dollar_ix + 1;
   11480       12473 :     if (peek_ix >= replacement_length) {
   11481             :       builder.AppendCharacter('$');
   11482          30 :       return builder.Finish();
   11483             :     }
   11484             : 
   11485             :     int continue_from_ix = -1;
   11486             :     const uint16_t peek = replacement->Get(peek_ix);
   11487       12443 :     switch (peek) {
   11488             :       case '$':  // $$
   11489             :         builder.AppendCharacter('$');
   11490          90 :         continue_from_ix = peek_ix + 1;
   11491          90 :         break;
   11492             :       case '&':  // $& - match
   11493          90 :         builder.AppendString(match->GetMatch());
   11494          90 :         continue_from_ix = peek_ix + 1;
   11495          90 :         break;
   11496             :       case '`':  // $` - prefix
   11497          60 :         builder.AppendString(match->GetPrefix());
   11498          60 :         continue_from_ix = peek_ix + 1;
   11499          60 :         break;
   11500             :       case '\'':  // $' - suffix
   11501          60 :         builder.AppendString(match->GetSuffix());
   11502          60 :         continue_from_ix = peek_ix + 1;
   11503          60 :         break;
   11504             :       case '0':
   11505             :       case '1':
   11506             :       case '2':
   11507             :       case '3':
   11508             :       case '4':
   11509             :       case '5':
   11510             :       case '6':
   11511             :       case '7':
   11512             :       case '8':
   11513             :       case '9': {
   11514             :         // Valid indices are $1 .. $9, $01 .. $09 and $10 .. $99
   11515       11678 :         int scaled_index = (peek - '0');
   11516             :         int advance = 1;
   11517             : 
   11518       11678 :         if (peek_ix + 1 < replacement_length) {
   11519             :           const uint16_t next_peek = replacement->Get(peek_ix + 1);
   11520        9731 :           if (next_peek >= '0' && next_peek <= '9') {
   11521        2235 :             const int new_scaled_index = scaled_index * 10 + (next_peek - '0');
   11522        2235 :             if (new_scaled_index < captures_length) {
   11523             :               scaled_index = new_scaled_index;
   11524             :               advance = 2;
   11525             :             }
   11526             :           }
   11527             :         }
   11528             : 
   11529       11678 :         if (scaled_index == 0 || scaled_index >= captures_length) {
   11530             :           builder.AppendCharacter('$');
   11531             :           continue_from_ix = peek_ix;
   11532       11828 :           break;
   11533             :         }
   11534             : 
   11535             :         bool capture_exists;
   11536             :         Handle<String> capture;
   11537       23056 :         ASSIGN_RETURN_ON_EXCEPTION(
   11538             :             isolate, capture, match->GetCapture(scaled_index, &capture_exists),
   11539             :             String);
   11540       11528 :         if (capture_exists) builder.AppendString(capture);
   11541       11528 :         continue_from_ix = peek_ix + advance;
   11542       11528 :         break;
   11543             :       }
   11544             :       case '<': {  // $<name> - named capture
   11545             :         typedef String::Match::CaptureState CaptureState;
   11546             : 
   11547         420 :         if (!match->HasNamedCaptures()) {
   11548             :           builder.AppendCharacter('$');
   11549             :           continue_from_ix = peek_ix;
   11550         336 :           break;
   11551             :         }
   11552             : 
   11553             :         Handle<String> bracket_string =
   11554         336 :             factory->LookupSingleCharacterStringFromCode('>');
   11555             :         const int closing_bracket_ix =
   11556         336 :             String::IndexOf(isolate, replacement, bracket_string, peek_ix + 1);
   11557             : 
   11558         336 :         if (closing_bracket_ix == -1) {
   11559          84 :           THROW_NEW_ERROR(
   11560             :               isolate,
   11561             :               NewSyntaxError(MessageTemplate::kRegExpInvalidReplaceString,
   11562             :                              replacement),
   11563             :               String);
   11564             :         }
   11565             : 
   11566             :         Handle<String> capture_name =
   11567         294 :             factory->NewSubString(replacement, peek_ix + 1, closing_bracket_ix);
   11568             :         Handle<String> capture;
   11569             :         CaptureState capture_state;
   11570         588 :         ASSIGN_RETURN_ON_EXCEPTION(
   11571             :             isolate, capture,
   11572             :             match->GetNamedCapture(capture_name, &capture_state), String);
   11573             : 
   11574         294 :         switch (capture_state) {
   11575             :           case CaptureState::INVALID:
   11576         252 :             THROW_NEW_ERROR(
   11577             :                 isolate,
   11578             :                 NewSyntaxError(MessageTemplate::kRegExpInvalidReplaceString,
   11579             :                                replacement),
   11580             :                 String);
   11581             :             break;
   11582             :           case CaptureState::UNMATCHED:
   11583             :             break;
   11584             :           case CaptureState::MATCHED:
   11585         112 :             builder.AppendString(capture);
   11586         112 :             break;
   11587             :         }
   11588             : 
   11589         168 :         continue_from_ix = closing_bracket_ix + 1;
   11590         168 :         break;
   11591             :       }
   11592             :       default:
   11593             :         builder.AppendCharacter('$');
   11594             :         continue_from_ix = peek_ix;
   11595          45 :         break;
   11596             :     }
   11597             : 
   11598             :     // Go the the next $ in the replacement.
   11599             :     // TODO(jgruber): Single-char lookups could be much more efficient.
   11600             :     DCHECK_NE(continue_from_ix, -1);
   11601             :     next_dollar_ix =
   11602       12275 :         String::IndexOf(isolate, replacement, dollar_string, continue_from_ix);
   11603             : 
   11604             :     // Return if there are no more $ characters in the replacement. If we
   11605             :     // haven't reached the end, we need to append the suffix.
   11606       12275 :     if (next_dollar_ix < 0) {
   11607        5327 :       if (continue_from_ix < replacement_length) {
   11608             :         builder.AppendString(factory->NewSubString(
   11609        1738 :             replacement, continue_from_ix, replacement_length));
   11610             :       }
   11611        5327 :       return builder.Finish();
   11612             :     }
   11613             : 
   11614             :     // Append substring between the previous and the next $ character.
   11615        6948 :     if (next_dollar_ix > continue_from_ix) {
   11616             :       builder.AppendString(
   11617          42 :           factory->NewSubString(replacement, continue_from_ix, next_dollar_ix));
   11618             :     }
   11619             :   }
   11620             : 
   11621             :   UNREACHABLE();
   11622             :   return MaybeHandle<String>();
   11623             : }
   11624             : 
   11625             : namespace {  // for String.Prototype.lastIndexOf
   11626             : 
   11627             : template <typename schar, typename pchar>
   11628        2260 : int StringMatchBackwards(Vector<const schar> subject,
   11629             :                          Vector<const pchar> pattern, int idx) {
   11630        2260 :   int pattern_length = pattern.length();
   11631             :   DCHECK(pattern_length >= 1);
   11632             :   DCHECK(idx + pattern_length <= subject.length());
   11633             : 
   11634             :   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
   11635           0 :     for (int i = 0; i < pattern_length; i++) {
   11636           0 :       uc16 c = pattern[i];
   11637           0 :       if (c > String::kMaxOneByteCharCode) {
   11638             :         return -1;
   11639             :       }
   11640             :     }
   11641             :   }
   11642             : 
   11643        2260 :   pchar pattern_first_char = pattern[0];
   11644        8229 :   for (int i = idx; i >= 0; i--) {
   11645       10210 :     if (subject[i] != pattern_first_char) continue;
   11646             :     int j = 1;
   11647        3116 :     while (j < pattern_length) {
   11648        2270 :       if (pattern[j] != subject[i + j]) {
   11649             :         break;
   11650             :       }
   11651        1105 :       j++;
   11652             :     }
   11653        2011 :     if (j == pattern_length) {
   11654             :       return i;
   11655             :     }
   11656             :   }
   11657             :   return -1;
   11658             : }
   11659             : 
   11660             : }  // namespace
   11661             : 
   11662        2905 : Object* String::LastIndexOf(Isolate* isolate, Handle<Object> receiver,
   11663             :                             Handle<Object> search, Handle<Object> position) {
   11664        2905 :   if (receiver->IsNullOrUndefined(isolate)) {
   11665         810 :     THROW_NEW_ERROR_RETURN_FAILURE(
   11666             :         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
   11667             :                               isolate->factory()->NewStringFromAsciiChecked(
   11668             :                                   "String.prototype.lastIndexOf")));
   11669             :   }
   11670             :   Handle<String> receiver_string;
   11671        5270 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_string,
   11672             :                                      Object::ToString(isolate, receiver));
   11673             : 
   11674             :   Handle<String> search_string;
   11675        5270 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, search_string,
   11676             :                                      Object::ToString(isolate, search));
   11677             : 
   11678        5270 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   11679             :                                      Object::ToNumber(position));
   11680             : 
   11681             :   uint32_t start_index;
   11682             : 
   11683        2635 :   if (position->IsNaN()) {
   11684        1885 :     start_index = receiver_string->length();
   11685             :   } else {
   11686         750 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   11687             :                                        Object::ToInteger(isolate, position));
   11688             :     start_index = receiver_string->ToValidIndex(*position);
   11689             :   }
   11690             : 
   11691        2635 :   uint32_t pattern_length = search_string->length();
   11692        2635 :   uint32_t receiver_length = receiver_string->length();
   11693             : 
   11694        2635 :   if (start_index + pattern_length > receiver_length) {
   11695        2005 :     start_index = receiver_length - pattern_length;
   11696             :   }
   11697             : 
   11698        2635 :   if (pattern_length == 0) {
   11699         750 :     return Smi::FromInt(start_index);
   11700             :   }
   11701             : 
   11702        2260 :   receiver_string = String::Flatten(receiver_string);
   11703        2260 :   search_string = String::Flatten(search_string);
   11704             : 
   11705             :   int last_index = -1;
   11706             :   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   11707             : 
   11708        2260 :   String::FlatContent receiver_content = receiver_string->GetFlatContent();
   11709        2260 :   String::FlatContent search_content = search_string->GetFlatContent();
   11710             : 
   11711        2260 :   if (search_content.IsOneByte()) {
   11712             :     Vector<const uint8_t> pat_vector = search_content.ToOneByteVector();
   11713        2260 :     if (receiver_content.IsOneByte()) {
   11714             :       last_index = StringMatchBackwards(receiver_content.ToOneByteVector(),
   11715        2253 :                                         pat_vector, start_index);
   11716             :     } else {
   11717             :       last_index = StringMatchBackwards(receiver_content.ToUC16Vector(),
   11718           7 :                                         pat_vector, start_index);
   11719             :     }
   11720             :   } else {
   11721             :     Vector<const uc16> pat_vector = search_content.ToUC16Vector();
   11722           0 :     if (receiver_content.IsOneByte()) {
   11723             :       last_index = StringMatchBackwards(receiver_content.ToOneByteVector(),
   11724           0 :                                         pat_vector, start_index);
   11725             :     } else {
   11726             :       last_index = StringMatchBackwards(receiver_content.ToUC16Vector(),
   11727           0 :                                         pat_vector, start_index);
   11728             :     }
   11729             :   }
   11730        2260 :   return Smi::FromInt(last_index);
   11731             : }
   11732             : 
   11733    59356243 : bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) {
   11734             :   int slen = length();
   11735             :   // Can't check exact length equality, but we can check bounds.
   11736    59356243 :   int str_len = str.length();
   11737    59356243 :   if (!allow_prefix_match &&
   11738    58028164 :       (str_len < slen ||
   11739    58028164 :           str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) {
   11740             :     return false;
   11741             :   }
   11742             :   int i;
   11743    56792688 :   size_t remaining_in_str = static_cast<size_t>(str_len);
   11744    56792688 :   const uint8_t* utf8_data = reinterpret_cast<const uint8_t*>(str.start());
   11745  1126237230 :   for (i = 0; i < slen && remaining_in_str > 0; i++) {
   11746   538742462 :     size_t cursor = 0;
   11747   538742462 :     uint32_t r = unibrow::Utf8::ValueOf(utf8_data, remaining_in_str, &cursor);
   11748             :     DCHECK(cursor > 0 && cursor <= remaining_in_str);
   11749   538742467 :     if (r > unibrow::Utf16::kMaxNonSurrogateCharCode) {
   11750    32416569 :       if (i > slen - 1) return false;
   11751          28 :       if (Get(i++) != unibrow::Utf16::LeadSurrogate(r)) return false;
   11752          21 :       if (Get(i) != unibrow::Utf16::TrailSurrogate(r)) return false;
   11753             :     } else {
   11754   538742461 :       if (Get(i) != r) return false;
   11755             :     }
   11756   506325927 :     utf8_data += cursor;
   11757   506325927 :     remaining_in_str -= cursor;
   11758             :   }
   11759    24376153 :   return (allow_prefix_match || i == slen) && remaining_in_str == 0;
   11760             : }
   11761             : 
   11762             : template <>
   11763         210 : bool String::IsEqualTo(Vector<const uint8_t> str) {
   11764         210 :   return IsOneByteEqualTo(str);
   11765             : }
   11766             : 
   11767             : template <>
   11768           0 : bool String::IsEqualTo(Vector<const uc16> str) {
   11769           0 :   return IsTwoByteEqualTo(str);
   11770             : }
   11771             : 
   11772    96515560 : bool String::IsOneByteEqualTo(Vector<const uint8_t> str) {
   11773             :   int slen = length();
   11774    96515560 :   if (str.length() != slen) return false;
   11775             :   DisallowHeapAllocation no_gc;
   11776    69374799 :   FlatContent content = GetFlatContent();
   11777    69374787 :   if (content.IsOneByte()) {
   11778    69374686 :     return CompareChars(content.ToOneByteVector().start(),
   11779   138749372 :                         str.start(), slen) == 0;
   11780             :   }
   11781         170 :   for (int i = 0; i < slen; i++) {
   11782         254 :     if (Get(i) != static_cast<uint16_t>(str[i])) return false;
   11783             :   }
   11784             :   return true;
   11785             : }
   11786             : 
   11787             : 
   11788       40747 : bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
   11789             :   int slen = length();
   11790       40747 :   if (str.length() != slen) return false;
   11791             :   DisallowHeapAllocation no_gc;
   11792       12511 :   FlatContent content = GetFlatContent();
   11793       12511 :   if (content.IsTwoByte()) {
   11794       24172 :     return CompareChars(content.ToUC16Vector().start(), str.start(), slen) == 0;
   11795             :   }
   11796           0 :   for (int i = 0; i < slen; i++) {
   11797         425 :     if (Get(i) != str[i]) return false;
   11798             :   }
   11799             :   return true;
   11800             : }
   11801             : 
   11802             : 
   11803    29115815 : uint32_t String::ComputeAndSetHash() {
   11804             :   // Should only be called if hash code has not yet been computed.
   11805             :   DCHECK(!HasHashCode());
   11806             : 
   11807             :   // Store the hash code in the object.
   11808    29115815 :   uint32_t field = IteratingStringHasher::Hash(this, GetHeap()->HashSeed());
   11809             :   set_hash_field(field);
   11810             : 
   11811             :   // Check the hash code is there.
   11812             :   DCHECK(HasHashCode());
   11813    29115820 :   uint32_t result = field >> kHashShift;
   11814             :   DCHECK(result != 0);  // Ensure that the hash value of 0 is never computed.
   11815    29115820 :   return result;
   11816             : }
   11817             : 
   11818             : 
   11819     4310076 : bool String::ComputeArrayIndex(uint32_t* index) {
   11820             :   int length = this->length();
   11821     4310076 :   if (length == 0 || length > kMaxArrayIndexSize) return false;
   11822             :   StringCharacterStream stream(this);
   11823     1840747 :   return StringToArrayIndex(&stream, index);
   11824             : }
   11825             : 
   11826             : 
   11827    23899348 : bool String::SlowAsArrayIndex(uint32_t* index) {
   11828    23899348 :   if (length() <= kMaxCachedArrayIndexLength) {
   11829    19589272 :     Hash();  // force computation of hash code
   11830             :     uint32_t field = hash_field();
   11831    19589273 :     if ((field & kIsNotArrayIndexMask) != 0) return false;
   11832             :     // Isolate the array index form the full hash field.
   11833     6708846 :     *index = ArrayIndexValueBits::decode(field);
   11834     6708846 :     return true;
   11835             :   } else {
   11836     4310076 :     return ComputeArrayIndex(index);
   11837             :   }
   11838             : }
   11839             : 
   11840             : 
   11841    38297751 : Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) {
   11842             :   Heap* heap = string->GetHeap();
   11843    38297751 :   if (new_length == 0) return heap->isolate()->factory()->empty_string();
   11844             : 
   11845             :   int new_size, old_size;
   11846             :   int old_length = string->length();
   11847    28893065 :   if (old_length <= new_length) return string;
   11848             : 
   11849    27264400 :   if (string->IsSeqOneByteString()) {
   11850             :     old_size = SeqOneByteString::SizeFor(old_length);
   11851             :     new_size = SeqOneByteString::SizeFor(new_length);
   11852             :   } else {
   11853             :     DCHECK(string->IsSeqTwoByteString());
   11854             :     old_size = SeqTwoByteString::SizeFor(old_length);
   11855             :     new_size = SeqTwoByteString::SizeFor(new_length);
   11856             :   }
   11857             : 
   11858    27264400 :   int delta = old_size - new_size;
   11859             : 
   11860    27264400 :   Address start_of_string = string->address();
   11861             :   DCHECK_OBJECT_ALIGNED(start_of_string);
   11862             :   DCHECK_OBJECT_ALIGNED(start_of_string + new_size);
   11863             : 
   11864             :   // Sizes are pointer size aligned, so that we can use filler objects
   11865             :   // that are a multiple of pointer size.
   11866             :   heap->CreateFillerObjectAt(start_of_string + new_size, delta,
   11867    27264400 :                              ClearRecordedSlots::kNo);
   11868    54528800 :   heap->AdjustLiveBytes(*string, -delta);
   11869             : 
   11870             :   // We are storing the new length using release store after creating a filler
   11871             :   // for the left-over space to avoid races with the sweeper thread.
   11872             :   string->synchronized_set_length(new_length);
   11873             : 
   11874    27264400 :   return string;
   11875             : }
   11876             : 
   11877             : 
   11878     2303138 : uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
   11879             :   // For array indexes mix the length into the hash as an array index could
   11880             :   // be zero.
   11881             :   DCHECK(length > 0);
   11882             :   DCHECK(length <= String::kMaxArrayIndexSize);
   11883             :   DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) <
   11884             :          (1 << String::kArrayIndexValueBits));
   11885             : 
   11886    13360334 :   value <<= String::ArrayIndexValueBits::kShift;
   11887    13360334 :   value |= length << String::ArrayIndexLengthBits::kShift;
   11888             : 
   11889             :   DCHECK((value & String::kIsNotArrayIndexMask) == 0);
   11890             :   DCHECK_EQ(length <= String::kMaxCachedArrayIndexLength,
   11891             :             (value & String::kContainsCachedArrayIndexMask) == 0);
   11892     2303138 :   return value;
   11893             : }
   11894             : 
   11895             : 
   11896   213005237 : uint32_t StringHasher::GetHashField() {
   11897   213005237 :   if (length_ <= String::kMaxHashCalcLength) {
   11898   212944188 :     if (is_array_index_) {
   11899    21147288 :       return MakeArrayIndexHash(array_index_, length_);
   11900             :     }
   11901   404741088 :     return (GetHashCore(raw_running_hash_) << String::kHashShift) |
   11902   202370544 :            String::kIsNotArrayIndexMask;
   11903             :   } else {
   11904       61049 :     return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask;
   11905             :   }
   11906             : }
   11907             : 
   11908             : 
   11909    24522790 : uint32_t StringHasher::ComputeUtf8Hash(Vector<const char> chars,
   11910             :                                        uint32_t seed,
   11911             :                                        int* utf16_length_out) {
   11912    24522790 :   int vector_length = chars.length();
   11913             :   // Handle some edge cases
   11914    24522790 :   if (vector_length <= 1) {
   11915             :     DCHECK(vector_length == 0 ||
   11916             :            static_cast<uint8_t>(chars.start()[0]) <=
   11917             :                unibrow::Utf8::kMaxOneByteChar);
   11918       42417 :     *utf16_length_out = vector_length;
   11919       42417 :     return HashSequentialString(chars.start(), vector_length, seed);
   11920             :   }
   11921             :   // Start with a fake length which won't affect computation.
   11922             :   // It will be updated later.
   11923             :   StringHasher hasher(String::kMaxArrayIndexSize, seed);
   11924    24480373 :   size_t remaining = static_cast<size_t>(vector_length);
   11925             :   const uint8_t* stream = reinterpret_cast<const uint8_t*>(chars.start());
   11926             :   int utf16_length = 0;
   11927             :   bool is_index = true;
   11928             :   DCHECK(hasher.is_array_index_);
   11929   576556721 :   while (remaining > 0) {
   11930   527595976 :     size_t consumed = 0;
   11931   527595976 :     uint32_t c = unibrow::Utf8::ValueOf(stream, remaining, &consumed);
   11932             :     DCHECK(consumed > 0 && consumed <= remaining);
   11933   527595976 :     stream += consumed;
   11934   527595976 :     remaining -= consumed;
   11935   527595976 :     bool is_two_characters = c > unibrow::Utf16::kMaxNonSurrogateCharCode;
   11936   527595976 :     utf16_length += is_two_characters ? 2 : 1;
   11937             :     // No need to keep hashing. But we do need to calculate utf16_length.
   11938   527595976 :     if (utf16_length > String::kMaxHashCalcLength) continue;
   11939   527595976 :     if (is_two_characters) {
   11940             :       uint16_t c1 = unibrow::Utf16::LeadSurrogate(c);
   11941             :       uint16_t c2 = unibrow::Utf16::TrailSurrogate(c);
   11942             :       hasher.AddCharacter(c1);
   11943             :       hasher.AddCharacter(c2);
   11944          14 :       if (is_index) is_index = hasher.UpdateIndex(c1);
   11945          13 :       if (is_index) is_index = hasher.UpdateIndex(c2);
   11946             :     } else {
   11947             :       hasher.AddCharacter(c);
   11948   527595962 :       if (is_index) is_index = hasher.UpdateIndex(c);
   11949             :     }
   11950             :   }
   11951    24480372 :   *utf16_length_out = static_cast<int>(utf16_length);
   11952             :   // Must set length here so that hash computation is correct.
   11953    24480372 :   hasher.length_ = utf16_length;
   11954    24480372 :   return hasher.GetHashField();
   11955             : }
   11956             : 
   11957             : 
   11958     2502618 : void IteratingStringHasher::VisitConsString(ConsString* cons_string) {
   11959             :   // Run small ConsStrings through ConsStringIterator.
   11960     2502618 :   if (cons_string->length() < 64) {
   11961             :     ConsStringIterator iter(cons_string);
   11962             :     int offset;
   11963             :     String* string;
   11964    15013468 :     while (nullptr != (string = iter.Next(&offset))) {
   11965             :       DCHECK_EQ(0, offset);
   11966    12825768 :       String::VisitFlat(this, string, 0);
   11967             :     }
   11968     2502618 :     return;
   11969             :   }
   11970             :   // Slow case.
   11971      314918 :   const int max_length = String::kMaxHashCalcLength;
   11972      629836 :   int length = std::min(cons_string->length(), max_length);
   11973      314918 :   if (cons_string->HasOnlyOneByteChars()) {
   11974      280285 :     uint8_t* buffer = new uint8_t[length];
   11975      280285 :     String::WriteToFlat(cons_string, buffer, 0, length);
   11976      280285 :     AddCharacters(buffer, length);
   11977      280285 :     delete[] buffer;
   11978             :   } else {
   11979       34633 :     uint16_t* buffer = new uint16_t[length];
   11980       34633 :     String::WriteToFlat(cons_string, buffer, 0, length);
   11981       34633 :     AddCharacters(buffer, length);
   11982       34633 :     delete[] buffer;
   11983             :   }
   11984             : }
   11985             : 
   11986             : 
   11987       51674 : void String::PrintOn(FILE* file) {
   11988             :   int length = this->length();
   11989     4535154 :   for (int i = 0; i < length; i++) {
   11990     4483480 :     PrintF(file, "%c", Get(i));
   11991             :   }
   11992       51674 : }
   11993             : 
   11994             : 
   11995     1413271 : int Map::Hash() {
   11996             :   // For performance reasons we only hash the 3 most variable fields of a map:
   11997             :   // constructor, prototype and bit_field2. For predictability reasons we
   11998             :   // use objects' offsets in respective pages for hashing instead of raw
   11999             :   // addresses.
   12000             : 
   12001             :   // Shift away the tag.
   12002     2826542 :   int hash = ObjectAddressForHashing(GetConstructor()) >> 2;
   12003             : 
   12004             :   // XOR-ing the prototype and constructor directly yields too many zero bits
   12005             :   // when the two pointers are close (which is fairly common).
   12006             :   // To avoid this we shift the prototype bits relatively to the constructor.
   12007     1413271 :   hash ^= ObjectAddressForHashing(prototype()) << (32 - kPageSizeBits);
   12008             : 
   12009     2826542 :   return hash ^ (hash >> 16) ^ bit_field2();
   12010             : }
   12011             : 
   12012             : 
   12013             : namespace {
   12014             : 
   12015     2464500 : bool CheckEquivalent(Map* first, Map* second) {
   12016     4873092 :   return first->GetConstructor() == second->GetConstructor() &&
   12017     2395584 :          first->prototype() == second->prototype() &&
   12018     2395556 :          first->instance_type() == second->instance_type() &&
   12019     2395556 :          first->bit_field() == second->bit_field() &&
   12020     2395367 :          first->is_extensible() == second->is_extensible() &&
   12021     4859837 :          first->new_target_is_base() == second->new_target_is_base() &&
   12022     2464500 :          first->has_hidden_prototype() == second->has_hidden_prototype();
   12023             : }
   12024             : 
   12025             : }  // namespace
   12026             : 
   12027             : 
   12028     1496958 : bool Map::EquivalentToForTransition(Map* other) {
   12029     1496958 :   if (!CheckEquivalent(this, other)) return false;
   12030     1496754 :   if (instance_type() == JS_FUNCTION_TYPE) {
   12031             :     // JSFunctions require more checks to ensure that sloppy function is
   12032             :     // not equvalent to strict function.
   12033             :     int nof = Min(NumberOfOwnDescriptors(), other->NumberOfOwnDescriptors());
   12034             :     return instance_descriptors()->IsEqualUpTo(other->instance_descriptors(),
   12035        8613 :                                                nof);
   12036             :   }
   12037             :   return true;
   12038             : }
   12039             : 
   12040             : 
   12041      967542 : bool Map::EquivalentToForNormalization(Map* other,
   12042             :                                        PropertyNormalizationMode mode) {
   12043             :   int properties =
   12044      967542 :       mode == CLEAR_INOBJECT_PROPERTIES ? 0 : other->GetInObjectProperties();
   12045     2764708 :   return CheckEquivalent(this, other) && bit_field2() == other->bit_field2() &&
   12046     1720944 :          GetInObjectProperties() == properties &&
   12047      753402 :          JSObject::GetEmbedderFieldCount(this) ==
   12048     1720944 :              JSObject::GetEmbedderFieldCount(other);
   12049             : }
   12050             : 
   12051             : 
   12052    24869981 : bool JSFunction::Inlines(SharedFunctionInfo* candidate) {
   12053             :   DisallowHeapAllocation no_gc;
   12054    24869981 :   if (shared() == candidate) return true;
   12055    24855668 :   if (code()->kind() != Code::OPTIMIZED_FUNCTION) return false;
   12056             :   DeoptimizationInputData* const data =
   12057             :       DeoptimizationInputData::cast(code()->deoptimization_data());
   12058      231508 :   if (data->length() == 0) return false;
   12059             :   FixedArray* const literals = data->LiteralArray();
   12060             :   int const inlined_count = data->InlinedFunctionCount()->value();
   12061      254422 :   for (int i = 0; i < inlined_count; ++i) {
   12062       22971 :     if (SharedFunctionInfo::cast(literals->get(i)) == candidate) {
   12063             :       return true;
   12064             :     }
   12065             :   }
   12066             :   return false;
   12067             : }
   12068             : 
   12069     1216932 : void JSFunction::MarkForOptimization() {
   12070             :   Isolate* isolate = GetIsolate();
   12071             :   DCHECK(!IsOptimized());
   12072             :   DCHECK(shared()->allows_lazy_compilation() ||
   12073             :          !shared()->optimization_disabled());
   12074             :   set_code_no_write_barrier(
   12075             :       isolate->builtins()->builtin(Builtins::kCompileOptimized));
   12076             :   // No write barrier required, since the builtin is part of the root set.
   12077     1217690 :   if (FLAG_mark_shared_functions_for_tier_up) {
   12078             :     shared()->set_marked_for_tier_up(true);
   12079             :   }
   12080     1216932 : }
   12081             : 
   12082             : 
   12083      141136 : void JSFunction::AttemptConcurrentOptimization() {
   12084      281519 :   Isolate* isolate = GetIsolate();
   12085      281519 :   if (!isolate->concurrent_recompilation_enabled() ||
   12086      140383 :       isolate->bootstrapper()->IsActive()) {
   12087             :     MarkForOptimization();
   12088      141136 :     return;
   12089             :   }
   12090             :   DCHECK(!IsInOptimizationQueue());
   12091             :   DCHECK(!IsOptimized());
   12092             :   DCHECK(shared()->allows_lazy_compilation() ||
   12093             :          !shared()->optimization_disabled());
   12094             :   DCHECK(isolate->concurrent_recompilation_enabled());
   12095      140378 :   if (FLAG_trace_concurrent_recompilation) {
   12096           0 :     PrintF("  ** Marking ");
   12097           0 :     ShortPrint();
   12098           0 :     PrintF(" for concurrent recompilation.\n");
   12099             :   }
   12100             : 
   12101             :   set_code_no_write_barrier(
   12102             :       isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
   12103             :   // No write barrier required, since the builtin is part of the root set.
   12104      140378 :   if (FLAG_mark_shared_functions_for_tier_up) {
   12105             :     // TODO(leszeks): The compilation isn't concurrent if we trigger it using
   12106             :     // this bit.
   12107             :     shared()->set_marked_for_tier_up(true);
   12108             :   }
   12109             : }
   12110             : 
   12111             : // static
   12112      278210 : void SharedFunctionInfo::AddToOptimizedCodeMap(
   12113             :     Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
   12114             :     Handle<Code> code, BailoutId osr_ast_id) {
   12115      278210 :   Isolate* isolate = shared->GetIsolate();
   12116      286599 :   if (isolate->serializer_enabled()) return;
   12117             :   DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
   12118             :   DCHECK(native_context->IsNativeContext());
   12119             :   STATIC_ASSERT(kEntryLength == 2);
   12120             :   Handle<FixedArray> new_code_map;
   12121             :   int entry;
   12122             : 
   12123      278210 :   if (!osr_ast_id.IsNone()) {
   12124        2546 :     Context::AddToOptimizedCodeMap(native_context, shared, code, osr_ast_id);
   12125        2546 :     return;
   12126             :   }
   12127             : 
   12128             :   DCHECK(osr_ast_id.IsNone());
   12129      275664 :   if (shared->OptimizedCodeMapIsCleared()) {
   12130      234368 :     new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
   12131             :     entry = kEntriesStart;
   12132             :   } else {
   12133             :     Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
   12134       41296 :     entry = shared->SearchOptimizedCodeMapEntry(*native_context);
   12135       41296 :     if (entry >= kEntriesStart) {
   12136             :       // Just set the code of the entry.
   12137        5843 :       Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code);
   12138       11686 :       old_code_map->set(entry + kCachedCodeOffset, *code_cell);
   12139             :       return;
   12140             :     }
   12141             : 
   12142             :     // Can we reuse an entry?
   12143             :     DCHECK(entry < kEntriesStart);
   12144             :     int length = old_code_map->length();
   12145      121555 :     for (int i = kEntriesStart; i < length; i += kEntryLength) {
   12146       90031 :       if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) {
   12147             :         new_code_map = old_code_map;
   12148             :         entry = i;
   12149             :         break;
   12150             :       }
   12151             :     }
   12152             : 
   12153       35453 :     if (entry < kEntriesStart) {
   12154             :       // Copy old optimized code map and append one new entry.
   12155             :       new_code_map = isolate->factory()->CopyFixedArrayAndGrow(
   12156       31524 :           old_code_map, kEntryLength, TENURED);
   12157             :       // TODO(mstarzinger): Temporary workaround. The allocation above might
   12158             :       // have flushed the optimized code map and the copy we created is full of
   12159             :       // holes. For now we just give up on adding the entry and pretend it got
   12160             :       // flushed.
   12161       31524 :       if (shared->OptimizedCodeMapIsCleared()) return;
   12162             :       entry = old_code_map->length();
   12163             :     }
   12164             :   }
   12165             : 
   12166      269823 :   Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code);
   12167             :   WeakCell* context_cell = native_context->self_weak_cell();
   12168             : 
   12169      269822 :   new_code_map->set(entry + kContextOffset, context_cell);
   12170      539646 :   new_code_map->set(entry + kCachedCodeOffset, *code_cell);
   12171             : 
   12172             : #ifdef DEBUG
   12173             :   for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
   12174             :     WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset));
   12175             :     DCHECK(cell->cleared() || cell->value()->IsNativeContext());
   12176             :     cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset));
   12177             :     DCHECK(cell->cleared() ||
   12178             :            (cell->value()->IsCode() &&
   12179             :             Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION));
   12180             :   }
   12181             : #endif
   12182             : 
   12183             :   FixedArray* old_code_map = shared->optimized_code_map();
   12184      269823 :   if (old_code_map != *new_code_map) {
   12185      265894 :     shared->set_optimized_code_map(*new_code_map);
   12186             :   }
   12187             : }
   12188             : 
   12189             : 
   12190         295 : void SharedFunctionInfo::ClearOptimizedCodeMap() {
   12191         295 :   FixedArray* empty_fixed_array = GetHeap()->empty_fixed_array();
   12192         295 :   set_optimized_code_map(empty_fixed_array, SKIP_WRITE_BARRIER);
   12193         295 : }
   12194             : 
   12195             : 
   12196      447512 : void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
   12197             :                                                    const char* reason) {
   12198             :   DisallowHeapAllocation no_gc;
   12199             :   Isolate* isolate = GetIsolate();
   12200             :   bool found = false;
   12201             : 
   12202      447512 :   if (!OptimizedCodeMapIsCleared()) {
   12203      182186 :     Heap* heap = isolate->heap();
   12204             :     FixedArray* code_map = optimized_code_map();
   12205             :     int length = code_map->length();
   12206      548746 :     for (int src = kEntriesStart; src < length; src += kEntryLength) {
   12207             :       DCHECK(WeakCell::cast(code_map->get(src))->cleared() ||
   12208             :              WeakCell::cast(code_map->get(src))->value()->IsNativeContext());
   12209      331066 :       found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() ==
   12210      331066 :               optimized_code;
   12211      331066 :       if (found) {
   12212      182186 :         if (FLAG_trace_opt) {
   12213           0 :           PrintF("[evicting entry from optimizing code map (%s) for ", reason);
   12214           0 :           ShortPrint();
   12215           0 :           PrintF("]\n");
   12216             :         }
   12217             :         // Just clear the code.
   12218             :         code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(),
   12219      182186 :                       SKIP_WRITE_BARRIER);
   12220             :       }
   12221             :     }
   12222             :   }
   12223             : 
   12224      447512 :   if (!found) {
   12225             :     // We didn't find the code in here. It must be osr'd code.
   12226      283556 :     isolate->EvictOSROptimizedCode(optimized_code, reason);
   12227             :   }
   12228      447512 : }
   12229             : 
   12230             : // static
   12231    18762118 : void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
   12232             :   Handle<SharedFunctionInfo> shared(function->shared());
   12233             :   Isolate* isolate = shared->GetIsolate();
   12234             : 
   12235    18762135 :   FeedbackVectorState state = function->GetFeedbackVectorState(isolate);
   12236    18762133 :   switch (state) {
   12237             :     case TOP_LEVEL_SCRIPT_NEEDS_VECTOR: {
   12238             :       // A top level script didn't get it's literals installed.
   12239             :       Handle<FeedbackVector> feedback_vector =
   12240     6123928 :           FeedbackVector::New(isolate, shared);
   12241             :       Handle<Cell> new_cell =
   12242     6123935 :           isolate->factory()->NewOneClosureCell(feedback_vector);
   12243     6123931 :       function->set_feedback_vector_cell(*new_cell);
   12244             :       break;
   12245             :     }
   12246             :     case NEEDS_VECTOR: {
   12247             :       Handle<FeedbackVector> feedback_vector =
   12248     2401017 :           FeedbackVector::New(isolate, shared);
   12249     2401017 :       function->feedback_vector_cell()->set_value(*feedback_vector);
   12250             :       break;
   12251             :     }
   12252             :     case HAS_VECTOR:
   12253             :       // Nothing to do.
   12254             :       break;
   12255             :   }
   12256    18762135 : }
   12257             : 
   12258      344769 : static void GetMinInobjectSlack(Map* map, void* data) {
   12259             :   int slack = map->unused_property_fields();
   12260      344769 :   if (*reinterpret_cast<int*>(data) > slack) {
   12261       88744 :     *reinterpret_cast<int*>(data) = slack;
   12262             :   }
   12263      344769 : }
   12264             : 
   12265             : 
   12266      337412 : static void ShrinkInstanceSize(Map* map, void* data) {
   12267      337412 :   int slack = *reinterpret_cast<int*>(data);
   12268      337412 :   map->SetInObjectProperties(map->GetInObjectProperties() - slack);
   12269      337412 :   map->set_unused_property_fields(map->unused_property_fields() - slack);
   12270      337412 :   map->set_instance_size(map->instance_size() - slack * kPointerSize);
   12271             :   map->set_construction_counter(Map::kNoSlackTracking);
   12272             : 
   12273             :   // Visitor id might depend on the instance size, recalculate it.
   12274      337412 :   map->set_visitor_id(Heap::GetStaticVisitorIdForMap(map));
   12275      337412 : }
   12276             : 
   12277        7357 : static void StopSlackTracking(Map* map, void* data) {
   12278             :   map->set_construction_counter(Map::kNoSlackTracking);
   12279        7357 : }
   12280             : 
   12281       93061 : void Map::CompleteInobjectSlackTracking() {
   12282             :   // Has to be an initial map.
   12283             :   DCHECK(GetBackPointer()->IsUndefined(GetIsolate()));
   12284             : 
   12285       93061 :   int slack = unused_property_fields();
   12286             :   TransitionArray::TraverseTransitionTree(this, &GetMinInobjectSlack, &slack);
   12287       93061 :   if (slack != 0) {
   12288             :     // Resize the initial map and all maps in its transition tree.
   12289             :     TransitionArray::TraverseTransitionTree(this, &ShrinkInstanceSize, &slack);
   12290             :   } else {
   12291             :     TransitionArray::TraverseTransitionTree(this, &StopSlackTracking, nullptr);
   12292             :   }
   12293       93061 : }
   12294             : 
   12295             : 
   12296    27787179 : static bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) {
   12297             :   DisallowHeapAllocation no_gc;
   12298    27787179 :   if (!object->HasFastProperties()) return false;
   12299    26487005 :   if (object->IsJSGlobalProxy()) return false;
   12300    26454752 :   if (object->GetIsolate()->bootstrapper()->IsActive()) return false;
   12301    11506444 :   return !object->map()->is_prototype_map() ||
   12302    11506444 :          !object->map()->should_be_fast_prototype_map();
   12303             : }
   12304             : 
   12305             : // static
   12306     5955150 : void JSObject::MakePrototypesFast(Handle<Object> receiver,
   12307             :                                   WhereToStart where_to_start,
   12308             :                                   Isolate* isolate) {
   12309     5955150 :   if (!receiver->IsJSReceiver()) return;
   12310    15995450 :   for (PrototypeIterator iter(isolate, Handle<JSReceiver>::cast(receiver),
   12311     5885809 :                               where_to_start);
   12312    14333473 :        !iter.IsAtEnd(); iter.Advance()) {
   12313             :     Handle<Object> current = PrototypeIterator::GetCurrent(iter);
   12314     9630426 :     if (!current->IsJSObject()) return;
   12315             :     Handle<JSObject> current_obj = Handle<JSObject>::cast(current);
   12316             :     Map* current_map = current_obj->map();
   12317     9624522 :     if (current_map->is_prototype_map()) {
   12318             :       // If the map is already marked as should be fast, we're done. Its
   12319             :       // prototypes will have been marked already as well.
   12320    11132049 :       if (current_map->should_be_fast_prototype_map()) return;
   12321             :       Handle<Map> map(current_map);
   12322      330669 :       Map::SetShouldBeFastPrototypeMap(map, true, isolate);
   12323      330669 :       JSObject::OptimizeAsPrototype(current_obj, FAST_PROTOTYPE);
   12324             :     }
   12325             :   }
   12326             : }
   12327             : 
   12328             : // static
   12329    27973272 : void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
   12330             :                                    PrototypeOptimizationMode mode) {
   12331    55946542 :   if (object->IsJSGlobalObject()) return;
   12332    27856965 :   if (mode == FAST_PROTOTYPE && PrototypeBenefitsFromNormalization(object)) {
   12333             :     // First normalize to ensure all JSFunctions are DATA_CONSTANT.
   12334             :     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0,
   12335      594868 :                                   "NormalizeAsPrototype");
   12336             :   }
   12337             :   Handle<Map> previous_map(object->map());
   12338    27856956 :   if (object->map()->is_prototype_map()) {
   12339    39995226 :     if (object->map()->should_be_fast_prototype_map() &&
   12340    17144557 :         !object->HasFastProperties()) {
   12341      293697 :       JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype");
   12342             :     }
   12343             :   } else {
   12344     5006289 :     if (object->map() == *previous_map) {
   12345     5006286 :       Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype");
   12346     5006288 :       JSObject::MigrateToMap(object, new_map);
   12347             :     }
   12348             :     object->map()->set_is_prototype_map(true);
   12349             : 
   12350             :     // Replace the pointer to the exact constructor with the Object function
   12351             :     // from the same context if undetectable from JS. This is to avoid keeping
   12352             :     // memory alive unnecessarily.
   12353     5006294 :     Object* maybe_constructor = object->map()->GetConstructor();
   12354     5006290 :     if (maybe_constructor->IsJSFunction()) {
   12355             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
   12356             :       Isolate* isolate = object->GetIsolate();
   12357     9517870 :       if (!constructor->shared()->IsApiFunction() &&
   12358     4515444 :           object->class_name() == isolate->heap()->Object_string()) {
   12359             :         Context* context = constructor->context()->native_context();
   12360             :         JSFunction* object_function = context->object_function();
   12361             :         object->map()->SetConstructor(object_function);
   12362             :       }
   12363             :     }
   12364             :   }
   12365             : }
   12366             : 
   12367             : 
   12368             : // static
   12369     6584382 : void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) {
   12370     6584382 :   if (!object->map()->is_prototype_map()) return;
   12371       90338 :   if (!object->map()->should_be_fast_prototype_map()) return;
   12372       60333 :   OptimizeAsPrototype(object, FAST_PROTOTYPE);
   12373             : }
   12374             : 
   12375             : 
   12376             : // static
   12377     3015481 : void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
   12378             :   // Contract: In line with InvalidatePrototypeChains()'s requirements,
   12379             :   // leaf maps don't need to register as users, only prototypes do.
   12380             :   DCHECK(user->is_prototype_map());
   12381             : 
   12382     3015481 :   Handle<Map> current_user = user;
   12383             :   Handle<PrototypeInfo> current_user_info =
   12384     3015481 :       Map::GetOrCreatePrototypeInfo(user, isolate);
   12385     7029262 :   for (PrototypeIterator iter(user); !iter.IsAtEnd(); iter.Advance()) {
   12386             :     // Walk up the prototype chain as far as links haven't been registered yet.
   12387     2912961 :     if (current_user_info->registry_slot() != PrototypeInfo::UNREGISTERED) {
   12388             :       break;
   12389             :     }
   12390             :     Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter);
   12391             :     // Proxies on the prototype chain are not supported. They make it
   12392             :     // impossible to make any assumptions about the prototype chain anyway.
   12393     3514715 :     if (maybe_proto->IsJSProxy()) return;
   12394             :     Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto);
   12395             :     Handle<PrototypeInfo> proto_info =
   12396      499150 :         Map::GetOrCreatePrototypeInfo(proto, isolate);
   12397             :     Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
   12398      499150 :     int slot = 0;
   12399             :     Handle<WeakFixedArray> new_array =
   12400      499150 :         WeakFixedArray::Add(maybe_registry, current_user, &slot);
   12401      499150 :     current_user_info->set_registry_slot(slot);
   12402      499150 :     if (!maybe_registry.is_identical_to(new_array)) {
   12403      151293 :       proto_info->set_prototype_users(*new_array);
   12404             :     }
   12405      499150 :     if (FLAG_trace_prototype_users) {
   12406             :       PrintF("Registering %p as a user of prototype %p (map=%p).\n",
   12407             :              reinterpret_cast<void*>(*current_user),
   12408             :              reinterpret_cast<void*>(*proto),
   12409           0 :              reinterpret_cast<void*>(proto->map()));
   12410             :     }
   12411             : 
   12412             :     current_user = handle(proto->map(), isolate);
   12413             :     current_user_info = proto_info;
   12414             :   }
   12415             : }
   12416             : 
   12417             : 
   12418             : // Can be called regardless of whether |user| was actually registered with
   12419             : // |prototype|. Returns true when there was a registration.
   12420             : // static
   12421     5501812 : bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
   12422             :   DCHECK(user->is_prototype_map());
   12423             :   // If it doesn't have a PrototypeInfo, it was never registered.
   12424     5501812 :   if (!user->prototype_info()->IsPrototypeInfo()) return false;
   12425             :   // If it had no prototype before, see if it had users that might expect
   12426             :   // registration.
   12427      540766 :   if (!user->prototype()->IsJSObject()) {
   12428             :     Object* users =
   12429             :         PrototypeInfo::cast(user->prototype_info())->prototype_users();
   12430      112479 :     return users->IsWeakFixedArray();
   12431             :   }
   12432             :   Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate);
   12433             :   Handle<PrototypeInfo> user_info =
   12434      428287 :       Map::GetOrCreatePrototypeInfo(user, isolate);
   12435             :   int slot = user_info->registry_slot();
   12436      428287 :   if (slot == PrototypeInfo::UNREGISTERED) return false;
   12437             :   DCHECK(prototype->map()->is_prototype_map());
   12438             :   Object* maybe_proto_info = prototype->map()->prototype_info();
   12439             :   // User knows its registry slot, prototype info and user registry must exist.
   12440             :   DCHECK(maybe_proto_info->IsPrototypeInfo());
   12441             :   Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info),
   12442             :                                    isolate);
   12443             :   Object* maybe_registry = proto_info->prototype_users();
   12444             :   DCHECK(maybe_registry->IsWeakFixedArray());
   12445             :   DCHECK(WeakFixedArray::cast(maybe_registry)->Get(slot) == *user);
   12446             :   WeakFixedArray::cast(maybe_registry)->Clear(slot);
   12447      176268 :   if (FLAG_trace_prototype_users) {
   12448             :     PrintF("Unregistering %p as a user of prototype %p.\n",
   12449           0 :            reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
   12450             :   }
   12451             :   return true;
   12452             : }
   12453             : 
   12454             : 
   12455     5741199 : static void InvalidatePrototypeChainsInternal(Map* map) {
   12456             :   DCHECK(map->is_prototype_map());
   12457     5741199 :   if (FLAG_trace_prototype_users) {
   12458             :     PrintF("Invalidating prototype map %p 's cell\n",
   12459           0 :            reinterpret_cast<void*>(map));
   12460             :   }
   12461             :   Object* maybe_proto_info = map->prototype_info();
   12462    10702776 :   if (!maybe_proto_info->IsPrototypeInfo()) return;
   12463             :   PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_proto_info);
   12464             :   Object* maybe_cell = proto_info->validity_cell();
   12465      779622 :   if (maybe_cell->IsCell()) {
   12466             :     // Just set the value; the cell will be replaced lazily.
   12467             :     Cell* cell = Cell::cast(maybe_cell);
   12468      503529 :     cell->set_value(Smi::FromInt(Map::kPrototypeChainInvalid));
   12469             :   }
   12470             : 
   12471             :   WeakFixedArray::Iterator iterator(proto_info->prototype_users());
   12472             :   // For now, only maps register themselves as users.
   12473             :   Map* user;
   12474     1017462 :   while ((user = iterator.Next<Map>()) != nullptr) {
   12475             :     // Walk the prototype chain (backwards, towards leaf objects) if necessary.
   12476      237840 :     InvalidatePrototypeChainsInternal(user);
   12477             :   }
   12478             : }
   12479             : 
   12480             : 
   12481             : // static
   12482           0 : void JSObject::InvalidatePrototypeChains(Map* map) {
   12483             :   DisallowHeapAllocation no_gc;
   12484     5503359 :   InvalidatePrototypeChainsInternal(map);
   12485           0 : }
   12486             : 
   12487             : 
   12488             : // static
   12489     4626005 : Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<JSObject> prototype,
   12490             :                                                     Isolate* isolate) {
   12491             :   Object* maybe_proto_info = prototype->map()->prototype_info();
   12492     4626005 :   if (maybe_proto_info->IsPrototypeInfo()) {
   12493             :     return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
   12494             :   }
   12495      196879 :   Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
   12496      196879 :   prototype->map()->set_prototype_info(*proto_info);
   12497      196879 :   return proto_info;
   12498             : }
   12499             : 
   12500             : 
   12501             : // static
   12502     3775133 : Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> prototype_map,
   12503             :                                                     Isolate* isolate) {
   12504             :   Object* maybe_proto_info = prototype_map->prototype_info();
   12505     3775133 :   if (maybe_proto_info->IsPrototypeInfo()) {
   12506             :     return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
   12507             :   }
   12508      303861 :   Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
   12509      303861 :   prototype_map->set_prototype_info(*proto_info);
   12510      303861 :   return proto_info;
   12511             : }
   12512             : 
   12513             : // static
   12514      331365 : void Map::SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
   12515             :                                       Isolate* isolate) {
   12516      331365 :   if (value == false && !map->prototype_info()->IsPrototypeInfo()) {
   12517             :     // "False" is the implicit default value, so there's nothing to do.
   12518      331365 :     return;
   12519             :   }
   12520      662730 :   GetOrCreatePrototypeInfo(map, isolate)->set_should_be_fast_map(value);
   12521             : }
   12522             : 
   12523             : // static
   12524     3069102 : Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
   12525             :                                                         Isolate* isolate) {
   12526             :   Handle<Object> maybe_prototype;
   12527     3069102 :   if (map->IsJSGlobalObjectMap()) {
   12528             :     DCHECK(map->is_prototype_map());
   12529             :     // Global object is prototype of a global proxy and therefore we can
   12530             :     // use its validity cell for guarding global object's prototype change.
   12531        2869 :     maybe_prototype = isolate->global_object();
   12532             :   } else {
   12533             :     maybe_prototype =
   12534     3066233 :         handle(map->GetPrototypeChainRootMap(isolate)->prototype(), isolate);
   12535     3066234 :     if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null();
   12536             :   }
   12537             :   Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
   12538             :   // Ensure the prototype is registered with its own prototypes so its cell
   12539             :   // will be invalidated when necessary.
   12540             :   JSObject::LazyRegisterPrototypeUser(handle(prototype->map(), isolate),
   12541     2730939 :                                       isolate);
   12542             :   Handle<PrototypeInfo> proto_info =
   12543     2730939 :       GetOrCreatePrototypeInfo(prototype, isolate);
   12544             :   Object* maybe_cell = proto_info->validity_cell();
   12545             :   // Return existing cell if it's still valid.
   12546     2730939 :   if (maybe_cell->IsCell()) {
   12547             :     Handle<Cell> cell(Cell::cast(maybe_cell), isolate);
   12548     2458054 :     if (cell->value() == Smi::FromInt(Map::kPrototypeChainValid)) {
   12549     2403976 :       return cell;
   12550             :     }
   12551             :   }
   12552             :   // Otherwise create a new cell.
   12553             :   Handle<Cell> cell = isolate->factory()->NewCell(
   12554      326963 :       handle(Smi::FromInt(Map::kPrototypeChainValid), isolate));
   12555      326963 :   proto_info->set_validity_cell(*cell);
   12556      326963 :   return cell;
   12557             : }
   12558             : 
   12559             : // static
   12560     1208300 : Handle<WeakCell> Map::GetOrCreatePrototypeWeakCell(Handle<JSObject> prototype,
   12561             :                                                    Isolate* isolate) {
   12562             :   DCHECK(!prototype.is_null());
   12563             :   Handle<PrototypeInfo> proto_info =
   12564     1208300 :       GetOrCreatePrototypeInfo(prototype, isolate);
   12565             :   Object* maybe_cell = proto_info->weak_cell();
   12566             :   // Return existing cell if it's already created.
   12567     1208300 :   if (maybe_cell->IsWeakCell()) {
   12568             :     Handle<WeakCell> cell(WeakCell::cast(maybe_cell), isolate);
   12569             :     DCHECK(!cell->cleared());
   12570     1052375 :     return cell;
   12571             :   }
   12572             :   // Otherwise create a new cell.
   12573      155925 :   Handle<WeakCell> cell = isolate->factory()->NewWeakCell(prototype);
   12574      155925 :   proto_info->set_weak_cell(*cell);
   12575      155925 :   return cell;
   12576             : }
   12577             : 
   12578             : // static
   12579    31795677 : void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype,
   12580             :                        PrototypeOptimizationMode proto_mode) {
   12581    31795677 :   RuntimeCallTimerScope stats_scope(*map, &RuntimeCallStats::Map_SetPrototype);
   12582             : 
   12583             :   bool is_hidden = false;
   12584    31795696 :   if (prototype->IsJSObject()) {
   12585             :     Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype);
   12586    26617447 :     JSObject::OptimizeAsPrototype(prototype_jsobj, proto_mode);
   12587             : 
   12588    26617444 :     Object* maybe_constructor = prototype_jsobj->map()->GetConstructor();
   12589    26617446 :     if (maybe_constructor->IsJSFunction()) {
   12590             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
   12591             :       Object* data = constructor->shared()->function_data();
   12592      715242 :       is_hidden = (data->IsFunctionTemplateInfo() &&
   12593    48569129 :                    FunctionTemplateInfo::cast(data)->hidden_prototype()) ||
   12594             :                   prototype->IsJSGlobalObject();
   12595     2332717 :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
   12596             :       is_hidden =
   12597          48 :           FunctionTemplateInfo::cast(maybe_constructor)->hidden_prototype() ||
   12598             :           prototype->IsJSGlobalObject();
   12599             :     }
   12600             :   }
   12601             :   map->set_has_hidden_prototype(is_hidden);
   12602             : 
   12603             :   WriteBarrierMode wb_mode = prototype->IsNull(map->GetIsolate())
   12604             :                                  ? SKIP_WRITE_BARRIER
   12605    31795691 :                                  : UPDATE_WRITE_BARRIER;
   12606    31795691 :   map->set_prototype(*prototype, wb_mode);
   12607    31795689 : }
   12608             : 
   12609             : 
   12610         158 : Handle<Object> CacheInitialJSArrayMaps(
   12611             :     Handle<Context> native_context, Handle<Map> initial_map) {
   12612             :   // Replace all of the cached initial array maps in the native context with
   12613             :   // the appropriate transitioned elements kind maps.
   12614         158 :   Handle<Map> current_map = initial_map;
   12615             :   ElementsKind kind = current_map->elements_kind();
   12616             :   DCHECK_EQ(GetInitialFastElementsKind(), kind);
   12617         158 :   native_context->set(Context::ArrayMapIndex(kind), *current_map);
   12618         948 :   for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
   12619             :        i < kFastElementsKindCount; ++i) {
   12620             :     Handle<Map> new_map;
   12621         790 :     ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
   12622         790 :     if (Map* maybe_elements_transition = current_map->ElementsTransitionMap()) {
   12623             :       new_map = handle(maybe_elements_transition);
   12624             :     } else {
   12625             :       new_map = Map::CopyAsElementsKind(
   12626         790 :           current_map, next_kind, INSERT_TRANSITION);
   12627             :     }
   12628             :     DCHECK_EQ(next_kind, new_map->elements_kind());
   12629         790 :     native_context->set(Context::ArrayMapIndex(next_kind), *new_map);
   12630             :     current_map = new_map;
   12631             :   }
   12632         158 :   return initial_map;
   12633             : }
   12634             : 
   12635             : namespace {
   12636             : 
   12637      696453 : void SetInstancePrototype(Isolate* isolate, Handle<JSFunction> function,
   12638             :                           Handle<JSReceiver> value) {
   12639             :   // Now some logic for the maps of the objects that are created by using this
   12640             :   // function as a constructor.
   12641      696453 :   if (function->has_initial_map()) {
   12642             :     // If the function has allocated the initial map replace it with a
   12643             :     // copy containing the new prototype.  Also complete any in-object
   12644             :     // slack tracking that is in progress at this point because it is
   12645             :     // still tracking the old copy.
   12646       42846 :     function->CompleteInobjectSlackTrackingIfActive();
   12647             : 
   12648             :     Handle<Map> initial_map(function->initial_map(), isolate);
   12649             : 
   12650       83164 :     if (!initial_map->GetIsolate()->bootstrapper()->IsActive() &&
   12651             :         initial_map->instance_type() == JS_OBJECT_TYPE) {
   12652             :       // Put the value in the initial map field until an initial map is needed.
   12653             :       // At that point, a new initial map is created and the prototype is put
   12654             :       // into the initial map where it belongs.
   12655       39954 :       function->set_prototype_or_initial_map(*value);
   12656             :     } else {
   12657        2892 :       Handle<Map> new_map = Map::Copy(initial_map, "SetInstancePrototype");
   12658        2892 :       JSFunction::SetInitialMap(function, new_map, value);
   12659             : 
   12660             :       // If the function is used as the global Array function, cache the
   12661             :       // updated initial maps (and transitioned versions) in the native context.
   12662             :       Handle<Context> native_context(function->context()->native_context(),
   12663             :                                      isolate);
   12664             :       Handle<Object> array_function(
   12665             :           native_context->get(Context::ARRAY_FUNCTION_INDEX), isolate);
   12666        5705 :       if (array_function->IsJSFunction() &&
   12667             :           *function == JSFunction::cast(*array_function)) {
   12668          79 :         CacheInitialJSArrayMaps(native_context, new_map);
   12669             :       }
   12670             :     }
   12671             : 
   12672             :     // Deoptimize all code that embeds the previous initial map.
   12673             :     initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
   12674       42846 :         isolate, DependentCode::kInitialMapChangedGroup);
   12675             :   } else {
   12676             :     // Put the value in the initial map field until an initial map is
   12677             :     // needed.  At that point, a new initial map is created and the
   12678             :     // prototype is put into the initial map where it belongs.
   12679      653607 :     function->set_prototype_or_initial_map(*value);
   12680      653607 :     if (value->IsJSObject()) {
   12681             :       // Optimize as prototype to detach it from its transition tree.
   12682             :       JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value),
   12683      653509 :                                     FAST_PROTOTYPE);
   12684             :     }
   12685             :   }
   12686             :   isolate->heap()->ClearInstanceofCache();
   12687      696453 : }
   12688             : 
   12689             : }  // anonymous namespace
   12690             : 
   12691      696452 : void JSFunction::SetPrototype(Handle<JSFunction> function,
   12692             :                               Handle<Object> value) {
   12693             :   DCHECK(function->IsConstructor() ||
   12694             :          IsGeneratorFunction(function->shared()->kind()));
   12695             :   Isolate* isolate = function->GetIsolate();
   12696             :   Handle<JSReceiver> construct_prototype;
   12697             : 
   12698             :   // If the value is not a JSReceiver, store the value in the map's
   12699             :   // constructor field so it can be accessed.  Also, set the prototype
   12700             :   // used for constructing objects to the original object prototype.
   12701             :   // See ECMA-262 13.2.2.
   12702      696453 :   if (!value->IsJSReceiver()) {
   12703             :     // Copy the map so this does not affect unrelated functions.
   12704             :     // Remove map transitions because they point to maps with a
   12705             :     // different prototype.
   12706        6612 :     Handle<Map> new_map = Map::Copy(handle(function->map()), "SetPrototype");
   12707             : 
   12708        6612 :     JSObject::MigrateToMap(function, new_map);
   12709             :     new_map->SetConstructor(*value);
   12710             :     new_map->set_non_instance_prototype(true);
   12711             : 
   12712             :     FunctionKind kind = function->shared()->kind();
   12713             :     Handle<Context> native_context(function->context()->native_context());
   12714             : 
   12715             :     construct_prototype = Handle<JSReceiver>(
   12716             :         IsGeneratorFunction(kind)
   12717             :             ? IsAsyncFunction(kind)
   12718             :                   ? native_context->initial_async_generator_prototype()
   12719             :                   : native_context->initial_generator_prototype()
   12720             :             : native_context->initial_object_prototype(),
   12721       13238 :         isolate);
   12722             :   } else {
   12723      689841 :     construct_prototype = Handle<JSReceiver>::cast(value);
   12724             :     function->map()->set_non_instance_prototype(false);
   12725             :   }
   12726             : 
   12727      696453 :   SetInstancePrototype(isolate, function, construct_prototype);
   12728      696452 : }
   12729             : 
   12730             : 
   12731       46991 : bool JSFunction::RemovePrototype() {
   12732             :   Context* native_context = context()->native_context();
   12733             :   Map* no_prototype_map =
   12734             :       is_strict(shared()->language_mode())
   12735             :           ? native_context->strict_function_without_prototype_map()
   12736       46991 :           : native_context->sloppy_function_without_prototype_map();
   12737             : 
   12738       46991 :   if (map() == no_prototype_map) return true;
   12739             : 
   12740             : #ifdef DEBUG
   12741             :   if (map() != (is_strict(shared()->language_mode())
   12742             :                     ? native_context->strict_function_map()
   12743             :                     : native_context->sloppy_function_map())) {
   12744             :     return false;
   12745             :   }
   12746             : #endif
   12747             : 
   12748       46043 :   set_map(no_prototype_map);
   12749       46043 :   set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
   12750       46043 :   return true;
   12751             : }
   12752             : 
   12753             : 
   12754     4864647 : void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
   12755             :                                Handle<Object> prototype) {
   12756     4864647 :   if (map->prototype() != *prototype) {
   12757     4864006 :     Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
   12758             :   }
   12759     4864649 :   function->set_prototype_or_initial_map(*map);
   12760             :   map->SetConstructor(*function);
   12761             : #if TRACE_MAPS
   12762             :   if (FLAG_trace_maps) {
   12763             :     PrintF("[TraceMaps: InitialMap map= %p SFI= %d_%s ]\n",
   12764             :            reinterpret_cast<void*>(*map), function->shared()->unique_id(),
   12765             :            function->shared()->DebugName()->ToCString().get());
   12766             :   }
   12767             : #endif
   12768     4864653 : }
   12769             : 
   12770             : 
   12771             : #ifdef DEBUG
   12772             : namespace {
   12773             : 
   12774             : bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
   12775             :   switch (instance_type) {
   12776             :     case JS_API_OBJECT_TYPE:
   12777             :     case JS_ARRAY_BUFFER_TYPE:
   12778             :     case JS_ARRAY_TYPE:
   12779             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
   12780             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
   12781             :     case JS_DATA_VIEW_TYPE:
   12782             :     case JS_DATE_TYPE:
   12783             :     case JS_FUNCTION_TYPE:
   12784             :     case JS_GENERATOR_OBJECT_TYPE:
   12785             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
   12786             :     case JS_MAP_ITERATOR_TYPE:
   12787             :     case JS_MAP_TYPE:
   12788             :     case JS_MESSAGE_OBJECT_TYPE:
   12789             :     case JS_OBJECT_TYPE:
   12790             :     case JS_ERROR_TYPE:
   12791             :     case JS_ARGUMENTS_TYPE:
   12792             :     case JS_PROMISE_TYPE:
   12793             :     case JS_REGEXP_TYPE:
   12794             :     case JS_SET_ITERATOR_TYPE:
   12795             :     case JS_SET_TYPE:
   12796             :     case JS_SPECIAL_API_OBJECT_TYPE:
   12797             :     case JS_TYPED_ARRAY_TYPE:
   12798             :     case JS_VALUE_TYPE:
   12799             :     case JS_WEAK_MAP_TYPE:
   12800             :     case JS_WEAK_SET_TYPE:
   12801             :       return true;
   12802             : 
   12803             :     case BYTECODE_ARRAY_TYPE:
   12804             :     case BYTE_ARRAY_TYPE:
   12805             :     case CELL_TYPE:
   12806             :     case CODE_TYPE:
   12807             :     case FILLER_TYPE:
   12808             :     case FIXED_ARRAY_TYPE:
   12809             :     case FIXED_DOUBLE_ARRAY_TYPE:
   12810             :     case FOREIGN_TYPE:
   12811             :     case FREE_SPACE_TYPE:
   12812             :     case HEAP_NUMBER_TYPE:
   12813             :     case JS_BOUND_FUNCTION_TYPE:
   12814             :     case JS_GLOBAL_OBJECT_TYPE:
   12815             :     case JS_GLOBAL_PROXY_TYPE:
   12816             :     case JS_PROXY_TYPE:
   12817             :     case MAP_TYPE:
   12818             :     case MUTABLE_HEAP_NUMBER_TYPE:
   12819             :     case ODDBALL_TYPE:
   12820             :     case PROPERTY_CELL_TYPE:
   12821             :     case SHARED_FUNCTION_INFO_TYPE:
   12822             :     case SYMBOL_TYPE:
   12823             :     case WEAK_CELL_TYPE:
   12824             : 
   12825             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
   12826             :   case FIXED_##TYPE##_ARRAY_TYPE:
   12827             : #undef TYPED_ARRAY_CASE
   12828             : 
   12829             : #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
   12830             :       STRUCT_LIST(MAKE_STRUCT_CASE)
   12831             : #undef MAKE_STRUCT_CASE
   12832             :       // We must not end up here for these instance types at all.
   12833             :       UNREACHABLE();
   12834             :     // Fall through.
   12835             :     default:
   12836             :       return false;
   12837             :   }
   12838             : }
   12839             : 
   12840             : }  // namespace
   12841             : #endif
   12842             : 
   12843             : 
   12844    20823967 : void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
   12845             :   DCHECK(function->IsConstructor() ||
   12846             :          IsResumableFunction(function->shared()->kind()));
   12847    41157828 :   if (function->has_initial_map()) return;
   12848             :   Isolate* isolate = function->GetIsolate();
   12849             : 
   12850             :   // First create a new map with the size and number of in-object properties
   12851             :   // suggested by the function.
   12852             :   InstanceType instance_type;
   12853      490109 :   if (IsResumableFunction(function->shared()->kind())) {
   12854             :     instance_type = IsAsyncGeneratorFunction(function->shared()->kind())
   12855             :                         ? JS_ASYNC_GENERATOR_OBJECT_TYPE
   12856       19742 :                         : JS_GENERATOR_OBJECT_TYPE;
   12857             :   } else {
   12858             :     instance_type = JS_OBJECT_TYPE;
   12859             :   }
   12860             : 
   12861             :   // The constructor should be compiled for the optimization hints to be
   12862             :   // available.
   12863             :   int expected_nof_properties = 0;
   12864      584479 :   if (function->shared()->is_compiled() ||
   12865       94370 :       Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) {
   12866             :     DCHECK(function->shared()->is_compiled());
   12867             :     expected_nof_properties = function->shared()->expected_nof_properties();
   12868             :   }
   12869             : 
   12870             :   int instance_size;
   12871             :   int in_object_properties;
   12872             :   CalculateInstanceSizeHelper(instance_type, 0, expected_nof_properties,
   12873      490109 :                               &instance_size, &in_object_properties);
   12874             : 
   12875      490109 :   Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size);
   12876             : 
   12877             :   // Fetch or allocate prototype.
   12878             :   Handle<Object> prototype;
   12879      490109 :   if (function->has_instance_prototype()) {
   12880      391572 :     prototype = handle(function->instance_prototype(), isolate);
   12881             :   } else {
   12882       98537 :     prototype = isolate->factory()->NewFunctionPrototype(function);
   12883             :   }
   12884      490109 :   map->SetInObjectProperties(in_object_properties);
   12885             :   map->set_unused_property_fields(in_object_properties);
   12886             :   DCHECK(map->has_fast_object_elements());
   12887             : 
   12888             :   // Finally link initial map and constructor function.
   12889             :   DCHECK(prototype->IsJSReceiver());
   12890      490109 :   JSFunction::SetInitialMap(function, map, prototype);
   12891             :   map->StartInobjectSlackTracking();
   12892             : }
   12893             : 
   12894             : 
   12895             : // static
   12896     3982599 : MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
   12897             :                                            Handle<JSFunction> constructor,
   12898             :                                            Handle<JSReceiver> new_target) {
   12899     3982599 :   EnsureHasInitialMap(constructor);
   12900             : 
   12901             :   Handle<Map> constructor_initial_map(constructor->initial_map(), isolate);
   12902     3982599 :   if (*new_target == *constructor) return constructor_initial_map;
   12903             : 
   12904             :   // Fast case, new.target is a subclass of constructor. The map is cacheable
   12905             :   // (and may already have been cached). new.target.prototype is guaranteed to
   12906             :   // be a JSReceiver.
   12907      133653 :   if (new_target->IsJSFunction()) {
   12908             :     Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
   12909             : 
   12910             :     // Check that |function|'s initial map still in sync with the |constructor|,
   12911             :     // otherwise we must create a new initial map for |function|.
   12912      255170 :     if (function->has_initial_map() &&
   12913      121849 :         function->initial_map()->GetConstructor() == *constructor) {
   12914             :       return handle(function->initial_map(), isolate);
   12915             :     }
   12916             : 
   12917             :     // Create a new map with the size and number of in-object properties
   12918             :     // suggested by |function|.
   12919             : 
   12920             :     // Link initial map and constructor function if the new.target is actually a
   12921             :     // subclass constructor.
   12922       11664 :     if (IsDerivedConstructor(function->shared()->kind())) {
   12923             :       Handle<Object> prototype(function->instance_prototype(), isolate);
   12924             :       InstanceType instance_type = constructor_initial_map->instance_type();
   12925             :       DCHECK(CanSubclassHaveInobjectProperties(instance_type));
   12926             :       int embedder_fields =
   12927        9296 :           JSObject::GetEmbedderFieldCount(*constructor_initial_map);
   12928             :       int pre_allocated = constructor_initial_map->GetInObjectProperties() -
   12929        9296 :                           constructor_initial_map->unused_property_fields();
   12930             :       int instance_size;
   12931             :       int in_object_properties;
   12932             :       CalculateInstanceSizeForDerivedClass(function, instance_type,
   12933             :                                            embedder_fields, &instance_size,
   12934        9296 :                                            &in_object_properties);
   12935             : 
   12936        9296 :       int unused_property_fields = in_object_properties - pre_allocated;
   12937             :       Handle<Map> map =
   12938             :           Map::CopyInitialMap(constructor_initial_map, instance_size,
   12939        9296 :                               in_object_properties, unused_property_fields);
   12940             :       map->set_new_target_is_base(false);
   12941             : 
   12942        9296 :       JSFunction::SetInitialMap(function, map, prototype);
   12943             :       map->SetConstructor(*constructor);
   12944             :       map->set_construction_counter(Map::kNoSlackTracking);
   12945             :       map->StartInobjectSlackTracking();
   12946             :       return map;
   12947             :     }
   12948             :   }
   12949             : 
   12950             :   // Slow path, new.target is either a proxy or can't cache the map.
   12951             :   // new.target.prototype is not guaranteed to be a JSReceiver, and may need to
   12952             :   // fall back to the intrinsicDefaultProto.
   12953             :   Handle<Object> prototype;
   12954        2700 :   if (new_target->IsJSFunction()) {
   12955             :     Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
   12956             :     // Make sure the new.target.prototype is cached.
   12957        2368 :     EnsureHasInitialMap(function);
   12958        2368 :     prototype = handle(function->prototype(), isolate);
   12959             :   } else {
   12960             :     Handle<String> prototype_string = isolate->factory()->prototype_string();
   12961         664 :     ASSIGN_RETURN_ON_EXCEPTION(
   12962             :         isolate, prototype,
   12963             :         JSReceiver::GetProperty(new_target, prototype_string), Map);
   12964             :     // The above prototype lookup might change the constructor and its
   12965             :     // prototype, hence we have to reload the initial map.
   12966         287 :     EnsureHasInitialMap(constructor);
   12967             :     constructor_initial_map = handle(constructor->initial_map(), isolate);
   12968             :   }
   12969             : 
   12970             :   // If prototype is not a JSReceiver, fetch the intrinsicDefaultProto from the
   12971             :   // correct realm. Rather than directly fetching the .prototype, we fetch the
   12972             :   // constructor that points to the .prototype. This relies on
   12973             :   // constructor.prototype being FROZEN for those constructors.
   12974        2655 :   if (!prototype->IsJSReceiver()) {
   12975             :     Handle<Context> context;
   12976        4090 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, context,
   12977             :                                JSReceiver::GetFunctionRealm(new_target), Map);
   12978             :     DCHECK(context->IsNativeContext());
   12979             :     Handle<Object> maybe_index = JSReceiver::GetDataProperty(
   12980        2045 :         constructor, isolate->factory()->native_context_index_symbol());
   12981             :     int index = maybe_index->IsSmi() ? Smi::cast(*maybe_index)->value()
   12982        2045 :                                      : Context::OBJECT_FUNCTION_INDEX;
   12983             :     Handle<JSFunction> realm_constructor(JSFunction::cast(context->get(index)));
   12984        2045 :     prototype = handle(realm_constructor->prototype(), isolate);
   12985             :   }
   12986             : 
   12987        2655 :   Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
   12988             :   map->set_new_target_is_base(false);
   12989             :   DCHECK(prototype->IsJSReceiver());
   12990        2655 :   if (map->prototype() != *prototype) {
   12991        1489 :     Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
   12992             :   }
   12993             :   map->SetConstructor(*constructor);
   12994             :   return map;
   12995             : }
   12996             : 
   12997             : 
   12998           0 : void JSFunction::PrintName(FILE* out) {
   12999           0 :   std::unique_ptr<char[]> name = shared()->DebugName()->ToCString();
   13000           0 :   PrintF(out, "%s", name.get());
   13001           0 : }
   13002             : 
   13003             : 
   13004      620875 : Handle<String> JSFunction::GetName(Handle<JSFunction> function) {
   13005             :   Isolate* isolate = function->GetIsolate();
   13006             :   Handle<Object> name =
   13007      620875 :       JSReceiver::GetDataProperty(function, isolate->factory()->name_string());
   13008      620875 :   if (name->IsString()) return Handle<String>::cast(name);
   13009      619872 :   return handle(function->shared()->DebugName(), isolate);
   13010             : }
   13011             : 
   13012             : 
   13013      375062 : Handle<String> JSFunction::GetDebugName(Handle<JSFunction> function) {
   13014             :   Isolate* isolate = function->GetIsolate();
   13015             :   Handle<Object> name = JSReceiver::GetDataProperty(
   13016      375062 :       function, isolate->factory()->display_name_string());
   13017      375062 :   if (name->IsString()) return Handle<String>::cast(name);
   13018      375016 :   return JSFunction::GetName(function);
   13019             : }
   13020             : 
   13021     1488194 : void JSFunction::SetName(Handle<JSFunction> function, Handle<Name> name,
   13022             :                          Handle<String> prefix) {
   13023             :   Isolate* isolate = function->GetIsolate();
   13024     2976393 :   Handle<String> function_name = Name::ToFunctionName(name).ToHandleChecked();
   13025     1488199 :   if (prefix->length() > 0) {
   13026        3480 :     IncrementalStringBuilder builder(isolate);
   13027        3480 :     builder.AppendString(prefix);
   13028             :     builder.AppendCharacter(' ');
   13029        3480 :     builder.AppendString(function_name);
   13030        6960 :     function_name = builder.Finish().ToHandleChecked();
   13031             :   }
   13032             :   JSObject::DefinePropertyOrElementIgnoreAttributes(
   13033             :       function, isolate->factory()->name_string(), function_name,
   13034             :       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY))
   13035     2976397 :       .ToHandleChecked();
   13036     1488198 : }
   13037             : 
   13038             : namespace {
   13039             : 
   13040             : char const kNativeCodeSource[] = "function () { [native code] }";
   13041             : 
   13042             : 
   13043     1552727 : Handle<String> NativeCodeFunctionSourceString(
   13044             :     Handle<SharedFunctionInfo> shared_info) {
   13045             :   Isolate* const isolate = shared_info->GetIsolate();
   13046     1552727 :   if (shared_info->name()->IsString()) {
   13047     1552727 :     IncrementalStringBuilder builder(isolate);
   13048             :     builder.AppendCString("function ");
   13049     1552727 :     builder.AppendString(handle(String::cast(shared_info->name()), isolate));
   13050             :     builder.AppendCString("() { [native code] }");
   13051     3105454 :     return builder.Finish().ToHandleChecked();
   13052             :   }
   13053           0 :   return isolate->factory()->NewStringFromAsciiChecked(kNativeCodeSource);
   13054             : }
   13055             : 
   13056             : }  // namespace
   13057             : 
   13058             : 
   13059             : // static
   13060          81 : Handle<String> JSBoundFunction::ToString(Handle<JSBoundFunction> function) {
   13061             :   Isolate* const isolate = function->GetIsolate();
   13062          81 :   return isolate->factory()->NewStringFromAsciiChecked(kNativeCodeSource);
   13063             : }
   13064             : 
   13065             : 
   13066             : // static
   13067     2636894 : Handle<String> JSFunction::ToString(Handle<JSFunction> function) {
   13068             :   Isolate* const isolate = function->GetIsolate();
   13069             :   Handle<SharedFunctionInfo> shared_info(function->shared(), isolate);
   13070             : 
   13071             :   // Check if {function} should hide its source code.
   13072     2636894 :   if (!shared_info->IsUserJavaScript()) {
   13073     1552727 :     return NativeCodeFunctionSourceString(shared_info);
   13074             :   }
   13075             : 
   13076             :   // Check if we should print {function} as a class.
   13077             :   Handle<Object> class_start_position = JSReceiver::GetDataProperty(
   13078     1084167 :       function, isolate->factory()->class_start_position_symbol());
   13079     1084167 :   if (class_start_position->IsSmi()) {
   13080             :     Handle<Object> class_end_position = JSReceiver::GetDataProperty(
   13081       33811 :         function, isolate->factory()->class_end_position_symbol());
   13082             :     Handle<String> script_source(
   13083             :         String::cast(Script::cast(shared_info->script())->source()), isolate);
   13084             :     return isolate->factory()->NewSubString(
   13085             :         script_source, Handle<Smi>::cast(class_start_position)->value(),
   13086       33811 :         Handle<Smi>::cast(class_end_position)->value());
   13087             :   }
   13088             : 
   13089             :   // Check if we have source code for the {function}.
   13090     1050356 :   if (!shared_info->HasSourceCode()) {
   13091           0 :     return NativeCodeFunctionSourceString(shared_info);
   13092             :   }
   13093             : 
   13094     1050356 :   if (FLAG_harmony_function_tostring) {
   13095        1260 :     return Handle<String>::cast(shared_info->GetSourceCodeHarmony());
   13096             :   }
   13097             : 
   13098     1049096 :   IncrementalStringBuilder builder(isolate);
   13099             :   FunctionKind kind = shared_info->kind();
   13100     1049096 :   if (!IsArrowFunction(kind)) {
   13101     1043685 :     if (IsConciseMethod(kind)) {
   13102          98 :       if (IsAsyncGeneratorFunction(kind)) {
   13103             :         builder.AppendCString("async *");
   13104          56 :       } else if (IsGeneratorFunction(kind)) {
   13105             :         builder.AppendCharacter('*');
   13106          42 :       } else if (IsAsyncFunction(kind)) {
   13107             :         builder.AppendCString("async ");
   13108             :       }
   13109             :     } else {
   13110     1043587 :       if (IsAsyncGeneratorFunction(kind)) {
   13111             :         builder.AppendCString("async function* ");
   13112     1043517 :       } else if (IsGeneratorFunction(kind)) {
   13113             :         builder.AppendCString("function* ");
   13114     1043323 :       } else if (IsAsyncFunction(kind)) {
   13115             :         builder.AppendCString("async function ");
   13116             :       } else {
   13117             :         builder.AppendCString("function ");
   13118             :       }
   13119             :     }
   13120     1043685 :     if (shared_info->name_should_print_as_anonymous()) {
   13121             :       builder.AppendCString("anonymous");
   13122     1043123 :     } else if (!shared_info->is_anonymous_expression()) {
   13123      939165 :       builder.AppendString(handle(String::cast(shared_info->name()), isolate));
   13124             :     }
   13125             :   }
   13126     1049096 :   builder.AppendString(Handle<String>::cast(shared_info->GetSourceCode()));
   13127     2098192 :   return builder.Finish().ToHandleChecked();
   13128             : }
   13129             : 
   13130         473 : void Oddball::Initialize(Isolate* isolate, Handle<Oddball> oddball,
   13131             :                          const char* to_string, Handle<Object> to_number,
   13132             :                          const char* type_of, byte kind) {
   13133             :   Handle<String> internalized_to_string =
   13134         473 :       isolate->factory()->InternalizeUtf8String(to_string);
   13135             :   Handle<String> internalized_type_of =
   13136         473 :       isolate->factory()->InternalizeUtf8String(type_of);
   13137         473 :   if (to_number->IsHeapNumber()) {
   13138             :     oddball->set_to_number_raw_as_bits(
   13139             :         Handle<HeapNumber>::cast(to_number)->value_as_bits());
   13140             :   } else {
   13141             :     oddball->set_to_number_raw(to_number->Number());
   13142             :   }
   13143         473 :   oddball->set_to_number(*to_number);
   13144         473 :   oddball->set_to_string(*internalized_to_string);
   13145         473 :   oddball->set_type_of(*internalized_type_of);
   13146             :   oddball->set_kind(kind);
   13147         473 : }
   13148             : 
   13149     1294323 : void Script::SetEvalOrigin(Handle<Script> script,
   13150             :                            Handle<SharedFunctionInfo> outer_info,
   13151             :                            int eval_position) {
   13152     1294323 :   if (eval_position == kNoSourcePosition) {
   13153             :     // If the position is missing, attempt to get the code offset from the
   13154             :     // current activation.  Do not translate the code offset into source
   13155             :     // position, but store it as negative value for lazy translation.
   13156      477363 :     StackTraceFrameIterator it(script->GetIsolate());
   13157      954649 :     if (!it.done() && it.is_javascript()) {
   13158      477286 :       FrameSummary summary = FrameSummary::GetTop(it.javascript_frame());
   13159      477286 :       script->set_eval_from_shared(summary.AsJavaScript().function()->shared());
   13160      477286 :       script->set_eval_from_position(-summary.code_offset());
   13161     1771609 :       return;
   13162             :     }
   13163             :     eval_position = 0;
   13164             :   }
   13165      817037 :   script->set_eval_from_shared(*outer_info);
   13166             :   script->set_eval_from_position(eval_position);
   13167             : }
   13168             : 
   13169       12476 : int Script::GetEvalPosition() {
   13170             :   DisallowHeapAllocation no_gc;
   13171             :   DCHECK(compilation_type() == Script::COMPILATION_TYPE_EVAL);
   13172             :   int position = eval_from_position();
   13173       12476 :   if (position < 0) {
   13174             :     // Due to laziness, the position may not have been translated from code
   13175             :     // offset yet, which would be encoded as negative integer. In that case,
   13176             :     // translate and set the position.
   13177        1105 :     if (eval_from_shared()->IsUndefined(GetIsolate())) {
   13178             :       position = 0;
   13179             :     } else {
   13180             :       SharedFunctionInfo* shared = SharedFunctionInfo::cast(eval_from_shared());
   13181        2210 :       position = shared->abstract_code()->SourcePosition(-position);
   13182             :     }
   13183             :     DCHECK(position >= 0);
   13184             :     set_eval_from_position(position);
   13185             :   }
   13186       12476 :   return position;
   13187             : }
   13188             : 
   13189     1672519 : void Script::InitLineEnds(Handle<Script> script) {
   13190             :   Isolate* isolate = script->GetIsolate();
   13191     3345038 :   if (!script->line_ends()->IsUndefined(isolate)) return;
   13192             :   DCHECK_NE(Script::TYPE_WASM, script->type());
   13193             : 
   13194             :   Object* src_obj = script->source();
   13195       63161 :   if (!src_obj->IsString()) {
   13196             :     DCHECK(src_obj->IsUndefined(isolate));
   13197          14 :     script->set_line_ends(isolate->heap()->empty_fixed_array());
   13198             :   } else {
   13199             :     DCHECK(src_obj->IsString());
   13200             :     Handle<String> src(String::cast(src_obj), isolate);
   13201       63154 :     Handle<FixedArray> array = String::CalculateLineEnds(src, true);
   13202       63154 :     script->set_line_ends(*array);
   13203             :   }
   13204             : 
   13205             :   DCHECK(script->line_ends()->IsFixedArray());
   13206             : }
   13207             : 
   13208     1386299 : bool Script::GetPositionInfo(Handle<Script> script, int position,
   13209             :                              PositionInfo* info, OffsetFlag offset_flag) {
   13210             :   // For wasm, we do not create an artificial line_ends array, but do the
   13211             :   // translation directly.
   13212     1386299 :   if (script->type() != Script::TYPE_WASM) InitLineEnds(script);
   13213     1386299 :   return script->GetPositionInfo(position, info, offset_flag);
   13214             : }
   13215             : 
   13216    54644495 : bool Script::IsUserJavaScript() { return type() == Script::TYPE_NORMAL; }
   13217             : 
   13218             : namespace {
   13219        1791 : bool GetPositionInfoSlow(const Script* script, int position,
   13220             :                          Script::PositionInfo* info) {
   13221        1791 :   if (!script->source()->IsString()) return false;
   13222        1791 :   if (position < 0) position = 0;
   13223             : 
   13224             :   String* source_string = String::cast(script->source());
   13225             :   int line = 0;
   13226             :   int line_start = 0;
   13227             :   int len = source_string->length();
   13228      539845 :   for (int pos = 0; pos <= len; ++pos) {
   13229     1079590 :     if (pos == len || source_string->Get(pos) == '\n') {
   13230       22152 :       if (position <= pos) {
   13231        1779 :         info->line = line;
   13232        1779 :         info->column = position - line_start;
   13233        1779 :         info->line_start = line_start;
   13234        1779 :         info->line_end = pos;
   13235        1779 :         return true;
   13236             :       }
   13237       20373 :       line++;
   13238       20373 :       line_start = pos + 1;
   13239             :     }
   13240             :   }
   13241             :   return false;
   13242             : }
   13243             : }  // namespace
   13244             : 
   13245             : #define SMI_VALUE(x) (Smi::cast(x)->value())
   13246     1443397 : bool Script::GetPositionInfo(int position, PositionInfo* info,
   13247             :                              OffsetFlag offset_flag) const {
   13248             :   DisallowHeapAllocation no_allocation;
   13249             : 
   13250             :   // For wasm, we do not rely on the line_ends array, but do the translation
   13251             :   // directly.
   13252     1443397 :   if (type() == Script::TYPE_WASM) {
   13253             :     Handle<WasmCompiledModule> compiled_module(
   13254             :         WasmCompiledModule::cast(wasm_compiled_module()));
   13255             :     DCHECK_LE(0, position);
   13256             :     return compiled_module->GetPositionInfo(static_cast<uint32_t>(position),
   13257        1036 :                                             info);
   13258             :   }
   13259             : 
   13260     1442879 :   if (line_ends()->IsUndefined(GetIsolate())) {
   13261             :     // Slow mode: we do not have line_ends. We have to iterate through source.
   13262        1791 :     if (!GetPositionInfoSlow(this, position, info)) return false;
   13263             :   } else {
   13264             :     DCHECK(line_ends()->IsFixedArray());
   13265             :     FixedArray* ends = FixedArray::cast(line_ends());
   13266             : 
   13267             :     const int ends_len = ends->length();
   13268     1441088 :     if (ends_len == 0) return false;
   13269             : 
   13270             :     // Return early on invalid positions. Negative positions behave as if 0 was
   13271             :     // passed, and positions beyond the end of the script return as failure.
   13272     1441067 :     if (position < 0) {
   13273             :       position = 0;
   13274     2881130 :     } else if (position > SMI_VALUE(ends->get(ends_len - 1))) {
   13275             :       return false;
   13276             :     }
   13277             : 
   13278             :     // Determine line number by doing a binary search on the line ends array.
   13279     1441041 :     if (SMI_VALUE(ends->get(0)) >= position) {
   13280      199218 :       info->line = 0;
   13281      199218 :       info->line_start = 0;
   13282      199218 :       info->column = position;
   13283             :     } else {
   13284             :       int left = 0;
   13285     1241823 :       int right = ends_len - 1;
   13286             : 
   13287     8767386 :       while (right > 0) {
   13288             :         DCHECK_LE(left, right);
   13289     7525563 :         const int mid = (left + right) / 2;
   13290     7525563 :         if (position > SMI_VALUE(ends->get(mid))) {
   13291     3844216 :           left = mid + 1;
   13292     7362694 :         } else if (position <= SMI_VALUE(ends->get(mid - 1))) {
   13293             :           right = mid - 1;
   13294             :         } else {
   13295     1241823 :           info->line = mid;
   13296     1241823 :           break;
   13297             :         }
   13298             :       }
   13299             :       DCHECK(SMI_VALUE(ends->get(info->line)) >= position &&
   13300             :              SMI_VALUE(ends->get(info->line - 1)) < position);
   13301     2483646 :       info->line_start = SMI_VALUE(ends->get(info->line - 1)) + 1;
   13302     1241823 :       info->column = position - info->line_start;
   13303             :     }
   13304             : 
   13305             :     // Line end is position of the linebreak character.
   13306     2882082 :     info->line_end = SMI_VALUE(ends->get(info->line));
   13307     1441041 :     if (info->line_end > 0) {
   13308             :       DCHECK(source()->IsString());
   13309             :       String* src = String::cast(source());
   13310     2881606 :       if (src->length() >= info->line_end &&
   13311     1440803 :           src->Get(info->line_end - 1) == '\r') {
   13312           0 :         info->line_end--;
   13313             :       }
   13314             :     }
   13315             :   }
   13316             : 
   13317             :   // Add offsets if requested.
   13318     1442820 :   if (offset_flag == WITH_OFFSET) {
   13319     1218696 :     if (info->line == 0) {
   13320      163878 :       info->column += column_offset();
   13321             :     }
   13322     1218696 :     info->line += line_offset();
   13323             :   }
   13324             : 
   13325             :   return true;
   13326             : }
   13327             : #undef SMI_VALUE
   13328             : 
   13329      203268 : int Script::GetColumnNumber(Handle<Script> script, int code_pos) {
   13330             :   PositionInfo info;
   13331      203268 :   GetPositionInfo(script, code_pos, &info, WITH_OFFSET);
   13332      203268 :   return info.column;
   13333             : }
   13334             : 
   13335           0 : int Script::GetColumnNumber(int code_pos) const {
   13336             :   PositionInfo info;
   13337           0 :   GetPositionInfo(code_pos, &info, WITH_OFFSET);
   13338           0 :   return info.column;
   13339             : }
   13340             : 
   13341      210499 : int Script::GetLineNumber(Handle<Script> script, int code_pos) {
   13342             :   PositionInfo info;
   13343      210499 :   GetPositionInfo(script, code_pos, &info, WITH_OFFSET);
   13344      210499 :   return info.line;
   13345             : }
   13346             : 
   13347       56978 : int Script::GetLineNumber(int code_pos) const {
   13348             :   PositionInfo info;
   13349       56978 :   GetPositionInfo(code_pos, &info, WITH_OFFSET);
   13350       56978 :   return info.line;
   13351             : }
   13352             : 
   13353       49078 : Object* Script::GetNameOrSourceURL() {
   13354             :   Isolate* isolate = GetIsolate();
   13355             :   // Keep in sync with ScriptNameOrSourceURL in messages.js.
   13356       51247 :   if (!source_url()->IsUndefined(isolate)) return source_url();
   13357       46909 :   return name();
   13358             : }
   13359             : 
   13360             : 
   13361     2036828 : Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
   13362      629346 :   Isolate* isolate = script->GetIsolate();
   13363     2036828 :   if (!script->wrapper()->IsUndefined(isolate)) {
   13364             :     DCHECK(script->wrapper()->IsWeakCell());
   13365             :     Handle<WeakCell> cell(WeakCell::cast(script->wrapper()));
   13366     1545864 :     if (!cell->cleared()) {
   13367             :       // Return a handle for the existing script wrapper from the cache.
   13368             :       return handle(JSObject::cast(cell->value()));
   13369             :     }
   13370             :     // If we found an empty WeakCell, that means the script wrapper was
   13371             :     // GCed.  We are not notified directly of that, so we decrement here
   13372             :     // so that we at least don't count double for any given script.
   13373       69191 :     isolate->counters()->script_wrappers()->Decrement();
   13374             :   }
   13375             :   // Construct a new script wrapper.
   13376      560155 :   isolate->counters()->script_wrappers()->Increment();
   13377      560155 :   Handle<JSFunction> constructor = isolate->script_function();
   13378             :   Handle<JSValue> result =
   13379      560155 :       Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
   13380      560155 :   result->set_value(*script);
   13381      560155 :   Handle<WeakCell> cell = isolate->factory()->NewWeakCell(result);
   13382      560155 :   script->set_wrapper(*cell);
   13383      560155 :   return result;
   13384             : }
   13385             : 
   13386     5867748 : MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
   13387     5867748 :     Isolate* isolate, const FunctionLiteral* fun) {
   13388             :   DCHECK_NE(fun->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
   13389             :   DCHECK_LT(fun->function_literal_id(), shared_function_infos()->length());
   13390             :   Object* shared = shared_function_infos()->get(fun->function_literal_id());
   13391     6841929 :   if (shared->IsUndefined(isolate) || WeakCell::cast(shared)->cleared()) {
   13392             :     return MaybeHandle<SharedFunctionInfo>();
   13393             :   }
   13394             :   return handle(SharedFunctionInfo::cast(WeakCell::cast(shared)->value()));
   13395             : }
   13396             : 
   13397      212463 : Script::Iterator::Iterator(Isolate* isolate)
   13398      436647 :     : iterator_(isolate->heap()->script_list()) {}
   13399             : 
   13400             : 
   13401     6115211 : Script* Script::Iterator::Next() { return iterator_.Next<Script>(); }
   13402             : 
   13403          42 : bool Script::HasPreparsedScopeData() const {
   13404          42 :   return preparsed_scope_data()->length() > 0;
   13405             : }
   13406             : 
   13407       90520 : SharedFunctionInfo::ScriptIterator::ScriptIterator(Handle<Script> script)
   13408             :     : ScriptIterator(script->GetIsolate(),
   13409       90520 :                      handle(script->shared_function_infos())) {}
   13410             : 
   13411         642 : SharedFunctionInfo::ScriptIterator::ScriptIterator(
   13412             :     Isolate* isolate, Handle<FixedArray> shared_function_infos)
   13413             :     : isolate_(isolate),
   13414             :       shared_function_infos_(shared_function_infos),
   13415       91162 :       index_(0) {}
   13416             : 
   13417    11846730 : SharedFunctionInfo* SharedFunctionInfo::ScriptIterator::Next() {
   13418    39476960 :   while (index_ < shared_function_infos_->length()) {
   13419    13365011 :     Object* raw = shared_function_infos_->get(index_++);
   13420    38479849 :     if (raw->IsUndefined(isolate_) || WeakCell::cast(raw)->cleared()) continue;
   13421    11396626 :     return SharedFunctionInfo::cast(WeakCell::cast(raw)->value());
   13422             :   }
   13423             :   return nullptr;
   13424             : }
   13425             : 
   13426      358957 : void SharedFunctionInfo::ScriptIterator::Reset(Handle<Script> script) {
   13427      358957 :   shared_function_infos_ = handle(script->shared_function_infos());
   13428      358957 :   index_ = 0;
   13429      358957 : }
   13430             : 
   13431       11721 : SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate)
   13432             :     : script_iterator_(isolate),
   13433             :       noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()),
   13434       23442 :       sfi_iterator_(handle(script_iterator_.Next(), isolate)) {}
   13435             : 
   13436    16605451 : SharedFunctionInfo* SharedFunctionInfo::GlobalIterator::Next() {
   13437    16605451 :   SharedFunctionInfo* next = noscript_sfi_iterator_.Next<SharedFunctionInfo>();
   13438    16605451 :   if (next != nullptr) return next;
   13439             :   for (;;) {
   13440    10677654 :     next = sfi_iterator_.Next();
   13441    10677654 :     if (next != nullptr) return next;
   13442             :     Script* next_script = script_iterator_.Next();
   13443      370678 :     if (next_script == nullptr) return nullptr;
   13444      358957 :     sfi_iterator_.Reset(handle(next_script));
   13445      358957 :   }
   13446             : }
   13447             : 
   13448             : 
   13449     6245756 : void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
   13450             :                                    Handle<Object> script_object) {
   13451             :   DCHECK_NE(shared->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
   13452    12491506 :   if (shared->script() == *script_object) return;
   13453             :   Isolate* isolate = shared->GetIsolate();
   13454             : 
   13455             :   // Add shared function info to new script's list. If a collection occurs,
   13456             :   // the shared function info may be temporarily in two lists.
   13457             :   // This is okay because the gc-time processing of these lists can tolerate
   13458             :   // duplicates.
   13459     6245762 :   if (script_object->IsScript()) {
   13460             :     Handle<Script> script = Handle<Script>::cast(script_object);
   13461             :     Handle<FixedArray> list = handle(script->shared_function_infos(), isolate);
   13462             : #ifdef DEBUG
   13463             :     DCHECK_LT(shared->function_literal_id(), list->length());
   13464             :     if (list->get(shared->function_literal_id())->IsWeakCell() &&
   13465             :         !WeakCell::cast(list->get(shared->function_literal_id()))->cleared()) {
   13466             :       DCHECK(
   13467             :           WeakCell::cast(list->get(shared->function_literal_id()))->value() ==
   13468             :           *shared);
   13469             :     }
   13470             : #endif
   13471     6239219 :     Handle<WeakCell> cell = isolate->factory()->NewWeakCell(shared);
   13472     6239225 :     list->set(shared->function_literal_id(), *cell);
   13473             :   } else {
   13474             :     Handle<Object> list = isolate->factory()->noscript_shared_function_infos();
   13475             : 
   13476             : #ifdef DEBUG
   13477             :     if (FLAG_enable_slow_asserts) {
   13478             :       WeakFixedArray::Iterator iterator(*list);
   13479             :       SharedFunctionInfo* next;
   13480             :       while ((next = iterator.Next<SharedFunctionInfo>()) != nullptr) {
   13481             :         DCHECK_NE(next, *shared);
   13482             :       }
   13483             :     }
   13484             : #endif  // DEBUG
   13485             : 
   13486        6539 :     list = WeakFixedArray::Add(list, shared);
   13487             : 
   13488             :     isolate->heap()->SetRootNoScriptSharedFunctionInfos(*list);
   13489             :   }
   13490             : 
   13491     6245764 :   if (shared->script()->IsScript()) {
   13492             :     // Remove shared function info from old script's list.
   13493             :     Script* old_script = Script::cast(shared->script());
   13494             : 
   13495             :     // Due to liveedit, it might happen that the old_script doesn't know
   13496             :     // about the SharedFunctionInfo, so we have to guard against that.
   13497             :     Handle<FixedArray> infos(old_script->shared_function_infos(), isolate);
   13498        6571 :     if (shared->function_literal_id() < infos->length()) {
   13499             :       Object* raw = old_script->shared_function_infos()->get(
   13500             :           shared->function_literal_id());
   13501       13080 :       if (!raw->IsWeakCell() || WeakCell::cast(raw)->value() == *shared) {
   13502             :         old_script->shared_function_infos()->set(
   13503        3450 :             shared->function_literal_id(), isolate->heap()->undefined_value());
   13504             :       }
   13505             :     }
   13506             :   } else {
   13507             :     // Remove shared function info from root array.
   13508     6239193 :     Object* list = isolate->heap()->noscript_shared_function_infos();
   13509     6239193 :     CHECK(WeakFixedArray::cast(list)->Remove(shared));
   13510             :   }
   13511             : 
   13512             :   // Finally set new script.
   13513     6245763 :   shared->set_script(*script_object);
   13514             : }
   13515             : 
   13516             : 
   13517     3098969 : String* SharedFunctionInfo::DebugName() {
   13518             :   Object* n = name();
   13519     6197945 :   if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name();
   13520             :   return String::cast(n);
   13521             : }
   13522             : 
   13523       14088 : bool SharedFunctionInfo::HasNoSideEffect() {
   13524       14088 :   if (!computed_has_no_side_effect()) {
   13525             :     DisallowHeapAllocation not_handlified;
   13526             :     Handle<SharedFunctionInfo> info(this);
   13527       11074 :     set_has_no_side_effect(DebugEvaluate::FunctionHasNoSideEffect(info));
   13528       11074 :     set_computed_has_no_side_effect(true);
   13529             :   }
   13530       14088 :   return has_no_side_effect();
   13531             : }
   13532             : 
   13533             : // The filter is a pattern that matches function names in this way:
   13534             : //   "*"      all; the default
   13535             : //   "-"      all but the top-level function
   13536             : //   "-name"  all but the function "name"
   13537             : //   ""       only the top-level function
   13538             : //   "name"   only the function "name"
   13539             : //   "name*"  only functions starting with "name"
   13540             : //   "~"      none; the tilde is not an identifier
   13541     4007662 : bool SharedFunctionInfo::PassesFilter(const char* raw_filter) {
   13542     4007662 :   if (*raw_filter == '*') return true;
   13543     1508807 :   String* name = DebugName();
   13544     1508812 :   Vector<const char> filter = CStrVector(raw_filter);
   13545     1508812 :   if (filter.length() == 0) return name->length() == 0;
   13546     1508812 :   if (filter[0] == '-') {
   13547             :     // Negative filter.
   13548           0 :     if (filter.length() == 1) {
   13549           0 :       return (name->length() != 0);
   13550           0 :     } else if (name->IsUtf8EqualTo(filter.SubVector(1, filter.length()))) {
   13551             :       return false;
   13552             :     }
   13553           0 :     if (filter[filter.length() - 1] == '*' &&
   13554           0 :         name->IsUtf8EqualTo(filter.SubVector(1, filter.length() - 1), true)) {
   13555             :       return false;
   13556             :     }
   13557           0 :     return true;
   13558             : 
   13559     1508812 :   } else if (name->IsUtf8EqualTo(filter)) {
   13560             :     return true;
   13561             :   }
   13562     3017053 :   if (filter[filter.length() - 1] == '*' &&
   13563         125 :       name->IsUtf8EqualTo(filter.SubVector(0, filter.length() - 1), true)) {
   13564             :     return true;
   13565             :   }
   13566     1508388 :   return false;
   13567             : }
   13568             : 
   13569    14230772 : bool SharedFunctionInfo::HasSourceCode() const {
   13570             :   Isolate* isolate = GetIsolate();
   13571    28461537 :   return !script()->IsUndefined(isolate) &&
   13572    14230772 :          !reinterpret_cast<Script*>(script())->source()->IsUndefined(isolate);
   13573             : }
   13574             : 
   13575             : 
   13576     1049488 : Handle<Object> SharedFunctionInfo::GetSourceCode() {
   13577     1049488 :   if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value();
   13578             :   Handle<String> source(String::cast(Script::cast(script())->source()));
   13579             :   return GetIsolate()->factory()->NewSubString(
   13580     1049488 :       source, start_position(), end_position());
   13581             : }
   13582             : 
   13583        1260 : Handle<Object> SharedFunctionInfo::GetSourceCodeHarmony() {
   13584             :   Isolate* isolate = GetIsolate();
   13585        1260 :   if (!HasSourceCode()) return isolate->factory()->undefined_value();
   13586             :   Handle<String> script_source(String::cast(Script::cast(script())->source()));
   13587             :   int start_pos = function_token_position();
   13588        1260 :   if (start_pos == kNoSourcePosition) start_pos = start_position();
   13589             :   return isolate->factory()->NewSubString(script_source, start_pos,
   13590        1260 :                                           end_position());
   13591             : }
   13592             : 
   13593      180640 : bool SharedFunctionInfo::IsInlineable() {
   13594             :   // Check that the function has a script associated with it.
   13595      180640 :   if (!script()->IsScript()) return false;
   13596      180652 :   if (GetIsolate()->is_precise_binary_code_coverage() &&
   13597             :       !has_reported_binary_coverage()) {
   13598             :     // We may miss invocations if this function is inlined.
   13599             :     return false;
   13600             :   }
   13601      180640 :   return !optimization_disabled();
   13602             : }
   13603             : 
   13604      151655 : int SharedFunctionInfo::SourceSize() {
   13605      151655 :   return end_position() - start_position();
   13606             : }
   13607             : 
   13608      710169 : void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type,
   13609             :                                              int requested_embedder_fields,
   13610             :                                              int requested_in_object_properties,
   13611             :                                              int* instance_size,
   13612             :                                              int* in_object_properties) {
   13613      710169 :   int header_size = JSObject::GetHeaderSize(instance_type);
   13614             :   DCHECK_LE(requested_embedder_fields,
   13615             :             (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2);
   13616             :   *instance_size =
   13617             :       Min(header_size +
   13618      710169 :               ((requested_embedder_fields + requested_in_object_properties)
   13619      710169 :                << kPointerSizeLog2),
   13620     1420338 :           JSObject::kMaxInstanceSize);
   13621      710169 :   *in_object_properties = ((*instance_size - header_size) >> kPointerSizeLog2) -
   13622      710169 :                           requested_embedder_fields;
   13623      710169 : }
   13624             : 
   13625        9296 : void JSFunction::CalculateInstanceSizeForDerivedClass(
   13626             :     Handle<JSFunction> function, InstanceType instance_type,
   13627             :     int requested_embedder_fields, int* instance_size,
   13628             :     int* in_object_properties) {
   13629             :   Isolate* isolate = function->GetIsolate();
   13630             :   int expected_nof_properties = 0;
   13631       38548 :   for (PrototypeIterator iter(isolate, function, kStartAtReceiver);
   13632       19956 :        !iter.IsAtEnd(); iter.Advance()) {
   13633             :     Handle<JSReceiver> current =
   13634             :         PrototypeIterator::GetCurrent<JSReceiver>(iter);
   13635       29252 :     if (!current->IsJSFunction()) break;
   13636             :     Handle<JSFunction> func(Handle<JSFunction>::cast(current));
   13637             :     // The super constructor should be compiled for the number of expected
   13638             :     // properties to be available.
   13639             :     Handle<SharedFunctionInfo> shared(func->shared());
   13640       29532 :     if (shared->is_compiled() ||
   13641         295 :         Compiler::Compile(func, Compiler::CLEAR_EXCEPTION)) {
   13642             :       DCHECK(shared->is_compiled());
   13643       29237 :       expected_nof_properties += shared->expected_nof_properties();
   13644             :     }
   13645       29237 :     if (!IsDerivedConstructor(shared->kind())) {
   13646             :       break;
   13647             :     }
   13648             :   }
   13649             :   CalculateInstanceSizeHelper(instance_type, requested_embedder_fields,
   13650             :                               expected_nof_properties, instance_size,
   13651        9296 :                               in_object_properties);
   13652        9296 : }
   13653             : 
   13654             : 
   13655             : // Output the source code without any allocation in the heap.
   13656          21 : std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) {
   13657          21 :   const SharedFunctionInfo* s = v.value;
   13658             :   // For some native functions there is no source.
   13659          21 :   if (!s->HasSourceCode()) return os << "<No Source>";
   13660             : 
   13661             :   // Get the source for the script which this function came from.
   13662             :   // Don't use String::cast because we don't want more assertion errors while
   13663             :   // we are already creating a stack dump.
   13664             :   String* script_source =
   13665             :       reinterpret_cast<String*>(Script::cast(s->script())->source());
   13666             : 
   13667          14 :   if (!script_source->LooksValid()) return os << "<Invalid Source>";
   13668             : 
   13669          14 :   if (!s->is_toplevel()) {
   13670          14 :     os << "function ";
   13671             :     Object* name = s->name();
   13672          28 :     if (name->IsString() && String::cast(name)->length() > 0) {
   13673          14 :       String::cast(name)->PrintUC16(os);
   13674             :     }
   13675             :   }
   13676             : 
   13677          14 :   int len = s->end_position() - s->start_position();
   13678          14 :   if (len <= v.max_length || v.max_length < 0) {
   13679          14 :     script_source->PrintUC16(os, s->start_position(), s->end_position());
   13680          14 :     return os;
   13681             :   } else {
   13682             :     script_source->PrintUC16(os, s->start_position(),
   13683           0 :                              s->start_position() + v.max_length);
   13684           0 :     return os << "...\n";
   13685             :   }
   13686             : }
   13687             : 
   13688             : 
   13689      231775 : static bool IsCodeEquivalent(Code* code, Code* recompiled) {
   13690      231775 :   if (code->instruction_size() != recompiled->instruction_size()) return false;
   13691             :   ByteArray* code_relocation = code->relocation_info();
   13692             :   ByteArray* recompiled_relocation = recompiled->relocation_info();
   13693             :   int length = code_relocation->length();
   13694      228705 :   if (length != recompiled_relocation->length()) return false;
   13695      228705 :   int compare = memcmp(code_relocation->GetDataStartAddress(),
   13696      228705 :                        recompiled_relocation->GetDataStartAddress(),
   13697      457410 :                        length);
   13698      228705 :   return compare == 0;
   13699             : }
   13700             : 
   13701             : 
   13702      231775 : void SharedFunctionInfo::EnableDeoptimizationSupport(Code* recompiled) {
   13703             :   DCHECK(!has_deoptimization_support());
   13704             :   DisallowHeapAllocation no_allocation;
   13705             :   Code* code = this->code();
   13706      231775 :   if (IsCodeEquivalent(code, recompiled)) {
   13707             :     // Copy the deoptimization data from the recompiled code.
   13708      228705 :     code->set_deoptimization_data(recompiled->deoptimization_data());
   13709             :     code->set_has_deoptimization_support(true);
   13710             :   } else {
   13711             :     // TODO(3025757): In case the recompiled isn't equivalent to the
   13712             :     // old code, we have to replace it. We should try to avoid this
   13713             :     // altogether because it flushes valuable type feedback by
   13714             :     // effectively resetting all IC state.
   13715        3070 :     ReplaceCode(recompiled);
   13716             :   }
   13717             :   DCHECK(has_deoptimization_support());
   13718      231775 : }
   13719             : 
   13720             : 
   13721       57075 : void SharedFunctionInfo::DisableOptimization(BailoutReason reason) {
   13722             :   // Disable optimization for the shared function info and mark the
   13723             :   // code as non-optimizable. The marker on the shared function info
   13724             :   // is there because we flush non-optimized code thereby loosing the
   13725             :   // non-optimizable information for the code. When the code is
   13726             :   // regenerated and set on the shared function info it is marked as
   13727             :   // non-optimizable if optimization is disabled for the shared
   13728             :   // function info.
   13729             :   DCHECK(reason != kNoReason);
   13730             :   set_optimization_disabled(true);
   13731             :   set_disable_optimization_reason(reason);
   13732             :   // Code should be the lazy compilation stub or else unoptimized.
   13733             :   DCHECK(abstract_code()->kind() == AbstractCode::FUNCTION ||
   13734             :          abstract_code()->kind() == AbstractCode::INTERPRETED_FUNCTION ||
   13735             :          abstract_code()->kind() == AbstractCode::BUILTIN);
   13736       57075 :   PROFILE(GetIsolate(), CodeDisableOptEvent(abstract_code(), this));
   13737       57075 :   if (FLAG_trace_opt) {
   13738           0 :     PrintF("[disabled optimization for ");
   13739           0 :     ShortPrint();
   13740           0 :     PrintF(", reason: %s]\n", GetBailoutReason(reason));
   13741             :   }
   13742       57075 : }
   13743             : 
   13744     6235385 : void SharedFunctionInfo::InitFromFunctionLiteral(
   13745    54611820 :     Handle<SharedFunctionInfo> shared_info, FunctionLiteral* lit) {
   13746             :   // When adding fields here, make sure DeclarationScope::AnalyzePartially is
   13747             :   // updated accordingly.
   13748             :   shared_info->set_internal_formal_parameter_count(lit->parameter_count());
   13749             :   shared_info->set_function_token_position(lit->function_token_position());
   13750     6235385 :   shared_info->set_start_position(lit->start_position());
   13751     6235387 :   shared_info->set_end_position(lit->end_position());
   13752             :   shared_info->set_is_declaration(lit->is_declaration());
   13753             :   shared_info->set_is_named_expression(lit->is_named_expression());
   13754     6235390 :   shared_info->set_is_anonymous_expression(lit->is_anonymous_expression());
   13755    12470779 :   shared_info->set_inferred_name(*lit->inferred_name());
   13756     6235391 :   shared_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
   13757     6235386 :   shared_info->set_language_mode(lit->language_mode());
   13758     6235391 :   shared_info->set_uses_arguments(lit->scope()->arguments() != NULL);
   13759     6235391 :   shared_info->set_kind(lit->kind());
   13760     6235394 :   if (!IsConstructable(lit->kind())) {
   13761             :     shared_info->SetConstructStub(
   13762      934422 :         *shared_info->GetIsolate()->builtins()->ConstructedNonConstructable());
   13763             :   }
   13764     6235393 :   shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject());
   13765             :   shared_info->set_asm_function(lit->scope()->asm_function());
   13766             :   shared_info->set_function_literal_id(lit->function_literal_id());
   13767             : 
   13768             :   // For lazy parsed functions, the following flags will be inaccurate since we
   13769             :   // don't have the information yet. They're set later in
   13770             :   // SetSharedFunctionFlagsFromLiteral (compiler.cc), when the function is
   13771             :   // really parsed and compiled.
   13772     6235394 :   if (lit->body() != nullptr) {
   13773             :     shared_info->set_length(lit->function_length());
   13774             :     shared_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
   13775             :     shared_info->SetExpectedNofPropertiesFromEstimate(lit);
   13776             :   } else {
   13777             :     // Set an invalid length for lazy functions. This way we can set the correct
   13778             :     // value after compiling, but avoid overwriting values set manually by the
   13779             :     // bootstrapper.
   13780             :     shared_info->set_length(SharedFunctionInfo::kInvalidLength);
   13781             :   }
   13782     6235394 : }
   13783             : 
   13784     3341373 : void SharedFunctionInfo::SetExpectedNofPropertiesFromEstimate(
   13785     8823415 :     FunctionLiteral* literal) {
   13786             :   int estimate = literal->expected_property_count();
   13787             : 
   13788             :   // If no properties are added in the constructor, they are more likely
   13789             :   // to be added later.
   13790     8823415 :   if (estimate == 0) estimate = 2;
   13791             : 
   13792             :   // Inobject slack tracking will reclaim redundant inobject space later,
   13793             :   // so we can afford to adjust the estimate generously.
   13794     8823415 :   estimate += 8;
   13795             : 
   13796             :   set_expected_nof_properties(estimate);
   13797     3341373 : }
   13798             : 
   13799           0 : bool SharedFunctionInfo::VerifyBailoutId(BailoutId id) {
   13800             :   DCHECK(!id.IsNone());
   13801             :   Code* unoptimized = code();
   13802             :   DeoptimizationOutputData* data =
   13803             :       DeoptimizationOutputData::cast(unoptimized->deoptimization_data());
   13804           0 :   unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this);
   13805             :   USE(ignore);
   13806           0 :   return true;  // Return true if there was no DCHECK.
   13807             : }
   13808             : 
   13809    14906648 : void SharedFunctionInfo::SetConstructStub(Code* code) {
   13810    14906648 :   if (code->kind() == Code::BUILTIN) code->set_is_construct_stub(true);
   13811    14906648 :   set_construct_stub(code);
   13812    14906655 : }
   13813             : 
   13814           0 : void Map::StartInobjectSlackTracking() {
   13815             :   DCHECK(!IsInobjectSlackTrackingInProgress());
   13816      499405 :   if (unused_property_fields() == 0) return;
   13817             :   set_construction_counter(Map::kSlackTrackingCounterStart);
   13818             : }
   13819             : 
   13820             : 
   13821     4504657 : void SharedFunctionInfo::ResetForNewContext(int new_ic_age) {
   13822     4504657 :   code()->ClearInlineCaches();
   13823             :   set_ic_age(new_ic_age);
   13824     4504677 :   if (code()->kind() == Code::FUNCTION) {
   13825             :     code()->set_profiler_ticks(0);
   13826        9714 :     if (optimization_disabled() && deopt_count() >= FLAG_max_deopt_count) {
   13827             :       // Re-enable optimizations if they were disabled due to deopt_count limit.
   13828             :       set_optimization_disabled(false);
   13829             :     }
   13830             :     set_opt_count(0);
   13831             :     set_deopt_count(0);
   13832     4495068 :   } else if (IsInterpreted()) {
   13833             :     set_profiler_ticks(0);
   13834       28230 :     if (optimization_disabled() && deopt_count() >= FLAG_max_deopt_count) {
   13835             :       // Re-enable optimizations if they were disabled due to deopt_count limit.
   13836             :       set_optimization_disabled(false);
   13837             :     }
   13838             :     set_opt_count(0);
   13839             :     set_deopt_count(0);
   13840             :   }
   13841     4504678 : }
   13842             : 
   13843    27990209 : int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context) {
   13844             :   DisallowHeapAllocation no_gc;
   13845             :   DCHECK(native_context->IsNativeContext());
   13846    27990209 :   if (!OptimizedCodeMapIsCleared()) {
   13847             :     FixedArray* optimized_code_map = this->optimized_code_map();
   13848             :     int length = optimized_code_map->length();
   13849     1902474 :     for (int i = kEntriesStart; i < length; i += kEntryLength) {
   13850     1647429 :       if (WeakCell::cast(optimized_code_map->get(i + kContextOffset))
   13851             :               ->value() == native_context) {
   13852             :         return i;
   13853             :       }
   13854             :     }
   13855             :   }
   13856             :   return -1;
   13857             : }
   13858             : 
   13859    16588750 : void SharedFunctionInfo::ClearCodeFromOptimizedCodeMap() {
   13860    16588750 :   if (!OptimizedCodeMapIsCleared()) {
   13861             :     FixedArray* optimized_code_map = this->optimized_code_map();
   13862             :     int length = optimized_code_map->length();
   13863      126857 :     WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell();
   13864      254875 :     for (int i = kEntriesStart; i < length; i += kEntryLength) {
   13865             :       optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell,
   13866      128018 :                               SKIP_WRITE_BARRIER);
   13867             :     }
   13868             :   }
   13869    16588750 : }
   13870             : 
   13871    27957392 : Code* SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
   13872             :                                                  BailoutId osr_ast_id) {
   13873             :   Code* result = nullptr;
   13874    27957392 :   if (!osr_ast_id.IsNone()) {
   13875        8477 :     return native_context->SearchOptimizedCodeMap(this, osr_ast_id);
   13876             :   }
   13877             : 
   13878             :   DCHECK(osr_ast_id.IsNone());
   13879    27948915 :   int entry = SearchOptimizedCodeMapEntry(native_context);
   13880    27948919 :   if (entry != kNotFound) {
   13881             :     FixedArray* code_map = optimized_code_map();
   13882             :     DCHECK_LE(entry + kEntryLength, code_map->length());
   13883      916935 :     WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset));
   13884      916935 :     result = cell->cleared() ? nullptr : Code::cast(cell->value());
   13885             :   }
   13886    27948919 :   return result;
   13887             : }
   13888             : 
   13889    14306693 : void ObjectVisitor::VisitCodeTarget(Code* host, RelocInfo* rinfo) {
   13890             :   DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
   13891    14306693 :   Object* old_pointer = Code::GetCodeFromTargetAddress(rinfo->target_address());
   13892    14306693 :   Object* new_pointer = old_pointer;
   13893    14306693 :   VisitPointer(host, &new_pointer);
   13894             :   DCHECK_EQ(old_pointer, new_pointer);
   13895    14306693 : }
   13896             : 
   13897           0 : void ObjectVisitor::VisitCodeAgeSequence(Code* host, RelocInfo* rinfo) {
   13898             :   DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
   13899             :   Object* old_pointer = rinfo->code_age_stub();
   13900           0 :   Object* new_pointer = old_pointer;
   13901           0 :   if (old_pointer != nullptr) {
   13902           0 :     VisitPointer(host, &new_pointer);
   13903             :     DCHECK_EQ(old_pointer, new_pointer);
   13904             :   }
   13905           0 : }
   13906             : 
   13907     2925048 : void ObjectVisitor::VisitCodeEntry(JSFunction* host, Address entry_address) {
   13908     2925048 :   Object* old_pointer = Code::GetObjectFromEntryAddress(entry_address);
   13909     2925048 :   Object* new_pointer = old_pointer;
   13910     2925048 :   VisitPointer(host, &new_pointer);
   13911             :   DCHECK_EQ(old_pointer, new_pointer);
   13912     2925048 : }
   13913             : 
   13914        3364 : void ObjectVisitor::VisitCellPointer(Code* host, RelocInfo* rinfo) {
   13915             :   DCHECK(rinfo->rmode() == RelocInfo::CELL);
   13916             :   Object* old_pointer = rinfo->target_cell();
   13917        3364 :   Object* new_pointer = old_pointer;
   13918        3364 :   VisitPointer(host, &new_pointer);
   13919             :   DCHECK_EQ(old_pointer, new_pointer);
   13920        3364 : }
   13921             : 
   13922          12 : void ObjectVisitor::VisitDebugTarget(Code* host, RelocInfo* rinfo) {
   13923             :   DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
   13924             :          rinfo->IsPatchedDebugBreakSlotSequence());
   13925             :   Object* old_pointer =
   13926          12 :       Code::GetCodeFromTargetAddress(rinfo->debug_call_address());
   13927          12 :   Object* new_pointer = old_pointer;
   13928          12 :   VisitPointer(host, &new_pointer);
   13929             :   DCHECK_EQ(old_pointer, new_pointer);
   13930          12 : }
   13931             : 
   13932     2081999 : void ObjectVisitor::VisitEmbeddedPointer(Code* host, RelocInfo* rinfo) {
   13933             :   DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
   13934             :   Object* old_pointer = rinfo->target_object();
   13935     2081999 :   Object* new_pointer = old_pointer;
   13936     2081999 :   VisitPointer(host, &new_pointer);
   13937             :   DCHECK_EQ(old_pointer, new_pointer);
   13938     2081999 : }
   13939             : 
   13940             : 
   13941      422165 : void Code::InvalidateRelocation() {
   13942      422165 :   InvalidateEmbeddedObjects();
   13943      422165 :   set_relocation_info(GetHeap()->empty_byte_array());
   13944      422165 : }
   13945             : 
   13946             : 
   13947      427482 : void Code::InvalidateEmbeddedObjects() {
   13948      427482 :   HeapObject* undefined = GetHeap()->undefined_value();
   13949      427482 :   Cell* undefined_cell = GetHeap()->undefined_cell();
   13950             :   int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
   13951             :                   RelocInfo::ModeMask(RelocInfo::CELL);
   13952     4934406 :   for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
   13953     4506924 :     RelocInfo::Mode mode = it.rinfo()->rmode();
   13954     4506924 :     if (mode == RelocInfo::EMBEDDED_OBJECT) {
   13955             :       it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER);
   13956           0 :     } else if (mode == RelocInfo::CELL) {
   13957             :       it.rinfo()->set_target_cell(undefined_cell, SKIP_WRITE_BARRIER);
   13958             :     }
   13959             :   }
   13960      427482 : }
   13961             : 
   13962             : 
   13963      183290 : void Code::Relocate(intptr_t delta) {
   13964      191645 :   if (trap_handler::UseTrapHandler() && is_wasm_code()) {
   13965             :     const int index = trap_handler_index()->value();
   13966        2299 :     if (index >= 0) {
   13967          42 :       trap_handler::UpdateHandlerDataCodePointer(index, instruction_start());
   13968             :     }
   13969             :   }
   13970      706338 :   for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
   13971             :     it.rinfo()->apply(delta);
   13972             :   }
   13973      366578 :   Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size());
   13974      183290 : }
   13975             : 
   13976             : 
   13977     2555735 : void Code::CopyFrom(const CodeDesc& desc) {
   13978             :   // copy code
   13979             :   CopyBytes(instruction_start(), desc.buffer,
   13980     2555735 :             static_cast<size_t>(desc.instr_size));
   13981             : 
   13982             :   // copy unwinding info, if any
   13983     2555721 :   if (desc.unwinding_info) {
   13984             :     DCHECK_GT(desc.unwinding_info_size, 0);
   13985          25 :     set_unwinding_info_size(desc.unwinding_info_size);
   13986             :     CopyBytes(unwinding_info_start(), desc.unwinding_info,
   13987          25 :               static_cast<size_t>(desc.unwinding_info_size));
   13988             :   }
   13989             : 
   13990             :   // copy reloc info
   13991             :   CopyBytes(relocation_start(),
   13992     2555721 :             desc.buffer + desc.buffer_size - desc.reloc_size,
   13993     7667163 :             static_cast<size_t>(desc.reloc_size));
   13994             : 
   13995             :   // unbox handles and relocate
   13996             :   int mode_mask = RelocInfo::kCodeTargetMask |
   13997             :                   RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
   13998             :                   RelocInfo::ModeMask(RelocInfo::CELL) |
   13999     2555735 :                   RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
   14000     2555735 :                   RelocInfo::kApplyMask;
   14001             :   // Needed to find target_object and runtime_entry on X64
   14002     2555735 :   Assembler* origin = desc.origin;
   14003             :   AllowDeferredHandleDereference embedding_raw_address;
   14004    37669396 :   for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
   14005    35113628 :     RelocInfo::Mode mode = it.rinfo()->rmode();
   14006    35113628 :     if (mode == RelocInfo::EMBEDDED_OBJECT) {
   14007    16196461 :       Handle<HeapObject> p = it.rinfo()->target_object_handle(origin);
   14008             :       it.rinfo()->set_target_object(*p, UPDATE_WRITE_BARRIER,
   14009             :                                     SKIP_ICACHE_FLUSH);
   14010    18917167 :     } else if (mode == RelocInfo::CELL) {
   14011       38676 :       Handle<Cell> cell  = it.rinfo()->target_cell_handle();
   14012             :       it.rinfo()->set_target_cell(*cell, UPDATE_WRITE_BARRIER,
   14013             :                                   SKIP_ICACHE_FLUSH);
   14014    18878491 :     } else if (RelocInfo::IsCodeTarget(mode)) {
   14015             :       // rewrite code handles to direct pointers to the first instruction in the
   14016             :       // code object
   14017    17875870 :       Handle<Object> p = it.rinfo()->target_object_handle(origin);
   14018             :       Code* code = Code::cast(*p);
   14019             :       it.rinfo()->set_target_address(GetIsolate(), code->instruction_start(),
   14020    35751748 :                                      UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
   14021     1002621 :     } else if (RelocInfo::IsRuntimeEntry(mode)) {
   14022      889879 :       Address p = it.rinfo()->target_runtime_entry(origin);
   14023             :       it.rinfo()->set_target_runtime_entry(
   14024             :           GetIsolate(), p, UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
   14025      112742 :     } else if (mode == RelocInfo::CODE_AGE_SEQUENCE) {
   14026          14 :       Handle<Object> p = it.rinfo()->code_age_stub_handle(origin);
   14027             :       Code* code = Code::cast(*p);
   14028          14 :       it.rinfo()->set_code_age_stub(code, SKIP_ICACHE_FLUSH);
   14029             :     } else {
   14030      112728 :       intptr_t delta = instruction_start() - desc.buffer;
   14031             :       it.rinfo()->apply(delta);
   14032             :     }
   14033             :   }
   14034     5111498 :   Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size());
   14035     2555741 : }
   14036             : 
   14037             : 
   14038     1732479 : SafepointEntry Code::GetSafepointEntry(Address pc) {
   14039     1732479 :   SafepointTable table(this);
   14040     1732479 :   return table.FindEntry(pc);
   14041             : }
   14042             : 
   14043             : 
   14044      830620 : Object* Code::FindNthObject(int n, Map* match_map) {
   14045             :   DCHECK(is_inline_cache_stub());
   14046             :   DisallowHeapAllocation no_allocation;
   14047             :   int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
   14048     1328530 :   for (RelocIterator it(this, mask); !it.done(); it.next()) {
   14049      573900 :     RelocInfo* info = it.rinfo();
   14050             :     Object* object = info->target_object();
   14051      573900 :     if (object->IsWeakCell()) object = WeakCell::cast(object)->value();
   14052      573900 :     if (object->IsHeapObject()) {
   14053      573900 :       if (HeapObject::cast(object)->map() == match_map) {
   14054       75990 :         if (--n == 0) return object;
   14055             :       }
   14056             :     }
   14057             :   }
   14058      754630 :   return NULL;
   14059             : }
   14060             : 
   14061             : 
   14062      382406 : AllocationSite* Code::FindFirstAllocationSite() {
   14063      382406 :   Object* result = FindNthObject(1, GetHeap()->allocation_site_map());
   14064      382406 :   return (result != NULL) ? AllocationSite::cast(result) : NULL;
   14065             : }
   14066             : 
   14067             : 
   14068      448214 : Map* Code::FindFirstMap() {
   14069      448214 :   Object* result = FindNthObject(1, GetHeap()->meta_map());
   14070      448214 :   return (result != NULL) ? Map::cast(result) : NULL;
   14071             : }
   14072             : 
   14073             : 
   14074       46824 : void Code::FindAndReplace(const FindAndReplacePattern& pattern) {
   14075             :   DCHECK(is_inline_cache_stub() || is_handler());
   14076             :   DisallowHeapAllocation no_allocation;
   14077             :   int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
   14078             :   STATIC_ASSERT(FindAndReplacePattern::kMaxCount < 32);
   14079             :   int current_pattern = 0;
   14080       46824 :   for (RelocIterator it(this, mask); !it.done(); it.next()) {
   14081       46824 :     RelocInfo* info = it.rinfo();
   14082             :     HeapObject* object = info->target_object();
   14083       46824 :     if (object->IsWeakCell()) {
   14084             :       object = HeapObject::cast(WeakCell::cast(object)->value());
   14085             :     }
   14086             :     Map* map = object->map();
   14087       93648 :     if (map == *pattern.find_[current_pattern]) {
   14088       46824 :       info->set_target_object(*pattern.replace_[current_pattern]);
   14089       93648 :       if (++current_pattern == pattern.count_) return;
   14090             :     }
   14091             :   }
   14092           0 :   UNREACHABLE();
   14093             : }
   14094             : 
   14095             : 
   14096     4538737 : void Code::ClearInlineCaches() {
   14097             :   int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
   14098             :              RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
   14099    19743720 :   for (RelocIterator it(this, mask); !it.done(); it.next()) {
   14100    15204984 :     RelocInfo* info = it.rinfo();
   14101             :     Code* target(Code::GetCodeFromTargetAddress(info->target_address()));
   14102    15204983 :     if (target->is_inline_cache_stub()) {
   14103             :       ICUtility::Clear(this->GetIsolate(), info->pc(),
   14104      132634 :                        info->host()->constant_pool());
   14105             :     }
   14106             :   }
   14107     4538756 : }
   14108             : 
   14109             : namespace {
   14110             : template <typename Code>
   14111        9579 : void SetStackFrameCacheCommon(Handle<Code> code,
   14112             :                               Handle<UnseededNumberDictionary> cache) {
   14113             :   Handle<Object> maybe_table(code->source_position_table(), code->GetIsolate());
   14114        9579 :   if (maybe_table->IsSourcePositionTableWithFrameCache()) {
   14115         638 :     Handle<SourcePositionTableWithFrameCache>::cast(maybe_table)
   14116             :         ->set_stack_frame_cache(*cache);
   14117       10217 :     return;
   14118             :   }
   14119             :   DCHECK(maybe_table->IsByteArray());
   14120        8941 :   Handle<ByteArray> table(Handle<ByteArray>::cast(maybe_table));
   14121             :   Handle<SourcePositionTableWithFrameCache> table_with_cache =
   14122             :       code->GetIsolate()->factory()->NewSourcePositionTableWithFrameCache(
   14123        8941 :           table, cache);
   14124        8941 :   code->set_source_position_table(*table_with_cache);
   14125             : }
   14126             : }  // namespace
   14127             : 
   14128             : // static
   14129        9579 : void AbstractCode::SetStackFrameCache(Handle<AbstractCode> abstract_code,
   14130             :                                       Handle<UnseededNumberDictionary> cache) {
   14131        9579 :   if (abstract_code->IsCode()) {
   14132        2902 :     SetStackFrameCacheCommon(handle(abstract_code->GetCode()), cache);
   14133             :   } else {
   14134        6677 :     SetStackFrameCacheCommon(handle(abstract_code->GetBytecodeArray()), cache);
   14135             :   }
   14136        9579 : }
   14137             : 
   14138             : namespace {
   14139             : template <typename Code>
   14140     8951201 : void DropStackFrameCacheCommon(Code* code) {
   14141             :   i::Object* maybe_table = code->source_position_table();
   14142    17902402 :   if (maybe_table->IsByteArray()) return;
   14143             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
   14144           0 :   code->set_source_position_table(
   14145             :       i::SourcePositionTableWithFrameCache::cast(maybe_table)
   14146             :           ->source_position_table());
   14147             : }
   14148             : }  // namespace
   14149             : 
   14150     8951201 : void AbstractCode::DropStackFrameCache() {
   14151     8951201 :   if (IsCode()) {
   14152     8940848 :     DropStackFrameCacheCommon(GetCode());
   14153             :   } else {
   14154       10353 :     DropStackFrameCacheCommon(GetBytecodeArray());
   14155             :   }
   14156     8951201 : }
   14157             : 
   14158     2061453 : int AbstractCode::SourcePosition(int offset) {
   14159             :   int position = 0;
   14160             :   // Subtract one because the current PC is one instruction after the call site.
   14161     2061453 :   if (IsCode()) offset--;
   14162    68753637 :   for (SourcePositionTableIterator iterator(source_position_table());
   14163    66692184 :        !iterator.done() && iterator.code_offset() <= offset;
   14164    64630731 :        iterator.Advance()) {
   14165    64630731 :     position = iterator.source_position().ScriptOffset();
   14166             :   }
   14167     2061453 :   return position;
   14168             : }
   14169             : 
   14170      155428 : int AbstractCode::SourceStatementPosition(int offset) {
   14171             :   // First find the closest position.
   14172      155428 :   int position = SourcePosition(offset);
   14173             :   // Now find the closest statement position before the position.
   14174             :   int statement_position = 0;
   14175    25648069 :   for (SourcePositionTableIterator it(source_position_table()); !it.done();
   14176    25337213 :        it.Advance()) {
   14177    25337213 :     if (it.is_statement()) {
   14178    10862058 :       int p = it.source_position().ScriptOffset();
   14179    10862058 :       if (statement_position < p && p <= position) {
   14180             :         statement_position = p;
   14181             :       }
   14182             :     }
   14183             :   }
   14184      155428 :   return statement_position;
   14185             : }
   14186             : 
   14187      245079 : void JSFunction::ClearTypeFeedbackInfo() {
   14188      245079 :   if (feedback_vector_cell()->value()->IsFeedbackVector()) {
   14189             :     FeedbackVector* vector = feedback_vector();
   14190       92298 :     vector->ClearSlots(this);
   14191             :   }
   14192      245079 : }
   14193             : 
   14194        2641 : BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) {
   14195             :   DisallowHeapAllocation no_gc;
   14196             :   DCHECK(kind() == FUNCTION);
   14197             :   BackEdgeTable back_edges(this, &no_gc);
   14198        3625 :   for (uint32_t i = 0; i < back_edges.length(); i++) {
   14199        3625 :     if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i);
   14200             :   }
   14201             :   return BailoutId::None();
   14202             : }
   14203             : 
   14204             : 
   14205           0 : uint32_t Code::TranslateAstIdToPcOffset(BailoutId ast_id) {
   14206             :   DisallowHeapAllocation no_gc;
   14207             :   DCHECK(kind() == FUNCTION);
   14208             :   BackEdgeTable back_edges(this, &no_gc);
   14209           0 :   for (uint32_t i = 0; i < back_edges.length(); i++) {
   14210           0 :     if (back_edges.ast_id(i) == ast_id) return back_edges.pc_offset(i);
   14211             :   }
   14212           0 :   UNREACHABLE();  // We expect to find the back edge.
   14213             :   return 0;
   14214             : }
   14215             : 
   14216      656095 : void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) {
   14217      656451 :   PatchPlatformCodeAge(isolate, sequence, kNoAgeCodeAge);
   14218      656095 : }
   14219             : 
   14220             : 
   14221          15 : void Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) {
   14222          15 :   PatchPlatformCodeAge(isolate, sequence, kExecutedOnceCodeAge);
   14223          15 : }
   14224             : 
   14225             : 
   14226             : // NextAge defines the Code::Age state transitions during a GC cycle.
   14227             : static Code::Age NextAge(Code::Age age) {
   14228     1179528 :   switch (age) {
   14229             :     case Code::kNotExecutedCodeAge:  // Keep, until we've been executed.
   14230             :     case Code::kToBeExecutedOnceCodeAge:  // Keep, until we've been executed.
   14231             :     case Code::kLastCodeAge:  // Clamp at last Code::Age value.
   14232             :       return age;
   14233             :     case Code::kExecutedOnceCodeAge:
   14234             :       // Pre-age code that has only been executed once.
   14235             :       return static_cast<Code::Age>(Code::kPreAgedCodeAge + 1);
   14236             :     default:
   14237     1010995 :       return static_cast<Code::Age>(age + 1);  // Default case: Increase age.
   14238             :   }
   14239             : }
   14240             : 
   14241             : 
   14242             : // IsOldAge defines the collection criteria for a Code object.
   14243             : static bool IsOldAge(Code::Age age) {
   14244    14061002 :   return age >= Code::kIsOldCodeAge || age == Code::kNotExecutedCodeAge;
   14245             : }
   14246             : 
   14247             : 
   14248      207516 : void Code::MakeYoung(Isolate* isolate) {
   14249      207516 :   byte* sequence = FindCodeAgeSequence();
   14250      207516 :   if (sequence != NULL) MakeCodeAgeSequenceYoung(sequence, isolate);
   14251      207516 : }
   14252             : 
   14253           6 : void Code::PreAge(Isolate* isolate) {
   14254           6 :   byte* sequence = FindCodeAgeSequence();
   14255           6 :   if (sequence != NULL) {
   14256           6 :     PatchPlatformCodeAge(isolate, sequence, kPreAgedCodeAge);
   14257             :   }
   14258           6 : }
   14259             : 
   14260          48 : void Code::MarkToBeExecutedOnce(Isolate* isolate) {
   14261          48 :   byte* sequence = FindCodeAgeSequence();
   14262          48 :   if (sequence != NULL) {
   14263          12 :     PatchPlatformCodeAge(isolate, sequence, kToBeExecutedOnceCodeAge);
   14264             :   }
   14265          48 : }
   14266             : 
   14267    74612653 : void Code::MakeOlder() {
   14268    74612653 :   byte* sequence = FindCodeAgeSequence();
   14269    74612666 :   if (sequence != NULL) {
   14270             :     Isolate* isolate = GetIsolate();
   14271     1179528 :     Age age = GetCodeAge(isolate, sequence);
   14272             :     Age next_age = NextAge(age);
   14273     1179528 :     if (age != next_age) {
   14274     1011003 :       PatchPlatformCodeAge(isolate, sequence, next_age);
   14275             :     }
   14276             :   }
   14277    74612666 : }
   14278             : 
   14279             : 
   14280    13882333 : bool Code::IsOld() {
   14281    27943335 :   return IsOldAge(GetAge());
   14282             : }
   14283             : 
   14284             : 
   14285   177813255 : byte* Code::FindCodeAgeSequence() {
   14286   177813290 :   return FLAG_age_code &&
   14287   113043475 :       prologue_offset() != Code::kPrologueOffsetNotSet &&
   14288   110748328 :       (kind() == OPTIMIZED_FUNCTION ||
   14289     4521432 :        (kind() == FUNCTION && !has_debug_break_slots()))
   14290     6303546 :       ? instruction_start() + prologue_offset()
   14291   184116801 :       : NULL;
   14292             : }
   14293             : 
   14294             : 
   14295    14061008 : Code::Age Code::GetAge() {
   14296    14061008 :   byte* sequence = FindCodeAgeSequence();
   14297    14061008 :   if (sequence == NULL) {
   14298             :     return kNoAgeCodeAge;
   14299             :   }
   14300      635994 :   return GetCodeAge(GetIsolate(), sequence);
   14301             : }
   14302             : 
   14303      623965 : Code::Age Code::GetAgeOfCodeAgeStub(Code* code) {
   14304             :   Isolate* isolate = code->GetIsolate();
   14305      623965 :   Builtins* builtins = isolate->builtins();
   14306             : #define HANDLE_CODE_AGE(AGE)                            \
   14307             :   if (code == *builtins->Make##AGE##CodeYoungAgain()) { \
   14308             :     return k##AGE##CodeAge;                             \
   14309             :   }
   14310     2286519 :   CODE_AGE_LIST(HANDLE_CODE_AGE)
   14311             : #undef HANDLE_CODE_AGE
   14312          98 :   if (code == *builtins->MarkCodeAsExecutedOnce()) {
   14313             :     return kNotExecutedCodeAge;
   14314             :   }
   14315          74 :   if (code == *builtins->MarkCodeAsExecutedTwice()) {
   14316             :     return kExecutedOnceCodeAge;
   14317             :   }
   14318          52 :   if (code == *builtins->MarkCodeAsToBeExecutedOnce()) {
   14319             :     return kToBeExecutedOnceCodeAge;
   14320             :   }
   14321           0 :   UNREACHABLE();
   14322             :   return kNoAgeCodeAge;
   14323             : }
   14324             : 
   14325     1011036 : Code* Code::GetCodeAgeStub(Isolate* isolate, Age age) {
   14326     1011036 :   Builtins* builtins = isolate->builtins();
   14327     1011036 :   switch (age) {
   14328             : #define HANDLE_CODE_AGE(AGE)                       \
   14329             :   case k##AGE##CodeAge: {                          \
   14330             :     return *builtins->Make##AGE##CodeYoungAgain(); \
   14331             :   }
   14332     1792441 :     CODE_AGE_LIST(HANDLE_CODE_AGE)
   14333             : #undef HANDLE_CODE_AGE
   14334             :     case kNotExecutedCodeAge: {
   14335           0 :       return *builtins->MarkCodeAsExecutedOnce();
   14336             :     }
   14337             :     case kExecutedOnceCodeAge: {
   14338          30 :       return *builtins->MarkCodeAsExecutedTwice();
   14339             :     }
   14340             :     case kToBeExecutedOnceCodeAge: {
   14341          24 :       return *builtins->MarkCodeAsToBeExecutedOnce();
   14342             :     }
   14343             :     default:
   14344           0 :       UNREACHABLE();
   14345             :       break;
   14346             :   }
   14347             :   return NULL;
   14348             : }
   14349             : 
   14350             : 
   14351           0 : void Code::PrintDeoptLocation(FILE* out, Address pc) {
   14352           0 :   Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(this, pc);
   14353           0 :   class SourcePosition pos = info.position;
   14354           0 :   if (info.deopt_reason != DeoptimizeReason::kNoReason || pos.IsKnown()) {
   14355           0 :     if (FLAG_hydrogen_track_positions) {
   14356             :       PrintF(out, "            ;;; deoptimize at %d_%d: %s\n", pos.InliningId(),
   14357           0 :              pos.ScriptOffset(), DeoptimizeReasonToString(info.deopt_reason));
   14358             :     } else {
   14359           0 :       PrintF(out, "            ;;; deoptimize at ");
   14360           0 :       OFStream outstr(out);
   14361           0 :       pos.Print(outstr, this);
   14362           0 :       PrintF(out, ", %s\n", DeoptimizeReasonToString(info.deopt_reason));
   14363             :     }
   14364             :   }
   14365           0 : }
   14366             : 
   14367             : 
   14368        5320 : bool Code::CanDeoptAt(Address pc) {
   14369             :   DeoptimizationInputData* deopt_data =
   14370             :       DeoptimizationInputData::cast(deoptimization_data());
   14371        5320 :   Address code_start_address = instruction_start();
   14372      186920 :   for (int i = 0; i < deopt_data->DeoptCount(); i++) {
   14373      185032 :     if (deopt_data->Pc(i)->value() == -1) continue;
   14374      124414 :     Address address = code_start_address + deopt_data->Pc(i)->value();
   14375       66584 :     if (address == pc && deopt_data->AstId(i) != BailoutId::None()) {
   14376             :       return true;
   14377             :     }
   14378             :   }
   14379             :   return false;
   14380             : }
   14381             : 
   14382             : 
   14383             : // Identify kind of code.
   14384       29547 : const char* Code::Kind2String(Kind kind) {
   14385       29547 :   switch (kind) {
   14386             : #define CASE(name) case name: return #name;
   14387           0 :     CODE_KIND_LIST(CASE)
   14388             : #undef CASE
   14389             :     case NUMBER_OF_KINDS: break;
   14390             :   }
   14391           0 :   UNREACHABLE();
   14392             :   return NULL;
   14393             : }
   14394             : 
   14395             : // Identify kind of code.
   14396           0 : const char* AbstractCode::Kind2String(Kind kind) {
   14397           0 :   if (kind < AbstractCode::INTERPRETED_FUNCTION)
   14398           0 :     return Code::Kind2String((Code::Kind)kind);
   14399           0 :   if (kind == AbstractCode::INTERPRETED_FUNCTION) return "INTERPRETED_FUNCTION";
   14400           0 :   UNREACHABLE();
   14401             :   return NULL;
   14402             : }
   14403             : 
   14404     2560818 : Handle<WeakCell> Code::WeakCellFor(Handle<Code> code) {
   14405             :   DCHECK(code->kind() == OPTIMIZED_FUNCTION);
   14406     2560818 :   WeakCell* raw_cell = code->CachedWeakCell();
   14407     4787618 :   if (raw_cell != NULL) return Handle<WeakCell>(raw_cell);
   14408      334024 :   Handle<WeakCell> cell = code->GetIsolate()->factory()->NewWeakCell(code);
   14409             :   DeoptimizationInputData::cast(code->deoptimization_data())
   14410             :       ->SetWeakCellCache(*cell);
   14411      334024 :   return cell;
   14412             : }
   14413             : 
   14414             : 
   14415     2560818 : WeakCell* Code::CachedWeakCell() {
   14416             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
   14417             :   Object* weak_cell_cache =
   14418             :       DeoptimizationInputData::cast(deoptimization_data())->WeakCellCache();
   14419     2560818 :   if (weak_cell_cache->IsWeakCell()) {
   14420             :     DCHECK(this == WeakCell::cast(weak_cell_cache)->value());
   14421     2226797 :     return WeakCell::cast(weak_cell_cache);
   14422             :   }
   14423             :   return NULL;
   14424             : }
   14425             : 
   14426             : #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   14427             : 
   14428             : const char* Code::ICState2String(InlineCacheState state) {
   14429             :   switch (state) {
   14430             :     case UNINITIALIZED:
   14431             :       return "UNINITIALIZED";
   14432             :     case PREMONOMORPHIC:
   14433             :       return "PREMONOMORPHIC";
   14434             :     case MONOMORPHIC:
   14435             :       return "MONOMORPHIC";
   14436             :     case RECOMPUTE_HANDLER:
   14437             :       return "RECOMPUTE_HANDLER";
   14438             :     case POLYMORPHIC:
   14439             :       return "POLYMORPHIC";
   14440             :     case MEGAMORPHIC:
   14441             :       return "MEGAMORPHIC";
   14442             :     case GENERIC:
   14443             :       return "GENERIC";
   14444             :   }
   14445             :   UNREACHABLE();
   14446             :   return NULL;
   14447             : }
   14448             : 
   14449             : void Code::PrintExtraICState(std::ostream& os,  // NOLINT
   14450             :                              Kind kind, ExtraICState extra) {
   14451             :   os << "extra_ic_state = ";
   14452             :   if ((kind == STORE_IC || kind == KEYED_STORE_IC) &&
   14453             :       is_strict(static_cast<LanguageMode>(extra))) {
   14454             :     os << "STRICT\n";
   14455             :   } else {
   14456             :     os << extra << "\n";
   14457             :   }
   14458             : }
   14459             : 
   14460             : #endif  // defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   14461             : 
   14462             : #ifdef ENABLE_DISASSEMBLER
   14463             : 
   14464             : void DeoptimizationInputData::DeoptimizationInputDataPrint(
   14465             :     std::ostream& os) {  // NOLINT
   14466             :   disasm::NameConverter converter;
   14467             :   int const inlined_function_count = InlinedFunctionCount()->value();
   14468             :   os << "Inlined functions (count = " << inlined_function_count << ")\n";
   14469             :   for (int id = 0; id < inlined_function_count; ++id) {
   14470             :     Object* info = LiteralArray()->get(id);
   14471             :     os << " " << Brief(SharedFunctionInfo::cast(info)) << "\n";
   14472             :   }
   14473             :   os << "\n";
   14474             :   int deopt_count = DeoptCount();
   14475             :   os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
   14476             :   if (0 != deopt_count) {
   14477             :     os << " index  ast id    argc     pc";
   14478             :     if (FLAG_print_code_verbose) os << "  commands";
   14479             :     os << "\n";
   14480             :   }
   14481             :   for (int i = 0; i < deopt_count; i++) {
   14482             :     os << std::setw(6) << i << "  " << std::setw(6) << AstId(i).ToInt() << "  "
   14483             :        << std::setw(6) << ArgumentsStackHeight(i)->value() << " "
   14484             :        << std::setw(6) << Pc(i)->value();
   14485             : 
   14486             :     if (!FLAG_print_code_verbose) {
   14487             :       os << "\n";
   14488             :       continue;
   14489             :     }
   14490             :     // Print details of the frame translation.
   14491             :     int translation_index = TranslationIndex(i)->value();
   14492             :     TranslationIterator iterator(TranslationByteArray(), translation_index);
   14493             :     Translation::Opcode opcode =
   14494             :         static_cast<Translation::Opcode>(iterator.Next());
   14495             :     DCHECK(Translation::BEGIN == opcode);
   14496             :     int frame_count = iterator.Next();
   14497             :     int jsframe_count = iterator.Next();
   14498             :     os << "  " << Translation::StringFor(opcode)
   14499             :        << " {frame count=" << frame_count
   14500             :        << ", js frame count=" << jsframe_count << "}\n";
   14501             : 
   14502             :     while (iterator.HasNext() &&
   14503             :            Translation::BEGIN !=
   14504             :            (opcode = static_cast<Translation::Opcode>(iterator.Next()))) {
   14505             :       os << std::setw(31) << "    " << Translation::StringFor(opcode) << " ";
   14506             : 
   14507             :       switch (opcode) {
   14508             :         case Translation::BEGIN:
   14509             :           UNREACHABLE();
   14510             :           break;
   14511             : 
   14512             :         case Translation::JS_FRAME: {
   14513             :           int ast_id = iterator.Next();
   14514             :           int shared_info_id = iterator.Next();
   14515             :           unsigned height = iterator.Next();
   14516             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14517             :           os << "{ast_id=" << ast_id << ", function="
   14518             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14519             :              << ", height=" << height << "}";
   14520             :           break;
   14521             :         }
   14522             : 
   14523             :         case Translation::INTERPRETED_FRAME: {
   14524             :           int bytecode_offset = iterator.Next();
   14525             :           int shared_info_id = iterator.Next();
   14526             :           unsigned height = iterator.Next();
   14527             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14528             :           os << "{bytecode_offset=" << bytecode_offset << ", function="
   14529             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14530             :              << ", height=" << height << "}";
   14531             :           break;
   14532             :         }
   14533             : 
   14534             :         case Translation::CONSTRUCT_STUB_FRAME: {
   14535             :           int bailout_id = iterator.Next();
   14536             :           int shared_info_id = iterator.Next();
   14537             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14538             :           unsigned height = iterator.Next();
   14539             :           os << "{bailout_id=" << bailout_id << ", function="
   14540             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14541             :              << ", height=" << height << "}";
   14542             :           break;
   14543             :         }
   14544             : 
   14545             :         case Translation::COMPILED_STUB_FRAME: {
   14546             :           Code::Kind stub_kind = static_cast<Code::Kind>(iterator.Next());
   14547             :           os << "{kind=" << stub_kind << "}";
   14548             :           break;
   14549             :         }
   14550             : 
   14551             :         case Translation::ARGUMENTS_ADAPTOR_FRAME: {
   14552             :           int shared_info_id = iterator.Next();
   14553             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14554             :           unsigned height = iterator.Next();
   14555             :           os << "{function="
   14556             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14557             :              << ", height=" << height << "}";
   14558             :           break;
   14559             :         }
   14560             : 
   14561             :         case Translation::TAIL_CALLER_FRAME: {
   14562             :           int shared_info_id = iterator.Next();
   14563             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14564             :           os << "{function="
   14565             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14566             :              << "}";
   14567             :           break;
   14568             :         }
   14569             : 
   14570             :         case Translation::GETTER_STUB_FRAME:
   14571             :         case Translation::SETTER_STUB_FRAME: {
   14572             :           int shared_info_id = iterator.Next();
   14573             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14574             :           os << "{function=" << Brief(SharedFunctionInfo::cast(shared_info)
   14575             :                                           ->DebugName()) << "}";
   14576             :           break;
   14577             :         }
   14578             : 
   14579             :         case Translation::REGISTER: {
   14580             :           int reg_code = iterator.Next();
   14581             :           os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
   14582             :           break;
   14583             :         }
   14584             : 
   14585             :         case Translation::INT32_REGISTER: {
   14586             :           int reg_code = iterator.Next();
   14587             :           os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
   14588             :           break;
   14589             :         }
   14590             : 
   14591             :         case Translation::UINT32_REGISTER: {
   14592             :           int reg_code = iterator.Next();
   14593             :           os << "{input=" << converter.NameOfCPURegister(reg_code)
   14594             :              << " (unsigned)}";
   14595             :           break;
   14596             :         }
   14597             : 
   14598             :         case Translation::BOOL_REGISTER: {
   14599             :           int reg_code = iterator.Next();
   14600             :           os << "{input=" << converter.NameOfCPURegister(reg_code)
   14601             :              << " (bool)}";
   14602             :           break;
   14603             :         }
   14604             : 
   14605             :         case Translation::FLOAT_REGISTER: {
   14606             :           int reg_code = iterator.Next();
   14607             :           os << "{input="
   14608             :              << RegisterConfiguration::Crankshaft()->GetFloatRegisterName(
   14609             :                     reg_code)
   14610             :              << "}";
   14611             :           break;
   14612             :         }
   14613             : 
   14614             :         case Translation::DOUBLE_REGISTER: {
   14615             :           int reg_code = iterator.Next();
   14616             :           os << "{input="
   14617             :              << RegisterConfiguration::Crankshaft()->GetDoubleRegisterName(
   14618             :                     reg_code)
   14619             :              << "}";
   14620             :           break;
   14621             :         }
   14622             : 
   14623             :         case Translation::STACK_SLOT: {
   14624             :           int input_slot_index = iterator.Next();
   14625             :           os << "{input=" << input_slot_index << "}";
   14626             :           break;
   14627             :         }
   14628             : 
   14629             :         case Translation::INT32_STACK_SLOT: {
   14630             :           int input_slot_index = iterator.Next();
   14631             :           os << "{input=" << input_slot_index << "}";
   14632             :           break;
   14633             :         }
   14634             : 
   14635             :         case Translation::UINT32_STACK_SLOT: {
   14636             :           int input_slot_index = iterator.Next();
   14637             :           os << "{input=" << input_slot_index << " (unsigned)}";
   14638             :           break;
   14639             :         }
   14640             : 
   14641             :         case Translation::BOOL_STACK_SLOT: {
   14642             :           int input_slot_index = iterator.Next();
   14643             :           os << "{input=" << input_slot_index << " (bool)}";
   14644             :           break;
   14645             :         }
   14646             : 
   14647             :         case Translation::FLOAT_STACK_SLOT:
   14648             :         case Translation::DOUBLE_STACK_SLOT: {
   14649             :           int input_slot_index = iterator.Next();
   14650             :           os << "{input=" << input_slot_index << "}";
   14651             :           break;
   14652             :         }
   14653             : 
   14654             :         case Translation::LITERAL: {
   14655             :           int literal_index = iterator.Next();
   14656             :           Object* literal_value = LiteralArray()->get(literal_index);
   14657             :           os << "{literal_id=" << literal_index << " (" << Brief(literal_value)
   14658             :              << ")}";
   14659             :           break;
   14660             :         }
   14661             : 
   14662             :         case Translation::DUPLICATED_OBJECT: {
   14663             :           int object_index = iterator.Next();
   14664             :           os << "{object_index=" << object_index << "}";
   14665             :           break;
   14666             :         }
   14667             : 
   14668             :         case Translation::ARGUMENTS_ELEMENTS:
   14669             :         case Translation::ARGUMENTS_LENGTH: {
   14670             :           bool is_rest = iterator.Next();
   14671             :           os << "{is_rest=" << (is_rest ? "true" : "false") << "}";
   14672             :           break;
   14673             :         }
   14674             : 
   14675             :         case Translation::ARGUMENTS_OBJECT:
   14676             :         case Translation::CAPTURED_OBJECT: {
   14677             :           int args_length = iterator.Next();
   14678             :           os << "{length=" << args_length << "}";
   14679             :           break;
   14680             :         }
   14681             :       }
   14682             :       os << "\n";
   14683             :     }
   14684             :   }
   14685             : }
   14686             : 
   14687             : 
   14688             : void DeoptimizationOutputData::DeoptimizationOutputDataPrint(
   14689             :     std::ostream& os) {  // NOLINT
   14690             :   os << "Deoptimization Output Data (deopt points = " << this->DeoptPoints()
   14691             :      << ")\n";
   14692             :   if (this->DeoptPoints() == 0) return;
   14693             : 
   14694             :   os << "ast id        pc  state\n";
   14695             :   for (int i = 0; i < this->DeoptPoints(); i++) {
   14696             :     int pc_and_state = this->PcAndState(i)->value();
   14697             :     os << std::setw(6) << this->AstId(i).ToInt() << "  " << std::setw(8)
   14698             :        << FullCodeGenerator::PcField::decode(pc_and_state) << "  "
   14699             :        << Deoptimizer::BailoutStateToString(
   14700             :               FullCodeGenerator::BailoutStateField::decode(pc_and_state))
   14701             :        << "\n";
   14702             :   }
   14703             : }
   14704             : 
   14705             : 
   14706             : void HandlerTable::HandlerTableRangePrint(std::ostream& os) {
   14707             :   os << "   from   to       hdlr\n";
   14708             :   for (int i = 0; i < length(); i += kRangeEntrySize) {
   14709             :     int pc_start = Smi::cast(get(i + kRangeStartIndex))->value();
   14710             :     int pc_end = Smi::cast(get(i + kRangeEndIndex))->value();
   14711             :     int handler_field = Smi::cast(get(i + kRangeHandlerIndex))->value();
   14712             :     int handler_offset = HandlerOffsetField::decode(handler_field);
   14713             :     CatchPrediction prediction = HandlerPredictionField::decode(handler_field);
   14714             :     int data = Smi::cast(get(i + kRangeDataIndex))->value();
   14715             :     os << "  (" << std::setw(4) << pc_start << "," << std::setw(4) << pc_end
   14716             :        << ")  ->  " << std::setw(4) << handler_offset
   14717             :        << " (prediction=" << prediction << ", data=" << data << ")\n";
   14718             :   }
   14719             : }
   14720             : 
   14721             : 
   14722             : void HandlerTable::HandlerTableReturnPrint(std::ostream& os) {
   14723             :   os << "   off      hdlr (c)\n";
   14724             :   for (int i = 0; i < length(); i += kReturnEntrySize) {
   14725             :     int pc_offset = Smi::cast(get(i + kReturnOffsetIndex))->value();
   14726             :     int handler_field = Smi::cast(get(i + kReturnHandlerIndex))->value();
   14727             :     int handler_offset = HandlerOffsetField::decode(handler_field);
   14728             :     CatchPrediction prediction = HandlerPredictionField::decode(handler_field);
   14729             :     os << "  " << std::setw(4) << pc_offset << "  ->  " << std::setw(4)
   14730             :        << handler_offset << " (prediction=" << prediction << ")\n";
   14731             :   }
   14732             : }
   14733             : 
   14734             : 
   14735             : void Code::Disassemble(const char* name, std::ostream& os) {  // NOLINT
   14736             :   os << "kind = " << Kind2String(kind()) << "\n";
   14737             :   if (IsCodeStubOrIC()) {
   14738             :     const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this));
   14739             :     os << "major_key = " << (n == NULL ? "null" : n) << "\n";
   14740             :   }
   14741             :   if (is_inline_cache_stub()) {
   14742             :     if (is_compare_ic_stub() || is_to_boolean_ic_stub() ||
   14743             :         is_binary_op_stub()) {
   14744             :       InlineCacheState ic_state = IC::StateFromCode(this);
   14745             :       os << "ic_state = " << ICState2String(ic_state) << "\n";
   14746             :       PrintExtraICState(os, kind(), extra_ic_state());
   14747             :     }
   14748             :     if (is_compare_ic_stub()) {
   14749             :       DCHECK(CodeStub::GetMajorKey(this) == CodeStub::CompareIC);
   14750             :       CompareICStub stub(stub_key(), GetIsolate());
   14751             :       os << "compare_state = " << CompareICState::GetStateName(stub.left())
   14752             :          << "*" << CompareICState::GetStateName(stub.right()) << " -> "
   14753             :          << CompareICState::GetStateName(stub.state()) << "\n";
   14754             :       os << "compare_operation = " << Token::Name(stub.op()) << "\n";
   14755             :     }
   14756             :   }
   14757             :   if ((name != nullptr) && (name[0] != '\0')) {
   14758             :     os << "name = " << name << "\n";
   14759             :   } else if (kind() == BUILTIN) {
   14760             :     name = GetIsolate()->builtins()->Lookup(instruction_start());
   14761             :     if (name != nullptr) {
   14762             :       os << "name = " << name << "\n";
   14763             :     }
   14764             :   } else if (kind() == BYTECODE_HANDLER) {
   14765             :     name = GetIsolate()->interpreter()->LookupNameOfBytecodeHandler(this);
   14766             :     if (name != nullptr) {
   14767             :       os << "name = " << name << "\n";
   14768             :     }
   14769             :   }
   14770             :   if (kind() == OPTIMIZED_FUNCTION) {
   14771             :     os << "stack_slots = " << stack_slots() << "\n";
   14772             :   }
   14773             :   os << "compiler = " << (is_turbofanned()
   14774             :                               ? "turbofan"
   14775             :                               : is_crankshafted() ? "crankshaft"
   14776             :                                                   : kind() == Code::FUNCTION
   14777             :                                                         ? "full-codegen"
   14778             :                                                         : "unknown") << "\n";
   14779             : 
   14780             :   os << "Instructions (size = " << instruction_size() << ")\n";
   14781             :   {
   14782             :     Isolate* isolate = GetIsolate();
   14783             :     int size = instruction_size();
   14784             :     int safepoint_offset =
   14785             :         is_crankshafted() ? static_cast<int>(safepoint_table_offset()) : size;
   14786             :     int back_edge_offset = (kind() == Code::FUNCTION)
   14787             :                                ? static_cast<int>(back_edge_table_offset())
   14788             :                                : size;
   14789             :     int constant_pool_offset = FLAG_enable_embedded_constant_pool
   14790             :                                    ? this->constant_pool_offset()
   14791             :                                    : size;
   14792             : 
   14793             :     // Stop before reaching any embedded tables
   14794             :     int code_size = Min(safepoint_offset, back_edge_offset);
   14795             :     code_size = Min(code_size, constant_pool_offset);
   14796             :     byte* begin = instruction_start();
   14797             :     byte* end = begin + code_size;
   14798             :     Disassembler::Decode(isolate, &os, begin, end, this);
   14799             : 
   14800             :     if (constant_pool_offset < size) {
   14801             :       int constant_pool_size = size - constant_pool_offset;
   14802             :       DCHECK((constant_pool_size & kPointerAlignmentMask) == 0);
   14803             :       os << "\nConstant Pool (size = " << constant_pool_size << ")\n";
   14804             :       Vector<char> buf = Vector<char>::New(50);
   14805             :       intptr_t* ptr = reinterpret_cast<intptr_t*>(begin + constant_pool_offset);
   14806             :       for (int i = 0; i < constant_pool_size; i += kPointerSize, ptr++) {
   14807             :         SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr);
   14808             :         os << static_cast<const void*>(ptr) << "  " << buf.start() << "\n";
   14809             :       }
   14810             :     }
   14811             :   }
   14812             :   os << "\n";
   14813             : 
   14814             :   SourcePositionTableIterator it(SourcePositionTable());
   14815             :   if (!it.done()) {
   14816             :     os << "Source positions:\n pc offset  position\n";
   14817             :     for (; !it.done(); it.Advance()) {
   14818             :       os << std::setw(10) << std::hex << it.code_offset() << std::dec
   14819             :          << std::setw(10) << it.source_position().ScriptOffset()
   14820             :          << (it.is_statement() ? "  statement" : "") << "\n";
   14821             :     }
   14822             :     os << "\n";
   14823             :   }
   14824             : 
   14825             :   if (kind() == FUNCTION) {
   14826             :     DeoptimizationOutputData* data =
   14827             :         DeoptimizationOutputData::cast(this->deoptimization_data());
   14828             :     data->DeoptimizationOutputDataPrint(os);
   14829             :   } else if (kind() == OPTIMIZED_FUNCTION) {
   14830             :     DeoptimizationInputData* data =
   14831             :         DeoptimizationInputData::cast(this->deoptimization_data());
   14832             :     data->DeoptimizationInputDataPrint(os);
   14833             :   }
   14834             :   os << "\n";
   14835             : 
   14836             :   if (is_crankshafted()) {
   14837             :     SafepointTable table(this);
   14838             :     os << "Safepoints (size = " << table.size() << ")\n";
   14839             :     for (unsigned i = 0; i < table.length(); i++) {
   14840             :       unsigned pc_offset = table.GetPcOffset(i);
   14841             :       os << static_cast<const void*>(instruction_start() + pc_offset) << "  ";
   14842             :       os << std::setw(4) << std::hex << pc_offset << std::dec << "  ";
   14843             :       table.PrintEntry(i, os);
   14844             :       os << " (sp -> fp)  ";
   14845             :       SafepointEntry entry = table.GetEntry(i);
   14846             :       if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
   14847             :         os << std::setw(6) << entry.deoptimization_index();
   14848             :       } else {
   14849             :         os << "<none>";
   14850             :       }
   14851             :       if (entry.argument_count() > 0) {
   14852             :         os << " argc: " << entry.argument_count();
   14853             :       }
   14854             :       os << "\n";
   14855             :     }
   14856             :     os << "\n";
   14857             :   } else if (kind() == FUNCTION) {
   14858             :     unsigned offset = back_edge_table_offset();
   14859             :     // If there is no back edge table, the "table start" will be at or after
   14860             :     // (due to alignment) the end of the instruction stream.
   14861             :     if (static_cast<int>(offset) < instruction_size()) {
   14862             :       DisallowHeapAllocation no_gc;
   14863             :       BackEdgeTable back_edges(this, &no_gc);
   14864             : 
   14865             :       os << "Back edges (size = " << back_edges.length() << ")\n";
   14866             :       os << "ast_id  pc_offset  loop_depth\n";
   14867             : 
   14868             :       for (uint32_t i = 0; i < back_edges.length(); i++) {
   14869             :         os << std::setw(6) << back_edges.ast_id(i).ToInt() << "  "
   14870             :            << std::setw(9) << std::hex << back_edges.pc_offset(i) << std::dec
   14871             :            << "  " << std::setw(10) << back_edges.loop_depth(i) << "\n";
   14872             :       }
   14873             : 
   14874             :       os << "\n";
   14875             :     }
   14876             : #ifdef OBJECT_PRINT
   14877             :     if (!type_feedback_info()->IsUndefined(GetIsolate())) {
   14878             :       TypeFeedbackInfo* info = TypeFeedbackInfo::cast(type_feedback_info());
   14879             :       HeapObject::PrintHeader(os, "TypeFeedbackInfo");
   14880             :       os << "\n - ic_total_count: " << info->ic_total_count()
   14881             :          << ", ic_with_type_info_count: " << info->ic_with_type_info_count()
   14882             :          << ", ic_generic_count: " << info->ic_generic_count() << "\n";
   14883             :       os << "\n";
   14884             :     }
   14885             : #endif
   14886             :   }
   14887             : 
   14888             :   if (handler_table()->length() > 0) {
   14889             :     os << "Handler Table (size = " << handler_table()->Size() << ")\n";
   14890             :     if (kind() == FUNCTION) {
   14891             :       HandlerTable::cast(handler_table())->HandlerTableRangePrint(os);
   14892             :     } else if (kind() == OPTIMIZED_FUNCTION) {
   14893             :       HandlerTable::cast(handler_table())->HandlerTableReturnPrint(os);
   14894             :     }
   14895             :     os << "\n";
   14896             :   }
   14897             : 
   14898             :   os << "RelocInfo (size = " << relocation_size() << ")\n";
   14899             :   for (RelocIterator it(this); !it.done(); it.next()) {
   14900             :     it.rinfo()->Print(GetIsolate(), os);
   14901             :   }
   14902             :   os << "\n";
   14903             : 
   14904             :   if (has_unwinding_info()) {
   14905             :     os << "UnwindingInfo (size = " << unwinding_info_size() << ")\n";
   14906             :     EhFrameDisassembler eh_frame_disassembler(unwinding_info_start(),
   14907             :                                               unwinding_info_end());
   14908             :     eh_frame_disassembler.DisassembleToStream(os);
   14909             :     os << "\n";
   14910             :   }
   14911             : }
   14912             : #endif  // ENABLE_DISASSEMBLER
   14913             : 
   14914             : 
   14915           0 : void BytecodeArray::Disassemble(std::ostream& os) {
   14916           0 :   os << "Parameter count " << parameter_count() << "\n";
   14917           0 :   os << "Frame size " << frame_size() << "\n";
   14918             : 
   14919           0 :   const uint8_t* base_address = GetFirstBytecodeAddress();
   14920           0 :   SourcePositionTableIterator source_positions(SourcePositionTable());
   14921             : 
   14922           0 :   interpreter::BytecodeArrayIterator iterator(handle(this));
   14923           0 :   while (!iterator.done()) {
   14924           0 :     if (!source_positions.done() &&
   14925           0 :         iterator.current_offset() == source_positions.code_offset()) {
   14926           0 :       os << std::setw(5) << source_positions.source_position().ScriptOffset();
   14927           0 :       os << (source_positions.is_statement() ? " S> " : " E> ");
   14928           0 :       source_positions.Advance();
   14929             :     } else {
   14930           0 :       os << "         ";
   14931             :     }
   14932           0 :     const uint8_t* current_address = base_address + iterator.current_offset();
   14933           0 :     os << reinterpret_cast<const void*>(current_address) << " @ "
   14934           0 :        << std::setw(4) << iterator.current_offset() << " : ";
   14935             :     interpreter::BytecodeDecoder::Decode(os, current_address,
   14936           0 :                                          parameter_count());
   14937           0 :     if (interpreter::Bytecodes::IsJump(iterator.current_bytecode())) {
   14938           0 :       const void* jump_target = base_address + iterator.GetJumpTargetOffset();
   14939           0 :       os << " (" << jump_target << " @ " << iterator.GetJumpTargetOffset()
   14940           0 :          << ")";
   14941             :     }
   14942             :     os << std::endl;
   14943           0 :     iterator.Advance();
   14944             :   }
   14945             : 
   14946           0 :   if (constant_pool()->length() > 0) {
   14947           0 :     os << "Constant pool (size = " << constant_pool()->length() << ")\n";
   14948             :     constant_pool()->Print();
   14949             :   }
   14950             : 
   14951             : #ifdef ENABLE_DISASSEMBLER
   14952             :   if (handler_table()->length() > 0) {
   14953             :     os << "Handler Table (size = " << handler_table()->Size() << ")\n";
   14954             :     HandlerTable::cast(handler_table())->HandlerTableRangePrint(os);
   14955             :   }
   14956             : #endif
   14957           0 : }
   14958             : 
   14959        9490 : void BytecodeArray::CopyBytecodesTo(BytecodeArray* to) {
   14960             :   BytecodeArray* from = this;
   14961             :   DCHECK_EQ(from->length(), to->length());
   14962        9490 :   CopyBytes(to->GetFirstBytecodeAddress(), from->GetFirstBytecodeAddress(),
   14963       18980 :             from->length());
   14964        9490 : }
   14965             : 
   14966     1944461 : void BytecodeArray::MakeOlder() {
   14967             :   Age age = bytecode_age();
   14968     1944461 :   if (age < kLastBytecodeAge) {
   14969     1405208 :     set_bytecode_age(static_cast<Age>(age + 1));
   14970             :   }
   14971             :   DCHECK_GE(bytecode_age(), kFirstBytecodeAge);
   14972             :   DCHECK_LE(bytecode_age(), kLastBytecodeAge);
   14973     1944461 : }
   14974             : 
   14975           0 : bool BytecodeArray::IsOld() const {
   14976      246687 :   return bytecode_age() >= kIsOldBytecodeAge;
   14977             : }
   14978             : 
   14979             : // static
   14980      352330 : void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) {
   14981             :   DCHECK(capacity >= 0);
   14982             :   array->GetIsolate()->factory()->NewJSArrayStorage(
   14983      352330 :       array, length, capacity, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
   14984      352330 : }
   14985             : 
   14986     1562733 : void JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) {
   14987             :   // We should never end in here with a pixel or external array.
   14988             :   DCHECK(array->AllowsSetLength());
   14989     1562733 :   if (array->SetLengthWouldNormalize(new_length)) {
   14990        1515 :     JSObject::NormalizeElements(array);
   14991             :   }
   14992     1562733 :   array->GetElementsAccessor()->SetLength(array, new_length);
   14993     1562733 : }
   14994             : 
   14995             : 
   14996             : // static
   14997      324603 : void Map::AddDependentCode(Handle<Map> map,
   14998             :                            DependentCode::DependencyGroup group,
   14999             :                            Handle<Code> code) {
   15000      324603 :   Handle<WeakCell> cell = Code::WeakCellFor(code);
   15001             :   Handle<DependentCode> codes = DependentCode::InsertWeakCode(
   15002             :       Handle<DependentCode>(map->dependent_code()), group, cell);
   15003      324603 :   if (*codes != map->dependent_code()) map->set_dependent_code(*codes);
   15004      324603 : }
   15005             : 
   15006             : 
   15007      905458 : Handle<DependentCode> DependentCode::InsertCompilationDependencies(
   15008             :     Handle<DependentCode> entries, DependencyGroup group,
   15009             :     Handle<Foreign> info) {
   15010      905458 :   return Insert(entries, group, info);
   15011             : }
   15012             : 
   15013             : 
   15014     1050332 : Handle<DependentCode> DependentCode::InsertWeakCode(
   15015             :     Handle<DependentCode> entries, DependencyGroup group,
   15016             :     Handle<WeakCell> code_cell) {
   15017     1374935 :   return Insert(entries, group, code_cell);
   15018             : }
   15019             : 
   15020             : 
   15021     2301002 : Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
   15022             :                                             DependencyGroup group,
   15023             :                                             Handle<Object> object) {
   15024     4225772 :   if (entries->length() == 0 || entries->group() > group) {
   15025             :     // There is no such group.
   15026      391634 :     return DependentCode::New(group, object, entries);
   15027             :   }
   15028     1909368 :   if (entries->group() < group) {
   15029             :     // The group comes later in the list.
   15030             :     Handle<DependentCode> old_next(entries->next_link());
   15031       20608 :     Handle<DependentCode> new_next = Insert(old_next, group, object);
   15032       20608 :     if (!old_next.is_identical_to(new_next)) {
   15033             :       entries->set_next_link(*new_next);
   15034             :     }
   15035       20608 :     return entries;
   15036             :   }
   15037             :   DCHECK_EQ(group, entries->group());
   15038             :   int count = entries->count();
   15039             :   // Check for existing entry to avoid duplicates.
   15040   168781175 :   for (int i = 0; i < count; i++) {
   15041   168082326 :     if (entries->object_at(i) == *object) return entries;
   15042             :   }
   15043     1397698 :   if (entries->length() < kCodesStartIndex + count + 1) {
   15044      271033 :     entries = EnsureSpace(entries);
   15045             :     // Count could have changed, reload it.
   15046             :     count = entries->count();
   15047             :   }
   15048             :   entries->set_object_at(count, *object);
   15049     1397698 :   entries->set_count(count + 1);
   15050      698849 :   return entries;
   15051             : }
   15052             : 
   15053             : 
   15054      391633 : Handle<DependentCode> DependentCode::New(DependencyGroup group,
   15055             :                                          Handle<Object> object,
   15056             :                                          Handle<DependentCode> next) {
   15057             :   Isolate* isolate = next->GetIsolate();
   15058             :   Handle<DependentCode> result = Handle<DependentCode>::cast(
   15059      391633 :       isolate->factory()->NewFixedArray(kCodesStartIndex + 1, TENURED));
   15060             :   result->set_next_link(*next);
   15061      391634 :   result->set_flags(GroupField::encode(group) | CountField::encode(1));
   15062             :   result->set_object_at(0, *object);
   15063      391634 :   return result;
   15064             : }
   15065             : 
   15066             : 
   15067      271033 : Handle<DependentCode> DependentCode::EnsureSpace(
   15068             :     Handle<DependentCode> entries) {
   15069      271033 :   if (entries->Compact()) return entries;
   15070             :   Isolate* isolate = entries->GetIsolate();
   15071      260886 :   int capacity = kCodesStartIndex + DependentCode::Grow(entries->count());
   15072      260886 :   int grow_by = capacity - entries->length();
   15073             :   return Handle<DependentCode>::cast(
   15074      260886 :       isolate->factory()->CopyFixedArrayAndGrow(entries, grow_by, TENURED));
   15075             : }
   15076             : 
   15077             : 
   15078      271033 : bool DependentCode::Compact() {
   15079             :   int old_count = count();
   15080             :   int new_count = 0;
   15081     2911822 :   for (int i = 0; i < old_count; i++) {
   15082             :     Object* obj = object_at(i);
   15083     5269032 :     if (!obj->IsWeakCell() || !WeakCell::cast(obj)->cleared()) {
   15084     2605292 :       if (i != new_count) {
   15085        8726 :         copy(i, new_count);
   15086             :       }
   15087     2605292 :       new_count++;
   15088             :     }
   15089             :   }
   15090      271033 :   set_count(new_count);
   15091      306530 :   for (int i = new_count; i < old_count; i++) {
   15092             :     clear_at(i);
   15093             :   }
   15094      271033 :   return new_count < old_count;
   15095             : }
   15096             : 
   15097             : 
   15098      870948 : void DependentCode::UpdateToFinishedCode(DependencyGroup group, Foreign* info,
   15099             :                                          WeakCell* code_cell) {
   15100     1770684 :   if (this->length() == 0 || this->group() > group) {
   15101             :     // There is no such group.
   15102             :     return;
   15103             :   }
   15104      885342 :   if (this->group() < group) {
   15105             :     // The group comes later in the list.
   15106             :     next_link()->UpdateToFinishedCode(group, info, code_cell);
   15107       14394 :     return;
   15108             :   }
   15109             :   DCHECK_EQ(group, this->group());
   15110             :   DisallowHeapAllocation no_gc;
   15111             :   int count = this->count();
   15112    87267598 :   for (int i = 0; i < count; i++) {
   15113    86887107 :     if (object_at(i) == info) {
   15114             :       set_object_at(i, code_cell);
   15115             :       break;
   15116             :     }
   15117             :   }
   15118             : #ifdef DEBUG
   15119             :   for (int i = 0; i < count; i++) {
   15120             :     DCHECK(object_at(i) != info);
   15121             :   }
   15122             : #endif
   15123             : }
   15124             : 
   15125             : 
   15126       34502 : void DependentCode::RemoveCompilationDependencies(
   15127             :     DependentCode::DependencyGroup group, Foreign* info) {
   15128       70188 :   if (this->length() == 0 || this->group() > group) {
   15129             :     // There is no such group.
   15130             :     return;
   15131             :   }
   15132       35094 :   if (this->group() < group) {
   15133             :     // The group comes later in the list.
   15134             :     next_link()->RemoveCompilationDependencies(group, info);
   15135         592 :     return;
   15136             :   }
   15137             :   DCHECK_EQ(group, this->group());
   15138             :   DisallowHeapAllocation no_allocation;
   15139             :   int old_count = count();
   15140             :   // Find compilation info wrapper.
   15141             :   int info_pos = -1;
   15142     1385671 :   for (int i = 0; i < old_count; i++) {
   15143     1371800 :     if (object_at(i) == info) {
   15144             :       info_pos = i;
   15145             :       break;
   15146             :     }
   15147             :   }
   15148       34502 :   if (info_pos == -1) return;  // Not found.
   15149             :   // Use the last code to fill the gap.
   15150       20631 :   if (info_pos < old_count - 1) {
   15151        4795 :     copy(old_count - 1, info_pos);
   15152             :   }
   15153             :   clear_at(old_count - 1);
   15154       20631 :   set_count(old_count - 1);
   15155             : 
   15156             : #ifdef DEBUG
   15157             :   for (int i = 0; i < old_count - 1; i++) {
   15158             :     DCHECK(object_at(i) != info);
   15159             :   }
   15160             : #endif
   15161             : }
   15162             : 
   15163             : 
   15164           0 : bool DependentCode::Contains(DependencyGroup group, WeakCell* code_cell) {
   15165           0 :   if (this->length() == 0 || this->group() > group) {
   15166             :     // There is no such group.
   15167             :     return false;
   15168             :   }
   15169           0 :   if (this->group() < group) {
   15170             :     // The group comes later in the list.
   15171           0 :     return next_link()->Contains(group, code_cell);
   15172             :   }
   15173             :   DCHECK_EQ(group, this->group());
   15174             :   int count = this->count();
   15175           0 :   for (int i = 0; i < count; i++) {
   15176           0 :     if (object_at(i) == code_cell) return true;
   15177             :   }
   15178             :   return false;
   15179             : }
   15180             : 
   15181             : 
   15182      204592 : bool DependentCode::IsEmpty(DependencyGroup group) {
   15183      381890 :   if (this->length() == 0 || this->group() > group) {
   15184             :     // There is no such group.
   15185             :     return true;
   15186             :   }
   15187      166451 :   if (this->group() < group) {
   15188             :     // The group comes later in the list.
   15189           0 :     return next_link()->IsEmpty(group);
   15190             :   }
   15191             :   DCHECK_EQ(group, this->group());
   15192      166451 :   return count() == 0;
   15193             : }
   15194             : 
   15195             : 
   15196    20085440 : bool DependentCode::MarkCodeForDeoptimization(
   15197             :     Isolate* isolate,
   15198             :     DependentCode::DependencyGroup group) {
   15199    20129087 :   if (this->length() == 0 || this->group() > group) {
   15200             :     // There is no such group.
   15201             :     return false;
   15202             :   }
   15203       41104 :   if (this->group() < group) {
   15204             :     // The group comes later in the list.
   15205        1931 :     return next_link()->MarkCodeForDeoptimization(isolate, group);
   15206             :   }
   15207             :   DCHECK_EQ(group, this->group());
   15208             :   DisallowHeapAllocation no_allocation_scope;
   15209             :   // Mark all the code that needs to be deoptimized.
   15210             :   bool marked = false;
   15211             :   bool invalidate_embedded_objects = group == kWeakCodeGroup;
   15212             :   int count = this->count();
   15213      124661 :   for (int i = 0; i < count; i++) {
   15214             :     Object* obj = object_at(i);
   15215       85488 :     if (obj->IsWeakCell()) {
   15216             :       WeakCell* cell = WeakCell::cast(obj);
   15217       85260 :       if (cell->cleared()) continue;
   15218             :       Code* code = Code::cast(cell->value());
   15219       23344 :       if (!code->marked_for_deoptimization()) {
   15220       14377 :         SetMarkedForDeoptimization(code, group);
   15221       14377 :         if (invalidate_embedded_objects) {
   15222        5302 :           code->InvalidateEmbeddedObjects();
   15223             :         }
   15224             :         marked = true;
   15225             :       }
   15226             :     } else {
   15227             :       DCHECK(obj->IsForeign());
   15228             :       CompilationDependencies* info =
   15229             :           reinterpret_cast<CompilationDependencies*>(
   15230             :               Foreign::cast(obj)->foreign_address());
   15231             :       info->Abort();
   15232             :     }
   15233             :   }
   15234       85488 :   for (int i = 0; i < count; i++) {
   15235             :     clear_at(i);
   15236             :   }
   15237       39173 :   set_count(0);
   15238       39173 :   return marked;
   15239             : }
   15240             : 
   15241             : 
   15242    20053205 : void DependentCode::DeoptimizeDependentCodeGroup(
   15243             :     Isolate* isolate,
   15244             :     DependentCode::DependencyGroup group) {
   15245             :   DisallowHeapAllocation no_allocation_scope;
   15246    20053205 :   bool marked = MarkCodeForDeoptimization(isolate, group);
   15247    20053205 :   if (marked) {
   15248             :     DCHECK(AllowCodeDependencyChange::IsAllowed());
   15249        5907 :     Deoptimizer::DeoptimizeMarkedCode(isolate);
   15250             :   }
   15251    20053205 : }
   15252             : 
   15253             : 
   15254       14392 : void DependentCode::SetMarkedForDeoptimization(Code* code,
   15255             :                                                DependencyGroup group) {
   15256             :   code->set_marked_for_deoptimization(true);
   15257       14392 :   if (FLAG_trace_deopt &&
   15258           0 :       (code->deoptimization_data() != code->GetHeap()->empty_fixed_array())) {
   15259             :     DeoptimizationInputData* deopt_data =
   15260             :         DeoptimizationInputData::cast(code->deoptimization_data());
   15261           0 :     CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer());
   15262             :     PrintF(scope.file(), "[marking dependent code 0x%08" V8PRIxPTR
   15263             :                          " (opt #%d) for deoptimization, reason: %s]\n",
   15264             :            reinterpret_cast<intptr_t>(code),
   15265           0 :            deopt_data->OptimizationId()->value(), DependencyGroupName(group));
   15266             :   }
   15267       14392 : }
   15268             : 
   15269             : 
   15270           0 : const char* DependentCode::DependencyGroupName(DependencyGroup group) {
   15271           0 :   switch (group) {
   15272             :     case kWeakCodeGroup:
   15273             :       return "weak-code";
   15274             :     case kTransitionGroup:
   15275           0 :       return "transition";
   15276             :     case kPrototypeCheckGroup:
   15277           0 :       return "prototype-check";
   15278             :     case kPropertyCellChangedGroup:
   15279           0 :       return "property-cell-changed";
   15280             :     case kFieldOwnerGroup:
   15281           0 :       return "field-owner";
   15282             :     case kInitialMapChangedGroup:
   15283           0 :       return "initial-map-changed";
   15284             :     case kAllocationSiteTenuringChangedGroup:
   15285           0 :       return "allocation-site-tenuring-changed";
   15286             :     case kAllocationSiteTransitionChangedGroup:
   15287           0 :       return "allocation-site-transition-changed";
   15288             :   }
   15289           0 :   UNREACHABLE();
   15290             :   return "?";
   15291             : }
   15292             : 
   15293             : 
   15294     4156555 : Handle<Map> Map::TransitionToPrototype(Handle<Map> map,
   15295             :                                        Handle<Object> prototype,
   15296             :                                        PrototypeOptimizationMode mode) {
   15297     4156555 :   Handle<Map> new_map = TransitionArray::GetPrototypeTransition(map, prototype);
   15298     4156555 :   if (new_map.is_null()) {
   15299      139748 :     new_map = Copy(map, "TransitionToPrototype");
   15300      139748 :     TransitionArray::PutPrototypeTransition(map, prototype, new_map);
   15301      139748 :     Map::SetPrototype(new_map, prototype, mode);
   15302             :   }
   15303     4156555 :   return new_map;
   15304             : }
   15305             : 
   15306             : 
   15307     4184280 : Maybe<bool> JSReceiver::SetPrototype(Handle<JSReceiver> object,
   15308             :                                      Handle<Object> value, bool from_javascript,
   15309             :                                      ShouldThrow should_throw) {
   15310     4184280 :   if (object->IsJSProxy()) {
   15311             :     return JSProxy::SetPrototype(Handle<JSProxy>::cast(object), value,
   15312         532 :                                  from_javascript, should_throw);
   15313             :   }
   15314             :   return JSObject::SetPrototype(Handle<JSObject>::cast(object), value,
   15315     4183748 :                                 from_javascript, should_throw);
   15316             : }
   15317             : 
   15318             : 
   15319             : // ES6: 9.5.2 [[SetPrototypeOf]] (V)
   15320             : // static
   15321         532 : Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value,
   15322             :                                   bool from_javascript,
   15323             :                                   ShouldThrow should_throw) {
   15324             :   Isolate* isolate = proxy->GetIsolate();
   15325         532 :   STACK_CHECK(isolate, Nothing<bool>());
   15326             :   Handle<Name> trap_name = isolate->factory()->setPrototypeOf_string();
   15327             :   // 1. Assert: Either Type(V) is Object or Type(V) is Null.
   15328             :   DCHECK(value->IsJSReceiver() || value->IsNull(isolate));
   15329             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
   15330             :   Handle<Object> handler(proxy->handler(), isolate);
   15331             :   // 3. If handler is null, throw a TypeError exception.
   15332             :   // 4. Assert: Type(handler) is Object.
   15333         532 :   if (proxy->IsRevoked()) {
   15334             :     isolate->Throw(*isolate->factory()->NewTypeError(
   15335          28 :         MessageTemplate::kProxyRevoked, trap_name));
   15336             :     return Nothing<bool>();
   15337             :   }
   15338             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot.
   15339             :   Handle<JSReceiver> target(proxy->target(), isolate);
   15340             :   // 6. Let trap be ? GetMethod(handler, "getPrototypeOf").
   15341             :   Handle<Object> trap;
   15342        1036 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   15343             :       isolate, trap,
   15344             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
   15345             :       Nothing<bool>());
   15346             :   // 7. If trap is undefined, then return target.[[SetPrototypeOf]]().
   15347         518 :   if (trap->IsUndefined(isolate)) {
   15348             :     return JSReceiver::SetPrototype(target, value, from_javascript,
   15349         364 :                                     should_throw);
   15350             :   }
   15351             :   // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, V»)).
   15352         154 :   Handle<Object> argv[] = {target, value};
   15353             :   Handle<Object> trap_result;
   15354         308 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   15355             :       isolate, trap_result,
   15356             :       Execution::Call(isolate, trap, handler, arraysize(argv), argv),
   15357             :       Nothing<bool>());
   15358         140 :   bool bool_trap_result = trap_result->BooleanValue();
   15359             :   // 9. If booleanTrapResult is false, return false.
   15360         140 :   if (!bool_trap_result) {
   15361         140 :     RETURN_FAILURE(
   15362             :         isolate, should_throw,
   15363             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
   15364             :   }
   15365             :   // 10. Let extensibleTarget be ? IsExtensible(target).
   15366          84 :   Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
   15367          84 :   if (is_extensible.IsNothing()) return Nothing<bool>();
   15368             :   // 11. If extensibleTarget is true, return true.
   15369          84 :   if (is_extensible.FromJust()) {
   15370          42 :     if (bool_trap_result) return Just(true);
   15371           0 :     RETURN_FAILURE(
   15372             :         isolate, should_throw,
   15373             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
   15374             :   }
   15375             :   // 12. Let targetProto be ? target.[[GetPrototypeOf]]().
   15376             :   Handle<Object> target_proto;
   15377          84 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_proto,
   15378             :                                    JSReceiver::GetPrototype(isolate, target),
   15379             :                                    Nothing<bool>());
   15380             :   // 13. If SameValue(V, targetProto) is false, throw a TypeError exception.
   15381          56 :   if (bool_trap_result && !value->SameValue(*target_proto)) {
   15382             :     isolate->Throw(*isolate->factory()->NewTypeError(
   15383          28 :         MessageTemplate::kProxySetPrototypeOfNonExtensible));
   15384             :     return Nothing<bool>();
   15385             :   }
   15386             :   // 14. Return true.
   15387             :   return Just(true);
   15388             : }
   15389             : 
   15390             : 
   15391     4196691 : Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
   15392             :                                    Handle<Object> value, bool from_javascript,
   15393             :                                    ShouldThrow should_throw) {
   15394          42 :   Isolate* isolate = object->GetIsolate();
   15395             : 
   15396             : #ifdef DEBUG
   15397             :   int size = object->Size();
   15398             : #endif
   15399             : 
   15400     4196691 :   if (from_javascript) {
   15401      116148 :     if (object->IsAccessCheckNeeded() &&
   15402          42 :         !isolate->MayAccess(handle(isolate->context()), object)) {
   15403           0 :       isolate->ReportFailedAccessCheck(object);
   15404           0 :       RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
   15405           0 :       RETURN_FAILURE(isolate, should_throw,
   15406             :                      NewTypeError(MessageTemplate::kNoAccess));
   15407             :     }
   15408             :   } else {
   15409             :     DCHECK(!object->IsAccessCheckNeeded());
   15410             :   }
   15411             : 
   15412             :   Heap* heap = isolate->heap();
   15413             :   // Silently ignore the change if value is not a JSObject or null.
   15414             :   // SpiderMonkey behaves this way.
   15415     8256218 :   if (!value->IsJSReceiver() && !value->IsNull(isolate)) return Just(true);
   15416             : 
   15417             :   bool all_extensible = object->map()->is_extensible();
   15418             :   Handle<JSObject> real_receiver = object;
   15419     4196673 :   if (from_javascript) {
   15420             :     // Find the first object in the chain whose prototype object is not
   15421             :     // hidden.
   15422             :     PrototypeIterator iter(isolate, real_receiver, kStartAtPrototype,
   15423      116106 :                            PrototypeIterator::END_AT_NON_HIDDEN);
   15424      236857 :     while (!iter.IsAtEnd()) {
   15425             :       // Casting to JSObject is fine because hidden prototypes are never
   15426             :       // JSProxies.
   15427             :       real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
   15428        4645 :       iter.Advance();
   15429        9290 :       all_extensible = all_extensible && real_receiver->map()->is_extensible();
   15430             :     }
   15431             :   }
   15432             :   Handle<Map> map(real_receiver->map());
   15433             : 
   15434             :   // Nothing to do if prototype is already set.
   15435     4196673 :   if (map->prototype() == *value) return Just(true);
   15436             : 
   15437             :   bool immutable_proto = map->is_immutable_proto();
   15438     4155854 :   if (immutable_proto) {
   15439         251 :     RETURN_FAILURE(
   15440             :         isolate, should_throw,
   15441             :         NewTypeError(MessageTemplate::kImmutablePrototypeSet, object));
   15442             :   }
   15443             : 
   15444             :   // From 8.6.2 Object Internal Methods
   15445             :   // ...
   15446             :   // In addition, if [[Extensible]] is false the value of the [[Class]] and
   15447             :   // [[Prototype]] internal properties of the object may not be modified.
   15448             :   // ...
   15449             :   // Implementation specific extensions that modify [[Class]], [[Prototype]]
   15450             :   // or [[Extensible]] must not violate the invariants defined in the preceding
   15451             :   // paragraph.
   15452     4155761 :   if (!all_extensible) {
   15453         822 :     RETURN_FAILURE(isolate, should_throw,
   15454             :                    NewTypeError(MessageTemplate::kNonExtensibleProto, object));
   15455             :   }
   15456             : 
   15457             :   // Before we can set the prototype we need to be sure prototype cycles are
   15458             :   // prevented.  It is sufficient to validate that the receiver is not in the
   15459             :   // new prototype chain.
   15460     4155365 :   if (value->IsJSReceiver()) {
   15461      359899 :     for (PrototypeIterator iter(isolate, JSReceiver::cast(*value),
   15462             :                                 kStartAtReceiver);
   15463      263900 :          !iter.IsAtEnd(); iter.Advance()) {
   15464      528044 :       if (iter.GetCurrent<JSReceiver>() == *object) {
   15465             :         // Cycle detected.
   15466         310 :         RETURN_FAILURE(isolate, should_throw,
   15467             :                        NewTypeError(MessageTemplate::kCyclicProto));
   15468             :       }
   15469             :     }
   15470             :   }
   15471             : 
   15472             :   // Set the new prototype of the object.
   15473             : 
   15474             :   isolate->UpdateArrayProtectorOnSetPrototype(real_receiver);
   15475             : 
   15476             :   PrototypeOptimizationMode mode =
   15477     4155243 :       from_javascript ? REGULAR_PROTOTYPE : FAST_PROTOTYPE;
   15478     4155243 :   Handle<Map> new_map = Map::TransitionToPrototype(map, value, mode);
   15479             :   DCHECK(new_map->prototype() == *value);
   15480     4155243 :   JSObject::MigrateToMap(real_receiver, new_map);
   15481             : 
   15482             :   heap->ClearInstanceofCache();
   15483             :   DCHECK(size == object->Size());
   15484             :   return Just(true);
   15485             : }
   15486             : 
   15487             : // static
   15488          28 : void JSObject::SetImmutableProto(Handle<JSObject> object) {
   15489             :   DCHECK(!object->IsAccessCheckNeeded());  // Never called from JS
   15490             :   Handle<Map> map(object->map());
   15491             : 
   15492             :   // Nothing to do if prototype is already set.
   15493          49 :   if (map->is_immutable_proto()) return;
   15494             : 
   15495           7 :   Handle<Map> new_map = Map::TransitionToImmutableProto(map);
   15496           7 :   object->set_map(*new_map);
   15497             : }
   15498             : 
   15499     1163917 : void JSObject::EnsureCanContainElements(Handle<JSObject> object,
   15500     1163917 :                                         Arguments* args,
   15501             :                                         uint32_t first_arg,
   15502             :                                         uint32_t arg_count,
   15503             :                                         EnsureElementsMode mode) {
   15504             :   // Elements in |Arguments| are ordered backwards (because they're on the
   15505             :   // stack), but the method that's called here iterates over them in forward
   15506             :   // direction.
   15507             :   return EnsureCanContainElements(
   15508     1163917 :       object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode);
   15509             : }
   15510             : 
   15511             : 
   15512   511513831 : ElementsAccessor* JSObject::GetElementsAccessor() {
   15513   511513831 :   return ElementsAccessor::ForKind(GetElementsKind());
   15514             : }
   15515             : 
   15516             : 
   15517    21514742 : void JSObject::ValidateElements(Handle<JSObject> object) {
   15518             : #ifdef ENABLE_SLOW_DCHECKS
   15519             :   if (FLAG_enable_slow_asserts) {
   15520             :     ElementsAccessor* accessor = object->GetElementsAccessor();
   15521             :     accessor->Validate(object);
   15522             :   }
   15523             : #endif
   15524    21514742 : }
   15525             : 
   15526             : 
   15527     1965412 : static bool ShouldConvertToSlowElements(JSObject* object, uint32_t capacity,
   15528             :                                         uint32_t index,
   15529             :                                         uint32_t* new_capacity) {
   15530             :   STATIC_ASSERT(JSObject::kMaxUncheckedOldFastElementsLength <=
   15531             :                 JSObject::kMaxUncheckedFastElementsLength);
   15532     1965412 :   if (index < capacity) {
   15533      963452 :     *new_capacity = capacity;
   15534      963452 :     return false;
   15535             :   }
   15536     1001960 :   if (index - capacity >= JSObject::kMaxGap) return true;
   15537     1226180 :   *new_capacity = JSObject::NewElementsCapacity(index + 1);
   15538             :   DCHECK_LT(index, *new_capacity);
   15539     1226180 :   if (*new_capacity <= JSObject::kMaxUncheckedOldFastElementsLength ||
   15540       69292 :       (*new_capacity <= JSObject::kMaxUncheckedFastElementsLength &&
   15541             :        object->GetHeap()->InNewSpace(object))) {
   15542             :     return false;
   15543             :   }
   15544             :   // If the fast-case backing storage takes up roughly three times as
   15545             :   // much space (in machine words) as a dictionary backing storage
   15546             :   // would, the object should have slow elements.
   15547        1776 :   int used_elements = object->GetFastElementsUsage();
   15548             :   int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) *
   15549        1776 :                         SeededNumberDictionary::kEntrySize;
   15550        1776 :   return 3 * static_cast<uint32_t>(dictionary_size) <= *new_capacity;
   15551             : }
   15552             : 
   15553             : 
   15554      186957 : bool JSObject::WouldConvertToSlowElements(uint32_t index) {
   15555      186957 :   if (HasFastElements()) {
   15556             :     Handle<FixedArrayBase> backing_store(FixedArrayBase::cast(elements()));
   15557       36241 :     uint32_t capacity = static_cast<uint32_t>(backing_store->length());
   15558             :     uint32_t new_capacity;
   15559       36241 :     return ShouldConvertToSlowElements(this, capacity, index, &new_capacity);
   15560             :   }
   15561             :   return false;
   15562             : }
   15563             : 
   15564             : 
   15565        2961 : static ElementsKind BestFittingFastElementsKind(JSObject* object) {
   15566        2961 :   if (object->HasSloppyArgumentsElements()) {
   15567             :     return FAST_SLOPPY_ARGUMENTS_ELEMENTS;
   15568             :   }
   15569        2931 :   if (object->HasStringWrapperElements()) {
   15570             :     return FAST_STRING_WRAPPER_ELEMENTS;
   15571             :   }
   15572             :   DCHECK(object->HasDictionaryElements());
   15573             :   SeededNumberDictionary* dictionary = object->element_dictionary();
   15574             :   ElementsKind kind = FAST_HOLEY_SMI_ELEMENTS;
   15575     3957332 :   for (int i = 0; i < dictionary->Capacity(); i++) {
   15576             :     Object* key = dictionary->KeyAt(i);
   15577     1975837 :     if (key->IsNumber()) {
   15578      655163 :       Object* value = dictionary->ValueAt(i);
   15579      655163 :       if (!value->IsNumber()) return FAST_HOLEY_ELEMENTS;
   15580      655076 :       if (!value->IsSmi()) {
   15581       73635 :         if (!FLAG_unbox_double_arrays) return FAST_HOLEY_ELEMENTS;
   15582             :         kind = FAST_HOLEY_DOUBLE_ELEMENTS;
   15583             :       }
   15584             :     }
   15585             :   }
   15586             :   return kind;
   15587             : }
   15588             : 
   15589             : 
   15590     1736806 : static bool ShouldConvertToFastElements(JSObject* object,
   15591             :                                         SeededNumberDictionary* dictionary,
   15592             :                                         uint32_t index,
   15593             :                                         uint32_t* new_capacity) {
   15594             :   // If properties with non-standard attributes or accessors were added, we
   15595             :   // cannot go back to fast elements.
   15596     1736806 :   if (dictionary->requires_slow_elements()) return false;
   15597             : 
   15598             :   // Adding a property with this index will require slow elements.
   15599     1697738 :   if (index >= static_cast<uint32_t>(Smi::kMaxValue)) return false;
   15600             : 
   15601     1697224 :   if (object->IsJSArray()) {
   15602             :     Object* length = JSArray::cast(object)->length();
   15603      903797 :     if (!length->IsSmi()) return false;
   15604      902537 :     *new_capacity = static_cast<uint32_t>(Smi::cast(length)->value());
   15605             :   } else {
   15606      793427 :     *new_capacity = dictionary->max_number_key() + 1;
   15607             :   }
   15608     3391928 :   *new_capacity = Max(index + 1, *new_capacity);
   15609             : 
   15610     1695964 :   uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
   15611     1695964 :                              SeededNumberDictionary::kEntrySize;
   15612             : 
   15613             :   // Turn fast if the dictionary only saves 50% space.
   15614     1695964 :   return 2 * dictionary_size >= *new_capacity;
   15615             : }
   15616             : 
   15617             : 
   15618             : // static
   15619       32929 : MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object,
   15620             :                                              uint32_t index,
   15621             :                                              Handle<Object> value,
   15622             :                                              PropertyAttributes attributes) {
   15623       32929 :   MAYBE_RETURN_NULL(
   15624             :       AddDataElement(object, index, value, attributes, THROW_ON_ERROR));
   15625             :   return value;
   15626             : }
   15627             : 
   15628             : 
   15629             : // static
   15630     3711839 : Maybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
   15631             :                                      Handle<Object> value,
   15632             :                                      PropertyAttributes attributes,
   15633             :                                      ShouldThrow should_throw) {
   15634             :   DCHECK(object->map()->is_extensible());
   15635             : 
   15636             :   Isolate* isolate = object->GetIsolate();
   15637             : 
   15638     3711839 :   uint32_t old_length = 0;
   15639     3711839 :   uint32_t new_capacity = 0;
   15640             : 
   15641     3711839 :   if (object->IsJSArray()) {
   15642     1551585 :     CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length));
   15643             :   }
   15644             : 
   15645             :   ElementsKind kind = object->GetElementsKind();
   15646             :   FixedArrayBase* elements = object->elements();
   15647             :   ElementsKind dictionary_kind = DICTIONARY_ELEMENTS;
   15648     3711839 :   if (IsSloppyArgumentsElementsKind(kind)) {
   15649             :     elements = FixedArrayBase::cast(FixedArray::cast(elements)->get(1));
   15650             :     dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
   15651     3512763 :   } else if (IsStringWrapperElementsKind(kind)) {
   15652             :     dictionary_kind = SLOW_STRING_WRAPPER_ELEMENTS;
   15653             :   }
   15654             : 
   15655     3711839 :   if (attributes != NONE) {
   15656             :     kind = dictionary_kind;
   15657     3664462 :   } else if (elements->IsSeededNumberDictionary()) {
   15658             :     kind = ShouldConvertToFastElements(*object,
   15659             :                                        SeededNumberDictionary::cast(elements),
   15660     1736806 :                                        index, &new_capacity)
   15661             :                ? BestFittingFastElementsKind(*object)
   15662     1739767 :                : dictionary_kind;  // Overwrite in case of arguments.
   15663     1927656 :   } else if (ShouldConvertToSlowElements(
   15664             :                  *object, static_cast<uint32_t>(elements->length()), index,
   15665     1927656 :                  &new_capacity)) {
   15666             :     kind = dictionary_kind;
   15667             :   }
   15668             : 
   15669     3711839 :   ElementsKind to = value->OptimalElementsKind();
   15670     4272655 :   if (IsHoleyElementsKind(kind) || !object->IsJSArray() || index > old_length) {
   15671             :     to = GetHoleyElementsKind(to);
   15672             :     kind = GetHoleyElementsKind(kind);
   15673             :   }
   15674             :   to = GetMoreGeneralElementsKind(kind, to);
   15675             :   ElementsAccessor* accessor = ElementsAccessor::ForKind(to);
   15676     3711839 :   accessor->Add(object, index, value, attributes, new_capacity);
   15677             : 
   15678     3711839 :   if (object->IsJSArray() && index >= old_length) {
   15679             :     Handle<Object> new_length =
   15680     1322776 :         isolate->factory()->NewNumberFromUint(index + 1);
   15681     1322776 :     JSArray::cast(*object)->set_length(*new_length);
   15682             :   }
   15683             : 
   15684     3711839 :   return Just(true);
   15685             : }
   15686             : 
   15687             : 
   15688     1562733 : bool JSArray::SetLengthWouldNormalize(uint32_t new_length) {
   15689     1562733 :   if (!HasFastElements()) return false;
   15690     1537844 :   uint32_t capacity = static_cast<uint32_t>(elements()->length());
   15691             :   uint32_t new_capacity;
   15692     1539359 :   return JSArray::SetLengthWouldNormalize(GetHeap(), new_length) &&
   15693             :          ShouldConvertToSlowElements(this, capacity, new_length - 1,
   15694     1539359 :                                      &new_capacity);
   15695             : }
   15696             : 
   15697             : 
   15698             : const double AllocationSite::kPretenureRatio = 0.85;
   15699             : 
   15700             : 
   15701           0 : void AllocationSite::ResetPretenureDecision() {
   15702             :   set_pretenure_decision(kUndecided);
   15703             :   set_memento_found_count(0);
   15704             :   set_memento_create_count(0);
   15705           0 : }
   15706             : 
   15707             : 
   15708       44968 : PretenureFlag AllocationSite::GetPretenureMode() {
   15709             :   PretenureDecision mode = pretenure_decision();
   15710             :   // Zombie objects "decide" to be untenured.
   15711       44968 :   return mode == kTenure ? TENURED : NOT_TENURED;
   15712             : }
   15713             : 
   15714             : 
   15715           0 : bool AllocationSite::IsNestedSite() {
   15716             :   DCHECK(FLAG_trace_track_allocation_sites);
   15717           0 :   Object* current = GetHeap()->allocation_sites_list();
   15718           0 :   while (current->IsAllocationSite()) {
   15719             :     AllocationSite* current_site = AllocationSite::cast(current);
   15720           0 :     if (current_site->nested_site() == this) {
   15721             :       return true;
   15722             :     }
   15723             :     current = current_site->weak_next();
   15724             :   }
   15725             :   return false;
   15726             : }
   15727             : 
   15728             : template <AllocationSiteUpdateMode update_or_check>
   15729      635739 : bool AllocationSite::DigestTransitionFeedback(Handle<AllocationSite> site,
   15730             :                                               ElementsKind to_kind) {
   15731             :   Isolate* isolate = site->GetIsolate();
   15732             :   bool result = false;
   15733             : 
   15734     1244154 :   if (site->SitePointsToLiteral() && site->transition_info()->IsJSArray()) {
   15735             :     Handle<JSArray> transition_info =
   15736             :         handle(JSArray::cast(site->transition_info()));
   15737             :     ElementsKind kind = transition_info->GetElementsKind();
   15738             :     // if kind is holey ensure that to_kind is as well.
   15739      608415 :     if (IsHoleyElementsKind(kind)) {
   15740             :       to_kind = GetHoleyElementsKind(to_kind);
   15741             :     }
   15742      608415 :     if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
   15743             :       // If the array is huge, it's not likely to be defined in a local
   15744             :       // function, so we shouldn't make new instances of it very often.
   15745       61665 :       uint32_t length = 0;
   15746       61665 :       CHECK(transition_info->length()->ToArrayLength(&length));
   15747       61665 :       if (length <= kMaximumArrayBytesToPretransition) {
   15748             :         if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) {
   15749           0 :           return true;
   15750             :         }
   15751       61665 :         if (FLAG_trace_track_allocation_sites) {
   15752           0 :           bool is_nested = site->IsNestedSite();
   15753           0 :           PrintF(
   15754             :               "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
   15755             :               reinterpret_cast<void*>(*site),
   15756             :               is_nested ? "(nested)" : "",
   15757             :               ElementsKindToString(kind),
   15758           0 :               ElementsKindToString(to_kind));
   15759             :         }
   15760       61665 :         JSObject::TransitionElementsKind(transition_info, to_kind);
   15761       61665 :         site->dependent_code()->DeoptimizeDependentCodeGroup(
   15762             :             isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
   15763             :         result = true;
   15764             :       }
   15765             :     }
   15766             :   } else {
   15767             :     ElementsKind kind = site->GetElementsKind();
   15768             :     // if kind is holey ensure that to_kind is as well.
   15769       27324 :     if (IsHoleyElementsKind(kind)) {
   15770             :       to_kind = GetHoleyElementsKind(to_kind);
   15771             :     }
   15772       27324 :     if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
   15773             :       if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) return true;
   15774       23619 :       if (FLAG_trace_track_allocation_sites) {
   15775           0 :         PrintF("AllocationSite: JSArray %p site updated %s->%s\n",
   15776             :                reinterpret_cast<void*>(*site),
   15777             :                ElementsKindToString(kind),
   15778           0 :                ElementsKindToString(to_kind));
   15779             :       }
   15780       23619 :       site->SetElementsKind(to_kind);
   15781       23619 :       site->dependent_code()->DeoptimizeDependentCodeGroup(
   15782             :           isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
   15783             :       result = true;
   15784             :     }
   15785             :   }
   15786             :   return result;
   15787             : }
   15788             : 
   15789        3310 : AllocationSiteMode AllocationSite::GetMode(ElementsKind from, ElementsKind to) {
   15790        5926 :   if (IsFastSmiElementsKind(from) &&
   15791        2616 :       IsMoreGeneralElementsKindTransition(from, to)) {
   15792             :     return TRACK_ALLOCATION_SITE;
   15793             :   }
   15794             : 
   15795         694 :   return DONT_TRACK_ALLOCATION_SITE;
   15796             : }
   15797             : 
   15798           0 : const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) {
   15799           0 :   switch (decision) {
   15800             :     case kUndecided: return "undecided";
   15801           0 :     case kDontTenure: return "don't tenure";
   15802           0 :     case kMaybeTenure: return "maybe tenure";
   15803           0 :     case kTenure: return "tenure";
   15804           0 :     case kZombie: return "zombie";
   15805           0 :     default: UNREACHABLE();
   15806             :   }
   15807             :   return NULL;
   15808             : }
   15809             : 
   15810             : template <AllocationSiteUpdateMode update_or_check>
   15811     1727178 : bool JSObject::UpdateAllocationSite(Handle<JSObject> object,
   15812             :                                     ElementsKind to_kind) {
   15813     1727178 :   if (!object->IsJSArray()) return false;
   15814             : 
   15815             :   Heap* heap = object->GetHeap();
   15816     1309332 :   if (!heap->InNewSpace(*object)) return false;
   15817             : 
   15818             :   Handle<AllocationSite> site;
   15819             :   {
   15820             :     DisallowHeapAllocation no_allocation;
   15821             : 
   15822             :     AllocationMemento* memento =
   15823     1240030 :         heap->FindAllocationMemento<Heap::kForRuntime>(*object);
   15824     1240030 :     if (memento == NULL) return false;
   15825             : 
   15826             :     // Walk through to the Allocation Site
   15827      635739 :     site = handle(memento->GetAllocationSite());
   15828             :   }
   15829             :   return AllocationSite::DigestTransitionFeedback<update_or_check>(site,
   15830      635739 :                                                                    to_kind);
   15831             : }
   15832             : 
   15833             : template bool
   15834             : JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kCheckOnly>(
   15835             :     Handle<JSObject> object, ElementsKind to_kind);
   15836             : 
   15837             : template bool JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kUpdate>(
   15838             :     Handle<JSObject> object, ElementsKind to_kind);
   15839             : 
   15840      445332 : void JSObject::TransitionElementsKind(Handle<JSObject> object,
   15841             :                                       ElementsKind to_kind) {
   15842             :   ElementsKind from_kind = object->GetElementsKind();
   15843             : 
   15844      445332 :   if (IsFastHoleyElementsKind(from_kind)) {
   15845             :     to_kind = GetHoleyElementsKind(to_kind);
   15846             :   }
   15847             : 
   15848      890664 :   if (from_kind == to_kind) return;
   15849             : 
   15850             :   // This method should never be called for any other case.
   15851             :   DCHECK(IsFastElementsKind(from_kind));
   15852             :   DCHECK(IsFastElementsKind(to_kind));
   15853             :   DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
   15854             : 
   15855      445243 :   UpdateAllocationSite(object, to_kind);
   15856      814759 :   if (object->elements() == object->GetHeap()->empty_fixed_array() ||
   15857             :       IsFastDoubleElementsKind(from_kind) ==
   15858             :           IsFastDoubleElementsKind(to_kind)) {
   15859             :     // No change is needed to the elements() buffer, the transition
   15860             :     // only requires a map change.
   15861      437344 :     Handle<Map> new_map = GetElementsTransitionMap(object, to_kind);
   15862      437344 :     MigrateToMap(object, new_map);
   15863             :     if (FLAG_trace_elements_transitions) {
   15864             :       Handle<FixedArrayBase> elms(object->elements());
   15865             :       PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms);
   15866             :     }
   15867             :   } else {
   15868             :     DCHECK((IsFastSmiElementsKind(from_kind) &&
   15869             :             IsFastDoubleElementsKind(to_kind)) ||
   15870             :            (IsFastDoubleElementsKind(from_kind) &&
   15871             :             IsFastObjectElementsKind(to_kind)));
   15872        7899 :     uint32_t c = static_cast<uint32_t>(object->elements()->length());
   15873        7899 :     ElementsAccessor::ForKind(to_kind)->GrowCapacityAndConvert(object, c);
   15874             :   }
   15875             : }
   15876             : 
   15877             : 
   15878             : // static
   15879           0 : bool Map::IsValidElementsTransition(ElementsKind from_kind,
   15880             :                                     ElementsKind to_kind) {
   15881             :   // Transitions can't go backwards.
   15882           0 :   if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
   15883             :     return false;
   15884             :   }
   15885             : 
   15886             :   // Transitions from HOLEY -> PACKED are not allowed.
   15887           0 :   return !IsFastHoleyElementsKind(from_kind) ||
   15888           0 :       IsFastHoleyElementsKind(to_kind);
   15889             : }
   15890             : 
   15891             : 
   15892     4365334 : bool JSArray::HasReadOnlyLength(Handle<JSArray> array) {
   15893             :   Map* map = array->map();
   15894             :   // Fast path: "length" is the first fast property of arrays. Since it's not
   15895             :   // configurable, it's guaranteed to be the first in the descriptor array.
   15896     4365334 :   if (!map->is_dictionary_map()) {
   15897             :     DCHECK(map->instance_descriptors()->GetKey(0) ==
   15898             :            array->GetHeap()->length_string());
   15899     8693438 :     return map->instance_descriptors()->GetDetails(0).IsReadOnly();
   15900             :   }
   15901             : 
   15902             :   Isolate* isolate = array->GetIsolate();
   15903             :   LookupIterator it(array, isolate->factory()->length_string(), array,
   15904       18615 :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
   15905       18615 :   CHECK_EQ(LookupIterator::ACCESSOR, it.state());
   15906       18615 :   return it.IsReadOnly();
   15907             : }
   15908             : 
   15909             : 
   15910     1519342 : bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
   15911             :                                         uint32_t index) {
   15912     1519342 :   uint32_t length = 0;
   15913     1519342 :   CHECK(array->length()->ToArrayLength(&length));
   15914     1519342 :   if (length <= index) return HasReadOnlyLength(array);
   15915             :   return false;
   15916             : }
   15917             : 
   15918             : 
   15919             : template <typename BackingStore>
   15920      439690 : static int FastHoleyElementsUsage(JSObject* object, BackingStore* store) {
   15921             :   Isolate* isolate = store->GetIsolate();
   15922             :   int limit = object->IsJSArray()
   15923             :                   ? Smi::cast(JSArray::cast(object)->length())->value()
   15924      439690 :                   : store->length();
   15925             :   int used = 0;
   15926   523603629 :   for (int i = 0; i < limit; ++i) {
   15927   523163939 :     if (!store->is_the_hole(isolate, i)) ++used;
   15928             :   }
   15929      439690 :   return used;
   15930             : }
   15931             : 
   15932             : 
   15933      466738 : int JSObject::GetFastElementsUsage() {
   15934             :   FixedArrayBase* store = elements();
   15935      466738 :   switch (GetElementsKind()) {
   15936             :     case FAST_SMI_ELEMENTS:
   15937             :     case FAST_DOUBLE_ELEMENTS:
   15938             :     case FAST_ELEMENTS:
   15939             :       return IsJSArray() ? Smi::cast(JSArray::cast(this)->length())->value()
   15940       54006 :                          : store->length();
   15941             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
   15942             :       store = SloppyArgumentsElements::cast(store)->arguments();
   15943             :     // Fall through.
   15944             :     case FAST_HOLEY_SMI_ELEMENTS:
   15945             :     case FAST_HOLEY_ELEMENTS:
   15946             :     case FAST_STRING_WRAPPER_ELEMENTS:
   15947      439542 :       return FastHoleyElementsUsage(this, FixedArray::cast(store));
   15948             :     case FAST_HOLEY_DOUBLE_ELEMENTS:
   15949         193 :       if (elements()->length() == 0) return 0;
   15950         148 :       return FastHoleyElementsUsage(this, FixedDoubleArray::cast(store));
   15951             : 
   15952             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
   15953             :     case SLOW_STRING_WRAPPER_ELEMENTS:
   15954             :     case DICTIONARY_ELEMENTS:
   15955             :     case NO_ELEMENTS:
   15956             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
   15957             :     case TYPE##_ELEMENTS:                                                    \
   15958             : 
   15959             :     TYPED_ARRAYS(TYPED_ARRAY_CASE)
   15960             : #undef TYPED_ARRAY_CASE
   15961           0 :     UNREACHABLE();
   15962             :   }
   15963             :   return 0;
   15964             : }
   15965             : 
   15966             : 
   15967             : // Certain compilers request function template instantiation when they
   15968             : // see the definition of the other template functions in the
   15969             : // class. This requires us to have the template functions put
   15970             : // together, so even though this function belongs in objects-debug.cc,
   15971             : // we keep it here instead to satisfy certain compilers.
   15972             : #ifdef OBJECT_PRINT
   15973             : template <typename Derived, typename Shape, typename Key>
   15974             : void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) {  // NOLINT
   15975             :   Isolate* isolate = this->GetIsolate();
   15976             :   int capacity = this->Capacity();
   15977             :   for (int i = 0; i < capacity; i++) {
   15978             :     Object* k = this->KeyAt(i);
   15979             :     if (this->IsKey(isolate, k)) {
   15980             :       os << "\n   ";
   15981             :       if (k->IsString()) {
   15982             :         String::cast(k)->StringPrint(os);
   15983             :       } else {
   15984             :         os << Brief(k);
   15985             :       }
   15986             :       os << ": " << Brief(this->ValueAt(i)) << " ";
   15987             :       this->DetailsAt(i).PrintAsSlowTo(os);
   15988             :     }
   15989             :   }
   15990             : }
   15991             : template <typename Derived, typename Shape, typename Key>
   15992             : void Dictionary<Derived, Shape, Key>::Print() {
   15993             :   OFStream os(stdout);
   15994             :   Print(os);
   15995             : }
   15996             : #endif
   15997             : 
   15998             : 
   15999        5152 : MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
   16000             :                                                          bool* done) {
   16001             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
   16002        5152 :   return GetPropertyWithInterceptorInternal(it, it->GetInterceptor(), done);
   16003             : }
   16004             : 
   16005    66902001 : Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object,
   16006             :                                            Handle<Name> name) {
   16007             :   LookupIterator it = LookupIterator::PropertyOrElement(
   16008    66902001 :       name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   16009    66902001 :   return HasProperty(&it);
   16010             : }
   16011             : 
   16012             : 
   16013          20 : Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object,
   16014             :                                              uint32_t index) {
   16015             :   Isolate* isolate = object->GetIsolate();
   16016             :   LookupIterator it(isolate, object, index, object,
   16017             :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
   16018          20 :   return HasProperty(&it);
   16019             : }
   16020             : 
   16021             : 
   16022           6 : Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
   16023             :                                                    Handle<Name> name) {
   16024             :   LookupIterator it = LookupIterator::PropertyOrElement(
   16025           6 :       name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   16026           6 :   Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
   16027           6 :   return maybe_result.IsJust() ? Just(it.state() == LookupIterator::ACCESSOR)
   16028          12 :                                : Nothing<bool>();
   16029             : }
   16030             : 
   16031        3448 : int FixedArrayBase::GetMaxLengthForNewSpaceAllocation(ElementsKind kind) {
   16032             :   return ((kMaxRegularHeapObjectSize - FixedArrayBase::kHeaderSize) >>
   16033        3448 :           ElementsKindToShiftSize(kind));
   16034             : }
   16035             : 
   16036       49011 : bool JSObject::WasConstructedFromApiFunction() {
   16037             :   auto instance_type = map()->instance_type();
   16038       49011 :   bool is_api_object = instance_type == JS_API_OBJECT_TYPE ||
   16039       49011 :                        instance_type == JS_SPECIAL_API_OBJECT_TYPE;
   16040             : #ifdef ENABLE_SLOW_DCHECKS
   16041             :   if (FLAG_enable_slow_asserts) {
   16042             :     Object* maybe_constructor = map()->GetConstructor();
   16043             :     if (maybe_constructor->IsJSFunction()) {
   16044             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
   16045             :       if (constructor->shared()->IsApiFunction()) {
   16046             :         DCHECK(is_api_object);
   16047             :       } else {
   16048             :         DCHECK(!is_api_object);
   16049             :       }
   16050             :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
   16051             :       DCHECK(is_api_object);
   16052             :     } else {
   16053             :       return false;
   16054             :     }
   16055             :   }
   16056             : #endif
   16057       49011 :   return is_api_object;
   16058             : }
   16059             : 
   16060         210 : const char* Symbol::PrivateSymbolToName() const {
   16061        7140 :   Heap* heap = GetIsolate()->heap();
   16062             : #define SYMBOL_CHECK_AND_PRINT(name) \
   16063             :   if (this == heap->name()) return #name;
   16064        7140 :   PRIVATE_SYMBOL_LIST(SYMBOL_CHECK_AND_PRINT)
   16065             : #undef SYMBOL_CHECK_AND_PRINT
   16066         210 :   return "UNKNOWN";
   16067             : }
   16068             : 
   16069             : 
   16070         227 : void Symbol::SymbolShortPrint(std::ostream& os) {
   16071         227 :   os << "<Symbol:";
   16072         227 :   if (!name()->IsUndefined(GetIsolate())) {
   16073          17 :     os << " ";
   16074             :     HeapStringAllocator allocator;
   16075             :     StringStream accumulator(&allocator);
   16076          17 :     String::cast(name())->StringShortPrint(&accumulator, false);
   16077          51 :     os << accumulator.ToCString().get();
   16078             :   } else {
   16079         210 :     os << " (" << PrivateSymbolToName() << ")";
   16080             :   }
   16081         227 :   os << ">";
   16082         227 : }
   16083             : 
   16084             : 
   16085             : // StringSharedKeys are used as keys in the eval cache.
   16086           0 : class StringSharedKey : public HashTableKey {
   16087             :  public:
   16088             :   // This tuple unambiguously identifies calls to eval() or
   16089             :   // CreateDynamicFunction() (such as through the Function() constructor).
   16090             :   // * source is the string passed into eval(). For dynamic functions, this is
   16091             :   //   the effective source for the function, some of which is implicitly
   16092             :   //   generated.
   16093             :   // * shared is the shared function info for the function containing the call
   16094             :   //   to eval(). for dynamic functions, shared is the native context closure.
   16095             :   // * When positive, position is the position in the source where eval is
   16096             :   //   called. When negative, position is the negation of the position in the
   16097             :   //   dynamic function's effective source where the ')' ends the parameters.
   16098             :   StringSharedKey(Handle<String> source, Handle<SharedFunctionInfo> shared,
   16099             :                   LanguageMode language_mode, int position)
   16100             :       : source_(source),
   16101             :         shared_(shared),
   16102             :         language_mode_(language_mode),
   16103     7850873 :         position_(position) {}
   16104             : 
   16105     9648723 :   bool IsMatch(Object* other) override {
   16106             :     DisallowHeapAllocation no_allocation;
   16107     9648723 :     if (!other->IsFixedArray()) {
   16108     2549774 :       if (!other->IsNumber()) return false;
   16109     2549774 :       uint32_t other_hash = static_cast<uint32_t>(other->Number());
   16110     2549774 :       return Hash() == other_hash;
   16111             :     }
   16112             :     FixedArray* other_array = FixedArray::cast(other);
   16113             :     SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
   16114     7098949 :     if (shared != *shared_) return false;
   16115             :     int language_unchecked = Smi::cast(other_array->get(2))->value();
   16116             :     DCHECK(is_valid_language_mode(language_unchecked));
   16117     6776263 :     LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
   16118     6776263 :     if (language_mode != language_mode_) return false;
   16119             :     int position = Smi::cast(other_array->get(3))->value();
   16120     6749831 :     if (position != position_) return false;
   16121             :     String* source = String::cast(other_array->get(1));
   16122     6749801 :     return source->Equals(*source_);
   16123             :   }
   16124             : 
   16125    12129647 :   static uint32_t StringSharedHashHelper(String* source,
   16126             :                                          SharedFunctionInfo* shared,
   16127             :                                          LanguageMode language_mode,
   16128             :                                          int position) {
   16129             :     uint32_t hash = source->Hash();
   16130    12129647 :     if (shared->HasSourceCode()) {
   16131             :       // Instead of using the SharedFunctionInfo pointer in the hash
   16132             :       // code computation, we use a combination of the hash of the
   16133             :       // script source code and the start position of the calling scope.
   16134             :       // We do this to ensure that the cache entries can survive garbage
   16135             :       // collection.
   16136             :       Script* script(Script::cast(shared->script()));
   16137    12129647 :       hash ^= String::cast(script->source())->Hash();
   16138             :       STATIC_ASSERT(LANGUAGE_END == 2);
   16139    12129647 :       if (is_strict(language_mode)) hash ^= 0x8000;
   16140    12129647 :       hash += position;
   16141             :     }
   16142    12129647 :     return hash;
   16143             :   }
   16144             : 
   16145    11954613 :   uint32_t Hash() override {
   16146             :     return StringSharedHashHelper(*source_, *shared_, language_mode_,
   16147    23909226 :                                   position_);
   16148             :   }
   16149             : 
   16150     1019703 :   uint32_t HashForObject(Object* obj) override {
   16151             :     DisallowHeapAllocation no_allocation;
   16152     1019703 :     if (obj->IsNumber()) {
   16153      844669 :       return static_cast<uint32_t>(obj->Number());
   16154             :     }
   16155             :     FixedArray* other_array = FixedArray::cast(obj);
   16156             :     SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
   16157             :     String* source = String::cast(other_array->get(1));
   16158             :     int language_unchecked = Smi::cast(other_array->get(2))->value();
   16159             :     DCHECK(is_valid_language_mode(language_unchecked));
   16160      175034 :     LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
   16161             :     int position = Smi::cast(other_array->get(3))->value();
   16162      175034 :     return StringSharedHashHelper(source, shared, language_mode, position);
   16163             :   }
   16164             : 
   16165             : 
   16166     1985370 :   Handle<Object> AsHandle(Isolate* isolate) override {
   16167     1985370 :     Handle<FixedArray> array = isolate->factory()->NewFixedArray(4);
   16168     1985370 :     array->set(0, *shared_);
   16169     1985370 :     array->set(1, *source_);
   16170     1985370 :     array->set(2, Smi::FromInt(language_mode_));
   16171     1985370 :     array->set(3, Smi::FromInt(position_));
   16172     1985370 :     return array;
   16173             :   }
   16174             : 
   16175             :  private:
   16176             :   Handle<String> source_;
   16177             :   Handle<SharedFunctionInfo> shared_;
   16178             :   LanguageMode language_mode_;
   16179             :   int position_;
   16180             : };
   16181             : 
   16182             : // static
   16183          30 : const char* JSPromise::Status(int status) {
   16184          30 :   switch (status) {
   16185             :     case v8::Promise::kFulfilled:
   16186             :       return "resolved";
   16187             :     case v8::Promise::kPending:
   16188          12 :       return "pending";
   16189             :     case v8::Promise::kRejected:
   16190           0 :       return "rejected";
   16191             :   }
   16192           0 :   UNREACHABLE();
   16193             :   return NULL;
   16194             : }
   16195             : 
   16196             : namespace {
   16197             : 
   16198      593209 : JSRegExp::Flags RegExpFlagsFromString(Handle<String> flags, bool* success) {
   16199             :   JSRegExp::Flags value = JSRegExp::kNone;
   16200             :   int length = flags->length();
   16201             :   // A longer flags string cannot be valid.
   16202      593209 :   if (length > JSRegExp::FlagCount()) return JSRegExp::Flags(0);
   16203       97165 :   for (int i = 0; i < length; i++) {
   16204             :     JSRegExp::Flag flag = JSRegExp::kNone;
   16205       97445 :     switch (flags->Get(i)) {
   16206             :       case 'g':
   16207             :         flag = JSRegExp::kGlobal;
   16208             :         break;
   16209             :       case 'i':
   16210             :         flag = JSRegExp::kIgnoreCase;
   16211       76841 :         break;
   16212             :       case 'm':
   16213             :         flag = JSRegExp::kMultiline;
   16214         719 :         break;
   16215             :       case 's':
   16216          84 :         if (FLAG_harmony_regexp_dotall) {
   16217             :           flag = JSRegExp::kDotAll;
   16218             :         } else {
   16219          28 :           return JSRegExp::Flags(0);
   16220             :         }
   16221             :         break;
   16222             :       case 'u':
   16223             :         flag = JSRegExp::kUnicode;
   16224        1835 :         break;
   16225             :       case 'y':
   16226             :         flag = JSRegExp::kSticky;
   16227         130 :         break;
   16228             :       default:
   16229          43 :         return JSRegExp::Flags(0);
   16230             :     }
   16231             :     // Duplicate flag.
   16232       97374 :     if (value & flag) return JSRegExp::Flags(0);
   16233             :     value |= flag;
   16234             :   }
   16235      592929 :   *success = true;
   16236      592929 :   return value;
   16237             : }
   16238             : 
   16239             : }  // namespace
   16240             : 
   16241             : 
   16242             : // static
   16243      125431 : MaybeHandle<JSRegExp> JSRegExp::New(Handle<String> pattern, Flags flags) {
   16244             :   Isolate* isolate = pattern->GetIsolate();
   16245      125431 :   Handle<JSFunction> constructor = isolate->regexp_function();
   16246             :   Handle<JSRegExp> regexp =
   16247      125431 :       Handle<JSRegExp>::cast(isolate->factory()->NewJSObject(constructor));
   16248             : 
   16249      125431 :   return JSRegExp::Initialize(regexp, pattern, flags);
   16250             : }
   16251             : 
   16252             : 
   16253             : // static
   16254      122017 : Handle<JSRegExp> JSRegExp::Copy(Handle<JSRegExp> regexp) {
   16255             :   Isolate* const isolate = regexp->GetIsolate();
   16256      122017 :   return Handle<JSRegExp>::cast(isolate->factory()->CopyJSObject(regexp));
   16257             : }
   16258             : 
   16259             : 
   16260             : template <typename Char>
   16261      719988 : inline int CountRequiredEscapes(Handle<String> source) {
   16262             :   DisallowHeapAllocation no_gc;
   16263             :   int escapes = 0;
   16264             :   Vector<const Char> src = source->GetCharVector<Char>();
   16265    16857335 :   for (int i = 0; i < src.length(); i++) {
   16266    16137347 :     if (src[i] == '\\') {
   16267             :       // Escape. Skip next character;
   16268      152815 :       i++;
   16269    15984532 :     } else if (src[i] == '/') {
   16270             :       // Not escaped forward-slash needs escape.
   16271        2627 :       escapes++;
   16272             :     }
   16273             :   }
   16274      719988 :   return escapes;
   16275             : }
   16276             : 
   16277             : 
   16278             : template <typename Char, typename StringType>
   16279         958 : inline Handle<StringType> WriteEscapedRegExpSource(Handle<String> source,
   16280             :                                                    Handle<StringType> result) {
   16281             :   DisallowHeapAllocation no_gc;
   16282             :   Vector<const Char> src = source->GetCharVector<Char>();
   16283         958 :   Vector<Char> dst(result->GetChars(), result->length());
   16284             :   int s = 0;
   16285             :   int d = 0;
   16286       52745 :   while (s < src.length()) {
   16287       50829 :     if (src[s] == '\\') {
   16288             :       // Escape. Copy this and next character.
   16289        6196 :       dst[d++] = src[s++];
   16290        3098 :       if (s == src.length()) break;
   16291       47731 :     } else if (src[s] == '/') {
   16292             :       // Not escaped forward-slash needs escape.
   16293        5254 :       dst[d++] = '\\';
   16294             :     }
   16295      152487 :     dst[d++] = src[s++];
   16296             :   }
   16297             :   DCHECK_EQ(result->length(), d);
   16298         958 :   return result;
   16299             : }
   16300             : 
   16301             : 
   16302      719988 : MaybeHandle<String> EscapeRegExpSource(Isolate* isolate,
   16303             :                                        Handle<String> source) {
   16304             :   DCHECK(source->IsFlat());
   16305      719988 :   if (source->length() == 0) return isolate->factory()->query_colon_string();
   16306      719988 :   bool one_byte = source->IsOneByteRepresentationUnderneath();
   16307             :   int escapes = one_byte ? CountRequiredEscapes<uint8_t>(source)
   16308      719988 :                          : CountRequiredEscapes<uc16>(source);
   16309      719988 :   if (escapes == 0) return source;
   16310         958 :   int length = source->length() + escapes;
   16311         958 :   if (one_byte) {
   16312             :     Handle<SeqOneByteString> result;
   16313        1916 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   16314             :                                isolate->factory()->NewRawOneByteString(length),
   16315             :                                String);
   16316         958 :     return WriteEscapedRegExpSource<uint8_t>(source, result);
   16317             :   } else {
   16318             :     Handle<SeqTwoByteString> result;
   16319           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   16320             :                                isolate->factory()->NewRawTwoByteString(length),
   16321             :                                String);
   16322           0 :     return WriteEscapedRegExpSource<uc16>(source, result);
   16323             :   }
   16324             : }
   16325             : 
   16326             : 
   16327             : // static
   16328      593209 : MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
   16329             :                                            Handle<String> source,
   16330             :                                            Handle<String> flags_string) {
   16331             :   Isolate* isolate = source->GetIsolate();
   16332      593209 :   bool success = false;
   16333      593209 :   Flags flags = RegExpFlagsFromString(flags_string, &success);
   16334      593209 :   if (!success) {
   16335         560 :     THROW_NEW_ERROR(
   16336             :         isolate,
   16337             :         NewSyntaxError(MessageTemplate::kInvalidRegExpFlags, flags_string),
   16338             :         JSRegExp);
   16339             :   }
   16340      592929 :   return Initialize(regexp, source, flags);
   16341             : }
   16342             : 
   16343             : 
   16344             : // static
   16345      719988 : MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
   16346             :                                            Handle<String> source, Flags flags) {
   16347             :   Isolate* isolate = regexp->GetIsolate();
   16348             :   Factory* factory = isolate->factory();
   16349             :   // If source is the empty string we set it to "(?:)" instead as
   16350             :   // suggested by ECMA-262, 5th, section 15.10.4.1.
   16351      719988 :   if (source->length() == 0) source = factory->query_colon_string();
   16352             : 
   16353      719988 :   source = String::Flatten(source);
   16354             : 
   16355             :   Handle<String> escaped_source;
   16356     1439976 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, escaped_source,
   16357             :                              EscapeRegExpSource(isolate, source), JSRegExp);
   16358             : 
   16359     1439976 :   RETURN_ON_EXCEPTION(isolate, RegExpImpl::Compile(regexp, source, flags),
   16360             :                       JSRegExp);
   16361             : 
   16362      716426 :   regexp->set_source(*escaped_source);
   16363      716426 :   regexp->set_flags(Smi::FromInt(flags));
   16364             : 
   16365             :   Map* map = regexp->map();
   16366      716426 :   Object* constructor = map->GetConstructor();
   16367     1432852 :   if (constructor->IsJSFunction() &&
   16368             :       JSFunction::cast(constructor)->initial_map() == map) {
   16369             :     // If we still have the original map, set in-object properties directly.
   16370             :     regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, Smi::kZero,
   16371      716128 :                                   SKIP_WRITE_BARRIER);
   16372             :   } else {
   16373             :     // Map has changed, so use generic, but slower, method.
   16374         596 :     RETURN_ON_EXCEPTION(isolate, JSReceiver::SetProperty(
   16375             :                                      regexp, factory->lastIndex_string(),
   16376             :                                      Handle<Smi>(Smi::kZero, isolate), STRICT),
   16377             :                         JSRegExp);
   16378             :   }
   16379             : 
   16380             :   return regexp;
   16381             : }
   16382             : 
   16383             : 
   16384             : // RegExpKey carries the source and flags of a regular expression as key.
   16385           0 : class RegExpKey : public HashTableKey {
   16386             :  public:
   16387             :   RegExpKey(Handle<String> string, JSRegExp::Flags flags)
   16388     2845370 :       : string_(string), flags_(Smi::FromInt(flags)) {}
   16389             : 
   16390             :   // Rather than storing the key in the hash table, a pointer to the
   16391             :   // stored value is stored where the key should be.  IsMatch then
   16392             :   // compares the search key to the found object, rather than comparing
   16393             :   // a key to a key.
   16394      845523 :   bool IsMatch(Object* obj) override {
   16395             :     FixedArray* val = FixedArray::cast(obj);
   16396      845523 :     return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex)))
   16397     1201983 :         && (flags_ == val->get(JSRegExp::kFlagsIndex));
   16398             :   }
   16399             : 
   16400     2845370 :   uint32_t Hash() override { return RegExpHash(*string_, flags_); }
   16401             : 
   16402           0 :   Handle<Object> AsHandle(Isolate* isolate) override {
   16403             :     // Plain hash maps, which is where regexp keys are used, don't
   16404             :     // use this function.
   16405           0 :     UNREACHABLE();
   16406             :     return MaybeHandle<Object>().ToHandleChecked();
   16407             :   }
   16408             : 
   16409      511813 :   uint32_t HashForObject(Object* obj) override {
   16410             :     FixedArray* val = FixedArray::cast(obj);
   16411             :     return RegExpHash(String::cast(val->get(JSRegExp::kSourceIndex)),
   16412      511813 :                       Smi::cast(val->get(JSRegExp::kFlagsIndex)));
   16413             :   }
   16414             : 
   16415     1934498 :   static uint32_t RegExpHash(String* string, Smi* flags) {
   16416     1934498 :     return string->Hash() + flags->value();
   16417             :   }
   16418             : 
   16419             :   Handle<String> string_;
   16420             :   Smi* flags_;
   16421             : };
   16422             : 
   16423             : 
   16424       55774 : Handle<Object> OneByteStringKey::AsHandle(Isolate* isolate) {
   16425       55774 :   if (hash_field_ == 0) Hash();
   16426       55774 :   return isolate->factory()->NewOneByteInternalizedString(string_, hash_field_);
   16427             : }
   16428             : 
   16429             : 
   16430           0 : Handle<Object> TwoByteStringKey::AsHandle(Isolate* isolate) {
   16431           0 :   if (hash_field_ == 0) Hash();
   16432           0 :   return isolate->factory()->NewTwoByteInternalizedString(string_, hash_field_);
   16433             : }
   16434             : 
   16435             : 
   16436      115049 : Handle<Object> SeqOneByteSubStringKey::AsHandle(Isolate* isolate) {
   16437      115049 :   if (hash_field_ == 0) Hash();
   16438             :   return isolate->factory()->NewOneByteInternalizedSubString(
   16439      115049 :       string_, from_, length_, hash_field_);
   16440             : }
   16441             : 
   16442             : 
   16443      163654 : bool SeqOneByteSubStringKey::IsMatch(Object* string) {
   16444      327308 :   Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
   16445      163654 :   return String::cast(string)->IsOneByteEqualTo(chars);
   16446             : }
   16447             : 
   16448             : 
   16449             : // InternalizedStringKey carries a string/internalized-string object as key.
   16450           0 : class InternalizedStringKey : public HashTableKey {
   16451             :  public:
   16452             :   explicit InternalizedStringKey(Handle<String> string)
   16453    22836612 :       : string_(String::Flatten(string)) {}
   16454             : 
   16455    30597821 :   bool IsMatch(Object* string) override {
   16456    30597821 :     return String::cast(string)->Equals(*string_);
   16457             :   }
   16458             : 
   16459    49481142 :   uint32_t Hash() override { return string_->Hash(); }
   16460             : 
   16461      551700 :   uint32_t HashForObject(Object* other) override {
   16462      551700 :     return String::cast(other)->Hash();
   16463             :   }
   16464             : 
   16465     1904345 :   Handle<Object> AsHandle(Isolate* isolate) override {
   16466             :     // Internalize the string if possible.
   16467             :     MaybeHandle<Map> maybe_map =
   16468     1904345 :         isolate->factory()->InternalizedStringMapForString(string_);
   16469             :     Handle<Map> map;
   16470     1904346 :     if (maybe_map.ToHandle(&map)) {
   16471             :       string_->set_map_no_write_barrier(*map);
   16472             :       DCHECK(string_->IsInternalizedString());
   16473       10904 :       return string_;
   16474             :     }
   16475     1893442 :     if (FLAG_thin_strings) {
   16476             :       // External strings get special treatment, to avoid copying their
   16477             :       // contents.
   16478     1331495 :       if (string_->IsExternalOneByteString()) {
   16479             :         return isolate->factory()
   16480           6 :             ->InternalizeExternalString<ExternalOneByteString>(string_);
   16481     1331490 :       } else if (string_->IsExternalTwoByteString()) {
   16482             :         return isolate->factory()
   16483           0 :             ->InternalizeExternalString<ExternalTwoByteString>(string_);
   16484             :       }
   16485             :     }
   16486             :     // Otherwise allocate a new internalized string.
   16487             :     return isolate->factory()->NewInternalizedStringImpl(
   16488     1893439 :         string_, string_->length(), string_->hash_field());
   16489             :   }
   16490             : 
   16491             :   static uint32_t StringHash(Object* obj) {
   16492             :     return String::cast(obj)->Hash();
   16493             :   }
   16494             : 
   16495             :  private:
   16496             :   Handle<String> string_;
   16497             : };
   16498             : 
   16499             : 
   16500             : template<typename Derived, typename Shape, typename Key>
   16501       53346 : void HashTable<Derived, Shape, Key>::IteratePrefix(ObjectVisitor* v) {
   16502             :   BodyDescriptorBase::IteratePointers(this, 0, kElementsStartOffset, v);
   16503       53346 : }
   16504             : 
   16505             : 
   16506             : template<typename Derived, typename Shape, typename Key>
   16507       71432 : void HashTable<Derived, Shape, Key>::IterateElements(ObjectVisitor* v) {
   16508             :   BodyDescriptorBase::IteratePointers(this, kElementsStartOffset,
   16509       71432 :                                       kHeaderSize + length() * kPointerSize, v);
   16510       71432 : }
   16511             : 
   16512             : 
   16513             : template<typename Derived, typename Shape, typename Key>
   16514     7433054 : Handle<Derived> HashTable<Derived, Shape, Key>::New(
   16515             :     Isolate* isolate,
   16516             :     int at_least_space_for,
   16517             :     MinimumCapacity capacity_option,
   16518             :     PretenureFlag pretenure) {
   16519             :   DCHECK(0 <= at_least_space_for);
   16520             :   DCHECK_IMPLIES(capacity_option == USE_CUSTOM_MINIMUM_CAPACITY,
   16521             :                  base::bits::IsPowerOfTwo32(at_least_space_for));
   16522             : 
   16523             :   int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
   16524             :                      ? at_least_space_for
   16525     7433054 :                      : ComputeCapacity(at_least_space_for);
   16526     7433054 :   if (capacity > HashTable::kMaxCapacity) {
   16527           0 :     v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
   16528             :   }
   16529     7433054 :   return New(isolate, capacity, pretenure);
   16530             : }
   16531             : 
   16532             : template <typename Derived, typename Shape, typename Key>
   16533     7433338 : Handle<Derived> HashTable<Derived, Shape, Key>::New(Isolate* isolate,
   16534             :                                                     int capacity,
   16535             :                                                     PretenureFlag pretenure) {
   16536             :   Factory* factory = isolate->factory();
   16537             :   int length = EntryToIndex(capacity);
   16538     7433338 :   Handle<FixedArray> array = factory->NewFixedArray(length, pretenure);
   16539             :   array->set_map_no_write_barrier(Shape::GetMap(isolate));
   16540             :   Handle<Derived> table = Handle<Derived>::cast(array);
   16541             : 
   16542             :   table->SetNumberOfElements(0);
   16543             :   table->SetNumberOfDeletedElements(0);
   16544             :   table->SetCapacity(capacity);
   16545     7433338 :   return table;
   16546             : }
   16547             : 
   16548             : // Find entry for key otherwise return kNotFound.
   16549             : template <typename Derived, typename Shape>
   16550    94104490 : int NameDictionaryBase<Derived, Shape>::FindEntry(Handle<Name> key) {
   16551    94104490 :   if (!key->IsUniqueName()) {
   16552           0 :     return DerivedDictionary::FindEntry(key);
   16553             :   }
   16554             : 
   16555             :   // Optimized for unique names. Knowledge of the key type allows:
   16556             :   // 1. Move the check if the key is unique out of the loop.
   16557             :   // 2. Avoid comparing hash codes in unique-to-unique comparison.
   16558             :   // 3. Detect a case when a dictionary key is not unique but the key is.
   16559             :   //    In case of positive result the dictionary key may be replaced by the
   16560             :   //    internalized string with minimal performance penalty. It gives a chance
   16561             :   //    to perform further lookups in code stubs (and significant performance
   16562             :   //    boost a certain style of code).
   16563             : 
   16564             :   // EnsureCapacity will guarantee the hash table is never full.
   16565    94104490 :   uint32_t capacity = this->Capacity();
   16566             :   uint32_t entry = Derived::FirstProbe(key->Hash(), capacity);
   16567             :   uint32_t count = 1;
   16568             :   Isolate* isolate = this->GetIsolate();
   16569             :   while (true) {
   16570   153144225 :     Object* element = this->KeyAt(entry);
   16571   153144201 :     if (element->IsUndefined(isolate)) break;  // Empty entry.
   16572   108522855 :     if (*key == element) return entry;
   16573             :     DCHECK(element->IsTheHole(isolate) || element->IsUniqueName());
   16574    59039736 :     entry = Derived::NextProbe(entry, count++, capacity);
   16575             :   }
   16576    59039736 :   return Derived::kNotFound;
   16577             : }
   16578             : 
   16579             : 
   16580             : template<typename Derived, typename Shape, typename Key>
   16581     3427317 : void HashTable<Derived, Shape, Key>::Rehash(
   16582             :     Handle<Derived> new_table,
   16583             :     Key key) {
   16584             :   DCHECK(NumberOfElements() < new_table->Capacity());
   16585             : 
   16586             :   DisallowHeapAllocation no_gc;
   16587     3427317 :   WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc);
   16588             : 
   16589             :   // Copy prefix to new array.
   16590    10226682 :   for (int i = kPrefixStartIndex;
   16591             :        i < kPrefixStartIndex + Shape::kPrefixSize;
   16592             :        i++) {
   16593     6817788 :     new_table->set(i, get(i), mode);
   16594             :   }
   16595             : 
   16596             :   // Rehash the elements.
   16597             :   int capacity = this->Capacity();
   16598     3427317 :   Heap* heap = new_table->GetHeap();
   16599             :   Object* the_hole = heap->the_hole_value();
   16600             :   Object* undefined = heap->undefined_value();
   16601    73606726 :   for (int i = 0; i < capacity; i++) {
   16602    70176896 :     uint32_t from_index = EntryToIndex(i);
   16603             :     Object* k = this->get(from_index);
   16604    70176896 :     if (k != the_hole && k != undefined) {
   16605             :       uint32_t hash = this->HashForObject(key, k);
   16606             :       uint32_t insertion_index =
   16607    78348964 :           EntryToIndex(new_table->FindInsertionEntry(hash));
   16608   135902091 :       for (int j = 0; j < Shape::kEntrySize; j++) {
   16609   290182827 :         new_table->set(insertion_index + j, get(from_index + j), mode);
   16610             :       }
   16611             :     }
   16612             :   }
   16613             :   new_table->SetNumberOfElements(NumberOfElements());
   16614             :   new_table->SetNumberOfDeletedElements(0);
   16615     3427317 : }
   16616             : 
   16617             : 
   16618             : template<typename Derived, typename Shape, typename Key>
   16619     1434830 : uint32_t HashTable<Derived, Shape, Key>::EntryForProbe(
   16620             :     Key key,
   16621             :     Object* k,
   16622             :     int probe,
   16623             :     uint32_t expected) {
   16624             :   uint32_t hash = this->HashForObject(key, k);
   16625     1434830 :   uint32_t capacity = this->Capacity();
   16626             :   uint32_t entry = FirstProbe(hash, capacity);
   16627     3514261 :   for (int i = 1; i < probe; i++) {
   16628     2853171 :     if (entry == expected) return expected;
   16629     2079431 :     entry = NextProbe(entry, i, capacity);
   16630             :   }
   16631             :   return entry;
   16632             : }
   16633             : 
   16634             : 
   16635             : template<typename Derived, typename Shape, typename Key>
   16636        9340 : void HashTable<Derived, Shape, Key>::Swap(uint32_t entry1,
   16637             :                                           uint32_t entry2,
   16638             :                                           WriteBarrierMode mode) {
   16639        9340 :   int index1 = EntryToIndex(entry1);
   16640        9340 :   int index2 = EntryToIndex(entry2);
   16641             :   Object* temp[Shape::kEntrySize];
   16642       28020 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   16643       37360 :     temp[j] = get(index1 + j);
   16644             :   }
   16645       18680 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   16646       37360 :     set(index1 + j, get(index2 + j), mode);
   16647             :   }
   16648       18680 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   16649       18680 :     set(index2 + j, temp[j], mode);
   16650             :   }
   16651        9340 : }
   16652             : 
   16653             : 
   16654             : template<typename Derived, typename Shape, typename Key>
   16655       53367 : void HashTable<Derived, Shape, Key>::Rehash(Key key) {
   16656             :   DisallowHeapAllocation no_gc;
   16657       53367 :   WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
   16658             :   Isolate* isolate = GetIsolate();
   16659       53367 :   uint32_t capacity = Capacity();
   16660             :   bool done = false;
   16661      141776 :   for (int probe = 1; !done; probe++) {
   16662             :     // All elements at entries given by one of the first _probe_ probes
   16663             :     // are placed correctly. Other elements might need to be moved.
   16664             :     done = true;
   16665     4198172 :     for (uint32_t current = 0; current < capacity; current++) {
   16666     4198172 :       Object* current_key = KeyAt(current);
   16667     4198172 :       if (IsKey(isolate, current_key)) {
   16668     1183496 :         uint32_t target = EntryForProbe(key, current_key, probe, current);
   16669     1183496 :         if (current == target) continue;
   16670      257744 :         Object* target_key = KeyAt(target);
   16671      509078 :         if (!IsKey(isolate, target_key) ||
   16672      251334 :             EntryForProbe(key, target_key, probe, target) != target) {
   16673             :           // Put the current element into the correct position.
   16674        9340 :           Swap(current, target, mode);
   16675             :           // The other element will be processed on the next iteration.
   16676        9340 :           current--;
   16677             :         } else {
   16678             :           // The place for the current element is occupied. Leave the element
   16679             :           // for the next probe.
   16680             :           done = false;
   16681             :         }
   16682             :       }
   16683             :     }
   16684             :   }
   16685             :   // Wipe deleted entries.
   16686       53367 :   Object* the_hole = isolate->heap()->the_hole_value();
   16687       53367 :   Object* undefined = isolate->heap()->undefined_value();
   16688     1979767 :   for (uint32_t current = 0; current < capacity; current++) {
   16689     3852800 :     if (KeyAt(current) == the_hole) {
   16690       15761 :       set(EntryToIndex(current) + Derived::kEntryKeyIndex, undefined);
   16691             :     }
   16692             :   }
   16693             :   SetNumberOfDeletedElements(0);
   16694       53367 : }
   16695             : 
   16696             : 
   16697             : template<typename Derived, typename Shape, typename Key>
   16698    69360565 : Handle<Derived> HashTable<Derived, Shape, Key>::EnsureCapacity(
   16699             :     Handle<Derived> table,
   16700             :     int n,
   16701             :     Key key,
   16702             :     PretenureFlag pretenure) {
   16703    69360565 :   if (table->HasSufficientCapacityToAdd(n)) return table;
   16704             : 
   16705             :   Isolate* isolate = table->GetIsolate();
   16706             :   int capacity = table->Capacity();
   16707     3426888 :   int new_nof = table->NumberOfElements() + n;
   16708             : 
   16709             :   const int kMinCapacityForPretenure = 256;
   16710             :   bool should_pretenure = pretenure == TENURED ||
   16711             :       ((capacity > kMinCapacityForPretenure) &&
   16712     3433916 :           !isolate->heap()->InNewSpace(*table));
   16713             :   Handle<Derived> new_table =
   16714             :       HashTable::New(isolate, new_nof, USE_DEFAULT_MINIMUM_CAPACITY,
   16715     3426888 :                      should_pretenure ? TENURED : NOT_TENURED);
   16716             : 
   16717     3426888 :   table->Rehash(new_table, key);
   16718     3426888 :   return new_table;
   16719             : }
   16720             : 
   16721             : template <typename Derived, typename Shape, typename Key>
   16722    69366378 : bool HashTable<Derived, Shape, Key>::HasSufficientCapacityToAdd(
   16723             :     int number_of_additional_elements) {
   16724             :   int capacity = Capacity();
   16725    69366378 :   int nof = NumberOfElements() + number_of_additional_elements;
   16726             :   int nod = NumberOfDeletedElements();
   16727             :   // Return true if:
   16728             :   //   50% is still free after adding number_of_additional_elements elements and
   16729             :   //   at most 50% of the free elements are deleted elements.
   16730    69366378 :   if ((nof < capacity) && ((nod <= (capacity - nof) >> 1))) {
   16731    66396204 :     int needed_free = nof >> 1;
   16732    66396204 :     if (nof + needed_free <= capacity) return true;
   16733             :   }
   16734     3427290 :   return false;
   16735             : }
   16736             : 
   16737             : 
   16738             : template<typename Derived, typename Shape, typename Key>
   16739     6170046 : Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table,
   16740             :                                                        Key key) {
   16741             :   int capacity = table->Capacity();
   16742             :   int nof = table->NumberOfElements();
   16743             : 
   16744             :   // Shrink to fit the number of elements if only a quarter of the
   16745             :   // capacity is filled with elements.
   16746     6170046 :   if (nof > (capacity >> 2)) return table;
   16747             :   // Allocate a new dictionary with room for at least the current
   16748             :   // number of elements. The allocation method will make sure that
   16749             :   // there is extra room in the dictionary for additions. Don't go
   16750             :   // lower than room for 16 elements.
   16751             :   int at_least_room_for = nof;
   16752     6119485 :   if (at_least_room_for < 16) return table;
   16753             : 
   16754             :   Isolate* isolate = table->GetIsolate();
   16755             :   const int kMinCapacityForPretenure = 256;
   16756             :   bool pretenure =
   16757             :       (at_least_room_for > kMinCapacityForPretenure) &&
   16758         458 :       !isolate->heap()->InNewSpace(*table);
   16759             :   Handle<Derived> new_table = HashTable::New(
   16760             :       isolate,
   16761             :       at_least_room_for,
   16762             :       USE_DEFAULT_MINIMUM_CAPACITY,
   16763         429 :       pretenure ? TENURED : NOT_TENURED);
   16764             : 
   16765         429 :   table->Rehash(new_table, key);
   16766         429 :   return new_table;
   16767             : }
   16768             : 
   16769             : 
   16770             : template<typename Derived, typename Shape, typename Key>
   16771   108534663 : uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) {
   16772   108534663 :   uint32_t capacity = Capacity();
   16773             :   uint32_t entry = FirstProbe(hash, capacity);
   16774             :   uint32_t count = 1;
   16775             :   // EnsureCapacity will guarantee the hash table is never full.
   16776             :   Isolate* isolate = GetIsolate();
   16777             :   while (true) {
   16778   181056264 :     Object* element = KeyAt(entry);
   16779   181056264 :     if (!IsKey(isolate, element)) break;
   16780    72521601 :     entry = NextProbe(entry, count++, capacity);
   16781             :   }
   16782    72521601 :   return entry;
   16783             : }
   16784             : 
   16785             : 
   16786             : // Force instantiation of template instances class.
   16787             : // Please note this list is compiler dependent.
   16788             : 
   16789             : template class HashTable<StringTable, StringTableShape, HashTableKey*>;
   16790             : 
   16791             : template class HashTable<CompilationCacheTable,
   16792             :                          CompilationCacheShape,
   16793             :                          HashTableKey*>;
   16794             : 
   16795             : template class HashTable<ObjectHashTable,
   16796             :                          ObjectHashTableShape,
   16797             :                          Handle<Object> >;
   16798             : 
   16799             : template class HashTable<WeakHashTable, WeakHashTableShape<2>, Handle<Object> >;
   16800             : 
   16801             : template class Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >;
   16802             : 
   16803             : template class Dictionary<GlobalDictionary, GlobalDictionaryShape,
   16804             :                           Handle<Name> >;
   16805             : 
   16806             : template class Dictionary<SeededNumberDictionary,
   16807             :                           SeededNumberDictionaryShape,
   16808             :                           uint32_t>;
   16809             : 
   16810             : template class Dictionary<UnseededNumberDictionary,
   16811             :                           UnseededNumberDictionaryShape,
   16812             :                           uint32_t>;
   16813             : 
   16814             : template Handle<SeededNumberDictionary>
   16815             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::New(
   16816             :     Isolate*, int at_least_space_for, PretenureFlag pretenure,
   16817             :     MinimumCapacity capacity_option);
   16818             : 
   16819             : template Handle<SeededNumberDictionary>
   16820             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape,
   16821             :            uint32_t>::NewEmpty(Isolate*, PretenureFlag pretenure);
   16822             : 
   16823             : template Handle<UnseededNumberDictionary>
   16824             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape,
   16825             :            uint32_t>::NewEmpty(Isolate*, PretenureFlag pretenure);
   16826             : 
   16827             : template Handle<UnseededNumberDictionary>
   16828             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape,
   16829             :            uint32_t>::New(Isolate*, int at_least_space_for,
   16830             :                           PretenureFlag pretenure,
   16831             :                           MinimumCapacity capacity_option);
   16832             : 
   16833             : template Handle<NameDictionary>
   16834             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::New(
   16835             :     Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
   16836             : 
   16837             : template Handle<NameDictionary>
   16838             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::NewEmpty(
   16839             :     Isolate*, PretenureFlag pretenure);
   16840             : 
   16841             : template Handle<GlobalDictionary>
   16842             : Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::New(
   16843             :     Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
   16844             : 
   16845             : template Handle<SeededNumberDictionary>
   16846             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
   16847             :     AtPut(Handle<SeededNumberDictionary>, uint32_t, Handle<Object>);
   16848             : 
   16849             : template Handle<UnseededNumberDictionary>
   16850             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
   16851             :     AtPut(Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>);
   16852             : 
   16853             : template Object*
   16854             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
   16855             :     SlowReverseLookup(Object* value);
   16856             : 
   16857             : template Object*
   16858             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
   16859             :     SlowReverseLookup(Object* value);
   16860             : 
   16861             : template Handle<Object>
   16862             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::DeleteProperty(
   16863             :     Handle<NameDictionary>, int);
   16864             : 
   16865             : template Handle<Object>
   16866             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape,
   16867             :            uint32_t>::DeleteProperty(Handle<SeededNumberDictionary>, int);
   16868             : 
   16869             : template Handle<Object>
   16870             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape,
   16871             :            uint32_t>::DeleteProperty(Handle<UnseededNumberDictionary>, int);
   16872             : 
   16873             : template Handle<NameDictionary>
   16874             : HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >::
   16875             :     New(Isolate*, int, MinimumCapacity, PretenureFlag);
   16876             : 
   16877             : template Handle<ObjectHashSet> HashTable<ObjectHashSet, ObjectHashSetShape,
   16878             :                                          Handle<Object>>::New(Isolate*, int n,
   16879             :                                                               MinimumCapacity,
   16880             :                                                               PretenureFlag);
   16881             : 
   16882             : template Handle<NameDictionary>
   16883             : HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >::
   16884             :     Shrink(Handle<NameDictionary>, Handle<Name>);
   16885             : 
   16886             : template Handle<SeededNumberDictionary>
   16887             : HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
   16888             :     Shrink(Handle<SeededNumberDictionary>, uint32_t);
   16889             : 
   16890             : template Handle<UnseededNumberDictionary>
   16891             :     HashTable<UnseededNumberDictionary, UnseededNumberDictionaryShape,
   16892             :               uint32_t>::Shrink(Handle<UnseededNumberDictionary>, uint32_t);
   16893             : 
   16894             : template Handle<NameDictionary>
   16895             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::Add(
   16896             :     Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
   16897             :     int*);
   16898             : 
   16899             : template Handle<GlobalDictionary>
   16900             : Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::Add(
   16901             :     Handle<GlobalDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
   16902             :     int*);
   16903             : 
   16904             : template Handle<SeededNumberDictionary>
   16905             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::Add(
   16906             :     Handle<SeededNumberDictionary>, uint32_t, Handle<Object>, PropertyDetails,
   16907             :     int*);
   16908             : 
   16909             : template Handle<UnseededNumberDictionary>
   16910             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape,
   16911             :            uint32_t>::Add(Handle<UnseededNumberDictionary>, uint32_t,
   16912             :                           Handle<Object>, PropertyDetails, int*);
   16913             : 
   16914             : template Handle<SeededNumberDictionary>
   16915             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
   16916             :     EnsureCapacity(Handle<SeededNumberDictionary>, int, uint32_t);
   16917             : 
   16918             : template Handle<UnseededNumberDictionary>
   16919             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
   16920             :     EnsureCapacity(Handle<UnseededNumberDictionary>, int, uint32_t);
   16921             : 
   16922             : template void Dictionary<NameDictionary, NameDictionaryShape,
   16923             :                          Handle<Name> >::SetRequiresCopyOnCapacityChange();
   16924             : 
   16925             : template Handle<NameDictionary>
   16926             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
   16927             :     EnsureCapacity(Handle<NameDictionary>, int, Handle<Name>);
   16928             : 
   16929             : template int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape,
   16930             :                        uint32_t>::FindEntry(uint32_t);
   16931             : 
   16932             : template int NameDictionaryBase<NameDictionary, NameDictionaryShape>::FindEntry(
   16933             :     Handle<Name>);
   16934             : 
   16935             : template int Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::
   16936             :     NumberOfElementsFilterAttributes(PropertyFilter filter);
   16937             : 
   16938             : template int Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::
   16939             :     NumberOfElementsFilterAttributes(PropertyFilter filter);
   16940             : 
   16941             : template void
   16942             : Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::
   16943             :     CopyEnumKeysTo(Handle<Dictionary<GlobalDictionary, GlobalDictionaryShape,
   16944             :                                      Handle<Name>>>
   16945             :                        dictionary,
   16946             :                    Handle<FixedArray> storage, KeyCollectionMode mode,
   16947             :                    KeyAccumulator* accumulator);
   16948             : 
   16949             : template void
   16950             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::CopyEnumKeysTo(
   16951             :     Handle<Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>>
   16952             :         dictionary,
   16953             :     Handle<FixedArray> storage, KeyCollectionMode mode,
   16954             :     KeyAccumulator* accumulator);
   16955             : 
   16956             : template Handle<FixedArray>
   16957             : Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::
   16958             :     IterationIndices(
   16959             :         Handle<
   16960             :             Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>>
   16961             :             dictionary);
   16962             : template void
   16963             : Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::
   16964             :     CollectKeysTo(Handle<Dictionary<GlobalDictionary, GlobalDictionaryShape,
   16965             :                                     Handle<Name>>>
   16966             :                       dictionary,
   16967             :                   KeyAccumulator* keys);
   16968             : 
   16969             : template Handle<FixedArray>
   16970             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::IterationIndices(
   16971             :     Handle<Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>>
   16972             :         dictionary);
   16973             : template void
   16974             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::CollectKeysTo(
   16975             :     Handle<Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>>
   16976             :         dictionary,
   16977             :     KeyAccumulator* keys);
   16978             : 
   16979         103 : Handle<Object> JSObject::PrepareSlowElementsForSort(
   16980             :     Handle<JSObject> object, uint32_t limit) {
   16981             :   DCHECK(object->HasDictionaryElements());
   16982             :   Isolate* isolate = object->GetIsolate();
   16983             :   // Must stay in dictionary mode, either because of requires_slow_elements,
   16984             :   // or because we are not going to sort (and therefore compact) all of the
   16985             :   // elements.
   16986             :   Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate);
   16987             :   Handle<SeededNumberDictionary> new_dict =
   16988         103 :       SeededNumberDictionary::New(isolate, dict->NumberOfElements());
   16989             : 
   16990             :   uint32_t pos = 0;
   16991             :   uint32_t undefs = 0;
   16992             :   int capacity = dict->Capacity();
   16993             :   Handle<Smi> bailout(Smi::FromInt(-1), isolate);
   16994             :   // Entry to the new dictionary does not cause it to grow, as we have
   16995             :   // allocated one that is large enough for all entries.
   16996             :   DisallowHeapAllocation no_gc;
   16997         429 :   for (int i = 0; i < capacity; i++) {
   16998             :     Object* k = dict->KeyAt(i);
   16999         385 :     if (!dict->IsKey(isolate, k)) continue;
   17000             : 
   17001             :     DCHECK(k->IsNumber());
   17002             :     DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0);
   17003             :     DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0);
   17004             :     DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32);
   17005             : 
   17006             :     HandleScope scope(isolate);
   17007         238 :     Handle<Object> value(dict->ValueAt(i), isolate);
   17008             :     PropertyDetails details = dict->DetailsAt(i);
   17009         432 :     if (details.kind() == kAccessor || details.IsReadOnly()) {
   17010             :       // Bail out and do the sorting of undefineds and array holes in JS.
   17011             :       // Also bail out if the element is not supposed to be moved.
   17012          44 :       return bailout;
   17013             :     }
   17014             : 
   17015         194 :     uint32_t key = NumberToUint32(k);
   17016         194 :     if (key < limit) {
   17017         164 :       if (value->IsUndefined(isolate)) {
   17018          15 :         undefs++;
   17019         149 :       } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
   17020             :         // Adding an entry with the key beyond smi-range requires
   17021             :         // allocation. Bailout.
   17022           0 :         return bailout;
   17023             :       } else {
   17024             :         Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
   17025         149 :             new_dict, pos, value, details, object);
   17026             :         DCHECK(result.is_identical_to(new_dict));
   17027             :         USE(result);
   17028         149 :         pos++;
   17029             :       }
   17030          30 :     } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) {
   17031             :       // Adding an entry with the key beyond smi-range requires
   17032             :       // allocation. Bailout.
   17033          15 :       return bailout;
   17034             :     } else {
   17035             :       Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
   17036          15 :           new_dict, key, value, details, object);
   17037             :       DCHECK(result.is_identical_to(new_dict));
   17038             :       USE(result);
   17039             :     }
   17040             :   }
   17041             : 
   17042             :   uint32_t result = pos;
   17043          44 :   PropertyDetails no_details = PropertyDetails::Empty();
   17044         103 :   while (undefs > 0) {
   17045          15 :     if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
   17046             :       // Adding an entry with the key beyond smi-range requires
   17047             :       // allocation. Bailout.
   17048           0 :       return bailout;
   17049             :     }
   17050             :     HandleScope scope(isolate);
   17051             :     Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
   17052             :         new_dict, pos, isolate->factory()->undefined_value(), no_details,
   17053          15 :         object);
   17054             :     DCHECK(result.is_identical_to(new_dict));
   17055             :     USE(result);
   17056          15 :     pos++;
   17057          15 :     undefs--;
   17058             :   }
   17059             : 
   17060          44 :   object->set_elements(*new_dict);
   17061             : 
   17062             :   AllowHeapAllocation allocate_return_value;
   17063          44 :   return isolate->factory()->NewNumberFromUint(result);
   17064             : }
   17065             : 
   17066             : 
   17067             : // Collects all defined (non-hole) and non-undefined (array) elements at
   17068             : // the start of the elements array.
   17069             : // If the object is in dictionary mode, it is converted to fast elements
   17070             : // mode.
   17071      126632 : Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
   17072             :                                                 uint32_t limit) {
   17073             :   Isolate* isolate = object->GetIsolate();
   17074      253234 :   if (object->HasSloppyArgumentsElements() || !object->map()->is_extensible()) {
   17075         105 :     return handle(Smi::FromInt(-1), isolate);
   17076             :   }
   17077             : 
   17078      126527 :   if (object->HasStringWrapperElements()) {
   17079             :     int len = String::cast(Handle<JSValue>::cast(object)->value())->length();
   17080          15 :     return handle(Smi::FromInt(len), isolate);
   17081             :   }
   17082             : 
   17083      126512 :   if (object->HasDictionaryElements()) {
   17084             :     // Convert to fast elements containing only the existing properties.
   17085             :     // Ordering is irrelevant, since we are going to sort anyway.
   17086             :     Handle<SeededNumberDictionary> dict(object->element_dictionary());
   17087         342 :     if (object->IsJSArray() || dict->requires_slow_elements() ||
   17088          60 :         dict->max_number_key() >= limit) {
   17089         103 :       return JSObject::PrepareSlowElementsForSort(object, limit);
   17090             :     }
   17091             :     // Convert to fast elements.
   17092             : 
   17093             :     Handle<Map> new_map =
   17094          60 :         JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS);
   17095             : 
   17096             :     PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ?
   17097          60 :         NOT_TENURED: TENURED;
   17098             :     Handle<FixedArray> fast_elements =
   17099          60 :         isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure);
   17100          60 :     dict->CopyValuesTo(*fast_elements);
   17101             :     JSObject::ValidateElements(object);
   17102             : 
   17103          60 :     JSObject::SetMapAndElements(object, new_map, fast_elements);
   17104      126349 :   } else if (object->HasFixedTypedArrayElements()) {
   17105             :     // Typed arrays cannot have holes or undefined elements.
   17106             :     return handle(Smi::FromInt(
   17107         141 :         FixedArrayBase::cast(object->elements())->length()), isolate);
   17108      126208 :   } else if (!object->HasFastDoubleElements()) {
   17109      126151 :     EnsureWritableFastElements(object);
   17110             :   }
   17111             :   DCHECK(object->HasFastSmiOrObjectElements() ||
   17112             :          object->HasFastDoubleElements());
   17113             : 
   17114             :   // Collect holes at the end, undefined before that and the rest at the
   17115             :   // start, and return the number of non-hole, non-undefined values.
   17116             : 
   17117             :   Handle<FixedArrayBase> elements_base(object->elements());
   17118      126268 :   uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
   17119      126268 :   if (limit > elements_length) {
   17120             :     limit = elements_length;
   17121             :   }
   17122      126268 :   if (limit == 0) {
   17123          15 :     return handle(Smi::kZero, isolate);
   17124             :   }
   17125             : 
   17126             :   uint32_t result = 0;
   17127      126253 :   if (elements_base->map() == isolate->heap()->fixed_double_array_map()) {
   17128             :     FixedDoubleArray* elements = FixedDoubleArray::cast(*elements_base);
   17129             :     // Split elements into defined and the_hole, in that order.
   17130             :     unsigned int holes = limit;
   17131             :     // Assume most arrays contain no holes and undefined values, so minimize the
   17132             :     // number of stores of non-undefined, non-the-hole values.
   17133        5915 :     for (unsigned int i = 0; i < holes; i++) {
   17134       11716 :       if (elements->is_the_hole(i)) {
   17135           0 :         holes--;
   17136             :       } else {
   17137             :         continue;
   17138             :       }
   17139             :       // Position i needs to be filled.
   17140           0 :       while (holes > i) {
   17141           0 :         if (elements->is_the_hole(holes)) {
   17142           0 :           holes--;
   17143             :         } else {
   17144             :           elements->set(i, elements->get_scalar(holes));
   17145             :           break;
   17146             :         }
   17147             :       }
   17148             :     }
   17149             :     result = holes;
   17150          57 :     while (holes < limit) {
   17151           0 :       elements->set_the_hole(holes);
   17152           0 :       holes++;
   17153             :     }
   17154             :   } else {
   17155             :     FixedArray* elements = FixedArray::cast(*elements_base);
   17156             :     DisallowHeapAllocation no_gc;
   17157             : 
   17158             :     // Split elements into defined, undefined and the_hole, in that order.  Only
   17159             :     // count locations for undefined and the hole, and fill them afterwards.
   17160      126196 :     WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_gc);
   17161             :     unsigned int undefs = limit;
   17162             :     unsigned int holes = limit;
   17163             :     // Assume most arrays contain no holes and undefined values, so minimize the
   17164             :     // number of stores of non-undefined, non-the-hole values.
   17165     5889807 :     for (unsigned int i = 0; i < undefs; i++) {
   17166     5763611 :       Object* current = elements->get(i);
   17167     5763611 :       if (current->IsTheHole(isolate)) {
   17168       31206 :         holes--;
   17169       31206 :         undefs--;
   17170     5732405 :       } else if (current->IsUndefined(isolate)) {
   17171        1136 :         undefs--;
   17172             :       } else {
   17173             :         continue;
   17174             :       }
   17175             :       // Position i needs to be filled.
   17176     7706829 :       while (undefs > i) {
   17177     7706137 :         current = elements->get(undefs);
   17178     7706137 :         if (current->IsTheHole(isolate)) {
   17179     7673296 :           holes--;
   17180     7673296 :           undefs--;
   17181       32841 :         } else if (current->IsUndefined(isolate)) {
   17182        1191 :           undefs--;
   17183             :         } else {
   17184       31650 :           elements->set(i, current, write_barrier);
   17185       31650 :           break;
   17186             :         }
   17187             :       }
   17188             :     }
   17189             :     result = undefs;
   17190      128523 :     while (undefs < holes) {
   17191        2327 :       elements->set_undefined(isolate, undefs);
   17192        2327 :       undefs++;
   17193             :     }
   17194     7830698 :     while (holes < limit) {
   17195     7704502 :       elements->set_the_hole(isolate, holes);
   17196     7704502 :       holes++;
   17197             :     }
   17198             :   }
   17199             : 
   17200      126253 :   return isolate->factory()->NewNumberFromUint(result);
   17201             : }
   17202             : 
   17203             : namespace {
   17204             : 
   17205        4492 : bool CanonicalNumericIndexString(Isolate* isolate, Handle<Object> s,
   17206             :                                  Handle<Object>* index) {
   17207             :   DCHECK(s->IsString() || s->IsSmi());
   17208             : 
   17209             :   Handle<Object> result;
   17210        4492 :   if (s->IsSmi()) {
   17211             :     result = s;
   17212             :   } else {
   17213        4464 :     result = String::ToNumber(Handle<String>::cast(s));
   17214        4464 :     if (!result->IsMinusZero()) {
   17215        8900 :       Handle<String> str = Object::ToString(isolate, result).ToHandleChecked();
   17216             :       // Avoid treating strings like "2E1" and "20" as the same key.
   17217        4450 :       if (!str->SameValue(*s)) return false;
   17218             :     }
   17219             :   }
   17220         275 :   *index = result;
   17221         275 :   return true;
   17222             : }
   17223             : 
   17224             : }  // anonymous namespace
   17225             : 
   17226             : // ES#sec-integer-indexed-exotic-objects-defineownproperty-p-desc
   17227             : // static
   17228        4786 : Maybe<bool> JSTypedArray::DefineOwnProperty(Isolate* isolate,
   17229             :                                             Handle<JSTypedArray> o,
   17230             :                                             Handle<Object> key,
   17231             :                                             PropertyDescriptor* desc,
   17232             :                                             ShouldThrow should_throw) {
   17233             :   // 1. Assert: IsPropertyKey(P) is true.
   17234             :   DCHECK(key->IsName() || key->IsNumber());
   17235             :   // 2. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot.
   17236             :   // 3. If Type(P) is String, then
   17237        5108 :   if (key->IsString() || key->IsSmi()) {
   17238             :     // 3a. Let numericIndex be ! CanonicalNumericIndexString(P)
   17239             :     // 3b. If numericIndex is not undefined, then
   17240             :     Handle<Object> numeric_index;
   17241        4492 :     if (CanonicalNumericIndexString(isolate, key, &numeric_index)) {
   17242             :       // 3b i. If IsInteger(numericIndex) is false, return false.
   17243             :       // 3b ii. If numericIndex = -0, return false.
   17244             :       // 3b iii. If numericIndex < 0, return false.
   17245             :       // FIXME: the standard allows up to 2^53 elements.
   17246             :       uint32_t index;
   17247         536 :       if (numeric_index->IsMinusZero() || !numeric_index->ToUint32(&index)) {
   17248         126 :         RETURN_FAILURE(isolate, should_throw,
   17249             :                        NewTypeError(MessageTemplate::kInvalidTypedArrayIndex));
   17250             :       }
   17251             :       // 3b iv. Let length be O.[[ArrayLength]].
   17252         233 :       uint32_t length = o->length()->Number();
   17253             :       // 3b v. If numericIndex ≥ length, return false.
   17254         233 :       if (index >= length) {
   17255          42 :         RETURN_FAILURE(isolate, should_throw,
   17256             :                        NewTypeError(MessageTemplate::kInvalidTypedArrayIndex));
   17257             :       }
   17258             :       // 3b vi. If IsAccessorDescriptor(Desc) is true, return false.
   17259         219 :       if (PropertyDescriptor::IsAccessorDescriptor(desc)) {
   17260         234 :         RETURN_FAILURE(isolate, should_throw,
   17261             :                        NewTypeError(MessageTemplate::kRedefineDisallowed, key));
   17262             :       }
   17263             :       // 3b vii. If Desc has a [[Configurable]] field and if
   17264             :       //         Desc.[[Configurable]] is true, return false.
   17265             :       // 3b viii. If Desc has an [[Enumerable]] field and if Desc.[[Enumerable]]
   17266             :       //          is false, return false.
   17267             :       // 3b ix. If Desc has a [[Writable]] field and if Desc.[[Writable]] is
   17268             :       //        false, return false.
   17269          30 :       if ((desc->has_configurable() && desc->configurable()) ||
   17270          30 :           (desc->has_enumerable() && !desc->enumerable()) ||
   17271          15 :           (desc->has_writable() && !desc->writable())) {
   17272          45 :         RETURN_FAILURE(isolate, should_throw,
   17273             :                        NewTypeError(MessageTemplate::kRedefineDisallowed, key));
   17274             :       }
   17275             :       // 3b x. If Desc has a [[Value]] field, then
   17276             :       //   3b x 1. Let value be Desc.[[Value]].
   17277             :       //   3b x 2. Return ? IntegerIndexedElementSet(O, numericIndex, value).
   17278           0 :       if (desc->has_value()) {
   17279           0 :         if (!desc->has_configurable()) desc->set_configurable(false);
   17280           0 :         if (!desc->has_enumerable()) desc->set_enumerable(true);
   17281           0 :         if (!desc->has_writable()) desc->set_writable(true);
   17282           0 :         Handle<Object> value = desc->value();
   17283           0 :         RETURN_ON_EXCEPTION_VALUE(isolate,
   17284             :                                   SetOwnElementIgnoreAttributes(
   17285             :                                       o, index, value, desc->ToAttributes()),
   17286             :                                   Nothing<bool>());
   17287             :       }
   17288             :       // 3b xi. Return true.
   17289             :       return Just(true);
   17290             :     }
   17291             :   }
   17292             :   // 4. Return ! OrdinaryDefineOwnProperty(O, P, Desc).
   17293        4511 :   return OrdinaryDefineOwnProperty(isolate, o, key, desc, should_throw);
   17294             : }
   17295             : 
   17296    18768174 : ExternalArrayType JSTypedArray::type() {
   17297    18768174 :   switch (elements()->map()->instance_type()) {
   17298             : #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size)            \
   17299             :     case FIXED_##TYPE##_ARRAY_TYPE:                                           \
   17300             :       return kExternal##Type##Array;
   17301             : 
   17302        5939 :     TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE)
   17303             : #undef INSTANCE_TYPE_TO_ARRAY_TYPE
   17304             : 
   17305             :     default:
   17306           0 :       UNREACHABLE();
   17307             :       return static_cast<ExternalArrayType>(-1);
   17308             :   }
   17309             : }
   17310             : 
   17311             : 
   17312       15924 : size_t JSTypedArray::element_size() {
   17313       15924 :   switch (elements()->map()->instance_type()) {
   17314             : #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \
   17315             :   case FIXED_##TYPE##_ARRAY_TYPE:                                    \
   17316             :     return size;
   17317             : 
   17318        1013 :     TYPED_ARRAYS(INSTANCE_TYPE_TO_ELEMENT_SIZE)
   17319             : #undef INSTANCE_TYPE_TO_ELEMENT_SIZE
   17320             : 
   17321             :     default:
   17322           0 :       UNREACHABLE();
   17323             :       return 0;
   17324             :   }
   17325             : }
   17326             : 
   17327             : 
   17328      326473 : void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
   17329             :                                             Handle<Name> name) {
   17330             :   DCHECK(!global->HasFastProperties());
   17331             :   auto dictionary = handle(global->global_dictionary());
   17332      326473 :   int entry = dictionary->FindEntry(name);
   17333      652946 :   if (entry == GlobalDictionary::kNotFound) return;
   17334          90 :   PropertyCell::InvalidateEntry(dictionary, entry);
   17335             : }
   17336             : 
   17337     8836940 : Handle<PropertyCell> JSGlobalObject::EnsureEmptyPropertyCell(
   17338             :     Handle<JSGlobalObject> global, Handle<Name> name,
   17339             :     PropertyCellType cell_type, int* entry_out) {
   17340             :   Isolate* isolate = global->GetIsolate();
   17341             :   DCHECK(!global->HasFastProperties());
   17342             :   Handle<GlobalDictionary> dictionary(global->global_dictionary(), isolate);
   17343     8836939 :   int entry = dictionary->FindEntry(name);
   17344             :   Handle<PropertyCell> cell;
   17345     8836938 :   if (entry != GlobalDictionary::kNotFound) {
   17346        6491 :     if (entry_out) *entry_out = entry;
   17347             :     // This call should be idempotent.
   17348             :     DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
   17349        6491 :     cell = handle(PropertyCell::cast(dictionary->ValueAt(entry)));
   17350             :     PropertyCellType original_cell_type = cell->property_details().cell_type();
   17351             :     DCHECK(original_cell_type == PropertyCellType::kInvalidated ||
   17352             :            original_cell_type == PropertyCellType::kUninitialized);
   17353             :     DCHECK(cell->value()->IsTheHole(isolate));
   17354        6491 :     if (original_cell_type == PropertyCellType::kInvalidated) {
   17355        2427 :       cell = PropertyCell::InvalidateEntry(dictionary, entry);
   17356             :     }
   17357             :     PropertyDetails details(kData, NONE, 0, cell_type);
   17358             :     cell->set_property_details(details);
   17359        6491 :     return cell;
   17360             :   }
   17361     8830447 :   cell = isolate->factory()->NewPropertyCell();
   17362             :   PropertyDetails details(kData, NONE, 0, cell_type);
   17363             :   dictionary =
   17364     8830445 :       GlobalDictionary::Add(dictionary, name, cell, details, entry_out);
   17365             :   // {*entry_out} is initialized inside GlobalDictionary::Add().
   17366     8830450 :   global->set_properties(*dictionary);
   17367     8830450 :   return cell;
   17368             : }
   17369             : 
   17370             : 
   17371             : // This class is used for looking up two character strings in the string table.
   17372             : // If we don't have a hit we don't want to waste much time so we unroll the
   17373             : // string hash calculation loop here for speed.  Doesn't work if the two
   17374             : // characters form a decimal integer, since such strings have a different hash
   17375             : // algorithm.
   17376           0 : class TwoCharHashTableKey : public HashTableKey {
   17377             :  public:
   17378     7323341 :   TwoCharHashTableKey(uint16_t c1, uint16_t c2, uint32_t seed)
   17379     7323341 :     : c1_(c1), c2_(c2) {
   17380             :     // Char 1.
   17381             :     uint32_t hash = seed;
   17382     7323341 :     hash += c1;
   17383     7323341 :     hash += hash << 10;
   17384     7323341 :     hash ^= hash >> 6;
   17385             :     // Char 2.
   17386     7323341 :     hash += c2;
   17387     7323341 :     hash += hash << 10;
   17388     7323341 :     hash ^= hash >> 6;
   17389             :     // GetHash.
   17390     7323341 :     hash += hash << 3;
   17391     7323341 :     hash ^= hash >> 11;
   17392     7323341 :     hash += hash << 15;
   17393     7323341 :     if ((hash & String::kHashBitMask) == 0) hash = StringHasher::kZeroHash;
   17394     7323341 :     hash_ = hash;
   17395             : #ifdef DEBUG
   17396             :     // If this assert fails then we failed to reproduce the two-character
   17397             :     // version of the string hashing algorithm above.  One reason could be
   17398             :     // that we were passed two digits as characters, since the hash
   17399             :     // algorithm is different in that case.
   17400             :     uint16_t chars[2] = {c1, c2};
   17401             :     uint32_t check_hash = StringHasher::HashSequentialString(chars, 2, seed);
   17402             :     hash = (hash << String::kHashShift) | String::kIsNotArrayIndexMask;
   17403             :     DCHECK_EQ(static_cast<int32_t>(hash), static_cast<int32_t>(check_hash));
   17404             : #endif
   17405     7323341 :   }
   17406             : 
   17407     1729827 :   bool IsMatch(Object* o) override {
   17408     1729827 :     if (!o->IsString()) return false;
   17409             :     String* other = String::cast(o);
   17410     1729827 :     if (other->length() != 2) return false;
   17411      106029 :     if (other->Get(0) != c1_) return false;
   17412       22301 :     return other->Get(1) == c2_;
   17413             :   }
   17414             : 
   17415     7323341 :   uint32_t Hash() override { return hash_; }
   17416           0 :   uint32_t HashForObject(Object* key) override {
   17417           0 :     if (!key->IsString()) return 0;
   17418           0 :     return String::cast(key)->Hash();
   17419             :   }
   17420             : 
   17421           0 :   Handle<Object> AsHandle(Isolate* isolate) override {
   17422             :     // The TwoCharHashTableKey is only used for looking in the string
   17423             :     // table, not for adding to it.
   17424           0 :     UNREACHABLE();
   17425             :     return MaybeHandle<Object>().ToHandleChecked();
   17426             :   }
   17427             : 
   17428             :  private:
   17429             :   uint16_t c1_;
   17430             :   uint16_t c2_;
   17431             :   uint32_t hash_;
   17432             : };
   17433             : 
   17434             : 
   17435     4262819 : MaybeHandle<String> StringTable::InternalizeStringIfExists(
   17436             :     Isolate* isolate,
   17437             :     Handle<String> string) {
   17438     4262819 :   if (string->IsInternalizedString()) {
   17439             :     return string;
   17440             :   }
   17441           0 :   if (string->IsThinString()) {
   17442             :     return handle(Handle<ThinString>::cast(string)->actual(), isolate);
   17443             :   }
   17444           0 :   return LookupStringIfExists(isolate, string);
   17445             : }
   17446             : 
   17447             : 
   17448           0 : MaybeHandle<String> StringTable::LookupStringIfExists(
   17449             :     Isolate* isolate,
   17450             :     Handle<String> string) {
   17451             :   Handle<StringTable> string_table = isolate->factory()->string_table();
   17452             :   InternalizedStringKey key(string);
   17453             :   int entry = string_table->FindEntry(&key);
   17454           0 :   if (entry == kNotFound) {
   17455             :     return MaybeHandle<String>();
   17456             :   } else {
   17457             :     Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
   17458             :     DCHECK(StringShape(*result).IsInternalized());
   17459             :     return result;
   17460             :   }
   17461             : }
   17462             : 
   17463             : 
   17464     7323341 : MaybeHandle<String> StringTable::LookupTwoCharsStringIfExists(
   17465             :     Isolate* isolate,
   17466             :     uint16_t c1,
   17467             :     uint16_t c2) {
   17468             :   Handle<StringTable> string_table = isolate->factory()->string_table();
   17469     7323341 :   TwoCharHashTableKey key(c1, c2, isolate->heap()->HashSeed());
   17470             :   int entry = string_table->FindEntry(&key);
   17471     7323341 :   if (entry == kNotFound) {
   17472             :     return MaybeHandle<String>();
   17473             :   } else {
   17474             :     Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
   17475             :     DCHECK(StringShape(*result).IsInternalized());
   17476             :     return result;
   17477             :   }
   17478             : }
   17479             : 
   17480             : 
   17481         385 : void StringTable::EnsureCapacityForDeserialization(Isolate* isolate,
   17482             :                                                    int expected) {
   17483             :   Handle<StringTable> table = isolate->factory()->string_table();
   17484             :   // We need a key instance for the virtual hash function.
   17485             :   InternalizedStringKey dummy_key(isolate->factory()->empty_string());
   17486         385 :   table = StringTable::EnsureCapacity(table, expected, &dummy_key);
   17487             :   isolate->heap()->SetRootStringTable(*table);
   17488         385 : }
   17489             : 
   17490             : namespace {
   17491             : 
   17492             : template <class StringClass>
   17493          20 : void MigrateExternalStringResource(Isolate* isolate, String* from, String* to) {
   17494             :   StringClass* cast_from = StringClass::cast(from);
   17495             :   StringClass* cast_to = StringClass::cast(to);
   17496             :   const typename StringClass::Resource* to_resource = cast_to->resource();
   17497          20 :   if (to_resource == nullptr) {
   17498             :     // |to| is a just-created internalized copy of |from|. Migrate the resource.
   17499             :     cast_to->set_resource(cast_from->resource());
   17500             :     // Zap |from|'s resource pointer to reflect the fact that |from| has
   17501             :     // relinquished ownership of its resource.
   17502             :     cast_from->set_resource(nullptr);
   17503          14 :   } else if (to_resource != cast_from->resource()) {
   17504             :     // |to| already existed and has its own resource. Finalize |from|.
   17505             :     isolate->heap()->FinalizeExternalString(from);
   17506             :   }
   17507          20 : }
   17508             : 
   17509     9703806 : void MakeStringThin(String* string, String* internalized, Isolate* isolate) {
   17510     9703812 :   if (string->IsExternalString()) {
   17511          20 :     if (internalized->IsExternalOneByteString()) {
   17512             :       MigrateExternalStringResource<ExternalOneByteString>(isolate, string,
   17513          11 :                                                            internalized);
   17514           9 :     } else if (internalized->IsExternalTwoByteString()) {
   17515             :       MigrateExternalStringResource<ExternalTwoByteString>(isolate, string,
   17516           9 :                                                            internalized);
   17517             :     } else {
   17518             :       // If the external string is duped into an existing non-external
   17519             :       // internalized string, free its resource (it's about to be rewritten
   17520             :       // into a ThinString below).
   17521             :       isolate->heap()->FinalizeExternalString(string);
   17522             :     }
   17523             :   }
   17524             : 
   17525     9703810 :   if (!string->IsInternalizedString()) {
   17526             :     DisallowHeapAllocation no_gc;
   17527             :     bool one_byte = internalized->IsOneByteRepresentation();
   17528             :     Handle<Map> map = one_byte ? isolate->factory()->thin_one_byte_string_map()
   17529     9696193 :                                : isolate->factory()->thin_string_map();
   17530     9696193 :     int old_size = string->Size();
   17531             :     DCHECK(old_size >= ThinString::kSize);
   17532     9696193 :     string->synchronized_set_map(*map);
   17533             :     ThinString* thin = ThinString::cast(string);
   17534     9696193 :     thin->set_actual(internalized);
   17535     9696192 :     Address thin_end = thin->address() + ThinString::kSize;
   17536     9696192 :     int size_delta = old_size - ThinString::kSize;
   17537     9696192 :     if (size_delta != 0) {
   17538     2395543 :       Heap* heap = isolate->heap();
   17539     2395543 :       heap->CreateFillerObjectAt(thin_end, size_delta, ClearRecordedSlots::kNo);
   17540     2395542 :       heap->AdjustLiveBytes(thin, -size_delta);
   17541             :     }
   17542             :   }
   17543     9703809 : }
   17544             : 
   17545             : }  // namespace
   17546             : 
   17547    23381586 : Handle<String> StringTable::LookupString(Isolate* isolate,
   17548             :                                          Handle<String> string) {
   17549    23381588 :   if (string->IsThinString()) {
   17550             :     DCHECK(Handle<ThinString>::cast(string)->actual()->IsInternalizedString());
   17551             :     return handle(Handle<ThinString>::cast(string)->actual(), isolate);
   17552             :   }
   17553    23332717 :   if (string->IsConsString() && string->IsFlat()) {
   17554             :     string = handle(Handle<ConsString>::cast(string)->first(), isolate);
   17555       22320 :     if (string->IsInternalizedString()) return string;
   17556             :   }
   17557             : 
   17558             :   InternalizedStringKey key(string);
   17559    22836227 :   Handle<String> result = LookupKey(isolate, &key);
   17560             : 
   17561    22836230 :   if (FLAG_thin_strings) {
   17562     9678304 :     MakeStringThin(*string, *result, isolate);
   17563             :   } else {  // !FLAG_thin_strings
   17564    13157926 :     if (string->IsConsString()) {
   17565             :       Handle<ConsString> cons = Handle<ConsString>::cast(string);
   17566      193005 :       cons->set_first(*result);
   17567      386010 :       cons->set_second(isolate->heap()->empty_string());
   17568    12964921 :     } else if (string->IsSlicedString()) {
   17569             :       STATIC_ASSERT(ConsString::kSize == SlicedString::kSize);
   17570             :       DisallowHeapAllocation no_gc;
   17571             :       bool one_byte = result->IsOneByteRepresentation();
   17572             :       Handle<Map> map = one_byte
   17573             :                             ? isolate->factory()->cons_one_byte_string_map()
   17574       24792 :                             : isolate->factory()->cons_string_map();
   17575       24792 :       string->set_map(*map);
   17576             :       Handle<ConsString> cons = Handle<ConsString>::cast(string);
   17577       24792 :       cons->set_first(*result);
   17578       49584 :       cons->set_second(isolate->heap()->empty_string());
   17579             :     }
   17580             :   }
   17581    22836231 :   return result;
   17582             : }
   17583             : 
   17584             : 
   17585    89053511 : Handle<String> StringTable::LookupKey(Isolate* isolate, HashTableKey* key) {
   17586             :   Handle<StringTable> table = isolate->factory()->string_table();
   17587             :   int entry = table->FindEntry(key);
   17588             : 
   17589             :   // String already in table.
   17590    89053558 :   if (entry != kNotFound) {
   17591             :     return handle(String::cast(table->KeyAt(entry)), isolate);
   17592             :   }
   17593             : 
   17594             :   // Adding new string. Grow table if needed.
   17595    13111844 :   table = StringTable::EnsureCapacity(table, 1, key);
   17596             : 
   17597             :   // Create string object.
   17598    13111843 :   Handle<Object> string = key->AsHandle(isolate);
   17599             :   // There must be no attempts to internalize strings that could throw
   17600             :   // InvalidStringLength error.
   17601    13111846 :   CHECK(!string.is_null());
   17602             : 
   17603             :   // Add the new string and return it along with the string table.
   17604    26223692 :   entry = table->FindInsertionEntry(key->Hash());
   17605    13111845 :   table->set(EntryToIndex(entry), *string);
   17606    13111843 :   table->ElementAdded();
   17607             : 
   17608             :   isolate->heap()->SetRootStringTable(*table);
   17609             :   return Handle<String>::cast(string);
   17610             : }
   17611             : 
   17612             : namespace {
   17613             : 
   17614             : class StringTableNoAllocateKey : public HashTableKey {
   17615             :  public:
   17616       25653 :   StringTableNoAllocateKey(String* string, uint32_t seed)
   17617       51306 :       : string_(string), length_(string->length()) {
   17618             :     StringShape shape(string);
   17619       25653 :     one_byte_ = shape.HasOnlyOneByteChars();
   17620             :     DCHECK(!shape.IsInternalized());
   17621             :     DCHECK(!shape.IsThin());
   17622       25653 :     if (shape.IsCons() && length_ <= String::kMaxHashCalcLength) {
   17623           0 :       special_flattening_ = true;
   17624             :       uint32_t hash_field = 0;
   17625           0 :       if (one_byte_) {
   17626           0 :         one_byte_content_ = new uint8_t[length_];
   17627           0 :         String::WriteToFlat(string, one_byte_content_, 0, length_);
   17628             :         hash_field = StringHasher::HashSequentialString(one_byte_content_,
   17629           0 :                                                         length_, seed);
   17630             :       } else {
   17631           0 :         two_byte_content_ = new uint16_t[length_];
   17632           0 :         String::WriteToFlat(string, two_byte_content_, 0, length_);
   17633             :         hash_field = StringHasher::HashSequentialString(two_byte_content_,
   17634           0 :                                                         length_, seed);
   17635             :       }
   17636             :       string->set_hash_field(hash_field);
   17637             :     } else {
   17638       25653 :       special_flattening_ = false;
   17639       25653 :       one_byte_content_ = nullptr;
   17640             :     }
   17641       25653 :     hash_ = string->Hash();
   17642       25653 :   }
   17643             : 
   17644       25653 :   ~StringTableNoAllocateKey() {
   17645       25653 :     if (one_byte_) {
   17646       23349 :       delete[] one_byte_content_;
   17647             :     } else {
   17648        2304 :       delete[] two_byte_content_;
   17649             :     }
   17650       25653 :   }
   17651             : 
   17652       45282 :   bool IsMatch(Object* otherstring) override {
   17653             :     String* other = String::cast(otherstring);
   17654             :     DCHECK(other->IsInternalizedString());
   17655             :     DCHECK(other->IsFlat());
   17656       90564 :     if (hash_ != other->Hash()) return false;
   17657       25542 :     int len = length_;
   17658       25542 :     if (len != other->length()) return false;
   17659             : 
   17660       25542 :     if (!special_flattening_) {
   17661       51084 :       if (string_->Get(0) != other->Get(0)) return false;
   17662       25542 :       if (string_->IsFlat()) {
   17663       25542 :         StringShape shape1(string_);
   17664             :         StringShape shape2(other);
   17665       48780 :         if (shape1.encoding_tag() == kOneByteStringTag &&
   17666             :             shape2.encoding_tag() == kOneByteStringTag) {
   17667       23238 :           String::FlatContent flat1 = string_->GetFlatContent();
   17668       23238 :           String::FlatContent flat2 = other->GetFlatContent();
   17669       23238 :           return CompareRawStringContents(flat1.ToOneByteVector().start(),
   17670       23238 :                                           flat2.ToOneByteVector().start(), len);
   17671             :         }
   17672        4608 :         if (shape1.encoding_tag() == kTwoByteStringTag &&
   17673             :             shape2.encoding_tag() == kTwoByteStringTag) {
   17674        2304 :           String::FlatContent flat1 = string_->GetFlatContent();
   17675        2304 :           String::FlatContent flat2 = other->GetFlatContent();
   17676        2304 :           return CompareRawStringContents(flat1.ToUC16Vector().start(),
   17677        2304 :                                           flat2.ToUC16Vector().start(), len);
   17678             :         }
   17679             :       }
   17680             :       StringComparator comparator;
   17681           0 :       return comparator.Equals(string_, other);
   17682             :     }
   17683             : 
   17684           0 :     String::FlatContent flat_content = other->GetFlatContent();
   17685           0 :     if (one_byte_) {
   17686           0 :       if (flat_content.IsOneByte()) {
   17687             :         return CompareRawStringContents(
   17688           0 :             one_byte_content_, flat_content.ToOneByteVector().start(), len);
   17689             :       } else {
   17690             :         DCHECK(flat_content.IsTwoByte());
   17691           0 :         for (int i = 0; i < len; i++) {
   17692           0 :           if (flat_content.Get(i) != one_byte_content_[i]) return false;
   17693             :         }
   17694             :         return true;
   17695             :       }
   17696             :     } else {
   17697           0 :       if (flat_content.IsTwoByte()) {
   17698             :         return CompareRawStringContents(
   17699           0 :             two_byte_content_, flat_content.ToUC16Vector().start(), len);
   17700             :       } else {
   17701             :         DCHECK(flat_content.IsOneByte());
   17702           0 :         for (int i = 0; i < len; i++) {
   17703           0 :           if (flat_content.Get(i) != two_byte_content_[i]) return false;
   17704             :         }
   17705             :         return true;
   17706             :       }
   17707             :     }
   17708             :   }
   17709             : 
   17710       25653 :   uint32_t Hash() override { return hash_; }
   17711             : 
   17712           0 :   uint32_t HashForObject(Object* key) override {
   17713           0 :     return String::cast(key)->Hash();
   17714             :   }
   17715             : 
   17716           0 :   MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) override {
   17717           0 :     UNREACHABLE();
   17718             :     return Handle<String>();
   17719             :   }
   17720             : 
   17721             :  private:
   17722             :   String* string_;
   17723             :   int length_;
   17724             :   bool one_byte_;
   17725             :   bool special_flattening_;
   17726             :   uint32_t hash_ = 0;
   17727             :   union {
   17728             :     uint8_t* one_byte_content_;
   17729             :     uint16_t* two_byte_content_;
   17730             :   };
   17731             : };
   17732             : 
   17733             : }  // namespace
   17734             : 
   17735             : // static
   17736       25653 : Object* StringTable::LookupStringIfExists_NoAllocate(String* string) {
   17737             :   DisallowHeapAllocation no_gc;
   17738       25653 :   Heap* heap = string->GetHeap();
   17739             :   Isolate* isolate = heap->isolate();
   17740             :   StringTable* table = heap->string_table();
   17741             : 
   17742       25653 :   StringTableNoAllocateKey key(string, heap->HashSeed());
   17743             : 
   17744             :   // String could be an array index.
   17745             :   DCHECK(string->HasHashCode());
   17746             :   uint32_t hash = string->hash_field();
   17747             : 
   17748             :   // Valid array indices are >= 0, so they cannot be mixed up with any of
   17749             :   // the result sentinels, which are negative.
   17750             :   STATIC_ASSERT(
   17751             :       !String::ArrayIndexValueBits::is_valid(ResultSentinel::kUnsupported));
   17752             :   STATIC_ASSERT(
   17753             :       !String::ArrayIndexValueBits::is_valid(ResultSentinel::kNotFound));
   17754             : 
   17755       25653 :   if ((hash & Name::kContainsCachedArrayIndexMask) == 0) {
   17756           0 :     return Smi::FromInt(String::ArrayIndexValueBits::decode(hash));
   17757             :   }
   17758       25653 :   if ((hash & Name::kIsNotArrayIndexMask) == 0) {
   17759             :     // It is an indexed, but it's not cached.
   17760             :     return Smi::FromInt(ResultSentinel::kUnsupported);
   17761             :   }
   17762             : 
   17763       25653 :   int entry = table->FindEntry(isolate, &key, key.Hash());
   17764       25653 :   if (entry != kNotFound) {
   17765             :     String* internalized = String::cast(table->KeyAt(entry));
   17766       25542 :     if (FLAG_thin_strings) {
   17767       25506 :       MakeStringThin(string, internalized, isolate);
   17768             :     }
   17769       25542 :     return internalized;
   17770             :   }
   17771             :   // A string that's not an array index, and not in the string table,
   17772             :   // cannot have been used as a property name before.
   17773       25653 :   return Smi::FromInt(ResultSentinel::kNotFound);
   17774             : }
   17775             : 
   17776        7460 : String* StringTable::LookupKeyIfExists(Isolate* isolate, HashTableKey* key) {
   17777             :   Handle<StringTable> table = isolate->factory()->string_table();
   17778        7460 :   int entry = table->FindEntry(isolate, key);
   17779       10216 :   if (entry != kNotFound) return String::cast(table->KeyAt(entry));
   17780             :   return NULL;
   17781             : }
   17782             : 
   17783      195620 : Handle<StringSet> StringSet::New(Isolate* isolate) {
   17784      195620 :   return HashTable::New(isolate, 0);
   17785             : }
   17786             : 
   17787     2616962 : Handle<StringSet> StringSet::Add(Handle<StringSet> stringset,
   17788             :                                  Handle<String> name) {
   17789     2616962 :   if (!stringset->Has(name)) {
   17790      172210 :     stringset = EnsureCapacity(stringset, 1, *name);
   17791             :     uint32_t hash = StringSetShape::Hash(*name);
   17792      172210 :     int entry = stringset->FindInsertionEntry(hash);
   17793      172210 :     stringset->set(EntryToIndex(entry), *name);
   17794      172210 :     stringset->ElementAdded();
   17795             :   }
   17796     2616962 :   return stringset;
   17797             : }
   17798             : 
   17799     2636860 : bool StringSet::Has(Handle<String> name) {
   17800     2636860 :   return FindEntry(*name) != kNotFound;
   17801             : }
   17802             : 
   17803    16034291 : Handle<ObjectHashSet> ObjectHashSet::Add(Handle<ObjectHashSet> set,
   17804             :                                          Handle<Object> key) {
   17805             :   Isolate* isolate = set->GetIsolate();
   17806    16034291 :   int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
   17807             : 
   17808    16034291 :   if (!set->Has(isolate, key, hash)) {
   17809    16031980 :     set = EnsureCapacity(set, 1, key);
   17810    32063960 :     int entry = set->FindInsertionEntry(hash);
   17811    16031980 :     set->set(EntryToIndex(entry), *key);
   17812    16031980 :     set->ElementAdded();
   17813             :   }
   17814    16034291 :   return set;
   17815             : }
   17816             : 
   17817           0 : Handle<Object> CompilationCacheTable::Lookup(Handle<String> src,
   17818             :                                              Handle<Context> context,
   17819             :                                              LanguageMode language_mode) {
   17820             :   Isolate* isolate = GetIsolate();
   17821             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   17822             :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17823             :   int entry = FindEntry(&key);
   17824           0 :   if (entry == kNotFound) return isolate->factory()->undefined_value();
   17825             :   int index = EntryToIndex(entry);
   17826           0 :   if (!get(index)->IsFixedArray()) return isolate->factory()->undefined_value();
   17827           0 :   return Handle<Object>(get(index + 1), isolate);
   17828             : }
   17829             : 
   17830             : namespace {
   17831             : 
   17832             : const int kLiteralEntryLength = 2;
   17833             : const int kLiteralInitialLength = 2;
   17834             : const int kLiteralContextOffset = 0;
   17835             : const int kLiteralLiteralsOffset = 1;
   17836             : 
   17837     5183889 : int SearchLiteralsMapEntry(CompilationCacheTable* cache, int cache_entry,
   17838             :                            Context* native_context) {
   17839             :   DisallowHeapAllocation no_gc;
   17840             :   DCHECK(native_context->IsNativeContext());
   17841             :   Object* obj = cache->get(cache_entry);
   17842             : 
   17843     5183889 :   if (obj->IsFixedArray()) {
   17844             :     FixedArray* literals_map = FixedArray::cast(obj);
   17845             :     int length = literals_map->length();
   17846    12442549 :     for (int i = 0; i < length; i += kLiteralEntryLength) {
   17847    10891447 :       if (WeakCell::cast(literals_map->get(i + kLiteralContextOffset))
   17848             :               ->value() == native_context) {
   17849             :         return i;
   17850             :       }
   17851             :     }
   17852             :   }
   17853             :   return -1;
   17854             : }
   17855             : 
   17856     1208386 : void AddToLiteralsMap(Handle<CompilationCacheTable> cache, int cache_entry,
   17857             :                       Handle<Context> native_context, Handle<Cell> literals) {
   17858             :   Isolate* isolate = native_context->GetIsolate();
   17859             :   DCHECK(native_context->IsNativeContext());
   17860             :   STATIC_ASSERT(kLiteralEntryLength == 2);
   17861             :   Handle<FixedArray> new_literals_map;
   17862             :   int entry;
   17863             : 
   17864             :   Object* obj = cache->get(cache_entry);
   17865             : 
   17866     1948250 :   if (!obj->IsFixedArray() || FixedArray::cast(obj)->length() == 0) {
   17867             :     new_literals_map =
   17868      468524 :         isolate->factory()->NewFixedArray(kLiteralInitialLength, TENURED);
   17869             :     entry = 0;
   17870             :   } else {
   17871             :     Handle<FixedArray> old_literals_map(FixedArray::cast(obj), isolate);
   17872      739863 :     entry = SearchLiteralsMapEntry(*cache, cache_entry, *native_context);
   17873      739863 :     if (entry >= 0) {
   17874             :       // Just set the code of the entry.
   17875             :       Handle<WeakCell> literals_cell =
   17876        1464 :           isolate->factory()->NewWeakCell(literals);
   17877        2928 :       old_literals_map->set(entry + kLiteralLiteralsOffset, *literals_cell);
   17878     1208387 :       return;
   17879             :     }
   17880             : 
   17881             :     // Can we reuse an entry?
   17882             :     DCHECK(entry < 0);
   17883             :     int length = old_literals_map->length();
   17884     2014368 :     for (int i = 0; i < length; i += kLiteralEntryLength) {
   17885     1359347 :       if (WeakCell::cast(old_literals_map->get(i + kLiteralContextOffset))
   17886             :               ->cleared()) {
   17887             :         new_literals_map = old_literals_map;
   17888             :         entry = i;
   17889             :         break;
   17890             :       }
   17891             :     }
   17892             : 
   17893      738399 :     if (entry < 0) {
   17894             :       // Copy old optimized code map and append one new entry.
   17895             :       new_literals_map = isolate->factory()->CopyFixedArrayAndGrow(
   17896      655021 :           old_literals_map, kLiteralEntryLength, TENURED);
   17897             :       entry = old_literals_map->length();
   17898             :     }
   17899             :   }
   17900             : 
   17901     1206923 :   Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals);
   17902             :   WeakCell* context_cell = native_context->self_weak_cell();
   17903             : 
   17904     1206923 :   new_literals_map->set(entry + kLiteralContextOffset, context_cell);
   17905     2413846 :   new_literals_map->set(entry + kLiteralLiteralsOffset, *literals_cell);
   17906             : 
   17907             : #ifdef DEBUG
   17908             :   for (int i = 0; i < new_literals_map->length(); i += kLiteralEntryLength) {
   17909             :     WeakCell* cell =
   17910             :         WeakCell::cast(new_literals_map->get(i + kLiteralContextOffset));
   17911             :     DCHECK(cell->cleared() || cell->value()->IsNativeContext());
   17912             :     cell = WeakCell::cast(new_literals_map->get(i + kLiteralLiteralsOffset));
   17913             :     DCHECK(cell->cleared() || (cell->value()->IsCell()));
   17914             :   }
   17915             : #endif
   17916             : 
   17917             :   Object* old_literals_map = cache->get(cache_entry);
   17918     1206923 :   if (old_literals_map != *new_literals_map) {
   17919     1123545 :     cache->set(cache_entry, *new_literals_map);
   17920             :   }
   17921             : }
   17922             : 
   17923     4444026 : Cell* SearchLiteralsMap(CompilationCacheTable* cache, int cache_entry,
   17924             :                         Context* native_context) {
   17925             :   Cell* result = nullptr;
   17926     4444026 :   int entry = SearchLiteralsMapEntry(cache, cache_entry, native_context);
   17927     4444026 :   if (entry >= 0) {
   17928             :     FixedArray* literals_map = FixedArray::cast(cache->get(cache_entry));
   17929             :     DCHECK_LE(entry + kLiteralEntryLength, literals_map->length());
   17930             :     WeakCell* cell =
   17931     3631323 :         WeakCell::cast(literals_map->get(entry + kLiteralLiteralsOffset));
   17932             : 
   17933     3631323 :     result = cell->cleared() ? nullptr : Cell::cast(cell->value());
   17934             :   }
   17935             :   DCHECK(result == nullptr || result->IsCell());
   17936     4444026 :   return result;
   17937             : }
   17938             : 
   17939             : }  // namespace
   17940             : 
   17941      311147 : InfoVectorPair CompilationCacheTable::LookupScript(Handle<String> src,
   17942             :                                                    Handle<Context> context,
   17943             :                                                    LanguageMode language_mode) {
   17944             :   InfoVectorPair empty_result;
   17945             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   17946             :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17947             :   int entry = FindEntry(&key);
   17948      311147 :   if (entry == kNotFound) return empty_result;
   17949             :   int index = EntryToIndex(entry);
   17950      141811 :   if (!get(index)->IsFixedArray()) return empty_result;
   17951      141811 :   Object* obj = get(index + 1);
   17952      141811 :   if (obj->IsSharedFunctionInfo()) {
   17953             :     Cell* literals =
   17954      141811 :         SearchLiteralsMap(this, index + 2, context->native_context());
   17955      141811 :     return InfoVectorPair(SharedFunctionInfo::cast(obj), literals);
   17956             :   }
   17957           0 :   return empty_result;
   17958             : }
   17959             : 
   17960     5554356 : InfoVectorPair CompilationCacheTable::LookupEval(
   17961             :     Handle<String> src, Handle<SharedFunctionInfo> outer_info,
   17962             :     Handle<Context> native_context, LanguageMode language_mode, int position) {
   17963             :   InfoVectorPair empty_result;
   17964             :   StringSharedKey key(src, outer_info, language_mode, position);
   17965             :   int entry = FindEntry(&key);
   17966     5554356 :   if (entry == kNotFound) return empty_result;
   17967             :   int index = EntryToIndex(entry);
   17968     4597179 :   if (!get(index)->IsFixedArray()) return empty_result;
   17969     4302215 :   Object* obj = get(EntryToIndex(entry) + 1);
   17970     4302215 :   if (obj->IsSharedFunctionInfo()) {
   17971             :     Cell* literals =
   17972     4302215 :         SearchLiteralsMap(this, EntryToIndex(entry) + 2, *native_context);
   17973     4302215 :     return InfoVectorPair(SharedFunctionInfo::cast(obj), literals);
   17974             :   }
   17975           0 :   return empty_result;
   17976             : }
   17977             : 
   17978     1069572 : Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src,
   17979             :                                                    JSRegExp::Flags flags) {
   17980             :   Isolate* isolate = GetIsolate();
   17981             :   DisallowHeapAllocation no_allocation;
   17982             :   RegExpKey key(src, flags);
   17983             :   int entry = FindEntry(&key);
   17984     1782729 :   if (entry == kNotFound) return isolate->factory()->undefined_value();
   17985      712830 :   return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
   17986             : }
   17987             : 
   17988             : 
   17989           0 : Handle<CompilationCacheTable> CompilationCacheTable::Put(
   17990             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   17991             :     Handle<Context> context, LanguageMode language_mode, Handle<Object> value) {
   17992             :   Isolate* isolate = cache->GetIsolate();
   17993             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   17994             :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17995           0 :   Handle<Object> k = key.AsHandle(isolate);
   17996           0 :   cache = EnsureCapacity(cache, 1, &key);
   17997           0 :   int entry = cache->FindInsertionEntry(key.Hash());
   17998           0 :   cache->set(EntryToIndex(entry), *k);
   17999           0 :   cache->set(EntryToIndex(entry) + 1, *value);
   18000           0 :   cache->ElementAdded();
   18001           0 :   return cache;
   18002             : }
   18003             : 
   18004      168528 : Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
   18005             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   18006             :     Handle<Context> context, LanguageMode language_mode,
   18007             :     Handle<SharedFunctionInfo> value, Handle<Cell> literals) {
   18008             :   Isolate* isolate = cache->GetIsolate();
   18009             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   18010             :   Handle<Context> native_context(context->native_context());
   18011             :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   18012      168529 :   Handle<Object> k = key.AsHandle(isolate);
   18013      168529 :   cache = EnsureCapacity(cache, 1, &key);
   18014      337058 :   int entry = cache->FindInsertionEntry(key.Hash());
   18015      168529 :   cache->set(EntryToIndex(entry), *k);
   18016      337058 :   cache->set(EntryToIndex(entry) + 1, *value);
   18017      168529 :   AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, literals);
   18018      168529 :   cache->ElementAdded();
   18019      168529 :   return cache;
   18020             : }
   18021             : 
   18022     1816841 : Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
   18023             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   18024             :     Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
   18025             :     Handle<Context> native_context, Handle<Cell> literals, int position) {
   18026             :   Isolate* isolate = cache->GetIsolate();
   18027             :   StringSharedKey key(src, outer_info, value->language_mode(), position);
   18028             :   {
   18029     1816841 :     Handle<Object> k = key.AsHandle(isolate);
   18030             :     int entry = cache->FindEntry(&key);
   18031     1816841 :     if (entry != kNotFound) {
   18032     1039858 :       cache->set(EntryToIndex(entry), *k);
   18033     2079716 :       cache->set(EntryToIndex(entry) + 1, *value);
   18034             :       // AddToLiteralsMap may allocate a new sub-array to live in the entry,
   18035             :       // but it won't change the cache array. Therefore EntryToIndex and
   18036             :       // entry remains correct.
   18037             :       AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context,
   18038     1039858 :                        literals);
   18039     1039858 :       return cache;
   18040             :     }
   18041             :   }
   18042             : 
   18043      776983 :   cache = EnsureCapacity(cache, 1, &key);
   18044     1553966 :   int entry = cache->FindInsertionEntry(key.Hash());
   18045             :   Handle<Object> k =
   18046      776983 :       isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
   18047      776983 :   cache->set(EntryToIndex(entry), *k);
   18048             :   cache->set(EntryToIndex(entry) + 1, Smi::FromInt(kHashGenerations));
   18049      776983 :   cache->ElementAdded();
   18050      776983 :   return cache;
   18051             : }
   18052             : 
   18053             : 
   18054      353113 : Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
   18055             :       Handle<CompilationCacheTable> cache, Handle<String> src,
   18056             :       JSRegExp::Flags flags, Handle<FixedArray> value) {
   18057             :   RegExpKey key(src, flags);
   18058      353113 :   cache = EnsureCapacity(cache, 1, &key);
   18059      353113 :   int entry = cache->FindInsertionEntry(key.Hash());
   18060             :   // We store the value in the key slot, and compare the search key
   18061             :   // to the stored value with a custon IsMatch function during lookups.
   18062      353113 :   cache->set(EntryToIndex(entry), *value);
   18063      706226 :   cache->set(EntryToIndex(entry) + 1, *value);
   18064      353113 :   cache->ElementAdded();
   18065      353113 :   return cache;
   18066             : }
   18067             : 
   18068             : 
   18069       19088 : void CompilationCacheTable::Age() {
   18070             :   DisallowHeapAllocation no_allocation;
   18071       19088 :   Object* the_hole_value = GetHeap()->the_hole_value();
   18072     3931728 :   for (int entry = 0, size = Capacity(); entry < size; entry++) {
   18073             :     int entry_index = EntryToIndex(entry);
   18074     3893552 :     int value_index = entry_index + 1;
   18075             : 
   18076     3893552 :     if (get(entry_index)->IsNumber()) {
   18077             :       Smi* count = Smi::cast(get(value_index));
   18078      305932 :       count = Smi::FromInt(count->value() - 1);
   18079      305932 :       if (count->value() == 0) {
   18080             :         NoWriteBarrierSet(this, entry_index, the_hole_value);
   18081             :         NoWriteBarrierSet(this, value_index, the_hole_value);
   18082         264 :         ElementRemoved();
   18083             :       } else {
   18084             :         NoWriteBarrierSet(this, value_index, count);
   18085             :       }
   18086     3587620 :     } else if (get(entry_index)->IsFixedArray()) {
   18087             :       SharedFunctionInfo* info = SharedFunctionInfo::cast(get(value_index));
   18088             :       bool is_old =
   18089             :           info->IsInterpreted()
   18090             :               ? info->bytecode_array()->IsOld()
   18091      782694 :               : info->code()->kind() != Code::FUNCTION || info->code()->IsOld();
   18092      425356 :       if (is_old) {
   18093       14049 :         for (int i = 0; i < kEntrySize; i++) {
   18094       14049 :           NoWriteBarrierSet(this, entry_index + i, the_hole_value);
   18095             :         }
   18096        4683 :         ElementRemoved();
   18097             :       }
   18098             :     }
   18099             :   }
   18100       19088 : }
   18101             : 
   18102             : 
   18103           0 : void CompilationCacheTable::Remove(Object* value) {
   18104             :   DisallowHeapAllocation no_allocation;
   18105           0 :   Object* the_hole_value = GetHeap()->the_hole_value();
   18106           0 :   for (int entry = 0, size = Capacity(); entry < size; entry++) {
   18107             :     int entry_index = EntryToIndex(entry);
   18108           0 :     int value_index = entry_index + 1;
   18109           0 :     if (get(value_index) == value) {
   18110           0 :       for (int i = 0; i < kEntrySize; i++) {
   18111           0 :         NoWriteBarrierSet(this, entry_index + i, the_hole_value);
   18112             :       }
   18113           0 :       ElementRemoved();
   18114             :     }
   18115             :   }
   18116           0 :   return;
   18117             : }
   18118             : 
   18119             : template <typename Derived, typename Shape, typename Key>
   18120     2281020 : Handle<Derived> Dictionary<Derived, Shape, Key>::New(
   18121             :     Isolate* isolate, int at_least_space_for, PretenureFlag pretenure,
   18122             :     MinimumCapacity capacity_option) {
   18123             :   DCHECK(0 <= at_least_space_for);
   18124             :   Handle<Derived> dict = DerivedHashTable::New(isolate, at_least_space_for,
   18125     2281020 :                                                capacity_option, pretenure);
   18126             : 
   18127             :   // Initialize the next enumeration index.
   18128             :   dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
   18129     2281020 :   return dict;
   18130             : }
   18131             : 
   18132             : template <typename Derived, typename Shape, typename Key>
   18133         284 : Handle<Derived> Dictionary<Derived, Shape, Key>::NewEmpty(
   18134             :     Isolate* isolate, PretenureFlag pretenure) {
   18135         284 :   Handle<Derived> dict = DerivedHashTable::New(isolate, 1, pretenure);
   18136             :   // Attempt to add one element to the empty dictionary must cause reallocation.
   18137             :   DCHECK(!dict->HasSufficientCapacityToAdd(1));
   18138             :   // Initialize the next enumeration index.
   18139             :   dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
   18140         284 :   return dict;
   18141             : }
   18142             : 
   18143             : template <typename Derived, typename Shape, typename Key>
   18144          50 : void Dictionary<Derived, Shape, Key>::SetRequiresCopyOnCapacityChange() {
   18145             :   DCHECK_EQ(0, DerivedHashTable::NumberOfElements());
   18146             :   DCHECK_EQ(0, DerivedHashTable::NumberOfDeletedElements());
   18147             :   // Make sure that HashTable::EnsureCapacity will create a copy.
   18148             :   DerivedHashTable::SetNumberOfDeletedElements(DerivedHashTable::Capacity());
   18149             :   DCHECK(!DerivedHashTable::HasSufficientCapacityToAdd(1));
   18150          50 : }
   18151             : 
   18152             : 
   18153             : template <typename Derived, typename Shape, typename Key>
   18154    38591409 : Handle<Derived> Dictionary<Derived, Shape, Key>::EnsureCapacity(
   18155             :     Handle<Derived> dictionary, int n, Key key) {
   18156             :   // Check whether there are enough enumeration indices to add n elements.
   18157    30903219 :   if (Shape::kIsEnumerable &&
   18158    30903219 :       !PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) {
   18159             :     // If not, we generate new indices for the properties.
   18160             :     int length = dictionary->NumberOfElements();
   18161             : 
   18162           0 :     Handle<FixedArray> iteration_order = IterationIndices(dictionary);
   18163             :     DCHECK_EQ(length, iteration_order->length());
   18164             : 
   18165             :     // Iterate over the dictionary using the enumeration order and update
   18166             :     // the dictionary with new enumeration indices.
   18167           0 :     for (int i = 0; i < length; i++) {
   18168             :       int index = Smi::cast(iteration_order->get(i))->value();
   18169             :       DCHECK(dictionary->IsKey(dictionary->GetIsolate(),
   18170             :                                dictionary->KeyAt(index)));
   18171             : 
   18172           0 :       int enum_index = PropertyDetails::kInitialIndex + i;
   18173             : 
   18174             :       PropertyDetails details = dictionary->DetailsAt(index);
   18175             :       PropertyDetails new_details = details.set_index(enum_index);
   18176             :       dictionary->DetailsAtPut(index, new_details);
   18177             :     }
   18178             : 
   18179             :     // Set the next enumeration index.
   18180           0 :     dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex +
   18181             :                                         length);
   18182             :   }
   18183    38591409 :   return DerivedHashTable::EnsureCapacity(dictionary, n, key);
   18184             : }
   18185             : 
   18186             : 
   18187             : template <typename Derived, typename Shape, typename Key>
   18188     6169666 : Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty(
   18189             :     Handle<Derived> dictionary, int entry) {
   18190             :   Factory* factory = dictionary->GetIsolate()->factory();
   18191             :   PropertyDetails details = dictionary->DetailsAt(entry);
   18192     6169666 :   if (!details.IsConfigurable()) return factory->false_value();
   18193             : 
   18194     6169666 :   dictionary->SetEntry(
   18195             :       entry, factory->the_hole_value(), factory->the_hole_value());
   18196     6169666 :   dictionary->ElementRemoved();
   18197     6169666 :   return factory->true_value();
   18198             : }
   18199             : 
   18200             : 
   18201             : template<typename Derived, typename Shape, typename Key>
   18202     1897664 : Handle<Derived> Dictionary<Derived, Shape, Key>::AtPut(
   18203             :     Handle<Derived> dictionary, Key key, Handle<Object> value) {
   18204             :   int entry = dictionary->FindEntry(key);
   18205             : 
   18206             :   // If the entry is present set the value;
   18207     1897664 :   if (entry != Dictionary::kNotFound) {
   18208             :     dictionary->ValueAtPut(entry, *value);
   18209          24 :     return dictionary;
   18210             :   }
   18211             : 
   18212             :   // Check whether the dictionary should be extended.
   18213     1897640 :   dictionary = EnsureCapacity(dictionary, 1, key);
   18214             : #ifdef DEBUG
   18215             :   USE(Shape::AsHandle(dictionary->GetIsolate(), key));
   18216             : #endif
   18217     1897640 :   PropertyDetails details = PropertyDetails::Empty();
   18218             : 
   18219     1897640 :   AddEntry(dictionary, key, value, details, dictionary->Hash(key));
   18220     1897640 :   return dictionary;
   18221             : }
   18222             : 
   18223             : template <typename Derived, typename Shape, typename Key>
   18224    36693767 : Handle<Derived> Dictionary<Derived, Shape, Key>::Add(Handle<Derived> dictionary,
   18225             :                                                      Key key,
   18226             :                                                      Handle<Object> value,
   18227             :                                                      PropertyDetails details,
   18228             :                                                      int* entry_out) {
   18229             :   // Valdate key is absent.
   18230             :   SLOW_DCHECK((dictionary->FindEntry(key) == Dictionary::kNotFound));
   18231             :   // Check whether the dictionary should be extended.
   18232    36693767 :   dictionary = EnsureCapacity(dictionary, 1, key);
   18233             : 
   18234    36693769 :   int entry = AddEntry(dictionary, key, value, details, dictionary->Hash(key));
   18235    36693771 :   if (entry_out) *entry_out = entry;
   18236    36693771 :   return dictionary;
   18237             : }
   18238             : 
   18239             : // Add a key, value pair to the dictionary. Returns entry value.
   18240             : template <typename Derived, typename Shape, typename Key>
   18241    38591409 : int Dictionary<Derived, Shape, Key>::AddEntry(Handle<Derived> dictionary,
   18242             :                                               Key key, Handle<Object> value,
   18243             :                                               PropertyDetails details,
   18244             :                                               uint32_t hash) {
   18245             :   // Compute the key object.
   18246             :   Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key);
   18247             : 
   18248    38591409 :   uint32_t entry = dictionary->FindInsertionEntry(hash);
   18249             :   // Insert element at empty or deleted entry
   18250    30903220 :   if (details.dictionary_index() == 0 && Shape::kIsEnumerable) {
   18251             :     // Assign an enumeration index to the property and update
   18252             :     // SetNextEnumerationIndex.
   18253             :     int index = dictionary->NextEnumerationIndex();
   18254             :     details = details.set_index(index);
   18255    25102231 :     dictionary->SetNextEnumerationIndex(index + 1);
   18256             :   }
   18257    38591408 :   dictionary->SetEntry(entry, k, value, details);
   18258             :   DCHECK((dictionary->KeyAt(entry)->IsNumber() ||
   18259             :           dictionary->KeyAt(entry)->IsName()));
   18260    38591411 :   dictionary->ElementAdded();
   18261    38591411 :   return entry;
   18262             : }
   18263             : 
   18264        4562 : bool SeededNumberDictionary::HasComplexElements() {
   18265        4562 :   if (!requires_slow_elements()) return false;
   18266             :   Isolate* isolate = this->GetIsolate();
   18267             :   int capacity = this->Capacity();
   18268       20595 :   for (int i = 0; i < capacity; i++) {
   18269             :     Object* k = this->KeyAt(i);
   18270       17970 :     if (!this->IsKey(isolate, k)) continue;
   18271             :     DCHECK(!IsDeleted(i));
   18272             :     PropertyDetails details = this->DetailsAt(i);
   18273        7290 :     if (details.kind() == kAccessor) return true;
   18274             :     PropertyAttributes attr = details.attributes();
   18275        7230 :     if (attr & ALL_ATTRIBUTES_MASK) return true;
   18276             :   }
   18277             :   return false;
   18278             : }
   18279             : 
   18280     6362579 : void SeededNumberDictionary::UpdateMaxNumberKey(
   18281             :     uint32_t key, Handle<JSObject> dictionary_holder) {
   18282             :   DisallowHeapAllocation no_allocation;
   18283             :   // If the dictionary requires slow elements an element has already
   18284             :   // been added at a high index.
   18285     6362579 :   if (requires_slow_elements()) return;
   18286             :   // Check if this index is high enough that we should require slow
   18287             :   // elements.
   18288     6289015 :   if (key > kRequiresSlowElementsLimit) {
   18289        1586 :     if (!dictionary_holder.is_null()) {
   18290        1178 :       dictionary_holder->RequireSlowElements(this);
   18291             :     }
   18292             :     set_requires_slow_elements();
   18293             :     return;
   18294             :   }
   18295             :   // Update max key value.
   18296             :   Object* max_index_object = get(kMaxNumberKeyIndex);
   18297     6287429 :   if (!max_index_object->IsSmi() || max_number_key() < key) {
   18298             :     FixedArray::set(kMaxNumberKeyIndex,
   18299     5378819 :                     Smi::FromInt(key << kRequiresSlowElementsTagSize));
   18300             :   }
   18301             : }
   18302             : 
   18303     5776105 : Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry(
   18304             :     Handle<SeededNumberDictionary> dictionary, uint32_t key,
   18305             :     Handle<Object> value, PropertyDetails details,
   18306             :     Handle<JSObject> dictionary_holder) {
   18307     5776105 :   dictionary->UpdateMaxNumberKey(key, dictionary_holder);
   18308             :   SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
   18309     5776105 :   return Add(dictionary, key, value, details);
   18310             : }
   18311             : 
   18312             : 
   18313           0 : Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry(
   18314             :     Handle<UnseededNumberDictionary> dictionary,
   18315             :     uint32_t key,
   18316             :     Handle<Object> value) {
   18317             :   SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
   18318         393 :   return Add(dictionary, key, value, PropertyDetails::Empty());
   18319             : }
   18320             : 
   18321           0 : Handle<UnseededNumberDictionary> UnseededNumberDictionary::DeleteKey(
   18322             :     Handle<UnseededNumberDictionary> dictionary, uint32_t key) {
   18323             :   int entry = dictionary->FindEntry(key);
   18324           0 :   if (entry == kNotFound) return dictionary;
   18325             : 
   18326             :   Factory* factory = dictionary->GetIsolate()->factory();
   18327             :   dictionary->SetEntry(entry, factory->the_hole_value(),
   18328             :                        factory->the_hole_value());
   18329           0 :   dictionary->ElementRemoved();
   18330           0 :   return dictionary->Shrink(dictionary, key);
   18331             : }
   18332             : 
   18333      586474 : Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut(
   18334             :     Handle<SeededNumberDictionary> dictionary, uint32_t key,
   18335             :     Handle<Object> value, Handle<JSObject> dictionary_holder) {
   18336      586474 :   dictionary->UpdateMaxNumberKey(key, dictionary_holder);
   18337      586474 :   return AtPut(dictionary, key, value);
   18338             : }
   18339             : 
   18340          60 : void SeededNumberDictionary::CopyValuesTo(FixedArray* elements) {
   18341             :   Isolate* isolate = this->GetIsolate();
   18342             :   int pos = 0;
   18343             :   int capacity = this->Capacity();
   18344             :   DisallowHeapAllocation no_gc;
   18345          60 :   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
   18346        1020 :   for (int i = 0; i < capacity; i++) {
   18347             :     Object* k = this->KeyAt(i);
   18348         960 :     if (this->IsKey(isolate, k)) {
   18349         450 :       elements->set(pos++, this->ValueAt(i), mode);
   18350             :     }
   18351             :   }
   18352             :   DCHECK(pos == elements->length());
   18353          60 : }
   18354             : 
   18355     1311190 : Handle<UnseededNumberDictionary> UnseededNumberDictionary::AtNumberPut(
   18356             :     Handle<UnseededNumberDictionary> dictionary,
   18357             :     uint32_t key,
   18358             :     Handle<Object> value) {
   18359     1311190 :   return AtPut(dictionary, key, value);
   18360             : }
   18361             : 
   18362       39328 : Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
   18363             :     Handle<SeededNumberDictionary> dictionary, uint32_t key,
   18364             :     Handle<Object> value, PropertyDetails details,
   18365             :     Handle<JSObject> dictionary_holder) {
   18366             :   int entry = dictionary->FindEntry(key);
   18367       39328 :   if (entry == kNotFound) {
   18368       37558 :     return AddNumberEntry(dictionary, key, value, details, dictionary_holder);
   18369             :   }
   18370             :   // Preserve enumeration index.
   18371             :   details = details.set_index(dictionary->DetailsAt(entry).dictionary_index());
   18372             :   Handle<Object> object_key =
   18373             :       SeededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
   18374             :   dictionary->SetEntry(entry, object_key, value, details);
   18375        1770 :   return dictionary;
   18376             : }
   18377             : 
   18378             : 
   18379        1818 : Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
   18380             :     Handle<UnseededNumberDictionary> dictionary,
   18381             :     uint32_t key,
   18382             :     Handle<Object> value) {
   18383             :   int entry = dictionary->FindEntry(key);
   18384        1818 :   if (entry == kNotFound) return AddNumberEntry(dictionary, key, value);
   18385             :   Handle<Object> object_key =
   18386             :       UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
   18387             :   dictionary->SetEntry(entry, object_key, value);
   18388        1425 :   return dictionary;
   18389             : }
   18390             : 
   18391             : 
   18392             : template <typename Derived, typename Shape, typename Key>
   18393       98702 : int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
   18394             :     PropertyFilter filter) {
   18395             :   Isolate* isolate = this->GetIsolate();
   18396             :   int capacity = this->Capacity();
   18397             :   int result = 0;
   18398    10286962 :   for (int i = 0; i < capacity; i++) {
   18399             :     Object* k = this->KeyAt(i);
   18400    10188260 :     if (this->IsKey(isolate, k) && !k->FilterKey(filter)) {
   18401     3211028 :       if (this->IsDeleted(i)) continue;
   18402             :       PropertyDetails details = this->DetailsAt(i);
   18403             :       PropertyAttributes attr = details.attributes();
   18404     4505899 :       if ((attr & filter) == 0) result++;
   18405             :     }
   18406             :   }
   18407       98702 :   return result;
   18408             : }
   18409             : 
   18410             : 
   18411             : template <typename Dictionary>
   18412             : struct EnumIndexComparator {
   18413      793630 :   explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {}
   18414   130759320 :   bool operator() (Smi* a, Smi* b) {
   18415   130759320 :     PropertyDetails da(dict->DetailsAt(a->value()));
   18416   130759320 :     PropertyDetails db(dict->DetailsAt(b->value()));
   18417   130759320 :     return da.dictionary_index() < db.dictionary_index();
   18418             :   }
   18419             :   Dictionary* dict;
   18420             : };
   18421             : 
   18422             : template <typename Derived, typename Shape, typename Key>
   18423       97481 : void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(
   18424             :     Handle<Dictionary<Derived, Shape, Key>> dictionary,
   18425             :     Handle<FixedArray> storage, KeyCollectionMode mode,
   18426             :     KeyAccumulator* accumulator) {
   18427             :   DCHECK_IMPLIES(mode != KeyCollectionMode::kOwnOnly, accumulator != nullptr);
   18428             :   Isolate* isolate = dictionary->GetIsolate();
   18429             :   int length = storage->length();
   18430             :   int capacity = dictionary->Capacity();
   18431             :   int properties = 0;
   18432    10089303 :   for (int i = 0; i < capacity; i++) {
   18433             :     Object* key = dictionary->KeyAt(i);
   18434             :     bool is_shadowing_key = false;
   18435    10031781 :     if (!dictionary->IsKey(isolate, key)) continue;
   18436     4475091 :     if (key->IsSymbol()) continue;
   18437             :     PropertyDetails details = dictionary->DetailsAt(i);
   18438     4446080 :     if (details.IsDontEnum()) {
   18439     1490117 :       if (mode == KeyCollectionMode::kIncludePrototypes) {
   18440             :         is_shadowing_key = true;
   18441             :       } else {
   18442             :         continue;
   18443             :       }
   18444             :     }
   18445     1682708 :     if (dictionary->IsDeleted(i)) continue;
   18446     2975492 :     if (is_shadowing_key) {
   18447       19664 :       accumulator->AddShadowingKey(key);
   18448       19664 :       continue;
   18449             :     } else {
   18450             :       storage->set(properties, Smi::FromInt(i));
   18451             :     }
   18452     2955828 :     properties++;
   18453     2955828 :     if (mode == KeyCollectionMode::kOwnOnly && properties == length) break;
   18454             :   }
   18455             : 
   18456       97481 :   CHECK_EQ(length, properties);
   18457             :   DisallowHeapAllocation no_gc;
   18458             :   Dictionary<Derived, Shape, Key>* raw_dictionary = *dictionary;
   18459             :   FixedArray* raw_storage = *storage;
   18460             :   EnumIndexComparator<Derived> cmp(static_cast<Derived*>(*dictionary));
   18461       97481 :   Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress());
   18462       97481 :   std::sort(start, start + length, cmp);
   18463     3053309 :   for (int i = 0; i < length; i++) {
   18464             :     int index = Smi::cast(raw_storage->get(i))->value();
   18465     2955828 :     raw_storage->set(i, raw_dictionary->KeyAt(index));
   18466             :   }
   18467       97481 : }
   18468             : 
   18469             : template <typename Derived, typename Shape, typename Key>
   18470      629872 : Handle<FixedArray> Dictionary<Derived, Shape, Key>::IterationIndices(
   18471             :     Handle<Dictionary<Derived, Shape, Key>> dictionary) {
   18472             :   Isolate* isolate = dictionary->GetIsolate();
   18473             :   int capacity = dictionary->Capacity();
   18474             :   int length = dictionary->NumberOfElements();
   18475      629872 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
   18476             :   int array_size = 0;
   18477             :   {
   18478             :     DisallowHeapAllocation no_gc;
   18479             :     Dictionary<Derived, Shape, Key>* raw_dict = *dictionary;
   18480    21470092 :     for (int i = 0; i < capacity; i++) {
   18481             :       Object* k = raw_dict->KeyAt(i);
   18482    20840220 :       if (!raw_dict->IsKey(isolate, k)) continue;
   18483     5554710 :       if (raw_dict->IsDeleted(i)) continue;
   18484     8754904 :       array->set(array_size++, Smi::FromInt(i));
   18485             :     }
   18486             : 
   18487             :     DCHECK_EQ(array_size, length);
   18488             : 
   18489             :     EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict));
   18490      629872 :     Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress());
   18491      629872 :     std::sort(start, start + array_size, cmp);
   18492             :   }
   18493      629872 :   array->Shrink(array_size);
   18494      629872 :   return array;
   18495             : }
   18496             : 
   18497             : template <typename Derived, typename Shape, typename Key>
   18498       66277 : void Dictionary<Derived, Shape, Key>::CollectKeysTo(
   18499             :     Handle<Dictionary<Derived, Shape, Key>> dictionary, KeyAccumulator* keys) {
   18500             :   Isolate* isolate = keys->isolate();
   18501             :   int capacity = dictionary->Capacity();
   18502             :   Handle<FixedArray> array =
   18503       66277 :       isolate->factory()->NewFixedArray(dictionary->NumberOfElements());
   18504             :   int array_size = 0;
   18505             :   PropertyFilter filter = keys->filter();
   18506             :   {
   18507             :     DisallowHeapAllocation no_gc;
   18508             :     Dictionary<Derived, Shape, Key>* raw_dict = *dictionary;
   18509    19381873 :     for (int i = 0; i < capacity; i++) {
   18510             :       Object* k = raw_dict->KeyAt(i);
   18511    19315596 :       if (!raw_dict->IsKey(isolate, k) || k->FilterKey(filter)) continue;
   18512     3174296 :       if (raw_dict->IsDeleted(i)) continue;
   18513             :       PropertyDetails details = raw_dict->DetailsAt(i);
   18514     5856902 :       if ((details.attributes() & filter) != 0) {
   18515         636 :         keys->AddShadowingKey(k);
   18516         636 :         continue;
   18517             :       }
   18518     5856266 :       if (filter & ONLY_ALL_CAN_READ) {
   18519         409 :         if (details.kind() != kAccessor) continue;
   18520          31 :         Object* accessors = raw_dict->ValueAt(i);
   18521          31 :         if (accessors->IsPropertyCell()) {
   18522             :           accessors = PropertyCell::cast(accessors)->value();
   18523             :         }
   18524          31 :         if (!accessors->IsAccessorInfo()) continue;
   18525          31 :         if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
   18526             :       }
   18527     5855876 :       array->set(array_size++, Smi::FromInt(i));
   18528             :     }
   18529             : 
   18530             :     EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict));
   18531       66277 :     Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress());
   18532       66277 :     std::sort(start, start + array_size, cmp);
   18533             :   }
   18534             : 
   18535             :   bool has_seen_symbol = false;
   18536     5922153 :   for (int i = 0; i < array_size; i++) {
   18537             :     int index = Smi::cast(array->get(i))->value();
   18538             :     Object* key = dictionary->KeyAt(index);
   18539     5855876 :     if (key->IsSymbol()) {
   18540             :       has_seen_symbol = true;
   18541             :       continue;
   18542             :     }
   18543     5827222 :     keys->AddKey(key, DO_NOT_CONVERT);
   18544             :   }
   18545       66277 :   if (has_seen_symbol) {
   18546       35075 :     for (int i = 0; i < array_size; i++) {
   18547             :       int index = Smi::cast(array->get(i))->value();
   18548             :       Object* key = dictionary->KeyAt(index);
   18549       35075 :       if (!key->IsSymbol()) continue;
   18550       28654 :       keys->AddKey(key, DO_NOT_CONVERT);
   18551             :     }
   18552             :   }
   18553       66277 : }
   18554             : 
   18555             : 
   18556             : // Backwards lookup (slow).
   18557             : template<typename Derived, typename Shape, typename Key>
   18558          14 : Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
   18559             :   Isolate* isolate = this->GetIsolate();
   18560             :   int capacity = this->Capacity();
   18561        1806 :   for (int i = 0; i < capacity; i++) {
   18562             :     Object* k = this->KeyAt(i);
   18563        1792 :     if (!this->IsKey(isolate, k)) continue;
   18564         756 :     Object* e = this->ValueAt(i);
   18565             :     // TODO(dcarney): this should be templatized.
   18566         756 :     if (e->IsPropertyCell()) {
   18567             :       e = PropertyCell::cast(e)->value();
   18568             :     }
   18569         756 :     if (e == value) return k;
   18570             :   }
   18571          14 :   return isolate->heap()->undefined_value();
   18572             : }
   18573             : 
   18574             : 
   18575        9158 : Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key,
   18576             :                                 int32_t hash) {
   18577             :   DisallowHeapAllocation no_gc;
   18578             :   DCHECK(IsKey(isolate, *key));
   18579             : 
   18580        9158 :   int entry = FindEntry(isolate, key, hash);
   18581        9158 :   if (entry == kNotFound) return isolate->heap()->the_hole_value();
   18582       15462 :   return get(EntryToIndex(entry) + 1);
   18583             : }
   18584             : 
   18585             : 
   18586        7462 : Object* ObjectHashTable::Lookup(Handle<Object> key) {
   18587             :   DisallowHeapAllocation no_gc;
   18588             : 
   18589             :   Isolate* isolate = GetIsolate();
   18590             :   DCHECK(IsKey(isolate, *key));
   18591             : 
   18592             :   // If the object does not have an identity hash, it was never used as a key.
   18593        7462 :   Object* hash = key->GetHash();
   18594        7462 :   if (hash->IsUndefined(isolate)) {
   18595         726 :     return isolate->heap()->the_hole_value();
   18596             :   }
   18597        6736 :   return Lookup(isolate, key, Smi::cast(hash)->value());
   18598             : }
   18599             : 
   18600           0 : Object* ObjectHashTable::ValueAt(int entry) {
   18601           0 :   return get(EntryToValueIndex(entry));
   18602             : }
   18603             : 
   18604        2422 : Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) {
   18605        2422 :   return Lookup(GetIsolate(), key, hash);
   18606             : }
   18607             : 
   18608             : 
   18609        3498 : Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
   18610             :                                              Handle<Object> key,
   18611             :                                              Handle<Object> value) {
   18612             :   Isolate* isolate = table->GetIsolate();
   18613             :   DCHECK(table->IsKey(isolate, *key));
   18614             :   DCHECK(!value->IsTheHole(isolate));
   18615             : 
   18616             :   // Make sure the key object has an identity hash code.
   18617        3498 :   int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
   18618             : 
   18619        3498 :   return Put(table, key, value, hash);
   18620             : }
   18621             : 
   18622             : 
   18623        6436 : Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
   18624             :                                              Handle<Object> key,
   18625             :                                              Handle<Object> value,
   18626             :                                              int32_t hash) {
   18627             :   Isolate* isolate = table->GetIsolate();
   18628             :   DCHECK(table->IsKey(isolate, *key));
   18629             :   DCHECK(!value->IsTheHole(isolate));
   18630             : 
   18631        6436 :   int entry = table->FindEntry(isolate, key, hash);
   18632             : 
   18633             :   // Key is already in table, just overwrite value.
   18634        6436 :   if (entry != kNotFound) {
   18635        1242 :     table->set(EntryToIndex(entry) + 1, *value);
   18636         621 :     return table;
   18637             :   }
   18638             : 
   18639             :   // Rehash if more than 33% of the entries are deleted entries.
   18640             :   // TODO(jochen): Consider to shrink the fixed array in place.
   18641       11630 :   if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) {
   18642           7 :     table->Rehash(isolate->factory()->undefined_value());
   18643             :   }
   18644             :   // If we're out of luck, we didn't get a GC recently, and so rehashing
   18645             :   // isn't enough to avoid a crash.
   18646        5815 :   if (!table->HasSufficientCapacityToAdd(1)) {
   18647         402 :     int nof = table->NumberOfElements() + 1;
   18648         402 :     int capacity = ObjectHashTable::ComputeCapacity(nof * 2);
   18649         402 :     if (capacity > ObjectHashTable::kMaxCapacity) {
   18650           0 :       for (size_t i = 0; i < 2; ++i) {
   18651             :         isolate->heap()->CollectAllGarbage(
   18652             :             Heap::kFinalizeIncrementalMarkingMask,
   18653           0 :             GarbageCollectionReason::kFullHashtable);
   18654             :       }
   18655           0 :       table->Rehash(isolate->factory()->undefined_value());
   18656             :     }
   18657             :   }
   18658             : 
   18659             :   // Check whether the hash table should be extended.
   18660        5815 :   table = EnsureCapacity(table, 1, key);
   18661       17445 :   table->AddEntry(table->FindInsertionEntry(hash), *key, *value);
   18662        5815 :   return table;
   18663             : }
   18664             : 
   18665             : 
   18666           7 : Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
   18667             :                                                 Handle<Object> key,
   18668             :                                                 bool* was_present) {
   18669             :   DCHECK(table->IsKey(table->GetIsolate(), *key));
   18670             : 
   18671           7 :   Object* hash = key->GetHash();
   18672           7 :   if (hash->IsUndefined(table->GetIsolate())) {
   18673           0 :     *was_present = false;
   18674           0 :     return table;
   18675             :   }
   18676             : 
   18677           7 :   return Remove(table, key, was_present, Smi::cast(hash)->value());
   18678             : }
   18679             : 
   18680             : 
   18681         125 : Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
   18682             :                                                 Handle<Object> key,
   18683             :                                                 bool* was_present,
   18684             :                                                 int32_t hash) {
   18685             :   Isolate* isolate = table->GetIsolate();
   18686             :   DCHECK(table->IsKey(isolate, *key));
   18687             : 
   18688         125 :   int entry = table->FindEntry(isolate, key, hash);
   18689         125 :   if (entry == kNotFound) {
   18690           0 :     *was_present = false;
   18691           0 :     return table;
   18692             :   }
   18693             : 
   18694         125 :   *was_present = true;
   18695         125 :   table->RemoveEntry(entry);
   18696             :   return Shrink(table, key);
   18697             : }
   18698             : 
   18699             : 
   18700        5815 : void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
   18701        5815 :   set(EntryToIndex(entry), key);
   18702        5815 :   set(EntryToIndex(entry) + 1, value);
   18703        5815 :   ElementAdded();
   18704        5815 : }
   18705             : 
   18706             : 
   18707         164 : void ObjectHashTable::RemoveEntry(int entry) {
   18708         164 :   set_the_hole(EntryToIndex(entry));
   18709         164 :   set_the_hole(EntryToIndex(entry) + 1);
   18710         164 :   ElementRemoved();
   18711         164 : }
   18712             : 
   18713             : 
   18714     1050331 : Object* WeakHashTable::Lookup(Handle<HeapObject> key) {
   18715             :   DisallowHeapAllocation no_gc;
   18716             :   Isolate* isolate = GetIsolate();
   18717             :   DCHECK(IsKey(isolate, *key));
   18718             :   int entry = FindEntry(key);
   18719     1050332 :   if (entry == kNotFound) return isolate->heap()->the_hole_value();
   18720      903083 :   return get(EntryToValueIndex(entry));
   18721             : }
   18722             : 
   18723             : 
   18724     1050332 : Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table,
   18725             :                                          Handle<HeapObject> key,
   18726             :                                          Handle<HeapObject> value) {
   18727             :   Isolate* isolate = key->GetIsolate();
   18728             :   DCHECK(table->IsKey(isolate, *key));
   18729             :   int entry = table->FindEntry(key);
   18730             :   // Key is already in table, just overwrite value.
   18731     1050332 :   if (entry != kNotFound) {
   18732      903083 :     table->set(EntryToValueIndex(entry), *value);
   18733      903083 :     return table;
   18734             :   }
   18735             : 
   18736      147249 :   Handle<WeakCell> key_cell = isolate->factory()->NewWeakCell(key);
   18737             : 
   18738             :   // Check whether the hash table should be extended.
   18739      147249 :   table = EnsureCapacity(table, 1, key, TENURED);
   18740             : 
   18741      294498 :   table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key_cell, value);
   18742      147249 :   return table;
   18743             : }
   18744             : 
   18745             : 
   18746      147248 : void WeakHashTable::AddEntry(int entry, Handle<WeakCell> key_cell,
   18747             :                              Handle<HeapObject> value) {
   18748             :   DisallowHeapAllocation no_allocation;
   18749      147248 :   set(EntryToIndex(entry), *key_cell);
   18750      147249 :   set(EntryToValueIndex(entry), *value);
   18751      147249 :   ElementAdded();
   18752      147249 : }
   18753             : 
   18754             : template <class Derived, int entrysize>
   18755    10162754 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate(
   18756             :     Isolate* isolate, int capacity, PretenureFlag pretenure) {
   18757             :   // Capacity must be a power of two, since we depend on being able
   18758             :   // to divide and multiple by 2 (kLoadFactor) to derive capacity
   18759             :   // from number of buckets. If we decide to change kLoadFactor
   18760             :   // to something other than 2, capacity should be stored as another
   18761             :   // field of this object.
   18762    10162754 :   capacity = base::bits::RoundUpToPowerOfTwo32(Max(kMinCapacity, capacity));
   18763    10162754 :   if (capacity > kMaxCapacity) {
   18764           0 :     v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
   18765             :   }
   18766    10162754 :   int num_buckets = capacity / kLoadFactor;
   18767             :   Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray(
   18768    10162754 :       kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure);
   18769             :   backing_store->set_map_no_write_barrier(
   18770    10162755 :       isolate->heap()->ordered_hash_table_map());
   18771             :   Handle<Derived> table = Handle<Derived>::cast(backing_store);
   18772    99716207 :   for (int i = 0; i < num_buckets; ++i) {
   18773             :     table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound));
   18774             :   }
   18775             :   table->SetNumberOfBuckets(num_buckets);
   18776             :   table->SetNumberOfElements(0);
   18777             :   table->SetNumberOfDeletedElements(0);
   18778    10162755 :   return table;
   18779             : }
   18780             : 
   18781             : template <class Derived, int entrysize>
   18782    78478684 : Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable(
   18783             :     Handle<Derived> table) {
   18784             :   DCHECK(!table->IsObsolete());
   18785             : 
   18786             :   int nof = table->NumberOfElements();
   18787             :   int nod = table->NumberOfDeletedElements();
   18788             :   int capacity = table->Capacity();
   18789    78478684 :   if ((nof + nod) < capacity) return table;
   18790             :   // Don't need to grow if we can simply clear out deleted entries instead.
   18791             :   // Note that we can't compact in place, though, so we always allocate
   18792             :   // a new table.
   18793      279167 :   return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity);
   18794             : }
   18795             : 
   18796             : template <class Derived, int entrysize>
   18797      202088 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink(
   18798             :     Handle<Derived> table) {
   18799             :   DCHECK(!table->IsObsolete());
   18800             : 
   18801             :   int nof = table->NumberOfElements();
   18802             :   int capacity = table->Capacity();
   18803      202088 :   if (nof >= (capacity >> 2)) return table;
   18804      202088 :   return Rehash(table, capacity / 2);
   18805             : }
   18806             : 
   18807             : template <class Derived, int entrysize>
   18808         359 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Clear(
   18809             :     Handle<Derived> table) {
   18810             :   DCHECK(!table->IsObsolete());
   18811             : 
   18812             :   Handle<Derived> new_table =
   18813             :       Allocate(table->GetIsolate(),
   18814             :                kMinCapacity,
   18815         718 :                table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
   18816             : 
   18817             :   table->SetNextTable(*new_table);
   18818             :   table->SetNumberOfDeletedElements(kClearedTableSentinel);
   18819             : 
   18820         359 :   return new_table;
   18821             : }
   18822             : 
   18823             : template <class Derived, int entrysize>
   18824           0 : bool OrderedHashTable<Derived, entrysize>::HasKey(Handle<Derived> table,
   18825             :                                                   Handle<Object> key) {
   18826             :   DisallowHeapAllocation no_gc;
   18827             :   Isolate* isolate = table->GetIsolate();
   18828             :   Object* raw_key = *key;
   18829           0 :   int entry = table->KeyToFirstEntry(isolate, raw_key);
   18830             :   // Walk the chain in the bucket to find the key.
   18831           0 :   while (entry != kNotFound) {
   18832           0 :     Object* candidate_key = table->KeyAt(entry);
   18833           0 :     if (candidate_key->SameValueZero(raw_key)) return true;
   18834           0 :     entry = table->NextChainEntry(entry);
   18835             :   }
   18836             :   return false;
   18837             : }
   18838             : 
   18839             : 
   18840    78461179 : Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
   18841             :                                            Handle<Object> key) {
   18842    78461179 :   int hash = Object::GetOrCreateHash(table->GetIsolate(), key)->value();
   18843    78461175 :   int entry = table->HashToEntry(hash);
   18844             :   // Walk the chain of the bucket and try finding the key.
   18845   207439382 :   while (entry != kNotFound) {
   18846    50517865 :     Object* candidate_key = table->KeyAt(entry);
   18847             :     // Do not add if we have the key already
   18848    50517865 :     if (candidate_key->SameValueZero(*key)) return table;
   18849    50517032 :     entry = table->NextChainEntry(entry);
   18850             :   }
   18851             : 
   18852    78460341 :   table = OrderedHashSet::EnsureGrowable(table);
   18853             :   // Read the existing bucket values.
   18854             :   int bucket = table->HashToBucket(hash);
   18855    78460341 :   int previous_entry = table->HashToEntry(hash);
   18856             :   int nof = table->NumberOfElements();
   18857             :   // Insert a new entry at the end,
   18858    78460341 :   int new_entry = nof + table->NumberOfDeletedElements();
   18859             :   int new_index = table->EntryToIndex(new_entry);
   18860    78460341 :   table->set(new_index, *key);
   18861             :   table->set(new_index + kChainOffset, Smi::FromInt(previous_entry));
   18862             :   // and point the bucket to the new entry.
   18863             :   table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
   18864    78460341 :   table->SetNumberOfElements(nof + 1);
   18865    78460341 :   return table;
   18866             : }
   18867             : 
   18868     9522106 : Handle<FixedArray> OrderedHashSet::ConvertToKeysArray(
   18869             :     Handle<OrderedHashSet> table, GetKeysConversion convert) {
   18870             :   Isolate* isolate = table->GetIsolate();
   18871             :   int length = table->NumberOfElements();
   18872             :   int nof_buckets = table->NumberOfBuckets();
   18873             :   // Convert the dictionary to a linear list.
   18874             :   Handle<FixedArray> result = Handle<FixedArray>::cast(table);
   18875             :   // From this point on table is no longer a valid OrderedHashSet.
   18876    19044212 :   result->set_map(isolate->heap()->fixed_array_map());
   18877    87982384 :   for (int i = 0; i < length; i++) {
   18878    78460278 :     int index = kHashTableStartIndex + nof_buckets + (i * kEntrySize);
   18879             :     Object* key = table->get(index);
   18880    78460278 :     if (convert == GetKeysConversion::kConvertToString) {
   18881             :       uint32_t index_value;
   18882    11071871 :       if (key->ToArrayIndex(&index_value)) {
   18883      603298 :         key = *isolate->factory()->Uint32ToString(index_value);
   18884             :       } else {
   18885    10770222 :         CHECK(key->IsName());
   18886             :       }
   18887             :     }
   18888    78460278 :     result->set(i, key);
   18889             :   }
   18890     9522106 :   result->Shrink(length);
   18891     9522106 :   return result;
   18892             : }
   18893             : 
   18894             : template <class Derived, int entrysize>
   18895      481255 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
   18896             :     Handle<Derived> table, int new_capacity) {
   18897             :   Isolate* isolate = table->GetIsolate();
   18898             :   DCHECK(!table->IsObsolete());
   18899             : 
   18900             :   Handle<Derived> new_table =
   18901             :       Allocate(isolate, new_capacity,
   18902      481255 :                isolate->heap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
   18903             :   int nof = table->NumberOfElements();
   18904             :   int nod = table->NumberOfDeletedElements();
   18905             :   int new_buckets = new_table->NumberOfBuckets();
   18906             :   int new_entry = 0;
   18907             :   int removed_holes_index = 0;
   18908             : 
   18909             :   DisallowHeapAllocation no_gc;
   18910    13348930 :   for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
   18911    12867675 :     Object* key = table->KeyAt(old_entry);
   18912    12867675 :     if (key->IsTheHole(isolate)) {
   18913      212839 :       table->SetRemovedIndexAt(removed_holes_index++, old_entry);
   18914             :       continue;
   18915             :     }
   18916             : 
   18917    12654836 :     Object* hash = key->GetHash();
   18918    12654837 :     int bucket = Smi::cast(hash)->value() & (new_buckets - 1);
   18919    12654837 :     Object* chain_entry = new_table->get(kHashTableStartIndex + bucket);
   18920             :     new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
   18921             :     int new_index = new_table->EntryToIndex(new_entry);
   18922             :     int old_index = table->EntryToIndex(old_entry);
   18923    25379116 :     for (int i = 0; i < entrysize; ++i) {
   18924    12724279 :       Object* value = table->get(old_index + i);
   18925    25448558 :       new_table->set(new_index + i, value);
   18926             :     }
   18927    25309674 :     new_table->set(new_index + kChainOffset, chain_entry);
   18928    12654837 :     ++new_entry;
   18929             :   }
   18930             : 
   18931             :   DCHECK_EQ(nod, removed_holes_index);
   18932             : 
   18933             :   new_table->SetNumberOfElements(nof);
   18934             :   table->SetNextTable(*new_table);
   18935             : 
   18936      481255 :   return new_table;
   18937             : }
   18938             : 
   18939             : template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Allocate(
   18940             :     Isolate* isolate, int capacity, PretenureFlag pretenure);
   18941             : 
   18942             : template Handle<OrderedHashSet> OrderedHashTable<
   18943             :     OrderedHashSet, 1>::EnsureGrowable(Handle<OrderedHashSet> table);
   18944             : 
   18945             : template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Shrink(
   18946             :     Handle<OrderedHashSet> table);
   18947             : 
   18948             : template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Clear(
   18949             :     Handle<OrderedHashSet> table);
   18950             : 
   18951             : template bool OrderedHashTable<OrderedHashSet, 1>::HasKey(
   18952             :     Handle<OrderedHashSet> table, Handle<Object> key);
   18953             : 
   18954             : template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Allocate(
   18955             :     Isolate* isolate, int capacity, PretenureFlag pretenure);
   18956             : 
   18957             : template Handle<OrderedHashMap> OrderedHashTable<
   18958             :     OrderedHashMap, 2>::EnsureGrowable(Handle<OrderedHashMap> table);
   18959             : 
   18960             : template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Shrink(
   18961             :     Handle<OrderedHashMap> table);
   18962             : 
   18963             : template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Clear(
   18964             :     Handle<OrderedHashMap> table);
   18965             : 
   18966             : template bool OrderedHashTable<OrderedHashMap, 2>::HasKey(
   18967             :     Handle<OrderedHashMap> table, Handle<Object> key);
   18968             : 
   18969             : template<class Derived, class TableType>
   18970       12187 : void OrderedHashTableIterator<Derived, TableType>::Transition() {
   18971             :   DisallowHeapAllocation no_allocation;
   18972             :   TableType* table = TableType::cast(this->table());
   18973       24374 :   if (!table->IsObsolete()) return;
   18974             : 
   18975             :   int index = Smi::cast(this->index())->value();
   18976         882 :   while (table->IsObsolete()) {
   18977             :     TableType* next_table = table->NextTable();
   18978             : 
   18979         490 :     if (index > 0) {
   18980             :       int nod = table->NumberOfDeletedElements();
   18981             : 
   18982         252 :       if (nod == TableType::kClearedTableSentinel) {
   18983             :         index = 0;
   18984             :       } else {
   18985             :         int old_index = index;
   18986         168 :         for (int i = 0; i < nod; ++i) {
   18987             :           int removed_index = table->RemovedIndexAt(i);
   18988         224 :           if (removed_index >= old_index) break;
   18989         168 :           --index;
   18990             :         }
   18991             :       }
   18992             :     }
   18993             : 
   18994             :     table = next_table;
   18995             :   }
   18996             : 
   18997         196 :   set_table(table);
   18998         196 :   set_index(Smi::FromInt(index));
   18999             : }
   19000             : 
   19001             : 
   19002             : template<class Derived, class TableType>
   19003       12283 : bool OrderedHashTableIterator<Derived, TableType>::HasMore() {
   19004             :   DisallowHeapAllocation no_allocation;
   19005             :   Isolate* isolate = this->GetIsolate();
   19006       12283 :   if (this->table()->IsUndefined(isolate)) return false;
   19007             : 
   19008       12187 :   Transition();
   19009             : 
   19010             :   TableType* table = TableType::cast(this->table());
   19011             :   int index = Smi::cast(this->index())->value();
   19012       12187 :   int used_capacity = table->UsedCapacity();
   19013             : 
   19014       35607 :   while (index < used_capacity && table->KeyAt(index)->IsTheHole(isolate)) {
   19015         406 :     index++;
   19016             :   }
   19017             : 
   19018       12187 :   set_index(Smi::FromInt(index));
   19019             : 
   19020       12187 :   if (index < used_capacity) return true;
   19021             : 
   19022        1766 :   set_table(isolate->heap()->undefined_value());
   19023        1766 :   return false;
   19024             : }
   19025             : 
   19026             : 
   19027             : template<class Derived, class TableType>
   19028       12031 : Smi* OrderedHashTableIterator<Derived, TableType>::Next(JSArray* value_array) {
   19029             :   DisallowHeapAllocation no_allocation;
   19030       12031 :   if (HasMore()) {
   19031             :     FixedArray* array = FixedArray::cast(value_array->elements());
   19032       10193 :     static_cast<Derived*>(this)->PopulateValueArray(array);
   19033       10193 :     MoveNext();
   19034       10193 :     return Smi::cast(kind());
   19035             :   }
   19036             :   return Smi::kZero;
   19037             : }
   19038             : 
   19039             : 
   19040             : template Smi*
   19041             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Next(
   19042             :     JSArray* value_array);
   19043             : 
   19044             : template bool
   19045             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::HasMore();
   19046             : 
   19047             : template void
   19048             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::MoveNext();
   19049             : 
   19050             : template Object*
   19051             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::CurrentKey();
   19052             : 
   19053             : template void
   19054             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Transition();
   19055             : 
   19056             : 
   19057             : template Smi*
   19058             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Next(
   19059             :     JSArray* value_array);
   19060             : 
   19061             : template bool
   19062             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::HasMore();
   19063             : 
   19064             : template void
   19065             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::MoveNext();
   19066             : 
   19067             : template Object*
   19068             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::CurrentKey();
   19069             : 
   19070             : template void
   19071             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Transition();
   19072             : 
   19073             : 
   19074       78947 : void JSSet::Initialize(Handle<JSSet> set, Isolate* isolate) {
   19075       78947 :   Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
   19076       78947 :   set->set_table(*table);
   19077       78947 : }
   19078             : 
   19079             : 
   19080          45 : void JSSet::Clear(Handle<JSSet> set) {
   19081             :   Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
   19082          45 :   table = OrderedHashSet::Clear(table);
   19083          45 :   set->set_table(*table);
   19084          45 : }
   19085             : 
   19086             : 
   19087       80032 : void JSMap::Initialize(Handle<JSMap> map, Isolate* isolate) {
   19088       80032 :   Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
   19089       80032 :   map->set_table(*table);
   19090       80032 : }
   19091             : 
   19092             : 
   19093         314 : void JSMap::Clear(Handle<JSMap> map) {
   19094             :   Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
   19095         314 :   table = OrderedHashMap::Clear(table);
   19096         314 :   map->set_table(*table);
   19097         314 : }
   19098             : 
   19099             : 
   19100      129288 : void JSWeakCollection::Initialize(Handle<JSWeakCollection> weak_collection,
   19101             :                                   Isolate* isolate) {
   19102      129288 :   Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
   19103      129288 :   weak_collection->set_table(*table);
   19104      129288 : }
   19105             : 
   19106             : 
   19107        2938 : void JSWeakCollection::Set(Handle<JSWeakCollection> weak_collection,
   19108             :                            Handle<Object> key, Handle<Object> value,
   19109             :                            int32_t hash) {
   19110             :   DCHECK(key->IsJSReceiver() || key->IsSymbol());
   19111             :   Handle<ObjectHashTable> table(
   19112             :       ObjectHashTable::cast(weak_collection->table()));
   19113             :   DCHECK(table->IsKey(table->GetIsolate(), *key));
   19114             :   Handle<ObjectHashTable> new_table =
   19115        2938 :       ObjectHashTable::Put(table, key, value, hash);
   19116        2938 :   weak_collection->set_table(*new_table);
   19117        2938 :   if (*table != *new_table) {
   19118             :     // Zap the old table since we didn't record slots for its elements.
   19119         238 :     table->FillWithHoles(0, table->length());
   19120             :   }
   19121        2938 : }
   19122             : 
   19123             : 
   19124         118 : bool JSWeakCollection::Delete(Handle<JSWeakCollection> weak_collection,
   19125             :                               Handle<Object> key, int32_t hash) {
   19126             :   DCHECK(key->IsJSReceiver() || key->IsSymbol());
   19127             :   Handle<ObjectHashTable> table(
   19128             :       ObjectHashTable::cast(weak_collection->table()));
   19129             :   DCHECK(table->IsKey(table->GetIsolate(), *key));
   19130         118 :   bool was_present = false;
   19131             :   Handle<ObjectHashTable> new_table =
   19132         118 :       ObjectHashTable::Remove(table, key, &was_present, hash);
   19133         118 :   weak_collection->set_table(*new_table);
   19134         118 :   if (*table != *new_table) {
   19135             :     // Zap the old table since we didn't record slots for its elements.
   19136           0 :     table->FillWithHoles(0, table->length());
   19137             :   }
   19138         118 :   return was_present;
   19139             : }
   19140             : 
   19141          36 : Handle<JSArray> JSWeakCollection::GetEntries(Handle<JSWeakCollection> holder,
   19142             :                                              int max_entries) {
   19143             :   Isolate* isolate = holder->GetIsolate();
   19144             :   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   19145          36 :   if (max_entries == 0 || max_entries > table->NumberOfElements()) {
   19146             :     max_entries = table->NumberOfElements();
   19147             :   }
   19148          36 :   int values_per_entry = holder->IsJSWeakMap() ? 2 : 1;
   19149             :   Handle<FixedArray> entries =
   19150          36 :       isolate->factory()->NewFixedArray(max_entries * values_per_entry);
   19151             :   // Recompute max_values because GC could have removed elements from the table.
   19152          36 :   if (max_entries > table->NumberOfElements()) {
   19153             :     max_entries = table->NumberOfElements();
   19154             :   }
   19155             : 
   19156             :   {
   19157             :     DisallowHeapAllocation no_gc;
   19158             :     int count = 0;
   19159         120 :     for (int i = 0;
   19160          84 :          count / values_per_entry < max_entries && i < table->Capacity(); i++) {
   19161             :       Handle<Object> key(table->KeyAt(i), isolate);
   19162          24 :       if (table->IsKey(isolate, *key)) {
   19163          48 :         entries->set(count++, *key);
   19164          24 :         if (values_per_entry > 1) {
   19165          12 :           Object* value = table->Lookup(key);
   19166          24 :           entries->set(count++, value);
   19167             :         }
   19168             :       }
   19169             :     }
   19170             :     DCHECK_EQ(max_entries * values_per_entry, count);
   19171             :   }
   19172          36 :   return isolate->factory()->NewJSArrayWithElements(entries);
   19173             : }
   19174             : 
   19175             : // Check if there is a break point at this source position.
   19176       94236 : bool DebugInfo::HasBreakPoint(int source_position) {
   19177             :   // Get the break point info object for this code offset.
   19178       94236 :   Object* break_point_info = GetBreakPointInfo(source_position);
   19179             : 
   19180             :   // If there is no break point info object or no break points in the break
   19181             :   // point info object there is no break point at this code offset.
   19182       94236 :   if (break_point_info->IsUndefined(GetIsolate())) return false;
   19183        5201 :   return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0;
   19184             : }
   19185             : 
   19186             : // Get the break point info object for this source position.
   19187      102246 : Object* DebugInfo::GetBreakPointInfo(int source_position) {
   19188             :   Isolate* isolate = GetIsolate();
   19189      102246 :   if (!break_points()->IsUndefined(isolate)) {
   19190      840146 :     for (int i = 0; i < break_points()->length(); i++) {
   19191      379333 :       if (!break_points()->get(i)->IsUndefined(isolate)) {
   19192             :         BreakPointInfo* break_point_info =
   19193             :             BreakPointInfo::cast(break_points()->get(i));
   19194       52425 :         if (break_point_info->source_position() == source_position) {
   19195             :           return break_point_info;
   19196             :         }
   19197             :       }
   19198             :     }
   19199             :   }
   19200       91863 :   return isolate->heap()->undefined_value();
   19201             : }
   19202             : 
   19203        2600 : bool DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info,
   19204             :                                 Handle<Object> break_point_object) {
   19205             :   Isolate* isolate = debug_info->GetIsolate();
   19206        2600 :   if (debug_info->break_points()->IsUndefined(isolate)) return false;
   19207             : 
   19208        4292 :   for (int i = 0; i < debug_info->break_points()->length(); i++) {
   19209        3446 :     if (debug_info->break_points()->get(i)->IsUndefined(isolate)) continue;
   19210             :     Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
   19211             :         BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate);
   19212        3446 :     if (BreakPointInfo::HasBreakPointObject(break_point_info,
   19213             :                                             break_point_object)) {
   19214        2600 :       BreakPointInfo::ClearBreakPoint(break_point_info, break_point_object);
   19215        2600 :       return true;
   19216             :     }
   19217             :   }
   19218             :   return false;
   19219             : }
   19220             : 
   19221        2977 : void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
   19222             :                               Handle<Object> break_point_object) {
   19223             :   Isolate* isolate = debug_info->GetIsolate();
   19224             :   Handle<Object> break_point_info(
   19225        2977 :       debug_info->GetBreakPointInfo(source_position), isolate);
   19226        2977 :   if (!break_point_info->IsUndefined(isolate)) {
   19227             :     BreakPointInfo::SetBreakPoint(
   19228             :         Handle<BreakPointInfo>::cast(break_point_info),
   19229         149 :         break_point_object);
   19230        3126 :     return;
   19231             :   }
   19232             : 
   19233             :   // Adding a new break point for a code offset which did not have any
   19234             :   // break points before. Try to find a free slot.
   19235             :   static const int kNoBreakPointInfo = -1;
   19236             :   int index = kNoBreakPointInfo;
   19237        4484 :   for (int i = 0; i < debug_info->break_points()->length(); i++) {
   19238        3638 :     if (debug_info->break_points()->get(i)->IsUndefined(isolate)) {
   19239             :       index = i;
   19240             :       break;
   19241             :     }
   19242             :   }
   19243        2828 :   if (index == kNoBreakPointInfo) {
   19244             :     // No free slot - extend break point info array.
   19245             :     Handle<FixedArray> old_break_points = Handle<FixedArray>(
   19246             :         FixedArray::cast(debug_info->break_points()), isolate);
   19247             :     Handle<FixedArray> new_break_points =
   19248             :         isolate->factory()->NewFixedArray(
   19249             :             old_break_points->length() +
   19250          18 :             DebugInfo::kEstimatedNofBreakPointsInFunction);
   19251             : 
   19252          18 :     debug_info->set_break_points(*new_break_points);
   19253         180 :     for (int i = 0; i < old_break_points->length(); i++) {
   19254          72 :       new_break_points->set(i, old_break_points->get(i));
   19255             :     }
   19256             :     index = old_break_points->length();
   19257             :   }
   19258             :   DCHECK(index != kNoBreakPointInfo);
   19259             : 
   19260             :   // Allocate new BreakPointInfo object and set the break point.
   19261             :   Handle<BreakPointInfo> new_break_point_info =
   19262        2828 :       isolate->factory()->NewBreakPointInfo(source_position);
   19263        2828 :   BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object);
   19264        2828 :   debug_info->break_points()->set(index, *new_break_point_info);
   19265             : }
   19266             : 
   19267             : // Get the break point objects for a source position.
   19268        5033 : Handle<Object> DebugInfo::GetBreakPointObjects(int source_position) {
   19269        5033 :   Object* break_point_info = GetBreakPointInfo(source_position);
   19270             :   Isolate* isolate = GetIsolate();
   19271        5033 :   if (break_point_info->IsUndefined(isolate)) {
   19272           0 :     return isolate->factory()->undefined_value();
   19273             :   }
   19274             :   return Handle<Object>(
   19275        5033 :       BreakPointInfo::cast(break_point_info)->break_point_objects(), isolate);
   19276             : }
   19277             : 
   19278             : 
   19279             : // Get the total number of break points.
   19280        3272 : int DebugInfo::GetBreakPointCount() {
   19281             :   Isolate* isolate = GetIsolate();
   19282        3272 :   if (break_points()->IsUndefined(isolate)) return 0;
   19283             :   int count = 0;
   19284       30744 :   for (int i = 0; i < break_points()->length(); i++) {
   19285       13736 :     if (!break_points()->get(i)->IsUndefined(isolate)) {
   19286             :       BreakPointInfo* break_point_info =
   19287             :           BreakPointInfo::cast(break_points()->get(i));
   19288        5952 :       count += break_point_info->GetBreakPointCount();
   19289             :     }
   19290             :   }
   19291             :   return count;
   19292             : }
   19293             : 
   19294             : 
   19295        9614 : Handle<Object> DebugInfo::FindBreakPointInfo(
   19296             :     Handle<DebugInfo> debug_info, Handle<Object> break_point_object) {
   19297             :   Isolate* isolate = debug_info->GetIsolate();
   19298        9614 :   if (!debug_info->break_points()->IsUndefined(isolate)) {
   19299       67850 :     for (int i = 0; i < debug_info->break_points()->length(); i++) {
   19300       31718 :       if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) {
   19301             :         Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
   19302             :             BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate);
   19303        8716 :         if (BreakPointInfo::HasBreakPointObject(break_point_info,
   19304             :                                                 break_point_object)) {
   19305        2600 :           return break_point_info;
   19306             :         }
   19307             :       }
   19308             :     }
   19309             :   }
   19310        7014 :   return isolate->factory()->undefined_value();
   19311             : }
   19312             : 
   19313             : // Remove the specified break point object.
   19314        2600 : void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info,
   19315             :                                      Handle<Object> break_point_object) {
   19316             :   Isolate* isolate = break_point_info->GetIsolate();
   19317             :   // If there are no break points just ignore.
   19318        2600 :   if (break_point_info->break_point_objects()->IsUndefined(isolate)) return;
   19319             :   // If there is a single break point clear it if it is the same.
   19320        2600 :   if (!break_point_info->break_point_objects()->IsFixedArray()) {
   19321        2428 :     if (break_point_info->break_point_objects() == *break_point_object) {
   19322             :       break_point_info->set_break_point_objects(
   19323        2428 :           isolate->heap()->undefined_value());
   19324             :     }
   19325             :     return;
   19326             :   }
   19327             :   // If there are multiple break points shrink the array
   19328             :   DCHECK(break_point_info->break_point_objects()->IsFixedArray());
   19329             :   Handle<FixedArray> old_array =
   19330             :       Handle<FixedArray>(
   19331             :           FixedArray::cast(break_point_info->break_point_objects()));
   19332             :   Handle<FixedArray> new_array =
   19333         172 :       isolate->factory()->NewFixedArray(old_array->length() - 1);
   19334             :   int found_count = 0;
   19335        1652 :   for (int i = 0; i < old_array->length(); i++) {
   19336         654 :     if (old_array->get(i) == *break_point_object) {
   19337             :       DCHECK(found_count == 0);
   19338         172 :       found_count++;
   19339             :     } else {
   19340         964 :       new_array->set(i - found_count, old_array->get(i));
   19341             :     }
   19342             :   }
   19343             :   // If the break point was found in the list change it.
   19344         344 :   if (found_count > 0) break_point_info->set_break_point_objects(*new_array);
   19345             : }
   19346             : 
   19347             : 
   19348             : // Add the specified break point object.
   19349        3083 : void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info,
   19350             :                                    Handle<Object> break_point_object) {
   19351             :   Isolate* isolate = break_point_info->GetIsolate();
   19352             : 
   19353             :   // If there was no break point objects before just set it.
   19354        3083 :   if (break_point_info->break_point_objects()->IsUndefined(isolate)) {
   19355        2934 :     break_point_info->set_break_point_objects(*break_point_object);
   19356        2934 :     return;
   19357             :   }
   19358             :   // If the break point object is the same as before just ignore.
   19359         149 :   if (break_point_info->break_point_objects() == *break_point_object) return;
   19360             :   // If there was one break point object before replace with array.
   19361         149 :   if (!break_point_info->break_point_objects()->IsFixedArray()) {
   19362          65 :     Handle<FixedArray> array = isolate->factory()->NewFixedArray(2);
   19363          65 :     array->set(0, break_point_info->break_point_objects());
   19364          65 :     array->set(1, *break_point_object);
   19365          65 :     break_point_info->set_break_point_objects(*array);
   19366             :     return;
   19367             :   }
   19368             :   // If there was more than one break point before extend array.
   19369             :   Handle<FixedArray> old_array =
   19370             :       Handle<FixedArray>(
   19371             :           FixedArray::cast(break_point_info->break_point_objects()));
   19372             :   Handle<FixedArray> new_array =
   19373          84 :       isolate->factory()->NewFixedArray(old_array->length() + 1);
   19374        1044 :   for (int i = 0; i < old_array->length(); i++) {
   19375             :     // If the break point was there before just ignore.
   19376         438 :     if (old_array->get(i) == *break_point_object) return;
   19377         438 :     new_array->set(i, old_array->get(i));
   19378             :   }
   19379             :   // Add the new break point.
   19380          84 :   new_array->set(old_array->length(), *break_point_object);
   19381          84 :   break_point_info->set_break_point_objects(*new_array);
   19382             : }
   19383             : 
   19384             : 
   19385       12162 : bool BreakPointInfo::HasBreakPointObject(
   19386             :     Handle<BreakPointInfo> break_point_info,
   19387             :     Handle<Object> break_point_object) {
   19388             :   // No break point.
   19389             :   Isolate* isolate = break_point_info->GetIsolate();
   19390       12162 :   if (break_point_info->break_point_objects()->IsUndefined(isolate)) {
   19391             :     return false;
   19392             :   }
   19393             :   // Single break point.
   19394       10524 :   if (!break_point_info->break_point_objects()->IsFixedArray()) {
   19395       10018 :     return break_point_info->break_point_objects() == *break_point_object;
   19396             :   }
   19397             :   // Multiple break points.
   19398             :   FixedArray* array = FixedArray::cast(break_point_info->break_point_objects());
   19399        1468 :   for (int i = 0; i < array->length(); i++) {
   19400         572 :     if (array->get(i) == *break_point_object) {
   19401             :       return true;
   19402             :     }
   19403             :   }
   19404             :   return false;
   19405             : }
   19406             : 
   19407             : 
   19408             : // Get the number of break points.
   19409       99917 : int BreakPointInfo::GetBreakPointCount() {
   19410             :   // No break point.
   19411       99917 :   if (break_point_objects()->IsUndefined(GetIsolate())) return 0;
   19412             :   // Single break point.
   19413       95473 :   if (!break_point_objects()->IsFixedArray()) return 1;
   19414             :   // Multiple break points.
   19415        1217 :   return FixedArray::cast(break_point_objects())->length();
   19416             : }
   19417             : 
   19418             : 
   19419             : // static
   19420      229130 : MaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor,
   19421             :                                 Handle<JSReceiver> new_target, double tv) {
   19422             :   Isolate* const isolate = constructor->GetIsolate();
   19423             :   Handle<JSObject> result;
   19424      458260 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   19425             :                              JSObject::New(constructor, new_target), JSDate);
   19426      229130 :   if (-DateCache::kMaxTimeInMs <= tv && tv <= DateCache::kMaxTimeInMs) {
   19427      228372 :     tv = DoubleToInteger(tv) + 0.0;
   19428             :   } else {
   19429             :     tv = std::numeric_limits<double>::quiet_NaN();
   19430             :   }
   19431      229130 :   Handle<Object> value = isolate->factory()->NewNumber(tv);
   19432      458260 :   Handle<JSDate>::cast(result)->SetValue(*value, std::isnan(tv));
   19433             :   return Handle<JSDate>::cast(result);
   19434             : }
   19435             : 
   19436             : 
   19437             : // static
   19438    28102331 : double JSDate::CurrentTimeValue(Isolate* isolate) {
   19439    28102331 :   if (FLAG_log_timer_events || FLAG_prof_cpp) LOG(isolate, CurrentTimeEvent());
   19440             : 
   19441             :   // According to ECMA-262, section 15.9.1, page 117, the precision of
   19442             :   // the number in a Date object representing a particular instant in
   19443             :   // time is milliseconds. Therefore, we floor the result of getting
   19444             :   // the OS time.
   19445             :   return Floor(FLAG_verify_predictable
   19446             :                    ? isolate->heap()->MonotonicallyIncreasingTimeInMs()
   19447    56204662 :                    : base::OS::TimeCurrentMillis());
   19448             : }
   19449             : 
   19450             : 
   19451             : // static
   19452       17182 : Object* JSDate::GetField(Object* object, Smi* index) {
   19453             :   return JSDate::cast(object)->DoGetField(
   19454       17182 :       static_cast<FieldIndex>(index->value()));
   19455             : }
   19456             : 
   19457             : 
   19458       17182 : Object* JSDate::DoGetField(FieldIndex index) {
   19459             :   DCHECK(index != kDateValue);
   19460             : 
   19461       25625 :   DateCache* date_cache = GetIsolate()->date_cache();
   19462             : 
   19463       17182 :   if (index < kFirstUncachedField) {
   19464             :     Object* stamp = cache_stamp();
   19465       16886 :     if (stamp != date_cache->stamp() && stamp->IsSmi()) {
   19466             :       // Since the stamp is not NaN, the value is also not NaN.
   19467             :       int64_t local_time_ms =
   19468         583 :           date_cache->ToLocal(static_cast<int64_t>(value()->Number()));
   19469         583 :       SetCachedFields(local_time_ms, date_cache);
   19470             :     }
   19471        8443 :     switch (index) {
   19472        1390 :       case kYear: return year();
   19473         380 :       case kMonth: return month();
   19474         113 :       case kDay: return day();
   19475           0 :       case kWeekday: return weekday();
   19476        4887 :       case kHour: return hour();
   19477        1322 :       case kMinute: return min();
   19478         351 :       case kSecond: return sec();
   19479           0 :       default: UNREACHABLE();
   19480             :     }
   19481             :   }
   19482             : 
   19483        8739 :   if (index >= kFirstUTCField) {
   19484        8485 :     return GetUTCField(index, value()->Number(), date_cache);
   19485             :   }
   19486             : 
   19487             :   double time = value()->Number();
   19488         254 :   if (std::isnan(time)) return GetIsolate()->heap()->nan_value();
   19489             : 
   19490         169 :   int64_t local_time_ms = date_cache->ToLocal(static_cast<int64_t>(time));
   19491             :   int days = DateCache::DaysFromTime(local_time_ms);
   19492             : 
   19493         169 :   if (index == kDays) return Smi::FromInt(days);
   19494             : 
   19495             :   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
   19496         338 :   if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000);
   19497             :   DCHECK(index == kTimeInDay);
   19498           0 :   return Smi::FromInt(time_in_day_ms);
   19499             : }
   19500             : 
   19501             : 
   19502        8485 : Object* JSDate::GetUTCField(FieldIndex index,
   19503             :                             double value,
   19504             :                             DateCache* date_cache) {
   19505             :   DCHECK(index >= kFirstUTCField);
   19506             : 
   19507       16430 :   if (std::isnan(value)) return GetIsolate()->heap()->nan_value();
   19508             : 
   19509         540 :   int64_t time_ms = static_cast<int64_t>(value);
   19510             : 
   19511         540 :   if (index == kTimezoneOffset) {
   19512          29 :     return Smi::FromInt(date_cache->TimezoneOffset(time_ms));
   19513             :   }
   19514             : 
   19515             :   int days = DateCache::DaysFromTime(time_ms);
   19516             : 
   19517         525 :   if (index == kWeekdayUTC) return Smi::FromInt(date_cache->Weekday(days));
   19518             : 
   19519         497 :   if (index <= kDayUTC) {
   19520             :     int year, month, day;
   19521         185 :     date_cache->YearMonthDayFromDays(days, &year, &month, &day);
   19522         242 :     if (index == kYearUTC) return Smi::FromInt(year);
   19523         184 :     if (index == kMonthUTC) return Smi::FromInt(month);
   19524             :     DCHECK(index == kDayUTC);
   19525         144 :     return Smi::FromInt(day);
   19526             :   }
   19527             : 
   19528             :   int time_in_day_ms = DateCache::TimeInDay(time_ms, days);
   19529         312 :   switch (index) {
   19530         288 :     case kHourUTC: return Smi::FromInt(time_in_day_ms / (60 * 60 * 1000));
   19531         140 :     case kMinuteUTC: return Smi::FromInt((time_in_day_ms / (60 * 1000)) % 60);
   19532         112 :     case kSecondUTC: return Smi::FromInt((time_in_day_ms / 1000) % 60);
   19533          84 :     case kMillisecondUTC: return Smi::FromInt(time_in_day_ms % 1000);
   19534           0 :     case kDaysUTC: return Smi::FromInt(days);
   19535           0 :     case kTimeInDayUTC: return Smi::FromInt(time_in_day_ms);
   19536           0 :     default: UNREACHABLE();
   19537             :   }
   19538             : 
   19539             :   UNREACHABLE();
   19540             :   return NULL;
   19541             : }
   19542             : 
   19543             : 
   19544             : // static
   19545       17391 : Handle<Object> JSDate::SetValue(Handle<JSDate> date, double v) {
   19546             :   Isolate* const isolate = date->GetIsolate();
   19547       17391 :   Handle<Object> value = isolate->factory()->NewNumber(v);
   19548             :   bool value_is_nan = std::isnan(v);
   19549       34782 :   date->SetValue(*value, value_is_nan);
   19550       17391 :   return value;
   19551             : }
   19552             : 
   19553             : 
   19554      246521 : void JSDate::SetValue(Object* value, bool is_value_nan) {
   19555      246521 :   set_value(value);
   19556      246521 :   if (is_value_nan) {
   19557       17376 :     HeapNumber* nan = GetIsolate()->heap()->nan_value();
   19558       17376 :     set_cache_stamp(nan, SKIP_WRITE_BARRIER);
   19559       17376 :     set_year(nan, SKIP_WRITE_BARRIER);
   19560       17376 :     set_month(nan, SKIP_WRITE_BARRIER);
   19561       17376 :     set_day(nan, SKIP_WRITE_BARRIER);
   19562       17376 :     set_hour(nan, SKIP_WRITE_BARRIER);
   19563       17376 :     set_min(nan, SKIP_WRITE_BARRIER);
   19564       17376 :     set_sec(nan, SKIP_WRITE_BARRIER);
   19565       17376 :     set_weekday(nan, SKIP_WRITE_BARRIER);
   19566             :   } else {
   19567      229145 :     set_cache_stamp(Smi::FromInt(DateCache::kInvalidStamp), SKIP_WRITE_BARRIER);
   19568             :   }
   19569      246521 : }
   19570             : 
   19571             : 
   19572        1166 : void JSDate::SetCachedFields(int64_t local_time_ms, DateCache* date_cache) {
   19573             :   int days = DateCache::DaysFromTime(local_time_ms);
   19574             :   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
   19575             :   int year, month, day;
   19576         583 :   date_cache->YearMonthDayFromDays(days, &year, &month, &day);
   19577             :   int weekday = date_cache->Weekday(days);
   19578         583 :   int hour = time_in_day_ms / (60 * 60 * 1000);
   19579         583 :   int min = (time_in_day_ms / (60 * 1000)) % 60;
   19580         583 :   int sec = (time_in_day_ms / 1000) % 60;
   19581         583 :   set_cache_stamp(date_cache->stamp());
   19582        1166 :   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
   19583        1166 :   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
   19584        1166 :   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
   19585         583 :   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
   19586         583 :   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
   19587         583 :   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
   19588         583 :   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
   19589         583 : }
   19590             : 
   19591             : namespace {
   19592             : 
   19593             : Script* ScriptFromJSValue(Object* in) {
   19594             :   DCHECK(in->IsJSValue());
   19595             :   JSValue* jsvalue = JSValue::cast(in);
   19596             :   DCHECK(jsvalue->value()->IsScript());
   19597             :   return Script::cast(jsvalue->value());
   19598             : }
   19599             : 
   19600             : }  // namespace
   19601             : 
   19602       13971 : int JSMessageObject::GetLineNumber() const {
   19603       13971 :   if (start_position() == -1) return Message::kNoLineNumberInfo;
   19604             : 
   19605       13917 :   Handle<Script> the_script = handle(ScriptFromJSValue(script()));
   19606             : 
   19607             :   Script::PositionInfo info;
   19608             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   19609       13917 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   19610       13917 :                                offset_flag)) {
   19611             :     return Message::kNoLineNumberInfo;
   19612             :   }
   19613             : 
   19614       13917 :   return info.line + 1;
   19615             : }
   19616             : 
   19617       24943 : int JSMessageObject::GetColumnNumber() const {
   19618       24943 :   if (start_position() == -1) return -1;
   19619             : 
   19620       24889 :   Handle<Script> the_script = handle(ScriptFromJSValue(script()));
   19621             : 
   19622             :   Script::PositionInfo info;
   19623             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   19624       24889 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   19625       24889 :                                offset_flag)) {
   19626             :     return -1;
   19627             :   }
   19628             : 
   19629       24889 :   return info.column;  // Note: No '+1' in contrast to GetLineNumber.
   19630             : }
   19631             : 
   19632       11538 : Handle<String> JSMessageObject::GetSourceLine() const {
   19633             :   Handle<Script> the_script = handle(ScriptFromJSValue(script()));
   19634             : 
   19635             :   Isolate* isolate = the_script->GetIsolate();
   19636       11538 :   if (the_script->type() == Script::TYPE_WASM) {
   19637             :     return isolate->factory()->empty_string();
   19638             :   }
   19639             : 
   19640             :   Script::PositionInfo info;
   19641             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   19642       11538 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   19643       11538 :                                offset_flag)) {
   19644             :     return isolate->factory()->empty_string();
   19645             :   }
   19646             : 
   19647       11538 :   Handle<String> src = handle(String::cast(the_script->source()), isolate);
   19648       11538 :   return isolate->factory()->NewSubString(src, info.line_start, info.line_end);
   19649             : }
   19650             : 
   19651        3268 : void JSArrayBuffer::Neuter() {
   19652        3268 :   CHECK(is_neuterable());
   19653        3268 :   CHECK(is_external());
   19654             :   set_backing_store(NULL);
   19655        3268 :   set_byte_length(Smi::kZero);
   19656             :   set_was_neutered(true);
   19657             :   // Invalidate the neutering protector.
   19658             :   Isolate* const isolate = GetIsolate();
   19659        3268 :   if (isolate->IsArrayBufferNeuteringIntact()) {
   19660         228 :     isolate->InvalidateArrayBufferNeuteringProtector();
   19661             :   }
   19662        3268 : }
   19663             : 
   19664             : 
   19665      133519 : void JSArrayBuffer::Setup(Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
   19666             :                           bool is_external, void* data, size_t allocated_length,
   19667             :                           SharedFlag shared) {
   19668             :   DCHECK(array_buffer->GetEmbedderFieldCount() ==
   19669             :          v8::ArrayBuffer::kEmbedderFieldCount);
   19670      400557 :   for (int i = 0; i < v8::ArrayBuffer::kEmbedderFieldCount; i++) {
   19671             :     array_buffer->SetEmbedderField(i, Smi::kZero);
   19672             :   }
   19673             :   array_buffer->set_bit_field(0);
   19674             :   array_buffer->set_is_external(is_external);
   19675      133519 :   array_buffer->set_is_neuterable(shared == SharedFlag::kNotShared);
   19676      133519 :   array_buffer->set_is_shared(shared == SharedFlag::kShared);
   19677             : 
   19678             :   Handle<Object> byte_length =
   19679      133519 :       isolate->factory()->NewNumberFromSize(allocated_length);
   19680      133613 :   CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
   19681      133519 :   array_buffer->set_byte_length(*byte_length);
   19682             :   // Initialize backing store at last to avoid handling of |JSArrayBuffers| that
   19683             :   // are currently being constructed in the |ArrayBufferTracker|. The
   19684             :   // registration method below handles the case of registering a buffer that has
   19685             :   // already been promoted.
   19686             :   array_buffer->set_backing_store(data);
   19687             : 
   19688      133519 :   if (data && !is_external) {
   19689      115730 :     isolate->heap()->RegisterNewArrayBuffer(*array_buffer);
   19690             :   }
   19691      133519 : }
   19692             : 
   19693             : namespace {
   19694             : 
   19695             : inline int ConvertToMb(size_t size) {
   19696      104522 :   return static_cast<int>(size / static_cast<size_t>(MB));
   19697             : }
   19698             : 
   19699             : }  // namespace
   19700             : 
   19701      121099 : bool JSArrayBuffer::SetupAllocatingData(Handle<JSArrayBuffer> array_buffer,
   19702      330144 :                                         Isolate* isolate,
   19703             :                                         size_t allocated_length,
   19704             :                                         bool initialize, SharedFlag shared) {
   19705             :   void* data;
   19706      121099 :   CHECK(isolate->array_buffer_allocator() != NULL);
   19707             :   // Prevent creating array buffers when serializing.
   19708             :   DCHECK(!isolate->serializer_enabled());
   19709      121099 :   if (allocated_length != 0) {
   19710             :     isolate->counters()->array_buffer_big_allocations()->AddSample(
   19711      104522 :         ConvertToMb(allocated_length));
   19712      104522 :     if (initialize) {
   19713      102996 :       data = isolate->array_buffer_allocator()->Allocate(allocated_length);
   19714             :     } else {
   19715             :       data = isolate->array_buffer_allocator()->AllocateUninitialized(
   19716        1526 :           allocated_length);
   19717             :     }
   19718      104522 :     if (data == NULL) {
   19719             :       isolate->counters()->array_buffer_new_size_failures()->AddSample(
   19720           1 :           ConvertToMb(allocated_length));
   19721           1 :       return false;
   19722             :     }
   19723             :   } else {
   19724             :     data = NULL;
   19725             :   }
   19726             : 
   19727             :   JSArrayBuffer::Setup(array_buffer, isolate, false, data, allocated_length,
   19728      121098 :                        shared);
   19729      121098 :   return true;
   19730             : }
   19731             : 
   19732             : 
   19733       15528 : Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer(
   19734             :     Handle<JSTypedArray> typed_array) {
   19735             : 
   19736             :   Handle<Map> map(typed_array->map());
   19737       15528 :   Isolate* isolate = typed_array->GetIsolate();
   19738             : 
   19739             :   DCHECK(IsFixedTypedArrayElementsKind(map->elements_kind()));
   19740             : 
   19741             :   Handle<FixedTypedArrayBase> fixed_typed_array(
   19742             :       FixedTypedArrayBase::cast(typed_array->elements()));
   19743             : 
   19744             :   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(typed_array->buffer()),
   19745             :                                isolate);
   19746             :   void* backing_store =
   19747             :       isolate->array_buffer_allocator()->AllocateUninitialized(
   19748       31056 :           fixed_typed_array->DataSize());
   19749             :   buffer->set_is_external(false);
   19750             :   DCHECK(buffer->byte_length()->IsSmi() ||
   19751             :          buffer->byte_length()->IsHeapNumber());
   19752             :   DCHECK(NumberToInt32(buffer->byte_length()) == fixed_typed_array->DataSize());
   19753             :   // Initialize backing store at last to avoid handling of |JSArrayBuffers| that
   19754             :   // are currently being constructed in the |ArrayBufferTracker|. The
   19755             :   // registration method below handles the case of registering a buffer that has
   19756             :   // already been promoted.
   19757             :   buffer->set_backing_store(backing_store);
   19758       15528 :   isolate->heap()->RegisterNewArrayBuffer(*buffer);
   19759             :   memcpy(buffer->backing_store(),
   19760             :          fixed_typed_array->DataPtr(),
   19761       15528 :          fixed_typed_array->DataSize());
   19762             :   Handle<FixedTypedArrayBase> new_elements =
   19763             :       isolate->factory()->NewFixedTypedArrayWithExternalPointer(
   19764             :           fixed_typed_array->length(), typed_array->type(),
   19765       31056 :           static_cast<uint8_t*>(buffer->backing_store()));
   19766             : 
   19767       15528 :   typed_array->set_elements(*new_elements);
   19768             : 
   19769       15528 :   return buffer;
   19770             : }
   19771             : 
   19772             : 
   19773    37463298 : Handle<JSArrayBuffer> JSTypedArray::GetBuffer() {
   19774             :   Handle<JSArrayBuffer> array_buffer(JSArrayBuffer::cast(buffer()),
   19775             :                                      GetIsolate());
   19776    74926563 :   if (array_buffer->was_neutered() ||
   19777             :       array_buffer->backing_store() != nullptr) {
   19778    37447776 :     return array_buffer;
   19779             :   }
   19780             :   Handle<JSTypedArray> self(this);
   19781       15528 :   return MaterializeArrayBuffer(self);
   19782             : }
   19783             : 
   19784       22497 : Handle<PropertyCell> PropertyCell::InvalidateEntry(
   19785             :     Handle<GlobalDictionary> dictionary, int entry) {
   19786             :   Isolate* isolate = dictionary->GetIsolate();
   19787             :   // Swap with a copy.
   19788             :   DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
   19789       22497 :   Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
   19790       22497 :   Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell();
   19791       22497 :   new_cell->set_value(cell->value());
   19792             :   dictionary->ValueAtPut(entry, *new_cell);
   19793             :   bool is_the_hole = cell->value()->IsTheHole(isolate);
   19794             :   // Cell is officially mutable henceforth.
   19795             :   PropertyDetails details = cell->property_details();
   19796             :   details = details.set_cell_type(is_the_hole ? PropertyCellType::kUninitialized
   19797       22497 :                                               : PropertyCellType::kMutable);
   19798             :   new_cell->set_property_details(details);
   19799             :   // Old cell is ready for invalidation.
   19800       22497 :   if (is_the_hole) {
   19801       19590 :     cell->set_value(isolate->heap()->undefined_value());
   19802             :   } else {
   19803       25404 :     cell->set_value(isolate->heap()->the_hole_value());
   19804             :   }
   19805             :   details = details.set_cell_type(PropertyCellType::kInvalidated);
   19806             :   cell->set_property_details(details);
   19807             :   cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19808       22497 :       isolate, DependentCode::kPropertyCellChangedGroup);
   19809       22497 :   return new_cell;
   19810             : }
   19811             : 
   19812             : 
   19813       12921 : PropertyCellConstantType PropertyCell::GetConstantType() {
   19814       12921 :   if (value()->IsSmi()) return PropertyCellConstantType::kSmi;
   19815        2748 :   return PropertyCellConstantType::kStableMap;
   19816             : }
   19817             : 
   19818             : 
   19819     1272645 : static bool RemainsConstantType(Handle<PropertyCell> cell,
   19820             :                                 Handle<Object> value) {
   19821             :   // TODO(dcarney): double->smi and smi->double transition from kConstant
   19822     2451510 :   if (cell->value()->IsSmi() && value->IsSmi()) {
   19823             :     return true;
   19824      190010 :   } else if (cell->value()->IsHeapObject() && value->IsHeapObject()) {
   19825             :     return HeapObject::cast(cell->value())->map() ==
   19826      172240 :                HeapObject::cast(*value)->map() &&
   19827       92754 :            HeapObject::cast(*value)->map()->is_stable();
   19828             :   }
   19829             :   return false;
   19830             : }
   19831             : 
   19832             : 
   19833    11918808 : PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell,
   19834             :                                            Handle<Object> value,
   19835             :                                            PropertyDetails details) {
   19836             :   PropertyCellType type = details.cell_type();
   19837             :   Isolate* isolate = cell->GetIsolate();
   19838             :   DCHECK(!value->IsTheHole(isolate));
   19839    11918808 :   if (cell->value()->IsTheHole(isolate)) {
   19840     8840745 :     switch (type) {
   19841             :       // Only allow a cell to transition once into constant state.
   19842             :       case PropertyCellType::kUninitialized:
   19843     8840745 :         if (value->IsUndefined(isolate)) return PropertyCellType::kUndefined;
   19844     7137426 :         return PropertyCellType::kConstant;
   19845             :       case PropertyCellType::kInvalidated:
   19846             :         return PropertyCellType::kMutable;
   19847             :       default:
   19848           0 :         UNREACHABLE();
   19849             :         return PropertyCellType::kMutable;
   19850             :     }
   19851             :   }
   19852     3078063 :   switch (type) {
   19853             :     case PropertyCellType::kUndefined:
   19854             :       return PropertyCellType::kConstant;
   19855             :     case PropertyCellType::kConstant:
   19856      102558 :       if (*value == cell->value()) return PropertyCellType::kConstant;
   19857             :     // Fall through.
   19858             :     case PropertyCellType::kConstantType:
   19859     1272645 :       if (RemainsConstantType(cell, value)) {
   19860             :         return PropertyCellType::kConstantType;
   19861             :       }
   19862             :     // Fall through.
   19863             :     case PropertyCellType::kMutable:
   19864             :       return PropertyCellType::kMutable;
   19865             :   }
   19866           0 :   UNREACHABLE();
   19867             :   return PropertyCellType::kMutable;
   19868             : }
   19869             : 
   19870     3085413 : Handle<PropertyCell> PropertyCell::PrepareForValue(
   19871             :     Handle<GlobalDictionary> dictionary, int entry, Handle<Object> value,
   19872             :     PropertyDetails details) {
   19873             :   Isolate* isolate = dictionary->GetIsolate();
   19874             :   DCHECK(!value->IsTheHole(isolate));
   19875             :   DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
   19876     3085413 :   Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
   19877             :   const PropertyDetails original_details = cell->property_details();
   19878             :   // Data accesses could be cached in ics or optimized code.
   19879             :   bool invalidate =
   19880     6169849 :       original_details.kind() == kData && details.kind() == kAccessor;
   19881             :   int index = original_details.dictionary_index();
   19882             :   PropertyCellType old_type = original_details.cell_type();
   19883             :   // Preserve the enumeration index unless the property was deleted or never
   19884             :   // initialized.
   19885     3085413 :   if (cell->value()->IsTheHole(isolate)) {
   19886             :     index = dictionary->NextEnumerationIndex();
   19887        7350 :     dictionary->SetNextEnumerationIndex(index + 1);
   19888             :   }
   19889             :   DCHECK(index > 0);
   19890             :   details = details.set_index(index);
   19891             : 
   19892     3085413 :   PropertyCellType new_type = UpdatedType(cell, value, original_details);
   19893     3085413 :   if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry);
   19894             : 
   19895             :   // Install new property details.
   19896             :   details = details.set_cell_type(new_type);
   19897             :   cell->set_property_details(details);
   19898             : 
   19899             :   // Deopt when transitioning from a constant type.
   19900     4504478 :   if (!invalidate && (old_type != new_type ||
   19901             :                       original_details.IsReadOnly() != details.IsReadOnly())) {
   19902             :     cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19903     1670051 :         isolate, DependentCode::kPropertyCellChangedGroup);
   19904             :   }
   19905     3085413 :   return cell;
   19906             : }
   19907             : 
   19908             : 
   19909             : // static
   19910        1018 : void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell,
   19911             :                                             Handle<Object> new_value) {
   19912        1018 :   if (cell->value() != *new_value) {
   19913        1018 :     cell->set_value(*new_value);
   19914             :     Isolate* isolate = cell->GetIsolate();
   19915             :     cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19916        1018 :         isolate, DependentCode::kPropertyCellChangedGroup);
   19917             :   }
   19918        1018 : }
   19919             : 
   19920          42 : int JSGeneratorObject::source_position() const {
   19921          42 :   CHECK(is_suspended());
   19922             :   DCHECK(function()->shared()->HasBytecodeArray());
   19923             :   DCHECK(!function()->shared()->HasBaselineCode());
   19924             : 
   19925             :   int code_offset;
   19926             :   const JSAsyncGeneratorObject* async =
   19927          42 :       IsJSAsyncGeneratorObject() ? JSAsyncGeneratorObject::cast(this) : nullptr;
   19928          42 :   if (async != nullptr && async->awaited_promise()->IsJSPromise()) {
   19929             :     code_offset = Smi::cast(async->await_input_or_debug_pos())->value();
   19930             :   } else {
   19931             :     code_offset = Smi::cast(input_or_debug_pos())->value();
   19932             :   }
   19933             : 
   19934             :   // The stored bytecode offset is relative to a different base than what
   19935             :   // is used in the source position table, hence the subtraction.
   19936          42 :   code_offset -= BytecodeArray::kHeaderSize - kHeapObjectTag;
   19937             :   AbstractCode* code =
   19938             :       AbstractCode::cast(function()->shared()->bytecode_array());
   19939          42 :   return code->SourcePosition(code_offset);
   19940             : }
   19941             : 
   19942             : // static
   19943        5978 : AccessCheckInfo* AccessCheckInfo::Get(Isolate* isolate,
   19944             :                                       Handle<JSObject> receiver) {
   19945             :   DisallowHeapAllocation no_gc;
   19946             :   DCHECK(receiver->map()->is_access_check_needed());
   19947        5978 :   Object* maybe_constructor = receiver->map()->GetConstructor();
   19948        5978 :   if (maybe_constructor->IsFunctionTemplateInfo()) {
   19949             :     Object* data_obj =
   19950             :         FunctionTemplateInfo::cast(maybe_constructor)->access_check_info();
   19951         203 :     if (data_obj->IsUndefined(isolate)) return nullptr;
   19952         203 :     return AccessCheckInfo::cast(data_obj);
   19953             :   }
   19954             :   // Might happen for a detached context.
   19955        5775 :   if (!maybe_constructor->IsJSFunction()) return nullptr;
   19956             :   JSFunction* constructor = JSFunction::cast(maybe_constructor);
   19957             :   // Might happen for the debug context.
   19958        5743 :   if (!constructor->shared()->IsApiFunction()) return nullptr;
   19959             : 
   19960             :   Object* data_obj =
   19961             :       constructor->shared()->get_api_func_data()->access_check_info();
   19962        5206 :   if (data_obj->IsUndefined(isolate)) return nullptr;
   19963             : 
   19964        4373 :   return AccessCheckInfo::cast(data_obj);
   19965             : }
   19966             : 
   19967        6145 : bool JSReceiver::HasProxyInPrototype(Isolate* isolate) {
   19968       25300 :   for (PrototypeIterator iter(isolate, this, kStartAtReceiver,
   19969             :                               PrototypeIterator::END_AT_NULL);
   19970       19155 :        !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) {
   19971       38396 :     if (iter.GetCurrent<Object>()->IsJSProxy()) return true;
   19972             :   }
   19973        6102 :   return false;
   19974             : }
   19975             : 
   19976         853 : MaybeHandle<Object> JSModuleNamespace::GetExport(Handle<String> name) {
   19977             :   Isolate* isolate = name->GetIsolate();
   19978             : 
   19979        1706 :   Handle<Object> object(module()->exports()->Lookup(name), isolate);
   19980         853 :   if (object->IsTheHole(isolate)) {
   19981             :     return isolate->factory()->undefined_value();
   19982             :   }
   19983             : 
   19984             :   Handle<Object> value(Handle<Cell>::cast(object)->value(), isolate);
   19985         853 :   if (value->IsTheHole(isolate)) {
   19986         210 :     THROW_NEW_ERROR(
   19987             :         isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object);
   19988             :   }
   19989             : 
   19990             :   return value;
   19991             : }
   19992             : 
   19993             : namespace {
   19994             : 
   19995             : struct ModuleHandleHash {
   19996             :   V8_INLINE size_t operator()(Handle<Module> module) const {
   19997         732 :     return module->hash();
   19998             :   }
   19999             : };
   20000             : 
   20001             : struct ModuleHandleEqual {
   20002             :   V8_INLINE bool operator()(Handle<Module> lhs, Handle<Module> rhs) const {
   20003             :     return *lhs == *rhs;
   20004             :   }
   20005             : };
   20006             : 
   20007             : struct StringHandleHash {
   20008             :   V8_INLINE size_t operator()(Handle<String> string) const {
   20009         552 :     return string->Hash();
   20010             :   }
   20011             : };
   20012             : 
   20013             : struct StringHandleEqual {
   20014             :   V8_INLINE bool operator()(Handle<String> lhs, Handle<String> rhs) const {
   20015          45 :     return lhs->Equals(*rhs);
   20016             :   }
   20017             : };
   20018             : 
   20019             : class UnorderedStringSet
   20020             :     : public std::unordered_set<Handle<String>, StringHandleHash,
   20021             :                                 StringHandleEqual,
   20022             :                                 ZoneAllocator<Handle<String>>> {
   20023             :  public:
   20024         314 :   explicit UnorderedStringSet(Zone* zone)
   20025             :       : std::unordered_set<Handle<String>, StringHandleHash, StringHandleEqual,
   20026             :                            ZoneAllocator<Handle<String>>>(
   20027             :             2 /* bucket count */, StringHandleHash(), StringHandleEqual(),
   20028         314 :             ZoneAllocator<Handle<String>>(zone)) {}
   20029             : };
   20030             : 
   20031             : class UnorderedModuleSet
   20032             :     : public std::unordered_set<Handle<Module>, ModuleHandleHash,
   20033             :                                 ModuleHandleEqual,
   20034             :                                 ZoneAllocator<Handle<Module>>> {
   20035             :  public:
   20036         300 :   explicit UnorderedModuleSet(Zone* zone)
   20037             :       : std::unordered_set<Handle<Module>, ModuleHandleHash, ModuleHandleEqual,
   20038             :                            ZoneAllocator<Handle<Module>>>(
   20039             :             2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(),
   20040         300 :             ZoneAllocator<Handle<Module>>(zone)) {}
   20041             : };
   20042             : 
   20043             : class UnorderedStringMap
   20044             :     : public std::unordered_map<
   20045             :           Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual,
   20046             :           ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>> {
   20047             :  public:
   20048         388 :   explicit UnorderedStringMap(Zone* zone)
   20049             :       : std::unordered_map<
   20050             :             Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual,
   20051             :             ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>>(
   20052             :             2 /* bucket count */, StringHandleHash(), StringHandleEqual(),
   20053             :             ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>(
   20054         388 :                 zone)) {}
   20055             : };
   20056             : 
   20057             : }  // anonymous namespace
   20058             : 
   20059             : class Module::ResolveSet
   20060             :     : public std::unordered_map<
   20061             :           Handle<Module>, UnorderedStringSet*, ModuleHandleHash,
   20062             :           ModuleHandleEqual,
   20063             :           ZoneAllocator<std::pair<const Handle<Module>, UnorderedStringSet*>>> {
   20064             :  public:
   20065        1077 :   explicit ResolveSet(Zone* zone)
   20066             :       : std::unordered_map<Handle<Module>, UnorderedStringSet*,
   20067             :                            ModuleHandleHash, ModuleHandleEqual,
   20068             :                            ZoneAllocator<std::pair<const Handle<Module>,
   20069             :                                                    UnorderedStringSet*>>>(
   20070             :             2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(),
   20071             :             ZoneAllocator<std::pair<const Handle<Module>, UnorderedStringSet*>>(
   20072             :                 zone)),
   20073        1077 :         zone_(zone) {}
   20074             : 
   20075             :   Zone* zone() const { return zone_; }
   20076             : 
   20077             :  private:
   20078             :   Zone* zone_;
   20079             : };
   20080             : 
   20081             : namespace {
   20082             : 
   20083             : int ExportIndex(int cell_index) {
   20084             :   DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
   20085             :             ModuleDescriptor::kExport);
   20086        2060 :   return cell_index - 1;
   20087             : }
   20088             : 
   20089             : int ImportIndex(int cell_index) {
   20090             :   DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
   20091             :             ModuleDescriptor::kImport);
   20092         991 :   return -cell_index - 1;
   20093             : }
   20094             : 
   20095             : }  // anonymous namespace
   20096             : 
   20097         180 : void Module::CreateIndirectExport(Handle<Module> module, Handle<String> name,
   20098             :                                   Handle<ModuleInfoEntry> entry) {
   20099             :   Isolate* isolate = module->GetIsolate();
   20100             :   Handle<ObjectHashTable> exports(module->exports(), isolate);
   20101             :   DCHECK(exports->Lookup(name)->IsTheHole(isolate));
   20102         180 :   exports = ObjectHashTable::Put(exports, name, entry);
   20103         180 :   module->set_exports(*exports);
   20104         180 : }
   20105             : 
   20106        1976 : void Module::CreateExport(Handle<Module> module, int cell_index,
   20107             :                           Handle<FixedArray> names) {
   20108             :   DCHECK_LT(0, names->length());
   20109             :   Isolate* isolate = module->GetIsolate();
   20110             : 
   20111             :   Handle<Cell> cell =
   20112        1976 :       isolate->factory()->NewCell(isolate->factory()->undefined_value());
   20113        1976 :   module->regular_exports()->set(ExportIndex(cell_index), *cell);
   20114             : 
   20115             :   Handle<ObjectHashTable> exports(module->exports(), isolate);
   20116        4147 :   for (int i = 0, n = names->length(); i < n; ++i) {
   20117             :     Handle<String> name(String::cast(names->get(i)), isolate);
   20118             :     DCHECK(exports->Lookup(name)->IsTheHole(isolate));
   20119        2171 :     exports = ObjectHashTable::Put(exports, name, cell);
   20120             :   }
   20121        1976 :   module->set_exports(*exports);
   20122        1976 : }
   20123             : 
   20124         192 : Handle<Object> Module::LoadVariable(Handle<Module> module, int cell_index) {
   20125             :   Isolate* isolate = module->GetIsolate();
   20126             :   Handle<Object> object;
   20127         192 :   switch (ModuleDescriptor::GetCellIndexKind(cell_index)) {
   20128             :     case ModuleDescriptor::kImport:
   20129             :       object = handle(module->regular_imports()->get(ImportIndex(cell_index)),
   20130             :                       isolate);
   20131         108 :       break;
   20132             :     case ModuleDescriptor::kExport:
   20133             :       object = handle(module->regular_exports()->get(ExportIndex(cell_index)),
   20134             :                       isolate);
   20135          84 :       break;
   20136             :     case ModuleDescriptor::kInvalid:
   20137           0 :       UNREACHABLE();
   20138             :       break;
   20139             :   }
   20140         192 :   return handle(Handle<Cell>::cast(object)->value(), isolate);
   20141             : }
   20142             : 
   20143           0 : void Module::StoreVariable(Handle<Module> module, int cell_index,
   20144             :                            Handle<Object> value) {
   20145             :   Isolate* isolate = module->GetIsolate();
   20146             :   DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
   20147             :             ModuleDescriptor::kExport);
   20148             :   Handle<Object> object(module->regular_exports()->get(ExportIndex(cell_index)),
   20149             :                         isolate);
   20150           0 :   Handle<Cell>::cast(object)->set_value(*value);
   20151           0 : }
   20152             : 
   20153        1227 : MaybeHandle<Cell> Module::ResolveImport(Handle<Module> module,
   20154             :                                         Handle<String> name, int module_request,
   20155             :                                         MessageLocation loc, bool must_resolve,
   20156             :                                         Module::ResolveSet* resolve_set) {
   20157             :   Isolate* isolate = module->GetIsolate();
   20158             :   Handle<Module> requested_module(
   20159             :       Module::cast(module->requested_modules()->get(module_request)), isolate);
   20160             :   return Module::ResolveExport(requested_module, name, loc, must_resolve,
   20161        1227 :                                resolve_set);
   20162             : }
   20163             : 
   20164        1407 : MaybeHandle<Cell> Module::ResolveExport(Handle<Module> module,
   20165             :                                         Handle<String> name,
   20166             :                                         MessageLocation loc, bool must_resolve,
   20167         314 :                                         Module::ResolveSet* resolve_set) {
   20168             :   DCHECK_EQ(module->status(), kPrepared);
   20169             :   Isolate* isolate = module->GetIsolate();
   20170        2814 :   Handle<Object> object(module->exports()->Lookup(name), isolate);
   20171        1407 :   if (object->IsCell()) {
   20172             :     // Already resolved (e.g. because it's a local export).
   20173             :     return Handle<Cell>::cast(object);
   20174             :   }
   20175             : 
   20176             :   // Check for cycle before recursing.
   20177             :   {
   20178             :     // Attempt insertion with a null string set.
   20179         329 :     auto result = resolve_set->insert({module, nullptr});
   20180             :     UnorderedStringSet*& name_set = result.first->second;
   20181         329 :     if (result.second) {
   20182             :       // |module| wasn't in the map previously, so allocate a new name set.
   20183             :       Zone* zone = resolve_set->zone();
   20184             :       name_set =
   20185         314 :           new (zone->New(sizeof(UnorderedStringSet))) UnorderedStringSet(zone);
   20186          30 :     } else if (name_set->count(name)) {
   20187             :       // Cycle detected.
   20188          15 :       if (must_resolve) {
   20189             :         return isolate->Throw<Cell>(
   20190             :             isolate->factory()->NewSyntaxError(
   20191             :                 MessageTemplate::kCyclicModuleDependency, name),
   20192           0 :             &loc);
   20193             :       }
   20194             :       return MaybeHandle<Cell>();
   20195             :     }
   20196         314 :     name_set->insert(name);
   20197             :   }
   20198             : 
   20199         314 :   if (object->IsModuleInfoEntry()) {
   20200             :     // Not yet resolved indirect export.
   20201             :     Handle<ModuleInfoEntry> entry = Handle<ModuleInfoEntry>::cast(object);
   20202             :     Handle<String> import_name(String::cast(entry->import_name()), isolate);
   20203             :     Handle<Script> script(
   20204             :         Script::cast(JSFunction::cast(module->code())->shared()->script()),
   20205             :         isolate);
   20206         180 :     MessageLocation new_loc(script, entry->beg_pos(), entry->end_pos());
   20207             : 
   20208             :     Handle<Cell> cell;
   20209         180 :     if (!ResolveImport(module, import_name, entry->module_request(), new_loc,
   20210             :                        true, resolve_set)
   20211         360 :              .ToHandle(&cell)) {
   20212             :       DCHECK(isolate->has_pending_exception());
   20213             :       return MaybeHandle<Cell>();
   20214             :     }
   20215             : 
   20216             :     // The export table may have changed but the entry in question should be
   20217             :     // unchanged.
   20218             :     Handle<ObjectHashTable> exports(module->exports(), isolate);
   20219             :     DCHECK(exports->Lookup(name)->IsModuleInfoEntry());
   20220             : 
   20221         180 :     exports = ObjectHashTable::Put(exports, name, cell);
   20222         180 :     module->set_exports(*exports);
   20223             :     return cell;
   20224             :   }
   20225             : 
   20226             :   DCHECK(object->IsTheHole(isolate));
   20227             :   return Module::ResolveExportUsingStarExports(module, name, loc, must_resolve,
   20228         134 :                                                resolve_set);
   20229             : }
   20230             : 
   20231         134 : MaybeHandle<Cell> Module::ResolveExportUsingStarExports(
   20232             :     Handle<Module> module, Handle<String> name, MessageLocation loc,
   20233             :     bool must_resolve, Module::ResolveSet* resolve_set) {
   20234             :   Isolate* isolate = module->GetIsolate();
   20235         268 :   if (!name->Equals(isolate->heap()->default_string())) {
   20236             :     // Go through all star exports looking for the given name.  If multiple star
   20237             :     // exports provide the name, make sure they all map it to the same cell.
   20238             :     Handle<Cell> unique_cell;
   20239             :     Handle<FixedArray> special_exports(module->info()->special_exports(),
   20240         120 :                                        isolate);
   20241         360 :     for (int i = 0, n = special_exports->length(); i < n; ++i) {
   20242             :       i::Handle<i::ModuleInfoEntry> entry(
   20243             :           i::ModuleInfoEntry::cast(special_exports->get(i)), isolate);
   20244         240 :       if (!entry->export_name()->IsUndefined(isolate)) {
   20245          90 :         continue;  // Indirect export.
   20246             :       }
   20247             : 
   20248             :       Handle<Script> script(
   20249             :           Script::cast(JSFunction::cast(module->code())->shared()->script()),
   20250             :           isolate);
   20251         150 :       MessageLocation new_loc(script, entry->beg_pos(), entry->end_pos());
   20252             : 
   20253             :       Handle<Cell> cell;
   20254         150 :       if (ResolveImport(module, name, entry->module_request(), new_loc, false,
   20255             :                         resolve_set)
   20256         300 :               .ToHandle(&cell)) {
   20257          90 :         if (unique_cell.is_null()) unique_cell = cell;
   20258          90 :         if (*unique_cell != *cell) {
   20259             :           return isolate->Throw<Cell>(
   20260             :               isolate->factory()->NewSyntaxError(
   20261             :                   MessageTemplate::kAmbiguousExport, name),
   20262           0 :               &loc);
   20263             :         }
   20264          60 :       } else if (isolate->has_pending_exception()) {
   20265             :         return MaybeHandle<Cell>();
   20266             :       }
   20267             :     }
   20268             : 
   20269         120 :     if (!unique_cell.is_null()) {
   20270             :       // Found a unique star export for this name.
   20271             :       Handle<ObjectHashTable> exports(module->exports(), isolate);
   20272             :       DCHECK(exports->Lookup(name)->IsTheHole(isolate));
   20273          75 :       exports = ObjectHashTable::Put(exports, name, unique_cell);
   20274          75 :       module->set_exports(*exports);
   20275             :       return unique_cell;
   20276             :     }
   20277             :   }
   20278             : 
   20279             :   // Unresolvable.
   20280          59 :   if (must_resolve) {
   20281             :     return isolate->Throw<Cell>(isolate->factory()->NewSyntaxError(
   20282             :                                     MessageTemplate::kUnresolvableExport, name),
   20283          28 :                                 &loc);
   20284             :   }
   20285             :   return MaybeHandle<Cell>();
   20286             : }
   20287             : 
   20288        1216 : bool Module::Instantiate(Handle<Module> module, v8::Local<v8::Context> context,
   20289             :                          v8::Module::ResolveCallback callback) {
   20290        2418 :   return PrepareInstantiate(module, context, callback) &&
   20291        2418 :          FinishInstantiate(module, context);
   20292             : }
   20293             : 
   20294        2362 : bool Module::PrepareInstantiate(Handle<Module> module,
   20295             :                                 v8::Local<v8::Context> context,
   20296             :                                 v8::Module::ResolveCallback callback) {
   20297        2362 :   if (module->status() == kPrepared) return true;
   20298             : 
   20299             :   // Obtain requested modules.
   20300             :   Isolate* isolate = module->GetIsolate();
   20301        1917 :   Handle<ModuleInfo> module_info(module->info(), isolate);
   20302             :   Handle<FixedArray> module_requests(module_info->module_requests(), isolate);
   20303             :   Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
   20304        3070 :   for (int i = 0, length = module_requests->length(); i < length; ++i) {
   20305             :     Handle<String> specifier(String::cast(module_requests->get(i)), isolate);
   20306             :     v8::Local<v8::Module> api_requested_module;
   20307        1167 :     if (!callback(context, v8::Utils::ToLocal(specifier),
   20308             :                   v8::Utils::ToLocal(module))
   20309        2334 :              .ToLocal(&api_requested_module)) {
   20310          14 :       isolate->PromoteScheduledException();
   20311             :       return false;
   20312             :     }
   20313             :     Handle<Module> requested_module = Utils::OpenHandle(*api_requested_module);
   20314        1153 :     requested_modules->set(i, *requested_module);
   20315             :   }
   20316             : 
   20317             :   // Recurse.
   20318             :   module->set_status(kPrepared);
   20319        3049 :   for (int i = 0, length = requested_modules->length(); i < length; ++i) {
   20320             :     Handle<Module> requested_module(Module::cast(requested_modules->get(i)),
   20321             :                                     isolate);
   20322        1146 :     if (!PrepareInstantiate(requested_module, context, callback)) return false;
   20323             :   }
   20324             : 
   20325             :   // Set up local exports.
   20326             :   // TODO(neis): Create regular_exports array here instead of in factory method?
   20327        3879 :   for (int i = 0, n = module_info->RegularExportCount(); i < n; ++i) {
   20328        1976 :     int cell_index = module_info->RegularExportCellIndex(i);
   20329             :     Handle<FixedArray> export_names(module_info->RegularExportExportNames(i),
   20330        1976 :                                     isolate);
   20331        1976 :     CreateExport(module, cell_index, export_names);
   20332             :   }
   20333             : 
   20334             :   // Partially set up indirect exports.
   20335             :   // For each indirect export, we create the appropriate slot in the export
   20336             :   // table and store its ModuleInfoEntry there.  When we later find the correct
   20337             :   // Cell in the module that actually provides the value, we replace the
   20338             :   // ModuleInfoEntry by that Cell (see ResolveExport).
   20339             :   Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
   20340        2290 :   for (int i = 0, n = special_exports->length(); i < n; ++i) {
   20341             :     Handle<ModuleInfoEntry> entry(
   20342             :         ModuleInfoEntry::cast(special_exports->get(i)), isolate);
   20343             :     Handle<Object> export_name(entry->export_name(), isolate);
   20344         387 :     if (export_name->IsUndefined(isolate)) continue;  // Star export.
   20345         180 :     CreateIndirectExport(module, Handle<String>::cast(export_name), entry);
   20346             :   }
   20347             : 
   20348             :   DCHECK_EQ(module->status(), kPrepared);
   20349             :   DCHECK(!module->instantiated());
   20350             :   return true;
   20351             : }
   20352             : 
   20353        2348 : bool Module::FinishInstantiate(Handle<Module> module,
   20354             :                                v8::Local<v8::Context> context) {
   20355             :   DCHECK_EQ(module->status(), kPrepared);
   20356        2348 :   if (module->instantiated()) return true;
   20357             : 
   20358             :   // Instantiate SharedFunctionInfo and mark module as instantiated for
   20359             :   // the recursion.
   20360        1903 :   Isolate* isolate = module->GetIsolate();
   20361             :   Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(module->code()),
   20362             :                                     isolate);
   20363             :   Handle<JSFunction> function =
   20364             :       isolate->factory()->NewFunctionFromSharedFunctionInfo(
   20365             :           shared,
   20366        1903 :           handle(Utils::OpenHandle(*context)->native_context(), isolate));
   20367        1903 :   module->set_code(*function);
   20368             :   DCHECK(module->instantiated());
   20369             : 
   20370             :   // Recurse.
   20371             :   Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
   20372        3049 :   for (int i = 0, length = requested_modules->length(); i < length; ++i) {
   20373             :     Handle<Module> requested_module(Module::cast(requested_modules->get(i)),
   20374             :                                     isolate);
   20375        1146 :     if (!FinishInstantiate(requested_module, context)) return false;
   20376             :   }
   20377             : 
   20378        1903 :   Zone zone(isolate->allocator(), ZONE_NAME);
   20379             : 
   20380             :   // Resolve imports.
   20381             :   Handle<ModuleInfo> module_info(shared->scope_info()->ModuleDescriptorInfo(),
   20382        1903 :                                  isolate);
   20383             :   Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
   20384        2786 :   for (int i = 0, n = regular_imports->length(); i < n; ++i) {
   20385             :     Handle<ModuleInfoEntry> entry(
   20386             :         ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
   20387             :     Handle<String> name(String::cast(entry->import_name()), isolate);
   20388             :     Handle<Script> script(
   20389             :         Script::cast(JSFunction::cast(module->code())->shared()->script()),
   20390             :         isolate);
   20391         897 :     MessageLocation loc(script, entry->beg_pos(), entry->end_pos());
   20392         897 :     ResolveSet resolve_set(&zone);
   20393             :     Handle<Cell> cell;
   20394         897 :     if (!ResolveImport(module, name, entry->module_request(), loc, true,
   20395             :                        &resolve_set)
   20396        1794 :              .ToHandle(&cell)) {
   20397             :       return false;
   20398             :     }
   20399         883 :     module->regular_imports()->set(ImportIndex(entry->cell_index()), *cell);
   20400             :   }
   20401             : 
   20402             :   // Resolve indirect exports.
   20403             :   Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
   20404        2276 :   for (int i = 0, n = special_exports->length(); i < n; ++i) {
   20405             :     Handle<ModuleInfoEntry> entry(
   20406             :         ModuleInfoEntry::cast(special_exports->get(i)), isolate);
   20407             :     Handle<Object> name(entry->export_name(), isolate);
   20408         594 :     if (name->IsUndefined(isolate)) continue;  // Star export.
   20409             :     Handle<Script> script(
   20410             :         Script::cast(JSFunction::cast(module->code())->shared()->script()),
   20411             :         isolate);
   20412         180 :     MessageLocation loc(script, entry->beg_pos(), entry->end_pos());
   20413         180 :     ResolveSet resolve_set(&zone);
   20414         180 :     if (ResolveExport(module, Handle<String>::cast(name), loc, true,
   20415             :                       &resolve_set)
   20416         360 :             .is_null()) {
   20417             :       return false;
   20418             :     }
   20419             :   }
   20420             : 
   20421        1903 :   return true;
   20422             : }
   20423             : 
   20424        2320 : MaybeHandle<Object> Module::Evaluate(Handle<Module> module) {
   20425             :   DCHECK(module->instantiated());
   20426             : 
   20427             :   // Each module can only be evaluated once.
   20428             :   Isolate* isolate = module->GetIsolate();
   20429        2320 :   if (module->evaluated()) return isolate->factory()->undefined_value();
   20430             :   Handle<JSFunction> function(JSFunction::cast(module->code()), isolate);
   20431        1875 :   module->set_evaluated();
   20432             : 
   20433             :   // Initialization.
   20434             :   DCHECK_EQ(MODULE_SCOPE, function->shared()->scope_info()->scope_type());
   20435             :   Handle<Object> receiver = isolate->factory()->undefined_value();
   20436             :   Handle<Object> argv[] = {module};
   20437             :   Handle<Object> generator;
   20438        3750 :   ASSIGN_RETURN_ON_EXCEPTION(
   20439             :       isolate, generator,
   20440             :       Execution::Call(isolate, function, receiver, arraysize(argv), argv),
   20441             :       Object);
   20442             : 
   20443             :   // Recursion.
   20444             :   Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
   20445        3007 :   for (int i = 0, length = requested_modules->length(); i < length; ++i) {
   20446             :     Handle<Module> import(Module::cast(requested_modules->get(i)), isolate);
   20447        2264 :     RETURN_ON_EXCEPTION(isolate, Evaluate(import), Object);
   20448             :   }
   20449             : 
   20450             :   // Evaluation of module body.
   20451             :   Handle<JSFunction> resume(
   20452        3750 :       isolate->native_context()->generator_next_internal(), isolate);
   20453             :   Handle<Object> result;
   20454        3750 :   ASSIGN_RETURN_ON_EXCEPTION(
   20455             :       isolate, result, Execution::Call(isolate, resume, generator, 0, nullptr),
   20456             :       Object);
   20457             :   DCHECK(static_cast<JSIteratorResult*>(JSObject::cast(*result))
   20458             :              ->done()
   20459             :              ->BooleanValue());
   20460             :   return handle(
   20461             :       static_cast<JSIteratorResult*>(JSObject::cast(*result))->value(),
   20462             :       isolate);
   20463             : }
   20464             : 
   20465             : namespace {
   20466             : 
   20467         403 : void FetchStarExports(Handle<Module> module, Zone* zone,
   20468             :                       UnorderedModuleSet* visited) {
   20469             :   DCHECK(module->instantiated());
   20470             : 
   20471         403 :   bool cycle = !visited->insert(module).second;
   20472         418 :   if (cycle) return;
   20473             : 
   20474             :   Isolate* isolate = module->GetIsolate();
   20475             :   Handle<ObjectHashTable> exports(module->exports(), isolate);
   20476         388 :   UnorderedStringMap more_exports(zone);
   20477             : 
   20478             :   // TODO(neis): Only allocate more_exports if there are star exports.
   20479             :   // Maybe split special_exports into indirect_exports and star_exports.
   20480             : 
   20481             :   Handle<FixedArray> special_exports(module->info()->special_exports(),
   20482         388 :                                      isolate);
   20483         536 :   for (int i = 0, n = special_exports->length(); i < n; ++i) {
   20484             :     Handle<ModuleInfoEntry> entry(
   20485             :         ModuleInfoEntry::cast(special_exports->get(i)), isolate);
   20486         148 :     if (!entry->export_name()->IsUndefined(isolate)) {
   20487             :       continue;  // Indirect export.
   20488             :     }
   20489             : 
   20490             :     Handle<Module> requested_module(
   20491             :         Module::cast(module->requested_modules()->get(entry->module_request())),
   20492             :         isolate);
   20493             : 
   20494             :     // Recurse.
   20495         103 :     FetchStarExports(requested_module, zone, visited);
   20496             : 
   20497             :     // Collect all of [requested_module]'s exports that must be added to
   20498             :     // [module]'s exports (i.e. to [exports]).  We record these in
   20499             :     // [more_exports].  Ambiguities (conflicting exports) are marked by mapping
   20500             :     // the name to undefined instead of a Cell.
   20501             :     Handle<ObjectHashTable> requested_exports(requested_module->exports(),
   20502             :                                               isolate);
   20503         815 :     for (int i = 0, n = requested_exports->Capacity(); i < n; ++i) {
   20504             :       Handle<Object> key(requested_exports->KeyAt(i), isolate);
   20505         712 :       if (!requested_exports->IsKey(isolate, *key)) continue;
   20506             :       Handle<String> name = Handle<String>::cast(key);
   20507             : 
   20508         298 :       if (name->Equals(isolate->heap()->default_string())) continue;
   20509         506 :       if (!exports->Lookup(name)->IsTheHole(isolate)) continue;
   20510             : 
   20511             :       Handle<Cell> cell(Cell::cast(requested_exports->ValueAt(i)), isolate);
   20512         446 :       auto insert_result = more_exports.insert(std::make_pair(name, cell));
   20513         223 :       if (!insert_result.second) {
   20514             :         auto it = insert_result.first;
   20515          45 :         if (*it->second == *cell || it->second->IsUndefined(isolate)) {
   20516             :           // We already recorded this mapping before, or the name is already
   20517             :           // known to be ambiguous.  In either case, there's nothing to do.
   20518             :         } else {
   20519             :           DCHECK(it->second->IsCell());
   20520             :           // Different star exports provide different cells for this name, hence
   20521             :           // mark the name as ambiguous.
   20522          15 :           it->second = isolate->factory()->undefined_value();
   20523             :         }
   20524             :       }
   20525             :     }
   20526             :   }
   20527             : 
   20528             :   // Copy [more_exports] into [exports].
   20529         969 :   for (const auto& elem : more_exports) {
   20530         193 :     if (elem.second->IsUndefined(isolate)) continue;  // Ambiguous export.
   20531             :     DCHECK(!elem.first->Equals(isolate->heap()->default_string()));
   20532             :     DCHECK(elem.second->IsCell());
   20533         178 :     exports = ObjectHashTable::Put(exports, elem.first, elem.second);
   20534             :   }
   20535         388 :   module->set_exports(*exports);
   20536             : }
   20537             : 
   20538             : }  // anonymous namespace
   20539             : 
   20540         161 : Handle<JSModuleNamespace> Module::GetModuleNamespace(Handle<Module> module,
   20541             :                                                      int module_request) {
   20542             :   Isolate* isolate = module->GetIsolate();
   20543             :   Handle<Module> requested_module(
   20544             :       Module::cast(module->requested_modules()->get(module_request)), isolate);
   20545         161 :   return Module::GetModuleNamespace(requested_module);
   20546             : }
   20547             : 
   20548         413 : Handle<JSModuleNamespace> Module::GetModuleNamespace(Handle<Module> module) {
   20549         300 :   Isolate* isolate = module->GetIsolate();
   20550             : 
   20551             :   Handle<HeapObject> object(module->module_namespace(), isolate);
   20552         413 :   if (!object->IsUndefined(isolate)) {
   20553             :     // Namespace object already exists.
   20554             :     return Handle<JSModuleNamespace>::cast(object);
   20555             :   }
   20556             : 
   20557             :   // Create the namespace object (initially empty).
   20558         300 :   Handle<JSModuleNamespace> ns = isolate->factory()->NewJSModuleNamespace();
   20559         300 :   ns->set_module(*module);
   20560         300 :   module->set_module_namespace(*ns);
   20561             : 
   20562             :   // Collect the export names.
   20563         300 :   Zone zone(isolate->allocator(), ZONE_NAME);
   20564         300 :   UnorderedModuleSet visited(&zone);
   20565         300 :   FetchStarExports(module, &zone, &visited);
   20566             :   Handle<ObjectHashTable> exports(module->exports(), isolate);
   20567             :   ZoneVector<Handle<String>> names(&zone);
   20568         300 :   names.reserve(exports->NumberOfElements());
   20569        1920 :   for (int i = 0, n = exports->Capacity(); i < n; ++i) {
   20570             :     Handle<Object> key(exports->KeyAt(i), isolate);
   20571        1620 :     if (!exports->IsKey(isolate, *key)) continue;
   20572             :     DCHECK(exports->ValueAt(i)->IsCell());
   20573         611 :     names.push_back(Handle<String>::cast(key));
   20574             :   }
   20575             :   DCHECK_EQ(static_cast<int>(names.size()), exports->NumberOfElements());
   20576             : 
   20577             :   // Sort them alphabetically.
   20578             :   struct {
   20579             :     bool operator()(Handle<String> a, Handle<String> b) {
   20580         712 :       return String::Compare(a, b) == ComparisonResult::kLessThan;
   20581             :     }
   20582             :   } StringLess;
   20583         300 :   std::sort(names.begin(), names.end(), StringLess);
   20584             : 
   20585             :   // Create the corresponding properties in the namespace object.
   20586             :   PropertyAttributes attr = DONT_DELETE;
   20587        1211 :   for (const auto& name : names) {
   20588             :     JSObject::SetAccessor(
   20589             :         ns, Accessors::ModuleNamespaceEntryInfo(isolate, name, attr))
   20590        1833 :         .Check();
   20591             :   }
   20592         600 :   JSObject::PreventExtensions(ns, THROW_ON_ERROR).ToChecked();
   20593             : 
   20594         600 :   return ns;
   20595             : }
   20596             : 
   20597     9379494 : MaybeHandle<Name> FunctionTemplateInfo::TryGetCachedPropertyName(
   20598             :     Isolate* isolate, Handle<Object> getter) {
   20599     9379494 :   if (getter->IsFunctionTemplateInfo()) {
   20600             :     Handle<FunctionTemplateInfo> fti =
   20601             :         Handle<FunctionTemplateInfo>::cast(getter);
   20602             :     // Check if the accessor uses a cached property.
   20603         536 :     if (!fti->cached_property_name()->IsTheHole(isolate)) {
   20604             :       return handle(Name::cast(fti->cached_property_name()));
   20605             :     }
   20606             :   }
   20607             :   return MaybeHandle<Name>();
   20608             : }
   20609             : 
   20610             : // static
   20611        1397 : ElementsKind JSArrayIterator::ElementsKindForInstanceType(InstanceType type) {
   20612             :   DCHECK_GE(type, FIRST_ARRAY_ITERATOR_TYPE);
   20613             :   DCHECK_LE(type, LAST_ARRAY_ITERATOR_TYPE);
   20614             : 
   20615        1397 :   if (type <= LAST_ARRAY_KEY_ITERATOR_TYPE) {
   20616             :     // Should be ignored for key iterators.
   20617             :     return FAST_ELEMENTS;
   20618             :   } else {
   20619             :     ElementsKind kind;
   20620        1384 :     if (type < FIRST_ARRAY_VALUE_ITERATOR_TYPE) {
   20621             :       // Convert `type` to a value iterator from an entries iterator
   20622          14 :       type = static_cast<InstanceType>(type +
   20623             :                                        (FIRST_ARRAY_VALUE_ITERATOR_TYPE -
   20624          14 :                                         FIRST_ARRAY_KEY_VALUE_ITERATOR_TYPE));
   20625             :       DCHECK_GE(type, FIRST_ARRAY_VALUE_ITERATOR_TYPE);
   20626             :       DCHECK_LE(type, LAST_ARRAY_ITERATOR_TYPE);
   20627             :     }
   20628             : 
   20629        1384 :     if (type <= JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE) {
   20630             :       kind =
   20631          14 :           static_cast<ElementsKind>(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND +
   20632          14 :                                     (type - FIRST_ARRAY_VALUE_ITERATOR_TYPE));
   20633             :       DCHECK_LE(kind, LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND);
   20634        1370 :     } else if (type < JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE) {
   20635             :       kind = static_cast<ElementsKind>(
   20636        1370 :           FIRST_FAST_ELEMENTS_KIND +
   20637        1370 :           (type - JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE));
   20638             :       DCHECK_LE(kind, LAST_FAST_ELEMENTS_KIND);
   20639             :     } else {
   20640             :       // For any slow element cases, the actual elements kind is not known.
   20641             :       // Simply
   20642             :       // return a slow elements kind in this case. Users of this function must
   20643             :       // not
   20644             :       // depend on this.
   20645             :       return DICTIONARY_ELEMENTS;
   20646             :     }
   20647             :     DCHECK_LE(kind, LAST_ELEMENTS_KIND);
   20648        1384 :     return kind;
   20649             :   }
   20650             : }
   20651             : 
   20652             : }  // namespace internal
   20653             : }  // namespace v8

Generated by: LCOV version 1.10