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    10645108 : Handle<FieldType> Object::OptimalType(Isolate* isolate,
      97             :                                       Representation representation) {
      98    10645108 :   if (representation.IsNone()) return FieldType::None(isolate);
      99    10205414 :   if (FLAG_track_field_types) {
     100    15187492 :     if (representation.IsHeapObject() && IsHeapObject()) {
     101             :       // We can track only JavaScript objects with stable maps.
     102             :       Handle<Map> map(HeapObject::cast(this)->map(), isolate);
     103     8977477 :       if (map->is_stable() && map->IsJSReceiverMap()) {
     104     1602713 :         return FieldType::Class(map, isolate);
     105             :       }
     106             :     }
     107             :   }
     108     8602704 :   return FieldType::Any(isolate);
     109             : }
     110             : 
     111             : 
     112        8470 : MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
     113             :                                          Handle<Object> object,
     114             :                                          Handle<Context> native_context) {
     115        8470 :   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
     116             :   Handle<JSFunction> constructor;
     117        8470 :   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        7847 :     if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
     123        1956 :       THROW_NEW_ERROR(isolate,
     124             :                       NewTypeError(MessageTemplate::kUndefinedOrNullToObject),
     125             :                       JSReceiver);
     126             :     }
     127             :     constructor = handle(
     128             :         JSFunction::cast(native_context->get(constructor_function_index)),
     129        6869 :         isolate);
     130             :   }
     131        7492 :   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
     132        7492 :   Handle<JSValue>::cast(result)->set_value(*object);
     133             :   return result;
     134             : }
     135             : 
     136             : // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
     137             : // static
     138       51901 : MaybeHandle<JSReceiver> Object::ConvertReceiver(Isolate* isolate,
     139             :                                                 Handle<Object> object) {
     140       51901 :   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
     141        1124 :   if (*object == isolate->heap()->null_value() ||
     142             :       object->IsUndefined(isolate)) {
     143         313 :     return isolate->global_proxy();
     144             :   }
     145         249 :   return Object::ToObject(isolate, object);
     146             : }
     147             : 
     148             : // static
     149     3476001 : MaybeHandle<Object> Object::ConvertToNumber(Isolate* isolate,
     150             :                                             Handle<Object> input) {
     151             :   while (true) {
     152     3481935 :     if (input->IsNumber()) {
     153             :       return input;
     154             :     }
     155     3458133 :     if (input->IsString()) {
     156       91713 :       return String::ToNumber(Handle<String>::cast(input));
     157             :     }
     158     3366420 :     if (input->IsOddball()) {
     159     3354337 :       return Oddball::ToNumber(Handle<Oddball>::cast(input));
     160             :     }
     161       12083 :     if (input->IsSymbol()) {
     162       10966 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber),
     163             :                       Object);
     164             :     }
     165       13200 :     ASSIGN_RETURN_ON_EXCEPTION(
     166             :         isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
     167             :                                                 ToPrimitiveHint::kNumber),
     168             :         Object);
     169             :   }
     170             : }
     171             : 
     172             : // static
     173       29747 : MaybeHandle<Object> Object::ConvertToInteger(Isolate* isolate,
     174             :                                              Handle<Object> input) {
     175       59494 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ConvertToNumber(isolate, input),
     176             :                              Object);
     177       29393 :   if (input->IsSmi()) return input;
     178       27129 :   return isolate->factory()->NewNumber(DoubleToInteger(input->Number()));
     179             : }
     180             : 
     181             : // static
     182        1232 : MaybeHandle<Object> Object::ConvertToInt32(Isolate* isolate,
     183             :                                            Handle<Object> input) {
     184        2464 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ConvertToNumber(isolate, input),
     185             :                              Object);
     186        1143 :   if (input->IsSmi()) return input;
     187         401 :   return isolate->factory()->NewNumberFromInt(DoubleToInt32(input->Number()));
     188             : }
     189             : 
     190             : // static
     191      533104 : MaybeHandle<Object> Object::ConvertToUint32(Isolate* isolate,
     192             :                                             Handle<Object> input) {
     193     1066208 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ConvertToNumber(isolate, input),
     194             :                              Object);
     195      533075 :   if (input->IsSmi()) return handle(Smi::cast(*input)->ToUint32Smi(), isolate);
     196         363 :   return isolate->factory()->NewNumberFromUint(DoubleToUint32(input->Number()));
     197             : }
     198             : 
     199             : // static
     200     4574649 : MaybeHandle<Name> Object::ConvertToName(Isolate* isolate,
     201             :                                         Handle<Object> input) {
     202     9149298 :   ASSIGN_RETURN_ON_EXCEPTION(
     203             :       isolate, input, Object::ToPrimitive(input, ToPrimitiveHint::kString),
     204             :       Name);
     205     4574394 :   if (input->IsName()) return Handle<Name>::cast(input);
     206      136914 :   return ToString(isolate, input);
     207             : }
     208             : 
     209             : // ES6 7.1.14
     210             : // static
     211         744 : MaybeHandle<Object> Object::ConvertToPropertyKey(Isolate* isolate,
     212             :                                                  Handle<Object> value) {
     213             :   // 1. Let key be ToPrimitive(argument, hint String).
     214             :   MaybeHandle<Object> maybe_key =
     215         744 :       Object::ToPrimitive(value, ToPrimitiveHint::kString);
     216             :   // 2. ReturnIfAbrupt(key).
     217             :   Handle<Object> key;
     218         744 :   if (!maybe_key.ToHandle(&key)) return key;
     219             :   // 3. If Type(key) is Symbol, then return key.
     220         744 :   if (key->IsSymbol()) return key;
     221             :   // 4. Return ToString(key).
     222             :   // Extending spec'ed behavior, we'd be happy to return an element index.
     223         744 :   if (key->IsSmi()) return key;
     224         744 :   if (key->IsHeapNumber()) {
     225             :     uint32_t uint_value;
     226          43 :     if (value->ToArrayLength(&uint_value) &&
     227          14 :         uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) {
     228           0 :       return handle(Smi::FromInt(static_cast<int>(uint_value)), isolate);
     229             :     }
     230             :   }
     231        1488 :   return Object::ToString(isolate, key);
     232             : }
     233             : 
     234             : // static
     235     8540846 : MaybeHandle<String> Object::ConvertToString(Isolate* isolate,
     236             :                                             Handle<Object> input) {
     237             :   while (true) {
     238     8822312 :     if (input->IsOddball()) {
     239             :       return handle(Handle<Oddball>::cast(input)->to_string(), isolate);
     240             :     }
     241     6260573 :     if (input->IsNumber()) {
     242      424498 :       return isolate->factory()->NumberToString(input);
     243             :     }
     244     5836075 :     if (input->IsSymbol()) {
     245        6428 :       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToString),
     246             :                       String);
     247             :     }
     248    11665722 :     ASSIGN_RETURN_ON_EXCEPTION(
     249             :         isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
     250             :                                                 ToPrimitiveHint::kString),
     251             :         String);
     252             :     // The previous isString() check happened in Object::ToString and thus we
     253             :     // put it at the end of the loop in this helper.
     254     5815737 :     if (input->IsString()) {
     255             :       return Handle<String>::cast(input);
     256             :     }
     257             :   }
     258             : }
     259             : 
     260             : namespace {
     261             : 
     262       42082 : bool IsErrorObject(Isolate* isolate, Handle<Object> object) {
     263       42082 :   if (!object->IsJSReceiver()) return false;
     264             :   Handle<Symbol> symbol = isolate->factory()->stack_trace_symbol();
     265       42082 :   return JSReceiver::HasOwnProperty(Handle<JSReceiver>::cast(object), symbol)
     266       84164 :       .FromMaybe(false);
     267             : }
     268             : 
     269       37546 : Handle<String> AsStringOrEmpty(Isolate* isolate, Handle<Object> object) {
     270             :   return object->IsString() ? Handle<String>::cast(object)
     271       75092 :                             : isolate->factory()->empty_string();
     272             : }
     273             : 
     274        5095 : Handle<String> NoSideEffectsErrorToString(Isolate* isolate,
     275             :                                           Handle<Object> input) {
     276        5095 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
     277             : 
     278             :   Handle<Name> name_key = isolate->factory()->name_string();
     279        5095 :   Handle<Object> name = JSReceiver::GetDataProperty(receiver, name_key);
     280        5095 :   Handle<String> name_str = AsStringOrEmpty(isolate, name);
     281             : 
     282             :   Handle<Name> msg_key = isolate->factory()->message_string();
     283        5095 :   Handle<Object> msg = JSReceiver::GetDataProperty(receiver, msg_key);
     284        5095 :   Handle<String> msg_str = AsStringOrEmpty(isolate, msg);
     285             : 
     286        5095 :   if (name_str->length() == 0) return msg_str;
     287        5065 :   if (msg_str->length() == 0) return name_str;
     288             : 
     289        4924 :   IncrementalStringBuilder builder(isolate);
     290        4924 :   builder.AppendString(name_str);
     291             :   builder.AppendCString(": ");
     292        4924 :   builder.AppendString(msg_str);
     293             : 
     294        9848 :   return builder.Finish().ToHandleChecked();
     295             : }
     296             : 
     297             : }  // namespace
     298             : 
     299             : // static
     300     3697596 : Handle<String> Object::NoSideEffectsToString(Isolate* isolate,
     301             :                                              Handle<Object> input) {
     302     3697596 :   DisallowJavascriptExecution no_js(isolate);
     303             : 
     304     8919795 :   if (input->IsString() || input->IsNumber() || input->IsOddball()) {
     305     7306348 :     return Object::ToString(isolate, input).ToHandleChecked();
     306       44422 :   } else if (input->IsFunction()) {
     307             :     // -- F u n c t i o n
     308             :     Handle<String> fun_str;
     309         858 :     if (input->IsJSBoundFunction()) {
     310           0 :       fun_str = JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(input));
     311             :     } else {
     312             :       DCHECK(input->IsJSFunction());
     313         858 :       fun_str = JSFunction::ToString(Handle<JSFunction>::cast(input));
     314             :     }
     315             : 
     316         858 :     if (fun_str->length() > 128) {
     317          15 :       IncrementalStringBuilder builder(isolate);
     318          15 :       builder.AppendString(isolate->factory()->NewSubString(fun_str, 0, 111));
     319             :       builder.AppendCString("...<omitted>...");
     320             :       builder.AppendString(isolate->factory()->NewSubString(
     321          15 :           fun_str, fun_str->length() - 2, fun_str->length()));
     322             : 
     323          30 :       return builder.Finish().ToHandleChecked();
     324             :     }
     325         843 :     return fun_str;
     326       43564 :   } else if (input->IsSymbol()) {
     327             :     // -- S y m b o l
     328             :     Handle<Symbol> symbol = Handle<Symbol>::cast(input);
     329             : 
     330        1482 :     IncrementalStringBuilder builder(isolate);
     331             :     builder.AppendCString("Symbol(");
     332        1482 :     if (symbol->name()->IsString()) {
     333         838 :       builder.AppendString(handle(String::cast(symbol->name()), isolate));
     334             :     }
     335             :     builder.AppendCharacter(')');
     336             : 
     337        2964 :     return builder.Finish().ToHandleChecked();
     338       42082 :   } else if (input->IsJSReceiver()) {
     339             :     // -- J S R e c e i v e r
     340       42082 :     Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
     341             :     Handle<Object> to_string = JSReceiver::GetDataProperty(
     342       42082 :         receiver, isolate->factory()->toString_string());
     343             : 
     344      126246 :     if (IsErrorObject(isolate, input) ||
     345      116086 :         *to_string == *isolate->error_to_string()) {
     346             :       // When internally formatting error objects, use a side-effects-free
     347             :       // version of Error.prototype.toString independent of the actually
     348             :       // installed toString method.
     349       36835 :       return NoSideEffectsErrorToString(isolate, input);
     350       73974 :     } else if (*to_string == *isolate->object_to_string()) {
     351             :       Handle<Object> ctor = JSReceiver::GetDataProperty(
     352       27790 :           receiver, isolate->factory()->constructor_string());
     353       27790 :       if (ctor->IsFunction()) {
     354             :         Handle<String> ctor_name;
     355       27356 :         if (ctor->IsJSBoundFunction()) {
     356             :           ctor_name = JSBoundFunction::GetName(
     357             :                           isolate, Handle<JSBoundFunction>::cast(ctor))
     358           0 :                           .ToHandleChecked();
     359       27356 :         } else if (ctor->IsJSFunction()) {
     360             :           Handle<Object> ctor_name_obj =
     361       27356 :               JSFunction::GetName(isolate, Handle<JSFunction>::cast(ctor));
     362       27356 :           ctor_name = AsStringOrEmpty(isolate, ctor_name_obj);
     363             :         }
     364             : 
     365       27356 :         if (ctor_name->length() != 0) {
     366       26645 :           IncrementalStringBuilder builder(isolate);
     367             :           builder.AppendCString("#<");
     368       26645 :           builder.AppendString(ctor_name);
     369             :           builder.AppendCString(">");
     370             : 
     371       53290 :           return builder.Finish().ToHandleChecked();
     372             :         }
     373             :       }
     374             :     }
     375             :   }
     376             : 
     377             :   // At this point, input is either none of the above or a JSReceiver.
     378             : 
     379             :   Handle<JSReceiver> receiver;
     380       10342 :   if (input->IsJSReceiver()) {
     381             :     receiver = Handle<JSReceiver>::cast(input);
     382             :   } else {
     383             :     // This is the only case where Object::ToObject throws.
     384             :     DCHECK(!input->IsSmi());
     385             :     int constructor_function_index =
     386             :         Handle<HeapObject>::cast(input)->map()->GetConstructorFunctionIndex();
     387           0 :     if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
     388           0 :       return isolate->factory()->NewStringFromAsciiChecked("[object Unknown]");
     389             :     }
     390             : 
     391             :     receiver = Object::ToObject(isolate, input, isolate->native_context())
     392           0 :                    .ToHandleChecked();
     393             :   }
     394             : 
     395       10342 :   Handle<String> builtin_tag = handle(receiver->class_name(), isolate);
     396             :   Handle<Object> tag_obj = JSReceiver::GetDataProperty(
     397       10342 :       receiver, isolate->factory()->to_string_tag_symbol());
     398             :   Handle<String> tag =
     399       10342 :       tag_obj->IsString() ? Handle<String>::cast(tag_obj) : builtin_tag;
     400             : 
     401       10342 :   IncrementalStringBuilder builder(isolate);
     402             :   builder.AppendCString("[object ");
     403       10342 :   builder.AppendString(tag);
     404             :   builder.AppendCString("]");
     405             : 
     406       20684 :   return builder.Finish().ToHandleChecked();
     407             : }
     408             : 
     409             : // static
     410        1058 : MaybeHandle<Object> Object::ConvertToLength(Isolate* isolate,
     411             :                                             Handle<Object> input) {
     412        2116 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
     413         918 :   if (input->IsSmi()) {
     414         672 :     int value = std::max(Smi::cast(*input)->value(), 0);
     415             :     return handle(Smi::FromInt(value), isolate);
     416             :   }
     417         694 :   double len = DoubleToInteger(input->Number());
     418         694 :   if (len <= 0.0) {
     419             :     return handle(Smi::kZero, isolate);
     420         212 :   } else if (len >= kMaxSafeInteger) {
     421             :     len = kMaxSafeInteger;
     422             :   }
     423         212 :   return isolate->factory()->NewNumber(len);
     424             : }
     425             : 
     426             : // static
     427        5303 : MaybeHandle<Object> Object::ConvertToIndex(
     428             :     Isolate* isolate, Handle<Object> input,
     429             :     MessageTemplate::Template error_index) {
     430        5303 :   if (input->IsUndefined(isolate)) return handle(Smi::kZero, isolate);
     431        4932 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
     432        3224 :   if (input->IsSmi() && Smi::cast(*input)->value() >= 0) return input;
     433        2408 :   double len = DoubleToInteger(input->Number()) + 0.0;
     434        2408 :   auto js_len = isolate->factory()->NewNumber(len);
     435        2408 :   if (len < 0.0 || len > kMaxSafeInteger) {
     436        1400 :     THROW_NEW_ERROR(isolate, NewRangeError(error_index, js_len), Object);
     437             :   }
     438             :   return js_len;
     439             : }
     440             : 
     441     7187949 : bool Object::BooleanValue() {
     442     7738043 :   if (IsSmi()) return Smi::cast(this)->value() != 0;
     443             :   DCHECK(IsHeapObject());
     444             :   Isolate* isolate = HeapObject::cast(this)->GetIsolate();
     445     9283753 :   if (IsBoolean()) return IsTrue(isolate);
     446     3991961 :   if (IsNullOrUndefined(isolate)) return false;
     447     3857836 :   if (IsUndetectable()) return false;  // Undetectable object is false.
     448     4616538 :   if (IsString()) return String::cast(this)->length() != 0;
     449     3164224 :   if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue();
     450             :   return true;
     451             : }
     452             : 
     453             : 
     454             : namespace {
     455             : 
     456             : // TODO(bmeurer): Maybe we should introduce a marker interface Number,
     457             : // where we put all these methods at some point?
     458             : ComparisonResult NumberCompare(double x, double y) {
     459      222904 :   if (std::isnan(x) || std::isnan(y)) {
     460             :     return ComparisonResult::kUndefined;
     461       89080 :   } else if (x < y) {
     462             :     return ComparisonResult::kLessThan;
     463       51564 :   } else if (x > y) {
     464             :     return ComparisonResult::kGreaterThan;
     465             :   } else {
     466             :     return ComparisonResult::kEqual;
     467             :   }
     468             : }
     469             : 
     470             : 
     471             : bool NumberEquals(double x, double y) {
     472             :   // Must check explicitly for NaN's on Windows, but -0 works fine.
     473        6795 :   if (std::isnan(x)) return false;
     474        6658 :   if (std::isnan(y)) return false;
     475        6557 :   return x == y;
     476             : }
     477             : 
     478             : 
     479        6795 : bool NumberEquals(const Object* x, const Object* y) {
     480        6795 :   return NumberEquals(x->Number(), y->Number());
     481             : }
     482             : 
     483             : 
     484             : bool NumberEquals(Handle<Object> x, Handle<Object> y) {
     485        5146 :   return NumberEquals(*x, *y);
     486             : }
     487             : 
     488             : }  // namespace
     489             : 
     490             : 
     491             : // static
     492      224238 : Maybe<ComparisonResult> Object::Compare(Handle<Object> x, Handle<Object> y) {
     493             :   // ES6 section 7.2.11 Abstract Relational Comparison step 3 and 4.
     494      896736 :   if (!Object::ToPrimitive(x, ToPrimitiveHint::kNumber).ToHandle(&x) ||
     495      448260 :       !Object::ToPrimitive(y, ToPrimitiveHint::kNumber).ToHandle(&y)) {
     496             :     return Nothing<ComparisonResult>();
     497             :   }
     498      289120 :   if (x->IsString() && y->IsString()) {
     499             :     // ES6 section 7.2.11 Abstract Relational Comparison step 5.
     500             :     return Just(
     501         938 :         String::Compare(Handle<String>::cast(x), Handle<String>::cast(y)));
     502             :   }
     503             :   // ES6 section 7.2.11 Abstract Relational Comparison step 6.
     504      669048 :   if (!Object::ToNumber(x).ToHandle(&x) || !Object::ToNumber(y).ToHandle(&y)) {
     505             :     return Nothing<ComparisonResult>();
     506             :   }
     507             :   return Just(NumberCompare(x->Number(), y->Number()));
     508             : }
     509             : 
     510             : 
     511             : // static
     512      193235 : Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
     513             :   // This is the generic version of Abstract Equality Comparison; a version in
     514             :   // JavaScript land is available in the EqualStub and NotEqualStub. Whenever
     515             :   // you change something functionality wise in here, remember to update the
     516             :   // TurboFan code stubs as well.
     517             :   while (true) {
     518      193242 :     if (x->IsNumber()) {
     519        5070 :       if (y->IsNumber()) {
     520             :         return Just(NumberEquals(x, y));
     521         112 :       } else if (y->IsBoolean()) {
     522           0 :         return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
     523         112 :       } else if (y->IsString()) {
     524         112 :         return Just(NumberEquals(x, String::ToNumber(Handle<String>::cast(y))));
     525           0 :       } else if (y->IsJSReceiver()) {
     526           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     527           0 :                  .ToHandle(&y)) {
     528             :           return Nothing<bool>();
     529             :         }
     530             :       } else {
     531             :         return Just(false);
     532             :       }
     533      188172 :     } else if (x->IsString()) {
     534      168452 :       if (y->IsString()) {
     535             :         return Just(
     536      168376 :             String::Equals(Handle<String>::cast(x), Handle<String>::cast(y)));
     537          76 :       } else if (y->IsNumber()) {
     538          76 :         x = String::ToNumber(Handle<String>::cast(x));
     539             :         return Just(NumberEquals(x, y));
     540           0 :       } else if (y->IsBoolean()) {
     541           0 :         x = String::ToNumber(Handle<String>::cast(x));
     542           0 :         return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
     543           0 :       } else if (y->IsJSReceiver()) {
     544           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     545           0 :                  .ToHandle(&y)) {
     546             :           return Nothing<bool>();
     547             :         }
     548             :       } else {
     549             :         return Just(false);
     550             :       }
     551       19720 :     } else if (x->IsBoolean()) {
     552         700 :       if (y->IsOddball()) {
     553             :         return Just(x.is_identical_to(y));
     554           0 :       } else if (y->IsNumber()) {
     555           0 :         return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
     556           0 :       } else if (y->IsString()) {
     557           0 :         y = String::ToNumber(Handle<String>::cast(y));
     558           0 :         return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
     559           0 :       } else if (y->IsJSReceiver()) {
     560           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     561           0 :                  .ToHandle(&y)) {
     562             :           return Nothing<bool>();
     563             :         }
     564           0 :         x = Oddball::ToNumber(Handle<Oddball>::cast(x));
     565             :       } else {
     566             :         return Just(false);
     567             :       }
     568       19020 :     } else if (x->IsSymbol()) {
     569          63 :       if (y->IsSymbol()) {
     570             :         return Just(x.is_identical_to(y));
     571           0 :       } else if (y->IsJSReceiver()) {
     572           0 :         if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
     573           0 :                  .ToHandle(&y)) {
     574             :           return Nothing<bool>();
     575             :         }
     576             :       } else {
     577             :         return Just(false);
     578             :       }
     579       18957 :     } else if (x->IsJSReceiver()) {
     580       18835 :       if (y->IsJSReceiver()) {
     581             :         return Just(x.is_identical_to(y));
     582           7 :       } else if (y->IsUndetectable()) {
     583             :         return Just(x->IsUndetectable());
     584           7 :       } else if (y->IsBoolean()) {
     585           0 :         y = Oddball::ToNumber(Handle<Oddball>::cast(y));
     586           7 :       } else if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x))
     587          14 :                       .ToHandle(&x)) {
     588             :         return Nothing<bool>();
     589             :       }
     590             :     } else {
     591         244 :       return Just(x->IsUndetectable() && y->IsUndetectable());
     592             :     }
     593             :   }
     594             : }
     595             : 
     596             : 
     597       16129 : bool Object::StrictEquals(Object* that) {
     598       16129 :   if (this->IsNumber()) {
     599        2466 :     if (!that->IsNumber()) return false;
     600        1649 :     return NumberEquals(this, that);
     601       13663 :   } else if (this->IsString()) {
     602       12013 :     if (!that->IsString()) return false;
     603       11922 :     return String::cast(this)->Equals(String::cast(that));
     604             :   }
     605        1650 :   return this == that;
     606             : }
     607             : 
     608             : 
     609             : // static
     610       22073 : Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
     611       22073 :   if (object->IsNumber()) return isolate->factory()->number_string();
     612       21229 :   if (object->IsOddball()) return handle(Oddball::cast(*object)->type_of());
     613       19076 :   if (object->IsUndetectable()) {
     614             :     return isolate->factory()->undefined_string();
     615             :   }
     616       19076 :   if (object->IsString()) return isolate->factory()->string_string();
     617       17832 :   if (object->IsSymbol()) return isolate->factory()->symbol_string();
     618       17759 :   if (object->IsString()) return isolate->factory()->string_string();
     619       17759 :   if (object->IsCallable()) return isolate->factory()->function_string();
     620             :   return isolate->factory()->object_string();
     621             : }
     622             : 
     623             : 
     624             : // static
     625       43151 : MaybeHandle<Object> Object::Multiply(Isolate* isolate, Handle<Object> lhs,
     626             :                                      Handle<Object> rhs) {
     627       83324 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     628        6054 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     629        5410 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     630             :   }
     631       42829 :   return isolate->factory()->NewNumber(lhs->Number() * rhs->Number());
     632             : }
     633             : 
     634             : 
     635             : // static
     636       11590 : MaybeHandle<Object> Object::Divide(Isolate* isolate, Handle<Object> lhs,
     637             :                                    Handle<Object> rhs) {
     638       23121 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     639         172 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     640         160 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     641             :   }
     642       11584 :   return isolate->factory()->NewNumber(lhs->Number() / rhs->Number());
     643             : }
     644             : 
     645             : 
     646             : // static
     647        5190 : MaybeHandle<Object> Object::Modulus(Isolate* isolate, Handle<Object> lhs,
     648             :                                     Handle<Object> rhs) {
     649       10314 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     650         162 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     651         150 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     652             :   }
     653        5184 :   return isolate->factory()->NewNumber(modulo(lhs->Number(), rhs->Number()));
     654             : }
     655             : 
     656             : 
     657             : // static
     658      225776 : MaybeHandle<Object> Object::Add(Isolate* isolate, Handle<Object> lhs,
     659             :                                 Handle<Object> rhs) {
     660      403085 :   if (lhs->IsNumber() && rhs->IsNumber()) {
     661      172508 :     return isolate->factory()->NewNumber(lhs->Number() + rhs->Number());
     662       96724 :   } else if (lhs->IsString() && rhs->IsString()) {
     663             :     return isolate->factory()->NewConsString(Handle<String>::cast(lhs),
     664       73770 :                                              Handle<String>::cast(rhs));
     665             :   }
     666       32766 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToPrimitive(lhs), Object);
     667       27540 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToPrimitive(rhs), Object);
     668       19863 :   if (lhs->IsString() || rhs->IsString()) {
     669       23550 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToString(isolate, rhs),
     670             :                                Object);
     671       23538 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToString(isolate, lhs),
     672             :                                Object);
     673             :     return isolate->factory()->NewConsString(Handle<String>::cast(lhs),
     674       22578 :                                              Handle<String>::cast(rhs));
     675             :   }
     676        3978 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     677        3954 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     678        1497 :   return isolate->factory()->NewNumber(lhs->Number() + rhs->Number());
     679             : }
     680             : 
     681             : 
     682             : // static
     683       19304 : MaybeHandle<Object> Object::Subtract(Isolate* isolate, Handle<Object> lhs,
     684             :                                      Handle<Object> rhs) {
     685       38483 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     686         388 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     687         376 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     688             :   }
     689       19298 :   return isolate->factory()->NewNumber(lhs->Number() - rhs->Number());
     690             : }
     691             : 
     692             : 
     693             : // static
     694        9158 : MaybeHandle<Object> Object::ShiftLeft(Isolate* isolate, Handle<Object> lhs,
     695             :                                       Handle<Object> rhs) {
     696       18259 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     697         170 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     698         158 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     699             :   }
     700        9152 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs)
     701        9152 :                                               << (NumberToUint32(*rhs) & 0x1F));
     702             : }
     703             : 
     704             : 
     705             : // static
     706       20865 : MaybeHandle<Object> Object::ShiftRight(Isolate* isolate, Handle<Object> lhs,
     707             :                                        Handle<Object> rhs) {
     708       41658 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     709         238 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     710         226 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     711             :   }
     712       20859 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) >>
     713       20859 :                                               (NumberToUint32(*rhs) & 0x1F));
     714             : }
     715             : 
     716             : 
     717             : // static
     718       10299 : MaybeHandle<Object> Object::ShiftRightLogical(Isolate* isolate,
     719             :                                               Handle<Object> lhs,
     720             :                                               Handle<Object> rhs) {
     721       20473 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     722         320 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     723         308 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     724             :   }
     725       10293 :   return isolate->factory()->NewNumberFromUint(NumberToUint32(*lhs) >>
     726       10293 :                                                (NumberToUint32(*rhs) & 0x1F));
     727             : }
     728             : 
     729             : 
     730             : // static
     731       19582 : MaybeHandle<Object> Object::BitwiseAnd(Isolate* isolate, Handle<Object> lhs,
     732             :                                        Handle<Object> rhs) {
     733       38175 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     734        3682 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     735        3670 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     736             :   }
     737       19576 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) &
     738       19576 :                                               NumberToInt32(*rhs));
     739             : }
     740             : 
     741             : 
     742             : // static
     743       64022 : MaybeHandle<Object> Object::BitwiseOr(Isolate* isolate, Handle<Object> lhs,
     744             :                                       Handle<Object> rhs) {
     745      126575 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     746        4616 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     747        4552 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     748             :   }
     749       63990 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) |
     750       63990 :                                               NumberToInt32(*rhs));
     751             : }
     752             : 
     753             : 
     754             : // static
     755        8254 : MaybeHandle<Object> Object::BitwiseXor(Isolate* isolate, Handle<Object> lhs,
     756             :                                        Handle<Object> rhs) {
     757       16352 :   if (!lhs->IsNumber() || !rhs->IsNumber()) {
     758         398 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
     759         386 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
     760             :   }
     761        8248 :   return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) ^
     762        8248 :                                               NumberToInt32(*rhs));
     763             : }
     764             : 
     765             : // static
     766      178702 : MaybeHandle<Object> Object::OrdinaryHasInstance(Isolate* isolate,
     767             :                                                 Handle<Object> callable,
     768             :                                                 Handle<Object> object) {
     769             :   // The {callable} must have a [[Call]] internal method.
     770      178702 :   if (!callable->IsCallable()) return isolate->factory()->false_value();
     771             : 
     772             :   // Check if {callable} is a bound function, and if so retrieve its
     773             :   // [[BoundTargetFunction]] and use that instead of {callable}.
     774      178642 :   if (callable->IsJSBoundFunction()) {
     775             :     Handle<Object> bound_callable(
     776             :         Handle<JSBoundFunction>::cast(callable)->bound_target_function(),
     777             :         isolate);
     778         409 :     return Object::InstanceOf(isolate, object, bound_callable);
     779             :   }
     780             : 
     781             :   // If {object} is not a receiver, return false.
     782      178233 :   if (!object->IsJSReceiver()) return isolate->factory()->false_value();
     783             : 
     784             :   // Get the "prototype" of {callable}; raise an error if it's not a receiver.
     785             :   Handle<Object> prototype;
     786      333460 :   ASSIGN_RETURN_ON_EXCEPTION(
     787             :       isolate, prototype,
     788             :       Object::GetProperty(callable, isolate->factory()->prototype_string()),
     789             :       Object);
     790      166730 :   if (!prototype->IsJSReceiver()) {
     791      331042 :     THROW_NEW_ERROR(
     792             :         isolate,
     793             :         NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype),
     794             :         Object);
     795             :   }
     796             : 
     797             :   // Return whether or not {prototype} is in the prototype chain of {object}.
     798             :   Maybe<bool> result = JSReceiver::HasInPrototypeChain(
     799        1209 :       isolate, Handle<JSReceiver>::cast(object), prototype);
     800        1209 :   if (result.IsNothing()) return MaybeHandle<Object>();
     801        1159 :   return isolate->factory()->ToBoolean(result.FromJust());
     802             : }
     803             : 
     804             : // static
     805         493 : MaybeHandle<Object> Object::InstanceOf(Isolate* isolate, Handle<Object> object,
     806             :                                        Handle<Object> callable) {
     807             :   // The {callable} must be a receiver.
     808         493 :   if (!callable->IsJSReceiver()) {
     809           0 :     THROW_NEW_ERROR(isolate,
     810             :                     NewTypeError(MessageTemplate::kNonObjectInInstanceOfCheck),
     811             :                     Object);
     812             :   }
     813             : 
     814             :   // Lookup the @@hasInstance method on {callable}.
     815             :   Handle<Object> inst_of_handler;
     816         986 :   ASSIGN_RETURN_ON_EXCEPTION(
     817             :       isolate, inst_of_handler,
     818             :       JSReceiver::GetMethod(Handle<JSReceiver>::cast(callable),
     819             :                             isolate->factory()->has_instance_symbol()),
     820             :       Object);
     821         493 :   if (!inst_of_handler->IsUndefined(isolate)) {
     822             :     // Call the {inst_of_handler} on the {callable}.
     823             :     Handle<Object> result;
     824         972 :     ASSIGN_RETURN_ON_EXCEPTION(
     825             :         isolate, result,
     826             :         Execution::Call(isolate, inst_of_handler, callable, 1, &object),
     827             :         Object);
     828         479 :     return isolate->factory()->ToBoolean(result->BooleanValue());
     829             :   }
     830             : 
     831             :   // The {callable} must have a [[Call]] internal method.
     832           7 :   if (!callable->IsCallable()) {
     833          14 :     THROW_NEW_ERROR(
     834             :         isolate, NewTypeError(MessageTemplate::kNonCallableInInstanceOfCheck),
     835             :         Object);
     836             :   }
     837             : 
     838             :   // Fall back to OrdinaryHasInstance with {callable} and {object}.
     839             :   Handle<Object> result;
     840           0 :   ASSIGN_RETURN_ON_EXCEPTION(
     841             :       isolate, result,
     842             :       JSReceiver::OrdinaryHasInstance(isolate, callable, object), Object);
     843             :   return result;
     844             : }
     845             : 
     846     1792529 : Maybe<bool> Object::IsArray(Handle<Object> object) {
     847     1792529 :   if (object->IsJSArray()) return Just(true);
     848     1745587 :   if (object->IsJSProxy()) {
     849             :     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
     850             :     Isolate* isolate = proxy->GetIsolate();
     851        1689 :     if (proxy->IsRevoked()) {
     852             :       isolate->Throw(*isolate->factory()->NewTypeError(
     853             :           MessageTemplate::kProxyRevoked,
     854         252 :           isolate->factory()->NewStringFromAsciiChecked("IsArray")));
     855             :       return Nothing<bool>();
     856             :     }
     857        1605 :     return Object::IsArray(handle(proxy->target(), isolate));
     858             :   }
     859             :   return Just(false);
     860             : }
     861             : 
     862             : 
     863             : // static
     864    17847067 : MaybeHandle<Object> Object::GetMethod(Handle<JSReceiver> receiver,
     865             :                                       Handle<Name> name) {
     866             :   Handle<Object> func;
     867             :   Isolate* isolate = receiver->GetIsolate();
     868    35694134 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, func,
     869             :                              JSReceiver::GetProperty(receiver, name), Object);
     870    17804002 :   if (func->IsNullOrUndefined(isolate)) {
     871             :     return isolate->factory()->undefined_value();
     872             :   }
     873     1628224 :   if (!func->IsCallable()) {
     874         728 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kPropertyNotFunction,
     875             :                                           func, name, receiver),
     876             :                     Object);
     877             :   }
     878             :   return func;
     879             : }
     880             : 
     881             : namespace {
     882       26935 : MaybeHandle<FixedArray> CreateListFromArrayLikeFastPath(
     883             :     Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
     884       52159 :   if (element_types != ElementTypes::kAll || !object->IsJSArray()) {
     885             :     return MaybeHandle<FixedArray>();
     886             :   }
     887             :   Handle<JSArray> array = Handle<JSArray>::cast(object);
     888             :   uint32_t length;
     889        3166 :   if (!array->HasArrayPrototype(isolate) ||
     890        3113 :       !array->length()->ToUint32(&length) || !array->HasFastElements() ||
     891         444 :       !JSObject::PrototypeHasNoElements(isolate, *array)) {
     892             :     return MaybeHandle<FixedArray>();
     893             :   }
     894         360 :   return array->GetElementsAccessor()->CreateListFromArray(isolate, array);
     895             : }
     896             : }  // namespace
     897             : 
     898             : // static
     899       26935 : MaybeHandle<FixedArray> Object::CreateListFromArrayLike(
     900             :     Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
     901             :   // Fast-path for JS_ARRAY_TYPE.
     902             :   MaybeHandle<FixedArray> fast_result =
     903       26935 :       CreateListFromArrayLikeFastPath(isolate, object, element_types);
     904       26935 :   if (!fast_result.is_null()) return fast_result;
     905             :   // 1. ReturnIfAbrupt(object).
     906             :   // 2. (default elementTypes -- not applicable.)
     907             :   // 3. If Type(obj) is not Object, throw a TypeError exception.
     908       26575 :   if (!object->IsJSReceiver()) {
     909        1773 :     THROW_NEW_ERROR(isolate,
     910             :                     NewTypeError(MessageTemplate::kCalledOnNonObject,
     911             :                                  isolate->factory()->NewStringFromAsciiChecked(
     912             :                                      "CreateListFromArrayLike")),
     913             :                     FixedArray);
     914             :   }
     915             : 
     916             :   // 4. Let len be ? ToLength(? Get(obj, "length")).
     917             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
     918             :   Handle<Object> raw_length_number;
     919       51968 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, raw_length_number,
     920             :                              Object::GetLengthFromArrayLike(isolate, receiver),
     921             :                              FixedArray);
     922             :   uint32_t len;
     923       51842 :   if (!raw_length_number->ToUint32(&len) ||
     924       25914 :       len > static_cast<uint32_t>(FixedArray::kMaxLength)) {
     925          84 :     THROW_NEW_ERROR(isolate,
     926             :                     NewRangeError(MessageTemplate::kInvalidArrayLength),
     927             :                     FixedArray);
     928             :   }
     929             :   // 5. Let list be an empty List.
     930       25886 :   Handle<FixedArray> list = isolate->factory()->NewFixedArray(len);
     931             :   // 6. Let index be 0.
     932             :   // 7. Repeat while index < len:
     933    62455423 :   for (uint32_t index = 0; index < len; ++index) {
     934             :     // 7a. Let indexName be ToString(index).
     935             :     // 7b. Let next be ? Get(obj, indexName).
     936             :     Handle<Object> next;
     937   124859298 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, next,
     938             :                                JSReceiver::GetElement(isolate, receiver, index),
     939             :                                FixedArray);
     940    62429593 :     switch (element_types) {
     941             :       case ElementTypes::kAll:
     942             :         // Nothing to do.
     943             :         break;
     944             :       case ElementTypes::kStringAndSymbol: {
     945             :         // 7c. If Type(next) is not an element of elementTypes, throw a
     946             :         //     TypeError exception.
     947        4247 :         if (!next->IsName()) {
     948         112 :           THROW_NEW_ERROR(isolate,
     949             :                           NewTypeError(MessageTemplate::kNotPropertyName, next),
     950             :                           FixedArray);
     951             :         }
     952             :         // 7d. Append next as the last element of list.
     953             :         // Internalize on the fly so we can use pointer identity later.
     954        4191 :         next = isolate->factory()->InternalizeName(Handle<Name>::cast(next));
     955        4191 :         break;
     956             :       }
     957             :     }
     958   124859074 :     list->set(index, *next);
     959             :     // 7e. Set index to index + 1. (See loop header.)
     960             :   }
     961             :   // 8. Return list.
     962             :   return list;
     963             : }
     964             : 
     965             : 
     966             : // static
     967       62056 : MaybeHandle<Object> Object::GetLengthFromArrayLike(Isolate* isolate,
     968             :                                                    Handle<Object> object) {
     969             :   Handle<Object> val;
     970             :   Handle<Object> key = isolate->factory()->length_string();
     971      124112 :   ASSIGN_RETURN_ON_EXCEPTION(
     972             :       isolate, val, Runtime::GetObjectProperty(isolate, object, key), Object);
     973       61942 :   return Object::ToLength(isolate, val);
     974             : }
     975             : 
     976             : // static
     977   167034504 : Maybe<bool> JSReceiver::HasProperty(LookupIterator* it) {
     978   167005766 :   for (; it->IsFound(); it->Next()) {
     979    43856563 :     switch (it->state()) {
     980             :       case LookupIterator::NOT_FOUND:
     981             :       case LookupIterator::TRANSITION:
     982           0 :         UNREACHABLE();
     983             :       case LookupIterator::JSPROXY:
     984             :         return JSProxy::HasProperty(it->isolate(), it->GetHolder<JSProxy>(),
     985      136398 :                                     it->GetName());
     986             :       case LookupIterator::INTERCEPTOR: {
     987             :         Maybe<PropertyAttributes> result =
     988         246 :             JSObject::GetPropertyAttributesWithInterceptor(it);
     989         321 :         if (result.IsNothing()) return Nothing<bool>();
     990         246 :         if (result.FromJust() != ABSENT) return Just(true);
     991         171 :         break;
     992             :       }
     993             :       case LookupIterator::ACCESS_CHECK: {
     994       39338 :         if (it->HasAccess()) break;
     995             :         Maybe<PropertyAttributes> result =
     996          48 :             JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
     997          96 :         if (result.IsNothing()) return Nothing<bool>();
     998           0 :         return Just(result.FromJust() != ABSENT);
     999             :       }
    1000             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1001             :         // TypedArray out-of-bounds access.
    1002             :         return Just(false);
    1003             :       case LookupIterator::ACCESSOR:
    1004             :       case LookupIterator::DATA:
    1005             :         return Just(true);
    1006             :     }
    1007             :   }
    1008             :   return Just(false);
    1009             : }
    1010             : 
    1011             : 
    1012             : // static
    1013   418142626 : MaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
    1014   385462379 :   for (; it->IsFound(); it->Next()) {
    1015   159011712 :     switch (it->state()) {
    1016             :       case LookupIterator::NOT_FOUND:
    1017             :       case LookupIterator::TRANSITION:
    1018           0 :         UNREACHABLE();
    1019             :       case LookupIterator::JSPROXY: {
    1020             :         bool was_found;
    1021             :         MaybeHandle<Object> result =
    1022             :             JSProxy::GetProperty(it->isolate(), it->GetHolder<JSProxy>(),
    1023      436900 :                                  it->GetName(), it->GetReceiver(), &was_found);
    1024      218450 :         if (!was_found) it->NotFound();
    1025      218450 :         return result;
    1026             :       }
    1027             :       case LookupIterator::INTERCEPTOR: {
    1028             :         bool done;
    1029             :         Handle<Object> result;
    1030       13447 :         ASSIGN_RETURN_ON_EXCEPTION(
    1031             :             it->isolate(), result,
    1032             :             JSObject::GetPropertyWithInterceptor(it, &done), Object);
    1033        5102 :         if (done) return result;
    1034        1901 :         break;
    1035             :       }
    1036             :       case LookupIterator::ACCESS_CHECK:
    1037     1261949 :         if (it->HasAccess()) break;
    1038        1378 :         return JSObject::GetPropertyWithFailedAccessCheck(it);
    1039             :       case LookupIterator::ACCESSOR:
    1040    10149997 :         return GetPropertyWithAccessor(it);
    1041             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1042             :         return it->isolate()->factory()->undefined_value();
    1043             :       case LookupIterator::DATA:
    1044   147371417 :         return it->GetDataValue();
    1045             :     }
    1046             :   }
    1047             :   return it->isolate()->factory()->undefined_value();
    1048             : }
    1049             : 
    1050             : 
    1051             : // static
    1052      218450 : MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate,
    1053             :                                          Handle<JSProxy> proxy,
    1054             :                                          Handle<Name> name,
    1055             :                                          Handle<Object> receiver,
    1056             :                                          bool* was_found) {
    1057      218450 :   *was_found = true;
    1058             : 
    1059             :   DCHECK(!name->IsPrivate());
    1060      218450 :   STACK_CHECK(isolate, MaybeHandle<Object>());
    1061             :   Handle<Name> trap_name = isolate->factory()->get_string();
    1062             :   // 1. Assert: IsPropertyKey(P) is true.
    1063             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    1064             :   Handle<Object> handler(proxy->handler(), isolate);
    1065             :   // 3. If handler is null, throw a TypeError exception.
    1066             :   // 4. Assert: Type(handler) is Object.
    1067      218226 :   if (proxy->IsRevoked()) {
    1068         112 :     THROW_NEW_ERROR(isolate,
    1069             :                     NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
    1070             :                     Object);
    1071             :   }
    1072             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    1073             :   Handle<JSReceiver> target(proxy->target(), isolate);
    1074             :   // 6. Let trap be ? GetMethod(handler, "get").
    1075             :   Handle<Object> trap;
    1076      436340 :   ASSIGN_RETURN_ON_EXCEPTION(
    1077             :       isolate, trap,
    1078             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), Object);
    1079             :   // 7. If trap is undefined, then
    1080      176035 :   if (trap->IsUndefined(isolate)) {
    1081             :     // 7.a Return target.[[Get]](P, Receiver).
    1082             :     LookupIterator it =
    1083       99844 :         LookupIterator::PropertyOrElement(isolate, receiver, name, target);
    1084       99844 :     MaybeHandle<Object> result = Object::GetProperty(&it);
    1085      199688 :     *was_found = it.IsFound();
    1086       99844 :     return result;
    1087             :   }
    1088             :   // 8. Let trapResult be ? Call(trap, handler, «target, P, Receiver»).
    1089             :   Handle<Object> trap_result;
    1090       76191 :   Handle<Object> args[] = {target, name, receiver};
    1091      152382 :   ASSIGN_RETURN_ON_EXCEPTION(
    1092             :       isolate, trap_result,
    1093             :       Execution::Call(isolate, trap, handler, arraysize(args), args), Object);
    1094             :   // 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
    1095             :   PropertyDescriptor target_desc;
    1096             :   Maybe<bool> target_found =
    1097       73639 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    1098       73639 :   MAYBE_RETURN_NULL(target_found);
    1099             :   // 10. If targetDesc is not undefined, then
    1100       73639 :   if (target_found.FromJust()) {
    1101             :     // 10.a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is
    1102             :     //       false and targetDesc.[[Writable]] is false, then
    1103             :     // 10.a.i. If SameValue(trapResult, targetDesc.[[Value]]) is false,
    1104             :     //        throw a TypeError exception.
    1105        6800 :     bool inconsistent = PropertyDescriptor::IsDataDescriptor(&target_desc) &&
    1106        1043 :                         !target_desc.configurable() &&
    1107        6988 :                         !target_desc.writable() &&
    1108         132 :                         !trap_result->SameValue(*target_desc.value());
    1109        6856 :     if (inconsistent) {
    1110          84 :       THROW_NEW_ERROR(
    1111             :           isolate, NewTypeError(MessageTemplate::kProxyGetNonConfigurableData,
    1112             :                                 name, target_desc.value(), trap_result),
    1113             :           Object);
    1114             :     }
    1115             :     // 10.b. If IsAccessorDescriptor(targetDesc) and targetDesc.[[Configurable]]
    1116             :     //       is false and targetDesc.[[Get]] is undefined, then
    1117             :     // 10.b.i. If trapResult is not undefined, throw a TypeError exception.
    1118          56 :     inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
    1119          56 :                    !target_desc.configurable() &&
    1120        6842 :                    target_desc.get()->IsUndefined(isolate) &&
    1121             :                    !trap_result->IsUndefined(isolate);
    1122        6814 :     if (inconsistent) {
    1123          28 :       THROW_NEW_ERROR(
    1124             :           isolate,
    1125             :           NewTypeError(MessageTemplate::kProxyGetNonConfigurableAccessor, name,
    1126             :                        trap_result),
    1127             :           Object);
    1128             :     }
    1129             :   }
    1130             :   // 11. Return trap_result
    1131             :   return trap_result;
    1132             : }
    1133             : 
    1134             : 
    1135    14865541 : Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) {
    1136    14193804 :   for (; it->IsFound(); it->Next()) {
    1137     7056468 :     switch (it->state()) {
    1138             :       case LookupIterator::INTERCEPTOR:
    1139             :       case LookupIterator::NOT_FOUND:
    1140             :       case LookupIterator::TRANSITION:
    1141           0 :         UNREACHABLE();
    1142             :       case LookupIterator::ACCESS_CHECK:
    1143             :         // Support calling this method without an active context, but refuse
    1144             :         // access to access-checked objects in that case.
    1145      890515 :         if (it->isolate()->context() != nullptr && it->HasAccess()) continue;
    1146             :       // Fall through.
    1147             :       case LookupIterator::JSPROXY:
    1148             :         it->NotFound();
    1149        3209 :         return it->isolate()->factory()->undefined_value();
    1150             :       case LookupIterator::ACCESSOR:
    1151             :         // TODO(verwaest): For now this doesn't call into AccessorInfo, since
    1152             :         // clients don't need it. Update once relevant.
    1153             :         it->NotFound();
    1154      627697 :         return it->isolate()->factory()->undefined_value();
    1155             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1156           0 :         return it->isolate()->factory()->undefined_value();
    1157             :       case LookupIterator::DATA:
    1158     5535444 :         return it->GetDataValue();
    1159             :     }
    1160             :   }
    1161       40434 :   return it->isolate()->factory()->undefined_value();
    1162             : }
    1163             : 
    1164             : 
    1165    62558874 : bool Object::ToInt32(int32_t* value) {
    1166    62558874 :   if (IsSmi()) {
    1167    62557349 :     *value = Smi::cast(this)->value();
    1168    62557349 :     return true;
    1169             :   }
    1170        1525 :   if (IsHeapNumber()) {
    1171             :     double num = HeapNumber::cast(this)->value();
    1172        1476 :     if (FastI2D(FastD2I(num)) == num) {
    1173          77 :       *value = FastD2I(num);
    1174          77 :       return true;
    1175             :     }
    1176             :   }
    1177             :   return false;
    1178             : }
    1179             : 
    1180     3888974 : Handle<SharedFunctionInfo> FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(
    1181             :     Isolate* isolate, Handle<FunctionTemplateInfo> info) {
    1182             :   Object* current_info = info->shared_function_info();
    1183     3888974 :   if (current_info->IsSharedFunctionInfo()) {
    1184             :     return handle(SharedFunctionInfo::cast(current_info), isolate);
    1185             :   }
    1186             : 
    1187             :   Handle<Object> class_name(info->class_name(), isolate);
    1188             :   Handle<String> name = class_name->IsString()
    1189             :                             ? Handle<String>::cast(class_name)
    1190     7456101 :                             : isolate->factory()->empty_string();
    1191     3759365 :   Handle<Code> code = isolate->builtins()->HandleApiCall();
    1192     3759365 :   bool is_constructor = !info->remove_prototype();
    1193             :   Handle<SharedFunctionInfo> result =
    1194     7518730 :       isolate->factory()->NewSharedFunctionInfo(name, code, is_constructor);
    1195     3759364 :   if (is_constructor) {
    1196     7436484 :     result->SetConstructStub(*isolate->builtins()->JSConstructStubApi());
    1197             :   }
    1198             : 
    1199             :   result->set_length(info->length());
    1200     3821993 :   if (class_name->IsString()) result->set_instance_class_name(*class_name);
    1201             :   result->set_api_func_data(*info);
    1202             :   result->DontAdaptArguments();
    1203             :   DCHECK(result->IsApiFunction());
    1204             : 
    1205     3759364 :   info->set_shared_function_info(*result);
    1206     3759364 :   return result;
    1207             : }
    1208             : 
    1209       18277 : bool FunctionTemplateInfo::IsTemplateFor(Map* map) {
    1210             :   // There is a constraint on the object; check.
    1211       18277 :   if (!map->IsJSObjectMap()) return false;
    1212             :   // Fetch the constructor function of the object.
    1213       18277 :   Object* cons_obj = map->GetConstructor();
    1214             :   Object* type;
    1215       18277 :   if (cons_obj->IsJSFunction()) {
    1216             :     JSFunction* fun = JSFunction::cast(cons_obj);
    1217             :     type = fun->shared()->function_data();
    1218          18 :   } else if (cons_obj->IsFunctionTemplateInfo()) {
    1219             :     type = FunctionTemplateInfo::cast(cons_obj);
    1220             :   } else {
    1221             :     return false;
    1222             :   }
    1223             :   // Iterate through the chain of inheriting function templates to
    1224             :   // see if the required one occurs.
    1225       18878 :   while (type->IsFunctionTemplateInfo()) {
    1226       10914 :     if (type == this) return true;
    1227             :     type = FunctionTemplateInfo::cast(type)->parent_template();
    1228             :   }
    1229             :   // Didn't find the required type in the inheritance chain.
    1230             :   return false;
    1231             : }
    1232             : 
    1233             : 
    1234             : // static
    1235      379945 : Handle<TemplateList> TemplateList::New(Isolate* isolate, int size) {
    1236             :   Handle<FixedArray> list =
    1237      379945 :       isolate->factory()->NewFixedArray(kLengthIndex + size);
    1238             :   list->set(kLengthIndex, Smi::kZero);
    1239      379945 :   return Handle<TemplateList>::cast(list);
    1240             : }
    1241             : 
    1242             : // static
    1243     6570929 : Handle<TemplateList> TemplateList::Add(Isolate* isolate,
    1244             :                                        Handle<TemplateList> list,
    1245             :                                        Handle<i::Object> value) {
    1246             :   STATIC_ASSERT(kFirstElementIndex == 1);
    1247     6570929 :   int index = list->length() + 1;
    1248             :   Handle<i::FixedArray> fixed_array = Handle<FixedArray>::cast(list);
    1249     6570929 :   fixed_array = FixedArray::SetAndGrow(fixed_array, index, value);
    1250             :   fixed_array->set(kLengthIndex, Smi::FromInt(index));
    1251     6570929 :   return Handle<TemplateList>::cast(fixed_array);
    1252             : }
    1253             : 
    1254             : // static
    1255     2463601 : MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
    1256             :                                     Handle<JSReceiver> new_target,
    1257             :                                     Handle<AllocationSite> site) {
    1258             :   // If called through new, new.target can be:
    1259             :   // - a subclass of constructor,
    1260             :   // - a proxy wrapper around constructor, or
    1261             :   // - the constructor itself.
    1262             :   // If called through Reflect.construct, it's guaranteed to be a constructor.
    1263     4927112 :   Isolate* const isolate = constructor->GetIsolate();
    1264             :   DCHECK(constructor->IsConstructor());
    1265             :   DCHECK(new_target->IsConstructor());
    1266             :   DCHECK(!constructor->has_initial_map() ||
    1267             :          constructor->initial_map()->instance_type() != JS_FUNCTION_TYPE);
    1268             : 
    1269             :   Handle<Map> initial_map;
    1270     4927202 :   ASSIGN_RETURN_ON_EXCEPTION(
    1271             :       isolate, initial_map,
    1272             :       JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject);
    1273             :   Handle<JSObject> result =
    1274     2463556 :       isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site);
    1275     2463556 :   if (initial_map->is_dictionary_map()) {
    1276             :     Handle<NameDictionary> dictionary =
    1277           0 :         NameDictionary::New(isolate, NameDictionary::kInitialCapacity);
    1278           0 :     result->set_properties(*dictionary);
    1279             :   }
    1280     2463556 :   isolate->counters()->constructed_objects()->Increment();
    1281     2463556 :   isolate->counters()->constructed_objects_runtime()->Increment();
    1282             :   return result;
    1283             : }
    1284             : 
    1285     2495402 : void JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
    1286             :   DCHECK(object->HasFastSmiOrObjectElements() ||
    1287             :          object->HasFastStringWrapperElements());
    1288             :   FixedArray* raw_elems = FixedArray::cast(object->elements());
    1289     2495402 :   Heap* heap = object->GetHeap();
    1290     4965018 :   if (raw_elems->map() != heap->fixed_cow_array_map()) return;
    1291       25786 :   Isolate* isolate = heap->isolate();
    1292             :   Handle<FixedArray> elems(raw_elems, isolate);
    1293             :   Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap(
    1294       25786 :       elems, isolate->factory()->fixed_array_map());
    1295       25786 :   object->set_elements(*writable_elems);
    1296       25786 :   isolate->counters()->cow_arrays_converted()->Increment();
    1297             : }
    1298             : 
    1299             : 
    1300             : // ES6 9.5.1
    1301             : // static
    1302     5702696 : MaybeHandle<Object> JSProxy::GetPrototype(Handle<JSProxy> proxy) {
    1303             :   Isolate* isolate = proxy->GetIsolate();
    1304             :   Handle<String> trap_name = isolate->factory()->getPrototypeOf_string();
    1305             : 
    1306     5702696 :   STACK_CHECK(isolate, MaybeHandle<Object>());
    1307             : 
    1308             :   // 1. Let handler be the value of the [[ProxyHandler]] internal slot.
    1309             :   // 2. If handler is null, throw a TypeError exception.
    1310             :   // 3. Assert: Type(handler) is Object.
    1311             :   // 4. Let target be the value of the [[ProxyTarget]] internal slot.
    1312     5702696 :   if (proxy->IsRevoked()) {
    1313          56 :     THROW_NEW_ERROR(isolate,
    1314             :                     NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
    1315             :                     Object);
    1316             :   }
    1317             :   Handle<JSReceiver> target(proxy->target(), isolate);
    1318             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    1319             : 
    1320             :   // 5. Let trap be ? GetMethod(handler, "getPrototypeOf").
    1321             :   Handle<Object> trap;
    1322    11405336 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, trap, GetMethod(handler, trap_name),
    1323             :                              Object);
    1324             :   // 6. If trap is undefined, then return target.[[GetPrototypeOf]]().
    1325     5702668 :   if (trap->IsUndefined(isolate)) {
    1326     4202080 :     return JSReceiver::GetPrototype(isolate, target);
    1327             :   }
    1328             :   // 7. Let handlerProto be ? Call(trap, handler, «target»).
    1329             :   Handle<Object> argv[] = {target};
    1330             :   Handle<Object> handler_proto;
    1331     3001176 :   ASSIGN_RETURN_ON_EXCEPTION(
    1332             :       isolate, handler_proto,
    1333             :       Execution::Call(isolate, trap, handler, arraysize(argv), argv), Object);
    1334             :   // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError.
    1335     1500476 :   if (!(handler_proto->IsJSReceiver() || handler_proto->IsNull(isolate))) {
    1336          28 :     THROW_NEW_ERROR(isolate,
    1337             :                     NewTypeError(MessageTemplate::kProxyGetPrototypeOfInvalid),
    1338             :                     Object);
    1339             :   }
    1340             :   // 9. Let extensibleTarget be ? IsExtensible(target).
    1341     1500420 :   Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
    1342     1500420 :   MAYBE_RETURN_NULL(is_extensible);
    1343             :   // 10. If extensibleTarget is true, return handlerProto.
    1344     1500420 :   if (is_extensible.FromJust()) return handler_proto;
    1345             :   // 11. Let targetProto be ? target.[[GetPrototypeOf]]().
    1346             :   Handle<Object> target_proto;
    1347           0 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, target_proto,
    1348             :                              JSReceiver::GetPrototype(isolate, target), Object);
    1349             :   // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError.
    1350           0 :   if (!handler_proto->SameValue(*target_proto)) {
    1351           0 :     THROW_NEW_ERROR(
    1352             :         isolate,
    1353             :         NewTypeError(MessageTemplate::kProxyGetPrototypeOfNonExtensible),
    1354             :         Object);
    1355             :   }
    1356             :   // 13. Return handlerProto.
    1357             :   return handler_proto;
    1358             : }
    1359             : 
    1360    10150548 : MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
    1361             :   Isolate* isolate = it->isolate();
    1362    10150548 :   Handle<Object> structure = it->GetAccessors();
    1363             :   Handle<Object> receiver = it->GetReceiver();
    1364             : 
    1365             :   // We should never get here to initialize a const with the hole value since a
    1366             :   // const declaration would conflict with the getter.
    1367             :   DCHECK(!structure->IsForeign());
    1368             : 
    1369             :   // API style callbacks.
    1370    10150548 :   if (structure->IsAccessorInfo()) {
    1371             :     Handle<JSObject> holder = it->GetHolder<JSObject>();
    1372      884886 :     Handle<Name> name = it->GetName();
    1373             :     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
    1374      884886 :     if (!info->IsCompatibleReceiver(*receiver)) {
    1375         210 :       THROW_NEW_ERROR(isolate,
    1376             :                       NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
    1377             :                                    name, receiver),
    1378             :                       Object);
    1379             :     }
    1380             : 
    1381             :     v8::AccessorNameGetterCallback call_fun =
    1382             :         v8::ToCData<v8::AccessorNameGetterCallback>(info->getter());
    1383      884781 :     if (call_fun == nullptr) return isolate->factory()->undefined_value();
    1384             : 
    1385      898837 :     if (info->is_sloppy() && !receiver->IsJSReceiver()) {
    1386          36 :       ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
    1387             :                                  Object::ConvertReceiver(isolate, receiver),
    1388             :                                  Object);
    1389             :     }
    1390             : 
    1391             :     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
    1392             :                                    Object::DONT_THROW);
    1393      884641 :     Handle<Object> result = args.Call(call_fun, name);
    1394      884641 :     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1395      884406 :     if (result.is_null()) return isolate->factory()->undefined_value();
    1396             :     Handle<Object> reboxed_result = handle(*result, isolate);
    1397      877302 :     if (info->replace_on_access() && receiver->IsJSReceiver()) {
    1398             :       args.Call(reinterpret_cast<GenericNamedPropertySetterCallback>(
    1399             :                     &Accessors::ReconfigureToDataProperty),
    1400           0 :                 name, result);
    1401           0 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1402             :     }
    1403             :     return reboxed_result;
    1404             :   }
    1405             : 
    1406             :   // AccessorPair with 'cached' private property.
    1407     9265662 :   if (it->TryLookupCachedProperty()) {
    1408          58 :     return Object::GetProperty(it);
    1409             :   }
    1410             : 
    1411             :   // Regular accessor.
    1412             :   Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate);
    1413     9265604 :   if (getter->IsFunctionTemplateInfo()) {
    1414             :     return Builtins::InvokeApiFunction(
    1415             :         isolate, false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0,
    1416         313 :         nullptr, isolate->factory()->undefined_value());
    1417     9265291 :   } else if (getter->IsCallable()) {
    1418             :     // TODO(rossberg): nicer would be to cast to some JSCallable here...
    1419             :     return Object::GetPropertyWithDefinedGetter(
    1420     9256830 :         receiver, Handle<JSReceiver>::cast(getter));
    1421             :   }
    1422             :   // Getter is not a function.
    1423             :   return isolate->factory()->undefined_value();
    1424             : }
    1425             : 
    1426             : // static
    1427           0 : Address AccessorInfo::redirect(Isolate* isolate, Address address,
    1428             :                                AccessorComponent component) {
    1429             :   ApiFunction fun(address);
    1430             :   DCHECK_EQ(ACCESSOR_GETTER, component);
    1431             :   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
    1432      245420 :   return ExternalReference(&fun, type, isolate).address();
    1433             : }
    1434             : 
    1435      124109 : Address AccessorInfo::redirected_getter() const {
    1436             :   Address accessor = v8::ToCData<Address>(getter());
    1437      124109 :   if (accessor == nullptr) return nullptr;
    1438      122710 :   return redirect(GetIsolate(), accessor, ACCESSOR_GETTER);
    1439             : }
    1440             : 
    1441       39760 : bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate,
    1442             :                                            Handle<AccessorInfo> info,
    1443             :                                            Handle<Map> map) {
    1444       39760 :   if (!info->HasExpectedReceiverType()) return true;
    1445          72 :   if (!map->IsJSObjectMap()) return false;
    1446             :   return FunctionTemplateInfo::cast(info->expected_receiver_type())
    1447          72 :       ->IsTemplateFor(*map);
    1448             : }
    1449             : 
    1450     1979712 : Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
    1451             :                                             Handle<Object> value,
    1452             :                                             ShouldThrow should_throw) {
    1453             :   Isolate* isolate = it->isolate();
    1454     1979712 :   Handle<Object> structure = it->GetAccessors();
    1455             :   Handle<Object> receiver = it->GetReceiver();
    1456             : 
    1457             :   // We should never get here to initialize a const with the hole value since a
    1458             :   // const declaration would conflict with the setter.
    1459             :   DCHECK(!structure->IsForeign());
    1460             : 
    1461             :   // API style callbacks.
    1462     1979712 :   if (structure->IsAccessorInfo()) {
    1463             :     Handle<JSObject> holder = it->GetHolder<JSObject>();
    1464     1781742 :     Handle<Name> name = it->GetName();
    1465             :     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
    1466     1781743 :     if (!info->IsCompatibleReceiver(*receiver)) {
    1467             :       isolate->Throw(*isolate->factory()->NewTypeError(
    1468         210 :           MessageTemplate::kIncompatibleMethodReceiver, name, receiver));
    1469             :       return Nothing<bool>();
    1470             :     }
    1471             : 
    1472             :     // The actual type of call_fun is either v8::AccessorNameSetterCallback or
    1473             :     // i::Accesors::AccessorNameBooleanSetterCallback, depending on whether the
    1474             :     // AccessorInfo was created by the API or internally (see accessors.cc).
    1475             :     // Here we handle both cases using GenericNamedPropertySetterCallback and
    1476             :     // its Call method.
    1477             :     GenericNamedPropertySetterCallback call_fun =
    1478             :         v8::ToCData<GenericNamedPropertySetterCallback>(info->setter());
    1479             : 
    1480     1781637 :     if (call_fun == nullptr) {
    1481             :       // TODO(verwaest): We should not get here anymore once all AccessorInfos
    1482             :       // are marked as special_data_property. They cannot both be writable and
    1483             :       // not have a setter.
    1484             :       return Just(true);
    1485             :     }
    1486             : 
    1487     1922319 :     if (info->is_sloppy() && !receiver->IsJSReceiver()) {
    1488           0 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1489             :           isolate, receiver, Object::ConvertReceiver(isolate, receiver),
    1490             :           Nothing<bool>());
    1491             :     }
    1492             : 
    1493             :     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
    1494             :                                    should_throw);
    1495     1781560 :     Handle<Object> result = args.Call(call_fun, name, value);
    1496             :     // In the case of AccessorNameSetterCallback, we know that the result value
    1497             :     // cannot have been set, so the result of Call will be null.  In the case of
    1498             :     // AccessorNameBooleanSetterCallback, the result will either be null
    1499             :     // (signalling an exception) or a boolean Oddball.
    1500     1781560 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    1501     1781295 :     if (result.is_null()) return Just(true);
    1502             :     DCHECK(result->BooleanValue() || should_throw == DONT_THROW);
    1503     1640606 :     return Just(result->BooleanValue());
    1504             :   }
    1505             : 
    1506             :   // Regular accessor.
    1507             :   Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
    1508      197970 :   if (setter->IsFunctionTemplateInfo()) {
    1509         159 :     Handle<Object> argv[] = {value};
    1510         318 :     RETURN_ON_EXCEPTION_VALUE(
    1511             :         isolate, Builtins::InvokeApiFunction(
    1512             :                      isolate, false, Handle<FunctionTemplateInfo>::cast(setter),
    1513             :                      receiver, arraysize(argv), argv,
    1514             :                      isolate->factory()->undefined_value()),
    1515             :         Nothing<bool>());
    1516             :     return Just(true);
    1517      197811 :   } else if (setter->IsCallable()) {
    1518             :     // TODO(rossberg): nicer would be to cast to some JSCallable here...
    1519             :     return SetPropertyWithDefinedSetter(
    1520      179220 :         receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
    1521             :   }
    1522             : 
    1523       45750 :   RETURN_FAILURE(isolate, should_throw,
    1524             :                  NewTypeError(MessageTemplate::kNoSetterInCallback,
    1525             :                               it->GetName(), it->GetHolder<JSObject>()));
    1526             : }
    1527             : 
    1528             : 
    1529     9256830 : MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
    1530             :     Handle<Object> receiver,
    1531             :     Handle<JSReceiver> getter) {
    1532             :   Isolate* isolate = getter->GetIsolate();
    1533             : 
    1534             :   // Platforms with simulators like arm/arm64 expose a funny issue. If the
    1535             :   // simulator has a separate JS stack pointer from the C++ stack pointer, it
    1536             :   // can miss C++ stack overflows in the stack guard at the start of JavaScript
    1537             :   // functions. It would be very expensive to check the C++ stack pointer at
    1538             :   // that location. The best solution seems to be to break the impasse by
    1539             :   // adding checks at possible recursion points. What's more, we don't put
    1540             :   // this stack check behind the USE_SIMULATOR define in order to keep
    1541             :   // behavior the same between hardware and simulators.
    1542             :   StackLimitCheck check(isolate);
    1543     9256830 :   if (check.JsHasOverflowed()) {
    1544          28 :     isolate->StackOverflow();
    1545             :     return MaybeHandle<Object>();
    1546             :   }
    1547             : 
    1548     9256802 :   return Execution::Call(isolate, getter, receiver, 0, NULL);
    1549             : }
    1550             : 
    1551             : 
    1552      179220 : Maybe<bool> Object::SetPropertyWithDefinedSetter(Handle<Object> receiver,
    1553             :                                                  Handle<JSReceiver> setter,
    1554             :                                                  Handle<Object> value,
    1555             :                                                  ShouldThrow should_throw) {
    1556             :   Isolate* isolate = setter->GetIsolate();
    1557             : 
    1558      179220 :   Handle<Object> argv[] = { value };
    1559      358440 :   RETURN_ON_EXCEPTION_VALUE(isolate, Execution::Call(isolate, setter, receiver,
    1560             :                                                      arraysize(argv), argv),
    1561             :                             Nothing<bool>());
    1562             :   return Just(true);
    1563             : }
    1564             : 
    1565             : 
    1566             : // static
    1567        4210 : bool JSObject::AllCanRead(LookupIterator* it) {
    1568             :   // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
    1569             :   // which have already been checked.
    1570             :   DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
    1571             :          it->state() == LookupIterator::INTERCEPTOR);
    1572        5552 :   for (it->Next(); it->IsFound(); it->Next()) {
    1573        1429 :     if (it->state() == LookupIterator::ACCESSOR) {
    1574         146 :       auto accessors = it->GetAccessors();
    1575         146 :       if (accessors->IsAccessorInfo()) {
    1576          92 :         if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
    1577             :       }
    1578        1283 :     } else if (it->state() == LookupIterator::INTERCEPTOR) {
    1579        1472 :       if (it->GetInterceptor()->all_can_read()) return true;
    1580         547 :     } else if (it->state() == LookupIterator::JSPROXY) {
    1581             :       // Stop lookupiterating. And no, AllCanNotRead.
    1582             :       return false;
    1583             :     }
    1584             :   }
    1585             :   return false;
    1586             : }
    1587             : 
    1588             : namespace {
    1589             : 
    1590        5313 : MaybeHandle<Object> GetPropertyWithInterceptorInternal(
    1591       10598 :     LookupIterator* it, Handle<InterceptorInfo> interceptor, bool* done) {
    1592        5313 :   *done = false;
    1593             :   Isolate* isolate = it->isolate();
    1594             :   // Make sure that the top context does not change when doing callbacks or
    1595             :   // interceptor calls.
    1596             :   AssertNoContextChange ncc(isolate);
    1597             : 
    1598        5313 :   if (interceptor->getter()->IsUndefined(isolate)) {
    1599             :     return isolate->factory()->undefined_value();
    1600             :   }
    1601             : 
    1602             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1603             :   Handle<Object> result;
    1604             :   Handle<Object> receiver = it->GetReceiver();
    1605        5285 :   if (!receiver->IsJSReceiver()) {
    1606          38 :     ASSIGN_RETURN_ON_EXCEPTION(
    1607             :         isolate, receiver, Object::ConvertReceiver(isolate, receiver), Object);
    1608             :   }
    1609             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1610             :                                  *holder, Object::DONT_THROW);
    1611             : 
    1612        5285 :   if (it->IsElement()) {
    1613             :     uint32_t index = it->index();
    1614             :     v8::IndexedPropertyGetterCallback getter =
    1615             :         v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
    1616        2471 :     result = args.Call(getter, index);
    1617             :   } else {
    1618        2814 :     Handle<Name> name = it->name();
    1619             :     DCHECK(!name->IsPrivate());
    1620             : 
    1621             :     DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
    1622             : 
    1623             :     v8::GenericNamedPropertyGetterCallback getter =
    1624             :         v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
    1625             :             interceptor->getter());
    1626        2814 :     result = args.Call(getter, name);
    1627             :   }
    1628             : 
    1629        5285 :   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1630        5257 :   if (result.is_null()) return isolate->factory()->undefined_value();
    1631        3288 :   *done = true;
    1632             :   // Rebox handle before return
    1633             :   return handle(*result, isolate);
    1634             : }
    1635             : 
    1636      281223 : Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptorInternal(
    1637      562338 :     LookupIterator* it, Handle<InterceptorInfo> interceptor) {
    1638             :   Isolate* isolate = it->isolate();
    1639             :   // Make sure that the top context does not change when doing
    1640             :   // callbacks or interceptor calls.
    1641             :   AssertNoContextChange ncc(isolate);
    1642             :   HandleScope scope(isolate);
    1643             : 
    1644             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1645             :   DCHECK_IMPLIES(!it->IsElement() && it->name()->IsSymbol(),
    1646             :                  interceptor->can_intercept_symbols());
    1647             :   Handle<Object> receiver = it->GetReceiver();
    1648      281223 :   if (!receiver->IsJSReceiver()) {
    1649          28 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1650             :                                      Object::ConvertReceiver(isolate, receiver),
    1651             :                                      Nothing<PropertyAttributes>());
    1652             :   }
    1653             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1654             :                                  *holder, Object::DONT_THROW);
    1655      281223 :   if (!interceptor->query()->IsUndefined(isolate)) {
    1656             :     Handle<Object> result;
    1657         268 :     if (it->IsElement()) {
    1658             :       uint32_t index = it->index();
    1659             :       v8::IndexedPropertyQueryCallback query =
    1660             :           v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
    1661         102 :       result = args.Call(query, index);
    1662             :     } else {
    1663         166 :       Handle<Name> name = it->name();
    1664             :       DCHECK(!name->IsPrivate());
    1665             :       v8::GenericNamedPropertyQueryCallback query =
    1666             :           v8::ToCData<v8::GenericNamedPropertyQueryCallback>(
    1667             :               interceptor->query());
    1668         166 :       result = args.Call(query, name);
    1669             :     }
    1670         268 :     if (!result.is_null()) {
    1671             :       int32_t value;
    1672          62 :       CHECK(result->ToInt32(&value));
    1673          62 :       return Just(static_cast<PropertyAttributes>(value));
    1674             :     }
    1675      280955 :   } else if (!interceptor->getter()->IsUndefined(isolate)) {
    1676             :     // TODO(verwaest): Use GetPropertyWithInterceptor?
    1677             :     Handle<Object> result;
    1678      280847 :     if (it->IsElement()) {
    1679             :       uint32_t index = it->index();
    1680             :       v8::IndexedPropertyGetterCallback getter =
    1681             :           v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
    1682      280250 :       result = args.Call(getter, index);
    1683             :     } else {
    1684         597 :       Handle<Name> name = it->name();
    1685             :       DCHECK(!name->IsPrivate());
    1686             :       v8::GenericNamedPropertyGetterCallback getter =
    1687             :           v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
    1688             :               interceptor->getter());
    1689         597 :       result = args.Call(getter, name);
    1690             :     }
    1691      280847 :     if (!result.is_null()) return Just(DONT_ENUM);
    1692             :   }
    1693             : 
    1694      280682 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
    1695             :   return Just(ABSENT);
    1696             : }
    1697             : 
    1698      225683 : Maybe<bool> SetPropertyWithInterceptorInternal(
    1699      660931 :     LookupIterator* it, Handle<InterceptorInfo> interceptor,
    1700             :     Object::ShouldThrow should_throw, Handle<Object> value) {
    1701             :   Isolate* isolate = it->isolate();
    1702             :   // Make sure that the top context does not change when doing callbacks or
    1703             :   // interceptor calls.
    1704             :   AssertNoContextChange ncc(isolate);
    1705             : 
    1706      225683 :   if (interceptor->setter()->IsUndefined(isolate)) return Just(false);
    1707             : 
    1708             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1709             :   bool result;
    1710             :   Handle<Object> receiver = it->GetReceiver();
    1711      217624 :   if (!receiver->IsJSReceiver()) {
    1712           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1713             :                                      Object::ConvertReceiver(isolate, receiver),
    1714             :                                      Nothing<bool>());
    1715             :   }
    1716             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1717             :                                  *holder, should_throw);
    1718             : 
    1719      217624 :   if (it->IsElement()) {
    1720             :     uint32_t index = it->index();
    1721             :     v8::IndexedPropertySetterCallback setter =
    1722             :         v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
    1723             :     // TODO(neis): In the future, we may want to actually return the
    1724             :     // interceptor's result, which then should be a boolean.
    1725      153226 :     result = !args.Call(setter, index, value).is_null();
    1726             :   } else {
    1727      141011 :     Handle<Name> name = it->name();
    1728             :     DCHECK(!name->IsPrivate());
    1729             : 
    1730             :     DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
    1731             : 
    1732             :     v8::GenericNamedPropertySetterCallback setter =
    1733             :         v8::ToCData<v8::GenericNamedPropertySetterCallback>(
    1734             :             interceptor->setter());
    1735      282022 :     result = !args.Call(setter, name, value).is_null();
    1736             :   }
    1737             : 
    1738      217624 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    1739             :   return Just(result);
    1740             : }
    1741             : 
    1742         208 : Maybe<bool> DefinePropertyWithInterceptorInternal(
    1743         400 :     LookupIterator* it, Handle<InterceptorInfo> interceptor,
    1744             :     Object::ShouldThrow should_throw, PropertyDescriptor& desc) {
    1745             :   Isolate* isolate = it->isolate();
    1746             :   // Make sure that the top context does not change when doing callbacks or
    1747             :   // interceptor calls.
    1748             :   AssertNoContextChange ncc(isolate);
    1749             : 
    1750         208 :   if (interceptor->definer()->IsUndefined(isolate)) return Just(false);
    1751             : 
    1752             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1753             :   bool result;
    1754             :   Handle<Object> receiver = it->GetReceiver();
    1755          96 :   if (!receiver->IsJSReceiver()) {
    1756           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1757             :                                      Object::ConvertReceiver(isolate, receiver),
    1758             :                                      Nothing<bool>());
    1759             :   }
    1760             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1761             :                                  *holder, should_throw);
    1762             : 
    1763             :   std::unique_ptr<v8::PropertyDescriptor> descriptor(
    1764          96 :       new v8::PropertyDescriptor());
    1765          96 :   if (PropertyDescriptor::IsAccessorDescriptor(&desc)) {
    1766             :     descriptor.reset(new v8::PropertyDescriptor(
    1767          70 :         v8::Utils::ToLocal(desc.get()), v8::Utils::ToLocal(desc.set())));
    1768          61 :   } else if (PropertyDescriptor::IsDataDescriptor(&desc)) {
    1769          49 :     if (desc.has_writable()) {
    1770             :       descriptor.reset(new v8::PropertyDescriptor(
    1771          21 :           v8::Utils::ToLocal(desc.value()), desc.writable()));
    1772             :     } else {
    1773             :       descriptor.reset(
    1774          84 :           new v8::PropertyDescriptor(v8::Utils::ToLocal(desc.value())));
    1775             :     }
    1776             :   }
    1777          96 :   if (desc.has_enumerable()) {
    1778          14 :     descriptor->set_enumerable(desc.enumerable());
    1779             :   }
    1780          96 :   if (desc.has_configurable()) {
    1781          14 :     descriptor->set_configurable(desc.configurable());
    1782             :   }
    1783             : 
    1784          96 :   if (it->IsElement()) {
    1785             :     uint32_t index = it->index();
    1786             :     v8::IndexedPropertyDefinerCallback definer =
    1787             :         v8::ToCData<v8::IndexedPropertyDefinerCallback>(interceptor->definer());
    1788          54 :     result = !args.Call(definer, index, *descriptor).is_null();
    1789             :   } else {
    1790          69 :     Handle<Name> name = it->name();
    1791             :     DCHECK(!name->IsPrivate());
    1792             : 
    1793             :     DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
    1794             : 
    1795             :     v8::GenericNamedPropertyDefinerCallback definer =
    1796             :         v8::ToCData<v8::GenericNamedPropertyDefinerCallback>(
    1797             :             interceptor->definer());
    1798         138 :     result = !args.Call(definer, name, *descriptor).is_null();
    1799             :   }
    1800             : 
    1801          96 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    1802             :   return Just(result);
    1803             : }
    1804             : 
    1805             : }  // namespace
    1806             : 
    1807        1378 : MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
    1808        1463 :     LookupIterator* it) {
    1809             :   Isolate* isolate = it->isolate();
    1810        1378 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    1811             :   Handle<InterceptorInfo> interceptor =
    1812        1378 :       it->GetInterceptorForFailedAccessCheck();
    1813        1378 :   if (interceptor.is_null()) {
    1814        1229 :     while (AllCanRead(it)) {
    1815          55 :       if (it->state() == LookupIterator::ACCESSOR) {
    1816          62 :         return GetPropertyWithAccessor(it);
    1817             :       }
    1818             :       DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    1819             :       bool done;
    1820             :       Handle<Object> result;
    1821          72 :       ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
    1822             :                                  GetPropertyWithInterceptor(it, &done), Object);
    1823          36 :       if (done) return result;
    1824             :     }
    1825             : 
    1826             :   } else {
    1827             :     Handle<Object> result;
    1828             :     bool done;
    1829         399 :     ASSIGN_RETURN_ON_EXCEPTION(
    1830             :         isolate, result,
    1831             :         GetPropertyWithInterceptorInternal(it, interceptor, &done), Object);
    1832         147 :     if (done) return result;
    1833             :   }
    1834             : 
    1835             :   // Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns
    1836             :   // undefined.
    1837        1258 :   Handle<Name> name = it->GetName();
    1838        1294 :   if (name->IsSymbol() && Symbol::cast(*name)->is_well_known_symbol()) {
    1839             :     return it->factory()->undefined_value();
    1840             :   }
    1841             : 
    1842        1228 :   isolate->ReportFailedAccessCheck(checked);
    1843        1228 :   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    1844             :   return it->factory()->undefined_value();
    1845             : }
    1846             : 
    1847             : 
    1848         145 : Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
    1849         157 :     LookupIterator* it) {
    1850             :   Isolate* isolate = it->isolate();
    1851         145 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    1852             :   Handle<InterceptorInfo> interceptor =
    1853         145 :       it->GetInterceptorForFailedAccessCheck();
    1854         145 :   if (interceptor.is_null()) {
    1855         145 :     while (AllCanRead(it)) {
    1856          12 :       if (it->state() == LookupIterator::ACCESSOR) {
    1857             :         return Just(it->property_attributes());
    1858             :       }
    1859             :       DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    1860           0 :       auto result = GetPropertyAttributesWithInterceptor(it);
    1861           0 :       if (isolate->has_scheduled_exception()) break;
    1862           0 :       if (result.IsJust() && result.FromJust() != ABSENT) return result;
    1863             :     }
    1864             :   } else {
    1865             :     Maybe<PropertyAttributes> result =
    1866           0 :         GetPropertyAttributesWithInterceptorInternal(it, interceptor);
    1867           0 :     if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>();
    1868           0 :     if (result.FromMaybe(ABSENT) != ABSENT) return result;
    1869             :   }
    1870         133 :   isolate->ReportFailedAccessCheck(checked);
    1871         133 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
    1872             :   return Just(ABSENT);
    1873             : }
    1874             : 
    1875             : 
    1876             : // static
    1877         327 : bool JSObject::AllCanWrite(LookupIterator* it) {
    1878         464 :   for (; it->IsFound() && it->state() != LookupIterator::JSPROXY; it->Next()) {
    1879         149 :     if (it->state() == LookupIterator::ACCESSOR) {
    1880          30 :       Handle<Object> accessors = it->GetAccessors();
    1881          30 :       if (accessors->IsAccessorInfo()) {
    1882          18 :         if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
    1883             :       }
    1884             :     }
    1885             :   }
    1886             :   return false;
    1887             : }
    1888             : 
    1889             : 
    1890         137 : Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck(
    1891         137 :     LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) {
    1892             :   Isolate* isolate = it->isolate();
    1893         137 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    1894             :   Handle<InterceptorInfo> interceptor =
    1895         137 :       it->GetInterceptorForFailedAccessCheck();
    1896         137 :   if (interceptor.is_null()) {
    1897          95 :     if (AllCanWrite(it)) {
    1898          12 :       return SetPropertyWithAccessor(it, value, should_throw);
    1899             :     }
    1900             :   } else {
    1901             :     Maybe<bool> result = SetPropertyWithInterceptorInternal(
    1902          42 :         it, interceptor, should_throw, value);
    1903          84 :     if (isolate->has_pending_exception()) return Nothing<bool>();
    1904          28 :     if (result.IsJust()) return result;
    1905             :   }
    1906          83 :   isolate->ReportFailedAccessCheck(checked);
    1907          83 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    1908             :   return Just(true);
    1909             : }
    1910             : 
    1911             : 
    1912      406670 : void JSObject::SetNormalizedProperty(Handle<JSObject> object,
    1913             :                                      Handle<Name> name,
    1914             :                                      Handle<Object> value,
    1915             :                                      PropertyDetails details) {
    1916             :   DCHECK(!object->HasFastProperties());
    1917      406670 :   if (!name->IsUniqueName()) {
    1918             :     name = object->GetIsolate()->factory()->InternalizeString(
    1919           0 :         Handle<String>::cast(name));
    1920             :   }
    1921             : 
    1922      406670 :   if (object->IsJSGlobalObject()) {
    1923             :     Handle<GlobalDictionary> dictionary(object->global_dictionary());
    1924             : 
    1925        9729 :     int entry = dictionary->FindEntry(name);
    1926        9729 :     if (entry == GlobalDictionary::kNotFound) {
    1927             :       Isolate* isolate = object->GetIsolate();
    1928        1150 :       auto cell = isolate->factory()->NewPropertyCell();
    1929        1150 :       cell->set_value(*value);
    1930             :       auto cell_type = value->IsUndefined(isolate)
    1931             :                            ? PropertyCellType::kUndefined
    1932        1150 :                            : PropertyCellType::kConstant;
    1933             :       details = details.set_cell_type(cell_type);
    1934             :       value = cell;
    1935        1150 :       dictionary = GlobalDictionary::Add(dictionary, name, value, details);
    1936        1150 :       object->set_properties(*dictionary);
    1937             :     } else {
    1938             :       Handle<PropertyCell> cell =
    1939        8579 :           PropertyCell::PrepareForValue(dictionary, entry, value, details);
    1940        8579 :       cell->set_value(*value);
    1941             :     }
    1942             :   } else {
    1943             :     Handle<NameDictionary> dictionary(object->property_dictionary());
    1944             : 
    1945      396941 :     int entry = dictionary->FindEntry(name);
    1946      396941 :     if (entry == NameDictionary::kNotFound) {
    1947      146262 :       dictionary = NameDictionary::Add(dictionary, name, value, details);
    1948      146262 :       object->set_properties(*dictionary);
    1949             :     } else {
    1950             :       PropertyDetails original_details = dictionary->DetailsAt(entry);
    1951             :       int enumeration_index = original_details.dictionary_index();
    1952             :       DCHECK(enumeration_index > 0);
    1953             :       details = details.set_index(enumeration_index);
    1954             :       dictionary->SetEntry(entry, name, value, details);
    1955             :     }
    1956             :   }
    1957      406670 : }
    1958             : 
    1959             : // static
    1960        2619 : Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate,
    1961             :                                             Handle<JSReceiver> object,
    1962             :                                             Handle<Object> proto) {
    1963        2619 :   PrototypeIterator iter(isolate, object, kStartAtReceiver);
    1964             :   while (true) {
    1965     5804637 :     if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
    1966     5804468 :     if (iter.IsAtEnd()) return Just(false);
    1967     5803131 :     if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) {
    1968             :       return Just(true);
    1969             :     }
    1970             :   }
    1971             : }
    1972             : 
    1973             : namespace {
    1974             : 
    1975         686 : bool HasExcludedProperty(
    1976             :     const ScopedVector<Handle<Object>>* excluded_properties,
    1977             :     Handle<Object> search_element) {
    1978             :   // TODO(gsathya): Change this to be a hashtable.
    1979        2184 :   for (int i = 0; i < excluded_properties->length(); i++) {
    1980        1764 :     if (search_element->SameValue(*excluded_properties->at(i))) {
    1981             :       return true;
    1982             :     }
    1983             :   }
    1984             : 
    1985             :   return false;
    1986             : }
    1987             : 
    1988        1306 : MUST_USE_RESULT Maybe<bool> FastAssign(
    1989             :     Handle<JSReceiver> target, Handle<Object> source,
    1990             :     const ScopedVector<Handle<Object>>* excluded_properties, bool use_set) {
    1991             :   // Non-empty strings are the only non-JSReceivers that need to be handled
    1992             :   // explicitly by Object.assign.
    1993        1306 :   if (!source->IsJSReceiver()) {
    1994          70 :     return Just(!source->IsString() || String::cast(*source)->length() == 0);
    1995             :   }
    1996             : 
    1997             :   // If the target is deprecated, the object will be updated on first store. If
    1998             :   // the source for that store equals the target, this will invalidate the
    1999             :   // cached representation of the source. Preventively upgrade the target.
    2000             :   // Do this on each iteration since any property load could cause deprecation.
    2001        1264 :   if (target->map()->is_deprecated()) {
    2002          30 :     JSObject::MigrateInstance(Handle<JSObject>::cast(target));
    2003             :   }
    2004             : 
    2005             :   Isolate* isolate = target->GetIsolate();
    2006             :   Handle<Map> map(JSReceiver::cast(*source)->map(), isolate);
    2007             : 
    2008        1264 :   if (!map->IsJSObjectMap()) return Just(false);
    2009        1124 :   if (!map->OnlyHasSimpleProperties()) return Just(false);
    2010             : 
    2011             :   Handle<JSObject> from = Handle<JSObject>::cast(source);
    2012        1011 :   if (from->elements() != isolate->heap()->empty_fixed_array()) {
    2013             :     return Just(false);
    2014             :   }
    2015             : 
    2016             :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    2017             :   int length = map->NumberOfOwnDescriptors();
    2018             : 
    2019             :   bool stable = true;
    2020             : 
    2021        2071 :   for (int i = 0; i < length; i++) {
    2022             :     Handle<Name> next_key(descriptors->GetKey(i), isolate);
    2023             :     Handle<Object> prop_value;
    2024             :     // Directly decode from the descriptor array if |from| did not change shape.
    2025        1214 :     if (stable) {
    2026        1186 :       PropertyDetails details = descriptors->GetDetails(i);
    2027        1186 :       if (!details.IsEnumerable()) continue;
    2028        1068 :       if (details.kind() == kData) {
    2029        1068 :         if (details.location() == kDescriptor) {
    2030           0 :           prop_value = handle(descriptors->GetValue(i), isolate);
    2031             :         } else {
    2032        1068 :           Representation representation = details.representation();
    2033        1068 :           FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    2034        1068 :           prop_value = JSObject::FastPropertyAt(from, representation, index);
    2035             :         }
    2036             :       } else {
    2037           0 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2038             :             isolate, prop_value, JSReceiver::GetProperty(from, next_key),
    2039             :             Nothing<bool>());
    2040           0 :         stable = from->map() == *map;
    2041             :       }
    2042             :     } else {
    2043             :       // If the map did change, do a slower lookup. We are still guaranteed that
    2044             :       // the object has a simple shape, and that the key is a name.
    2045             :       LookupIterator it(from, next_key, from,
    2046          28 :                         LookupIterator::OWN_SKIP_INTERCEPTOR);
    2047          42 :       if (!it.IsFound()) continue;
    2048             :       DCHECK(it.state() == LookupIterator::DATA ||
    2049             :              it.state() == LookupIterator::ACCESSOR);
    2050          28 :       if (!it.IsEnumerable()) continue;
    2051          28 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2052             :           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
    2053             :     }
    2054             : 
    2055        1082 :     if (use_set) {
    2056         284 :       LookupIterator it(target, next_key, target);
    2057         284 :       bool call_to_js = it.IsFound() && it.state() != LookupIterator::DATA;
    2058             :       Maybe<bool> result = Object::SetProperty(
    2059         284 :           &it, prop_value, STRICT, Object::CERTAINLY_NOT_STORE_FROM_KEYED);
    2060         284 :       if (result.IsNothing()) return result;
    2061         284 :       if (stable && call_to_js) stable = from->map() == *map;
    2062             :     } else {
    2063        2394 :       if (excluded_properties != nullptr &&
    2064        1694 :           HasExcludedProperty(excluded_properties, next_key)) {
    2065         154 :         continue;
    2066             :       }
    2067             : 
    2068             :       // 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue).
    2069             :       bool success;
    2070             :       LookupIterator it = LookupIterator::PropertyOrElement(
    2071         644 :           isolate, target, next_key, &success, LookupIterator::OWN);
    2072         644 :       CHECK(success);
    2073        1288 :       CHECK(
    2074             :           JSObject::CreateDataProperty(&it, prop_value, Object::THROW_ON_ERROR)
    2075             :               .FromJust());
    2076             :     }
    2077             :   }
    2078             : 
    2079             :   return Just(true);
    2080             : }
    2081             : }  // namespace
    2082             : 
    2083             : // static
    2084        1306 : Maybe<bool> JSReceiver::SetOrCopyDataProperties(
    2085             :     Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
    2086             :     const ScopedVector<Handle<Object>>* excluded_properties, bool use_set) {
    2087             :   Maybe<bool> fast_assign =
    2088        1306 :       FastAssign(target, source, excluded_properties, use_set);
    2089        1306 :   if (fast_assign.IsNothing()) return Nothing<bool>();
    2090        1264 :   if (fast_assign.FromJust()) return Just(true);
    2091             : 
    2092         786 :   Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked();
    2093             :   // 3b. Let keys be ? from.[[OwnPropertyKeys]]().
    2094             :   Handle<FixedArray> keys;
    2095         786 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2096             :       isolate, keys,
    2097             :       KeyAccumulator::GetKeys(from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
    2098             :                               GetKeysConversion::kKeepNumbers),
    2099             :       Nothing<bool>());
    2100             : 
    2101             :   // 4. Repeat for each element nextKey of keys in List order,
    2102        1403 :   for (int j = 0; j < keys->length(); ++j) {
    2103             :     Handle<Object> next_key(keys->get(j), isolate);
    2104             :     // 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey).
    2105             :     PropertyDescriptor desc;
    2106             :     Maybe<bool> found =
    2107         589 :         JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc);
    2108         631 :     if (found.IsNothing()) return Nothing<bool>();
    2109             :     // 4a ii. If desc is not undefined and desc.[[Enumerable]] is true, then
    2110        1178 :     if (found.FromJust() && desc.enumerable()) {
    2111             :       // 4a ii 1. Let propValue be ? Get(from, nextKey).
    2112             :       Handle<Object> prop_value;
    2113        1108 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2114             :           isolate, prop_value,
    2115             :           Runtime::GetObjectProperty(isolate, from, next_key), Nothing<bool>());
    2116             : 
    2117         491 :       if (use_set) {
    2118             :         // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true).
    2119             :         Handle<Object> status;
    2120         310 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    2121             :             isolate, status, Runtime::SetObjectProperty(
    2122             :                                  isolate, target, next_key, prop_value, STRICT),
    2123             :             Nothing<bool>());
    2124             :       } else {
    2125         574 :         if (excluded_properties != nullptr &&
    2126         238 :             HasExcludedProperty(excluded_properties, next_key)) {
    2127         112 :           continue;
    2128             :         }
    2129             : 
    2130             :         // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue).
    2131             :         bool success;
    2132             :         LookupIterator it = LookupIterator::PropertyOrElement(
    2133         224 :             isolate, target, next_key, &success, LookupIterator::OWN);
    2134         224 :         CHECK(success);
    2135         448 :         CHECK(JSObject::CreateDataProperty(&it, prop_value,
    2136             :                                            Object::THROW_ON_ERROR)
    2137             :                   .FromJust());
    2138             :       }
    2139             :     }
    2140             :   }
    2141             : 
    2142             :   return Just(true);
    2143             : }
    2144             : 
    2145      280841 : Map* Object::GetPrototypeChainRootMap(Isolate* isolate) {
    2146             :   DisallowHeapAllocation no_alloc;
    2147      250652 :   if (IsSmi()) {
    2148             :     Context* native_context = isolate->context()->native_context();
    2149       30189 :     return native_context->number_function()->initial_map();
    2150             :   }
    2151             : 
    2152             :   // The object is either a number, a string, a symbol, a boolean, a real JS
    2153             :   // object, or a Harmony proxy.
    2154             :   HeapObject* heap_object = HeapObject::cast(this);
    2155      220463 :   return heap_object->map()->GetPrototypeChainRootMap(isolate);
    2156             : }
    2157             : 
    2158     9845703 : Map* Map::GetPrototypeChainRootMap(Isolate* isolate) {
    2159             :   DisallowHeapAllocation no_alloc;
    2160     9471641 :   if (IsJSReceiverMap()) {
    2161             :     return this;
    2162             :   }
    2163             :   int constructor_function_index = GetConstructorFunctionIndex();
    2164      374076 :   if (constructor_function_index != Map::kNoConstructorFunctionIndex) {
    2165             :     Context* native_context = isolate->context()->native_context();
    2166             :     JSFunction* constructor_function =
    2167             :         JSFunction::cast(native_context->get(constructor_function_index));
    2168      374062 :     return constructor_function->initial_map();
    2169             :   }
    2170          28 :   return isolate->heap()->null_value()->map();
    2171             : }
    2172             : 
    2173             : namespace {
    2174             : 
    2175             : // Returns a non-SMI for JSObjects, but returns the hash code for simple
    2176             : // objects.  This avoids a double lookup in the cases where we know we will
    2177             : // add the hash to the JSObject if it does not already exist.
    2178   107529362 : Object* GetSimpleHash(Object* object) {
    2179             :   // The object is either a Smi, a HeapNumber, a name, an odd-ball, a real JS
    2180             :   // object, or a Harmony proxy.
    2181   107529362 :   if (object->IsSmi()) {
    2182             :     uint32_t hash =
    2183     1079907 :         ComputeIntegerHash(Smi::cast(object)->value(), kZeroHashSeed);
    2184     2159814 :     return Smi::FromInt(hash & Smi::kMaxValue);
    2185             :   }
    2186   106449446 :   if (object->IsHeapNumber()) {
    2187             :     double num = HeapNumber::cast(object)->value();
    2188        8922 :     if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue);
    2189        8217 :     if (i::IsMinusZero(num)) num = 0;
    2190        8217 :     if (IsSmiDouble(num)) {
    2191         600 :       return Smi::FromInt(FastD2I(num))->GetHash();
    2192             :     }
    2193             :     uint32_t hash = ComputeLongHash(double_to_uint64(num));
    2194       15234 :     return Smi::FromInt(hash & Smi::kMaxValue);
    2195             :   }
    2196   106440497 :   if (object->IsName()) {
    2197             :     uint32_t hash = Name::cast(object)->Hash();
    2198   212831570 :     return Smi::FromInt(hash);
    2199             :   }
    2200       24711 :   if (object->IsOddball()) {
    2201             :     uint32_t hash = Oddball::cast(object)->to_string()->Hash();
    2202        4396 :     return Smi::FromInt(hash);
    2203             :   }
    2204             :   DCHECK(object->IsJSReceiver());
    2205             :   // Simply return the receiver as it is guaranteed to not be a SMI.
    2206             :   return object;
    2207             : }
    2208             : 
    2209             : }  // namespace
    2210             : 
    2211    12997029 : Object* Object::GetHash() {
    2212    12997029 :   Object* hash = GetSimpleHash(this);
    2213    12997029 :   if (hash->IsSmi()) return hash;
    2214             : 
    2215             :   DisallowHeapAllocation no_gc;
    2216             :   DCHECK(IsJSReceiver());
    2217             :   JSReceiver* receiver = JSReceiver::cast(this);
    2218             :   Isolate* isolate = receiver->GetIsolate();
    2219       16991 :   return JSReceiver::GetIdentityHash(isolate, handle(receiver, isolate));
    2220             : }
    2221             : 
    2222    94532376 : Smi* Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) {
    2223    94532376 :   Object* hash = GetSimpleHash(*object);
    2224    94532363 :   if (hash->IsSmi()) return Smi::cast(hash);
    2225             : 
    2226             :   DCHECK(object->IsJSReceiver());
    2227             :   return JSReceiver::GetOrCreateIdentityHash(isolate,
    2228        5522 :                                              Handle<JSReceiver>::cast(object));
    2229             : }
    2230             : 
    2231             : 
    2232     1905731 : bool Object::SameValue(Object* other) {
    2233     1905731 :   if (other == this) return true;
    2234             : 
    2235             :   // The object is either a number, a name, an odd-ball,
    2236             :   // a real JS object, or a Harmony proxy.
    2237     1582461 :   if (IsNumber() && other->IsNumber()) {
    2238             :     double this_value = Number();
    2239             :     double other_value = other->Number();
    2240             :     // SameValue(NaN, NaN) is true.
    2241       32466 :     if (this_value != other_value) {
    2242       29029 :       return std::isnan(this_value) && std::isnan(other_value);
    2243             :     }
    2244             :     // SameValue(0.0, -0.0) is false.
    2245        3437 :     return (std::signbit(this_value) == std::signbit(other_value));
    2246             :   }
    2247     2924237 :   if (IsString() && other->IsString()) {
    2248     1420101 :     return String::cast(this)->Equals(String::cast(other));
    2249             :   }
    2250             :   return false;
    2251             : }
    2252             : 
    2253             : 
    2254    50532831 : bool Object::SameValueZero(Object* other) {
    2255    50532831 :   if (other == this) return true;
    2256             : 
    2257             :   // The object is either a number, a name, an odd-ball,
    2258             :   // a real JS object, or a Harmony proxy.
    2259    50944557 :   if (IsNumber() && other->IsNumber()) {
    2260             :     double this_value = Number();
    2261             :     double other_value = other->Number();
    2262             :     // +0 == -0 is true
    2263      410323 :     return this_value == other_value ||
    2264          17 :            (std::isnan(this_value) && std::isnan(other_value));
    2265             :   }
    2266   100227673 :   if (IsString() && other->IsString()) {
    2267    50106467 :     return String::cast(this)->Equals(String::cast(other));
    2268             :   }
    2269             :   return false;
    2270             : }
    2271             : 
    2272             : 
    2273       71717 : MaybeHandle<Object> Object::ArraySpeciesConstructor(
    2274             :     Isolate* isolate, Handle<Object> original_array) {
    2275       71717 :   Handle<Object> default_species = isolate->array_function();
    2276      138366 :   if (original_array->IsJSArray() &&
    2277      203407 :       Handle<JSArray>::cast(original_array)->HasArrayPrototype(isolate) &&
    2278             :       isolate->IsArraySpeciesLookupChainIntact()) {
    2279             :     return default_species;
    2280             :   }
    2281             :   Handle<Object> constructor = isolate->factory()->undefined_value();
    2282        7541 :   Maybe<bool> is_array = Object::IsArray(original_array);
    2283        7541 :   MAYBE_RETURN_NULL(is_array);
    2284        7541 :   if (is_array.FromJust()) {
    2285        5088 :     ASSIGN_RETURN_ON_EXCEPTION(
    2286             :         isolate, constructor,
    2287             :         Object::GetProperty(original_array,
    2288             :                             isolate->factory()->constructor_string()),
    2289             :         Object);
    2290        2530 :     if (constructor->IsConstructor()) {
    2291             :       Handle<Context> constructor_context;
    2292        4572 :       ASSIGN_RETURN_ON_EXCEPTION(
    2293             :           isolate, constructor_context,
    2294             :           JSReceiver::GetFunctionRealm(Handle<JSReceiver>::cast(constructor)),
    2295             :           Object);
    2296        4600 :       if (*constructor_context != *isolate->native_context() &&
    2297             :           *constructor == constructor_context->array_function()) {
    2298             :         constructor = isolate->factory()->undefined_value();
    2299             :       }
    2300             :     }
    2301        2530 :     if (constructor->IsJSReceiver()) {
    2302        4516 :       ASSIGN_RETURN_ON_EXCEPTION(
    2303             :           isolate, constructor,
    2304             :           JSReceiver::GetProperty(Handle<JSReceiver>::cast(constructor),
    2305             :                                   isolate->factory()->species_symbol()),
    2306             :           Object);
    2307        2244 :       if (constructor->IsNull(isolate)) {
    2308             :         constructor = isolate->factory()->undefined_value();
    2309             :       }
    2310             :     }
    2311             :   }
    2312        7513 :   if (constructor->IsUndefined(isolate)) {
    2313             :     return default_species;
    2314             :   } else {
    2315        2200 :     if (!constructor->IsConstructor()) {
    2316           0 :       THROW_NEW_ERROR(isolate,
    2317             :           NewTypeError(MessageTemplate::kSpeciesNotConstructor),
    2318             :           Object);
    2319             :     }
    2320             :     return constructor;
    2321             :   }
    2322             : }
    2323             : 
    2324             : // ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
    2325       14360 : MUST_USE_RESULT MaybeHandle<Object> Object::SpeciesConstructor(
    2326             :     Isolate* isolate, Handle<JSReceiver> recv,
    2327             :     Handle<JSFunction> default_ctor) {
    2328             :   Handle<Object> ctor_obj;
    2329       28720 :   ASSIGN_RETURN_ON_EXCEPTION(
    2330             :       isolate, ctor_obj,
    2331             :       JSObject::GetProperty(recv, isolate->factory()->constructor_string()),
    2332             :       Object);
    2333             : 
    2334       14360 :   if (ctor_obj->IsUndefined(isolate)) return default_ctor;
    2335             : 
    2336       14346 :   if (!ctor_obj->IsJSReceiver()) {
    2337           0 :     THROW_NEW_ERROR(isolate,
    2338             :                     NewTypeError(MessageTemplate::kConstructorNotReceiver),
    2339             :                     Object);
    2340             :   }
    2341             : 
    2342       14346 :   Handle<JSReceiver> ctor = Handle<JSReceiver>::cast(ctor_obj);
    2343             : 
    2344             :   Handle<Object> species;
    2345       28692 :   ASSIGN_RETURN_ON_EXCEPTION(
    2346             :       isolate, species,
    2347             :       JSObject::GetProperty(ctor, isolate->factory()->species_symbol()),
    2348             :       Object);
    2349             : 
    2350       14346 :   if (species->IsNullOrUndefined(isolate)) {
    2351             :     return default_ctor;
    2352             :   }
    2353             : 
    2354       14346 :   if (species->IsConstructor()) return species;
    2355             : 
    2356           0 :   THROW_NEW_ERROR(
    2357             :       isolate, NewTypeError(MessageTemplate::kSpeciesNotConstructor), Object);
    2358             : }
    2359             : 
    2360       34034 : bool Object::IterationHasObservableEffects() {
    2361             :   // Check that this object is an array.
    2362       34034 :   if (!IsJSArray()) return true;
    2363             :   JSArray* array = JSArray::cast(this);
    2364             :   Isolate* isolate = array->GetIsolate();
    2365             : 
    2366             :   // Check that we have the original ArrayPrototype.
    2367       34034 :   if (!array->map()->prototype()->IsJSObject()) return true;
    2368             :   JSObject* array_proto = JSObject::cast(array->map()->prototype());
    2369       34019 :   if (!isolate->is_initial_array_prototype(array_proto)) return true;
    2370             : 
    2371             :   // Check that the ArrayPrototype hasn't been modified in a way that would
    2372             :   // affect iteration.
    2373       34019 :   if (!isolate->IsArrayIteratorLookupChainIntact()) return true;
    2374             : 
    2375             :   // Check that the map of the initial array iterator hasn't changed.
    2376       65010 :   Map* iterator_map = isolate->initial_array_iterator_prototype()->map();
    2377       32505 :   if (!isolate->is_initial_array_iterator_prototype_map(iterator_map)) {
    2378             :     return true;
    2379             :   }
    2380             : 
    2381             :   // For FastPacked kinds, iteration will have the same effect as simply
    2382             :   // accessing each property in order.
    2383             :   ElementsKind array_kind = array->GetElementsKind();
    2384       32505 :   if (IsFastPackedElementsKind(array_kind)) return false;
    2385             : 
    2386             :   // For FastHoley kinds, an element access on a hole would cause a lookup on
    2387             :   // the prototype. This could have different results if the prototype has been
    2388             :   // changed.
    2389       11760 :   if (IsFastHoleyElementsKind(array_kind) &&
    2390        5880 :       isolate->IsFastArrayConstructorPrototypeChainIntact()) {
    2391             :     return false;
    2392             :   }
    2393          80 :   return true;
    2394             : }
    2395             : 
    2396          14 : void Object::ShortPrint(FILE* out) {
    2397          14 :   OFStream os(out);
    2398          14 :   os << Brief(this);
    2399          14 : }
    2400             : 
    2401             : 
    2402         260 : void Object::ShortPrint(StringStream* accumulator) {
    2403         260 :   std::ostringstream os;
    2404         260 :   os << Brief(this);
    2405         520 :   accumulator->Add(os.str().c_str());
    2406         260 : }
    2407             : 
    2408             : 
    2409           0 : void Object::ShortPrint(std::ostream& os) { os << Brief(this); }
    2410             : 
    2411             : 
    2412        1714 : std::ostream& operator<<(std::ostream& os, const Brief& v) {
    2413        3428 :   if (v.value->IsSmi()) {
    2414             :     Smi::cast(v.value)->SmiPrint(os);
    2415             :   } else {
    2416             :     // TODO(svenpanne) Const-correct HeapObjectShortPrint!
    2417             :     HeapObject* obj = const_cast<HeapObject*>(HeapObject::cast(v.value));
    2418        1356 :     obj->HeapObjectShortPrint(os);
    2419             :   }
    2420        1714 :   return os;
    2421             : }
    2422             : 
    2423         189 : void Smi::SmiPrint(std::ostream& os) const {  // NOLINT
    2424         547 :   os << value();
    2425         189 : }
    2426             : 
    2427     6108049 : Handle<String> String::SlowFlatten(Handle<ConsString> cons,
    2428             :                                    PretenureFlag pretenure) {
    2429             :   DCHECK(cons->second()->length() != 0);
    2430             : 
    2431             :   // TurboFan can create cons strings with empty first parts.
    2432    12216111 :   while (cons->first()->length() == 0) {
    2433             :     // We do not want to call this function recursively. Therefore we call
    2434             :     // String::Flatten only in those cases where String::SlowFlatten is not
    2435             :     // called again.
    2436          60 :     if (cons->second()->IsConsString() && !cons->second()->IsFlat()) {
    2437             :       cons = handle(ConsString::cast(cons->second()));
    2438             :     } else {
    2439          34 :       return String::Flatten(handle(cons->second()));
    2440             :     }
    2441             :   }
    2442             : 
    2443             :   DCHECK(AllowHeapAllocation::IsAllowed());
    2444             :   Isolate* isolate = cons->GetIsolate();
    2445             :   int length = cons->length();
    2446             :   PretenureFlag tenure = isolate->heap()->InNewSpace(*cons) ? pretenure
    2447     6108015 :                                                             : TENURED;
    2448             :   Handle<SeqString> result;
    2449     6108015 :   if (cons->IsOneByteRepresentation()) {
    2450             :     Handle<SeqOneByteString> flat = isolate->factory()->NewRawOneByteString(
    2451    11743144 :         length, tenure).ToHandleChecked();
    2452             :     DisallowHeapAllocation no_gc;
    2453    11743144 :     WriteToFlat(*cons, flat->GetChars(), 0, length);
    2454             :     result = flat;
    2455             :   } else {
    2456             :     Handle<SeqTwoByteString> flat = isolate->factory()->NewRawTwoByteString(
    2457      472886 :         length, tenure).ToHandleChecked();
    2458             :     DisallowHeapAllocation no_gc;
    2459      472886 :     WriteToFlat(*cons, flat->GetChars(), 0, length);
    2460             :     result = flat;
    2461             :   }
    2462     6108015 :   cons->set_first(*result);
    2463    12216030 :   cons->set_second(isolate->heap()->empty_string());
    2464             :   DCHECK(result->IsFlat());
    2465     6108015 :   return result;
    2466             : }
    2467             : 
    2468             : 
    2469             : 
    2470         468 : bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
    2471             :   // Externalizing twice leaks the external resource, so it's
    2472             :   // prohibited by the API.
    2473             :   DCHECK(!this->IsExternalString());
    2474             :   DCHECK(!resource->IsCompressible());
    2475             : #ifdef ENABLE_SLOW_DCHECKS
    2476             :   if (FLAG_enable_slow_asserts) {
    2477             :     // Assert that the resource and the string are equivalent.
    2478             :     DCHECK(static_cast<size_t>(this->length()) == resource->length());
    2479             :     ScopedVector<uc16> smart_chars(this->length());
    2480             :     String::WriteToFlat(this, smart_chars.start(), 0, this->length());
    2481             :     DCHECK(memcmp(smart_chars.start(),
    2482             :                   resource->data(),
    2483             :                   resource->length() * sizeof(smart_chars[0])) == 0);
    2484             :   }
    2485             : #endif  // DEBUG
    2486         468 :   int size = this->Size();  // Byte size of the original string.
    2487             :   // Abort if size does not allow in-place conversion.
    2488         468 :   if (size < ExternalString::kShortSize) return false;
    2489         274 :   Heap* heap = GetHeap();
    2490             :   bool is_one_byte = this->IsOneByteRepresentation();
    2491             :   bool is_internalized = this->IsInternalizedString();
    2492             :   bool has_pointers = StringShape(this).IsIndirect();
    2493             : 
    2494             :   // Morph the string to an external string by replacing the map and
    2495             :   // reinitializing the fields.  This won't work if the space the existing
    2496             :   // string occupies is too small for a regular  external string.
    2497             :   // Instead, we resort to a short external string instead, omitting
    2498             :   // the field caching the address of the backing store.  When we encounter
    2499             :   // short external strings in generated code, we need to bailout to runtime.
    2500             :   Map* new_map;
    2501         468 :   if (size < ExternalString::kSize) {
    2502             :     new_map = is_internalized
    2503             :         ? (is_one_byte
    2504             :            ? heap->short_external_internalized_string_with_one_byte_data_map()
    2505             :            : heap->short_external_internalized_string_map())
    2506             :         : (is_one_byte ? heap->short_external_string_with_one_byte_data_map()
    2507         327 :                        : heap->short_external_string_map());
    2508             :   } else {
    2509             :     new_map = is_internalized
    2510             :         ? (is_one_byte
    2511             :            ? heap->external_internalized_string_with_one_byte_data_map()
    2512             :            : heap->external_internalized_string_map())
    2513             :         : (is_one_byte ? heap->external_string_with_one_byte_data_map()
    2514         543 :                        : heap->external_string_map());
    2515             :   }
    2516             : 
    2517             :   // Byte size of the external String object.
    2518         468 :   int new_size = this->SizeFromMap(new_map);
    2519         468 :   heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
    2520         936 :                              ClearRecordedSlots::kNo);
    2521         468 :   if (has_pointers) {
    2522          88 :     heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
    2523             :   }
    2524             : 
    2525             :   // We are storing the new map using release store after creating a filler for
    2526             :   // the left-over space to avoid races with the sweeper thread.
    2527         468 :   this->synchronized_set_map(new_map);
    2528             : 
    2529             :   ExternalTwoByteString* self = ExternalTwoByteString::cast(this);
    2530             :   self->set_resource(resource);
    2531         468 :   if (is_internalized) self->Hash();  // Force regeneration of the hash value.
    2532             : 
    2533         468 :   heap->AdjustLiveBytes(this, new_size - size);
    2534         468 :   return true;
    2535             : }
    2536             : 
    2537             : 
    2538         458 : bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
    2539             :   // Externalizing twice leaks the external resource, so it's
    2540             :   // prohibited by the API.
    2541             :   DCHECK(!this->IsExternalString());
    2542             :   DCHECK(!resource->IsCompressible());
    2543             : #ifdef ENABLE_SLOW_DCHECKS
    2544             :   if (FLAG_enable_slow_asserts) {
    2545             :     // Assert that the resource and the string are equivalent.
    2546             :     DCHECK(static_cast<size_t>(this->length()) == resource->length());
    2547             :     if (this->IsTwoByteRepresentation()) {
    2548             :       ScopedVector<uint16_t> smart_chars(this->length());
    2549             :       String::WriteToFlat(this, smart_chars.start(), 0, this->length());
    2550             :       DCHECK(String::IsOneByte(smart_chars.start(), this->length()));
    2551             :     }
    2552             :     ScopedVector<char> smart_chars(this->length());
    2553             :     String::WriteToFlat(this, smart_chars.start(), 0, this->length());
    2554             :     DCHECK(memcmp(smart_chars.start(),
    2555             :                   resource->data(),
    2556             :                   resource->length() * sizeof(smart_chars[0])) == 0);
    2557             :   }
    2558             : #endif  // DEBUG
    2559         458 :   int size = this->Size();  // Byte size of the original string.
    2560             :   // Abort if size does not allow in-place conversion.
    2561         458 :   if (size < ExternalString::kShortSize) return false;
    2562          52 :   Heap* heap = GetHeap();
    2563             :   bool is_internalized = this->IsInternalizedString();
    2564             :   bool has_pointers = StringShape(this).IsIndirect();
    2565             : 
    2566             :   // Morph the string to an external string by replacing the map and
    2567             :   // reinitializing the fields.  This won't work if the space the existing
    2568             :   // string occupies is too small for a regular  external string.
    2569             :   // Instead, we resort to a short external string instead, omitting
    2570             :   // the field caching the address of the backing store.  When we encounter
    2571             :   // short external strings in generated code, we need to bailout to runtime.
    2572             :   Map* new_map;
    2573         458 :   if (size < ExternalString::kSize) {
    2574             :     new_map = is_internalized
    2575             :                   ? heap->short_external_one_byte_internalized_string_map()
    2576          13 :                   : heap->short_external_one_byte_string_map();
    2577             :   } else {
    2578             :     new_map = is_internalized
    2579             :                   ? heap->external_one_byte_internalized_string_map()
    2580         445 :                   : heap->external_one_byte_string_map();
    2581             :   }
    2582             : 
    2583             :   // Byte size of the external String object.
    2584         458 :   int new_size = this->SizeFromMap(new_map);
    2585         458 :   heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
    2586         916 :                              ClearRecordedSlots::kNo);
    2587         458 :   if (has_pointers) {
    2588         396 :     heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
    2589             :   }
    2590             : 
    2591             :   // We are storing the new map using release store after creating a filler for
    2592             :   // the left-over space to avoid races with the sweeper thread.
    2593         458 :   this->synchronized_set_map(new_map);
    2594             : 
    2595             :   ExternalOneByteString* self = ExternalOneByteString::cast(this);
    2596             :   self->set_resource(resource);
    2597         458 :   if (is_internalized) self->Hash();  // Force regeneration of the hash value.
    2598             : 
    2599         458 :   heap->AdjustLiveBytes(this, new_size - size);
    2600         458 :   return true;
    2601             : }
    2602             : 
    2603          94 : void String::StringShortPrint(StringStream* accumulator, bool show_details) {
    2604             :   int len = length();
    2605          94 :   if (len > kMaxShortPrintLength) {
    2606           0 :     accumulator->Add("<Very long string[%u]>", len);
    2607           0 :     return;
    2608             :   }
    2609             : 
    2610          94 :   if (!LooksValid()) {
    2611           0 :     accumulator->Add("<Invalid String>");
    2612           0 :     return;
    2613             :   }
    2614             : 
    2615             :   StringCharacterStream stream(this);
    2616             : 
    2617             :   bool truncated = false;
    2618          94 :   if (len > kMaxShortPrintLength) {
    2619             :     len = kMaxShortPrintLength;
    2620             :     truncated = true;
    2621             :   }
    2622             :   bool one_byte = true;
    2623         782 :   for (int i = 0; i < len; i++) {
    2624         688 :     uint16_t c = stream.GetNext();
    2625             : 
    2626         688 :     if (c < 32 || c >= 127) {
    2627             :       one_byte = false;
    2628             :     }
    2629             :   }
    2630          94 :   stream.Reset(this);
    2631          94 :   if (one_byte) {
    2632         171 :     if (show_details) accumulator->Add("<String[%u]: ", length());
    2633         688 :     for (int i = 0; i < len; i++) {
    2634         688 :       accumulator->Put(static_cast<char>(stream.GetNext()));
    2635             :     }
    2636          94 :     if (show_details) accumulator->Put('>');
    2637             :   } else {
    2638             :     // Backslash indicates that the string contains control
    2639             :     // characters and that backslashes are therefore escaped.
    2640           0 :     if (show_details) accumulator->Add("<String[%u]\\: ", length());
    2641           0 :     for (int i = 0; i < len; i++) {
    2642           0 :       uint16_t c = stream.GetNext();
    2643           0 :       if (c == '\n') {
    2644           0 :         accumulator->Add("\\n");
    2645           0 :       } else if (c == '\r') {
    2646           0 :         accumulator->Add("\\r");
    2647           0 :       } else if (c == '\\') {
    2648           0 :         accumulator->Add("\\\\");
    2649           0 :       } else if (c < 32 || c > 126) {
    2650           0 :         accumulator->Add("\\x%02x", c);
    2651             :       } else {
    2652           0 :         accumulator->Put(static_cast<char>(c));
    2653             :       }
    2654             :     }
    2655           0 :     if (truncated) {
    2656           0 :       accumulator->Put('.');
    2657           0 :       accumulator->Put('.');
    2658           0 :       accumulator->Put('.');
    2659             :     }
    2660           0 :     if (show_details) accumulator->Put('>');
    2661             :   }
    2662             :   return;
    2663             : }
    2664             : 
    2665             : 
    2666          28 : void String::PrintUC16(std::ostream& os, int start, int end) {  // NOLINT
    2667          28 :   if (end < 0) end = length();
    2668             :   StringCharacterStream stream(this, start);
    2669         560 :   for (int i = start; i < end && stream.HasMore(); i++) {
    2670        1064 :     os << AsUC16(stream.GetNext());
    2671             :   }
    2672          28 : }
    2673             : 
    2674             : 
    2675         840 : void JSObject::JSObjectShortPrint(StringStream* accumulator) {
    2676         840 :   switch (map()->instance_type()) {
    2677             :     case JS_ARRAY_TYPE: {
    2678             :       double length = JSArray::cast(this)->length()->IsUndefined(GetIsolate())
    2679             :                           ? 0
    2680         201 :                           : JSArray::cast(this)->length()->Number();
    2681         201 :       accumulator->Add("<JSArray[%u]>", static_cast<uint32_t>(length));
    2682         201 :       break;
    2683             :     }
    2684             :     case JS_BOUND_FUNCTION_TYPE: {
    2685             :       JSBoundFunction* bound_function = JSBoundFunction::cast(this);
    2686           0 :       accumulator->Add("<JSBoundFunction");
    2687             :       accumulator->Add(
    2688             :           " (BoundTargetFunction %p)>",
    2689           0 :           reinterpret_cast<void*>(bound_function->bound_target_function()));
    2690           0 :       break;
    2691             :     }
    2692             :     case JS_WEAK_MAP_TYPE: {
    2693           0 :       accumulator->Add("<JSWeakMap>");
    2694           0 :       break;
    2695             :     }
    2696             :     case JS_WEAK_SET_TYPE: {
    2697           0 :       accumulator->Add("<JSWeakSet>");
    2698           0 :       break;
    2699             :     }
    2700             :     case JS_REGEXP_TYPE: {
    2701          30 :       accumulator->Add("<JSRegExp");
    2702             :       JSRegExp* regexp = JSRegExp::cast(this);
    2703          30 :       if (regexp->source()->IsString()) {
    2704          30 :         accumulator->Add(" ");
    2705          30 :         String::cast(regexp->source())->StringShortPrint(accumulator);
    2706             :       }
    2707          30 :       accumulator->Add(">");
    2708             : 
    2709          30 :       break;
    2710             :     }
    2711             :     case JS_FUNCTION_TYPE: {
    2712             :       JSFunction* function = JSFunction::cast(this);
    2713          73 :       Object* fun_name = function->shared()->DebugName();
    2714             :       bool printed = false;
    2715          73 :       if (fun_name->IsString()) {
    2716             :         String* str = String::cast(fun_name);
    2717          73 :         if (str->length() > 0) {
    2718          73 :           accumulator->Add("<JSFunction ");
    2719          73 :           accumulator->Put(str);
    2720             :           printed = true;
    2721             :         }
    2722             :       }
    2723          73 :       if (!printed) {
    2724           0 :         accumulator->Add("<JSFunction");
    2725             :       }
    2726          73 :       if (FLAG_trace_file_names) {
    2727             :         Object* source_name =
    2728             :             Script::cast(function->shared()->script())->name();
    2729           0 :         if (source_name->IsString()) {
    2730             :           String* str = String::cast(source_name);
    2731           0 :           if (str->length() > 0) {
    2732           0 :             accumulator->Add(" <");
    2733           0 :             accumulator->Put(str);
    2734           0 :             accumulator->Add(">");
    2735             :           }
    2736             :         }
    2737             :       }
    2738             :       accumulator->Add(" (sfi = %p)",
    2739          73 :                        reinterpret_cast<void*>(function->shared()));
    2740          73 :       accumulator->Put('>');
    2741          73 :       break;
    2742             :     }
    2743             :     case JS_GENERATOR_OBJECT_TYPE: {
    2744           0 :       accumulator->Add("<JSGenerator>");
    2745           0 :       break;
    2746             :     }
    2747             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE: {
    2748           0 :       accumulator->Add("<JS AsyncGenerator>");
    2749           0 :       break;
    2750             :     }
    2751             : 
    2752             :     // All other JSObjects are rather similar to each other (JSObject,
    2753             :     // JSGlobalProxy, JSGlobalObject, JSUndetectable, JSValue).
    2754             :     default: {
    2755             :       Map* map_of_this = map();
    2756             :       Heap* heap = GetHeap();
    2757         536 :       Object* constructor = map_of_this->GetConstructor();
    2758             :       bool printed = false;
    2759        1072 :       if (constructor->IsHeapObject() &&
    2760         536 :           !heap->Contains(HeapObject::cast(constructor))) {
    2761           0 :         accumulator->Add("!!!INVALID CONSTRUCTOR!!!");
    2762             :       } else {
    2763             :         bool global_object = IsJSGlobalProxy();
    2764         536 :         if (constructor->IsJSFunction()) {
    2765         536 :           if (!heap->Contains(JSFunction::cast(constructor)->shared())) {
    2766           0 :             accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!");
    2767             :           } else {
    2768             :             Object* constructor_name =
    2769             :                 JSFunction::cast(constructor)->shared()->name();
    2770         536 :             if (constructor_name->IsString()) {
    2771             :               String* str = String::cast(constructor_name);
    2772         536 :               if (str->length() > 0) {
    2773         472 :                 accumulator->Add(global_object ? "<GlobalObject " : "<");
    2774         472 :                 accumulator->Put(str);
    2775             :                 accumulator->Add(
    2776             :                     " %smap = %p",
    2777             :                     map_of_this->is_deprecated() ? "deprecated-" : "",
    2778         472 :                     map_of_this);
    2779             :                 printed = true;
    2780             :               }
    2781             :             }
    2782             :           }
    2783           0 :         } else if (constructor->IsFunctionTemplateInfo()) {
    2784           0 :           accumulator->Add(global_object ? "<RemoteObject>" : "<RemoteObject>");
    2785             :           printed = true;
    2786             :         }
    2787         536 :         if (!printed) {
    2788          64 :           accumulator->Add("<JS%sObject", global_object ? "Global " : "");
    2789             :         }
    2790             :       }
    2791         536 :       if (IsJSValue()) {
    2792          15 :         accumulator->Add(" value = ");
    2793          15 :         JSValue::cast(this)->value()->ShortPrint(accumulator);
    2794             :       }
    2795         536 :       accumulator->Put('>');
    2796         536 :       break;
    2797             :     }
    2798             :   }
    2799         840 : }
    2800             : 
    2801             : 
    2802           0 : void JSObject::PrintElementsTransition(
    2803             :     FILE* file, Handle<JSObject> object,
    2804             :     ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
    2805             :     ElementsKind to_kind, Handle<FixedArrayBase> to_elements) {
    2806           0 :   if (from_kind != to_kind) {
    2807           0 :     OFStream os(file);
    2808           0 :     os << "elements transition [" << ElementsKindToString(from_kind) << " -> "
    2809           0 :        << ElementsKindToString(to_kind) << "] in ";
    2810           0 :     JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true);
    2811           0 :     PrintF(file, " for ");
    2812           0 :     object->ShortPrint(file);
    2813           0 :     PrintF(file, " from ");
    2814           0 :     from_elements->ShortPrint(file);
    2815           0 :     PrintF(file, " to ");
    2816           0 :     to_elements->ShortPrint(file);
    2817           0 :     PrintF(file, "\n");
    2818             :   }
    2819           0 : }
    2820             : 
    2821             : 
    2822             : // static
    2823      213145 : MaybeHandle<JSFunction> Map::GetConstructorFunction(
    2824             :     Handle<Map> map, Handle<Context> native_context) {
    2825      213145 :   if (map->IsPrimitiveMap()) {
    2826             :     int const constructor_function_index = map->GetConstructorFunctionIndex();
    2827       36003 :     if (constructor_function_index != kNoConstructorFunctionIndex) {
    2828             :       return handle(
    2829             :           JSFunction::cast(native_context->get(constructor_function_index)));
    2830             :     }
    2831             :   }
    2832             :   return MaybeHandle<JSFunction>();
    2833             : }
    2834             : 
    2835             : 
    2836           0 : void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
    2837             :                                PropertyAttributes attributes) {
    2838           0 :   OFStream os(file);
    2839           0 :   os << "[reconfiguring]";
    2840             :   Name* name = instance_descriptors()->GetKey(modify_index);
    2841           0 :   if (name->IsString()) {
    2842           0 :     String::cast(name)->PrintOn(file);
    2843             :   } else {
    2844           0 :     os << "{symbol " << static_cast<void*>(name) << "}";
    2845             :   }
    2846           0 :   os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: ";
    2847           0 :   os << attributes << " [";
    2848           0 :   JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
    2849           0 :   os << "]\n";
    2850           0 : }
    2851             : 
    2852           0 : void Map::PrintGeneralization(
    2853             :     FILE* file, const char* reason, int modify_index, int split,
    2854             :     int descriptors, bool descriptor_to_field,
    2855             :     Representation old_representation, Representation new_representation,
    2856             :     MaybeHandle<FieldType> old_field_type, MaybeHandle<Object> old_value,
    2857             :     MaybeHandle<FieldType> new_field_type, MaybeHandle<Object> new_value) {
    2858           0 :   OFStream os(file);
    2859           0 :   os << "[generalizing]";
    2860             :   Name* name = instance_descriptors()->GetKey(modify_index);
    2861           0 :   if (name->IsString()) {
    2862           0 :     String::cast(name)->PrintOn(file);
    2863             :   } else {
    2864           0 :     os << "{symbol " << static_cast<void*>(name) << "}";
    2865             :   }
    2866           0 :   os << ":";
    2867           0 :   if (descriptor_to_field) {
    2868           0 :     os << "c";
    2869             :   } else {
    2870           0 :     os << old_representation.Mnemonic() << "{";
    2871           0 :     if (old_field_type.is_null()) {
    2872           0 :       os << Brief(*(old_value.ToHandleChecked()));
    2873             :     } else {
    2874           0 :       old_field_type.ToHandleChecked()->PrintTo(os);
    2875             :     }
    2876           0 :     os << "}";
    2877             :   }
    2878           0 :   os << "->" << new_representation.Mnemonic() << "{";
    2879           0 :   if (new_field_type.is_null()) {
    2880           0 :     os << Brief(*(new_value.ToHandleChecked()));
    2881             :   } else {
    2882           0 :     new_field_type.ToHandleChecked()->PrintTo(os);
    2883             :   }
    2884           0 :   os << "} (";
    2885           0 :   if (strlen(reason) > 0) {
    2886           0 :     os << reason;
    2887             :   } else {
    2888           0 :     os << "+" << (descriptors - split) << " maps";
    2889             :   }
    2890           0 :   os << ") [";
    2891           0 :   JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
    2892           0 :   os << "]\n";
    2893           0 : }
    2894             : 
    2895             : 
    2896           0 : void JSObject::PrintInstanceMigration(FILE* file,
    2897             :                                       Map* original_map,
    2898             :                                       Map* new_map) {
    2899           0 :   if (new_map->is_dictionary_map()) {
    2900           0 :     PrintF(file, "[migrating to slow]\n");
    2901           0 :     return;
    2902             :   }
    2903           0 :   PrintF(file, "[migrating]");
    2904             :   DescriptorArray* o = original_map->instance_descriptors();
    2905             :   DescriptorArray* n = new_map->instance_descriptors();
    2906           0 :   for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) {
    2907           0 :     Representation o_r = o->GetDetails(i).representation();
    2908           0 :     Representation n_r = n->GetDetails(i).representation();
    2909           0 :     if (!o_r.Equals(n_r)) {
    2910           0 :       String::cast(o->GetKey(i))->PrintOn(file);
    2911           0 :       PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic());
    2912           0 :     } else if (o->GetDetails(i).location() == kDescriptor &&
    2913           0 :                n->GetDetails(i).location() == kField) {
    2914             :       Name* name = o->GetKey(i);
    2915           0 :       if (name->IsString()) {
    2916           0 :         String::cast(name)->PrintOn(file);
    2917             :       } else {
    2918           0 :         PrintF(file, "{symbol %p}", static_cast<void*>(name));
    2919             :       }
    2920           0 :       PrintF(file, " ");
    2921             :     }
    2922             :   }
    2923           0 :   if (original_map->elements_kind() != new_map->elements_kind()) {
    2924             :     PrintF(file, "elements_kind[%i->%i]", original_map->elements_kind(),
    2925           0 :            new_map->elements_kind());
    2926             :   }
    2927           0 :   PrintF(file, "\n");
    2928             : }
    2929             : 
    2930             : 
    2931        1356 : void HeapObject::HeapObjectShortPrint(std::ostream& os) {  // NOLINT
    2932             :   Heap* heap = GetHeap();
    2933             :   Isolate* isolate = heap->isolate();
    2934        1356 :   if (!heap->Contains(this)) {
    2935           0 :     os << "!!!INVALID POINTER!!!";
    2936           0 :     return;
    2937             :   }
    2938        1356 :   if (!heap->Contains(map())) {
    2939           0 :     os << "!!!INVALID MAP!!!";
    2940           0 :     return;
    2941             :   }
    2942             : 
    2943        1356 :   os << this << " ";
    2944             : 
    2945        1356 :   if (IsString()) {
    2946             :     HeapStringAllocator allocator;
    2947             :     StringStream accumulator(&allocator);
    2948          47 :     String::cast(this)->StringShortPrint(&accumulator);
    2949         141 :     os << accumulator.ToCString().get();
    2950             :     return;
    2951             :   }
    2952        1309 :   if (IsJSObject()) {
    2953             :     HeapStringAllocator allocator;
    2954             :     StringStream accumulator(&allocator);
    2955         840 :     JSObject::cast(this)->JSObjectShortPrint(&accumulator);
    2956        2520 :     os << accumulator.ToCString().get();
    2957             :     return;
    2958             :   }
    2959         469 :   switch (map()->instance_type()) {
    2960             :     case MAP_TYPE:
    2961           0 :       os << "<Map(" << ElementsKindToString(Map::cast(this)->elements_kind())
    2962           0 :          << ")>";
    2963           0 :       break;
    2964             :     case FIXED_ARRAY_TYPE:
    2965           0 :       os << "<FixedArray[" << FixedArray::cast(this)->length() << "]>";
    2966           0 :       break;
    2967             :     case FIXED_DOUBLE_ARRAY_TYPE:
    2968           0 :       os << "<FixedDoubleArray[" << FixedDoubleArray::cast(this)->length()
    2969           0 :          << "]>";
    2970           0 :       break;
    2971             :     case BYTE_ARRAY_TYPE:
    2972           0 :       os << "<ByteArray[" << ByteArray::cast(this)->length() << "]>";
    2973           0 :       break;
    2974             :     case BYTECODE_ARRAY_TYPE:
    2975           0 :       os << "<BytecodeArray[" << BytecodeArray::cast(this)->length() << "]>";
    2976           0 :       break;
    2977             :     case TRANSITION_ARRAY_TYPE:
    2978           0 :       os << "<TransitionArray[" << TransitionArray::cast(this)->length()
    2979           0 :          << "]>";
    2980           0 :       break;
    2981             :     case FREE_SPACE_TYPE:
    2982           0 :       os << "<FreeSpace[" << FreeSpace::cast(this)->size() << "]>";
    2983           0 :       break;
    2984             : #define TYPED_ARRAY_SHORT_PRINT(Type, type, TYPE, ctype, size)                \
    2985             :   case FIXED_##TYPE##_ARRAY_TYPE:                                             \
    2986             :     os << "<Fixed" #Type "Array[" << Fixed##Type##Array::cast(this)->length() \
    2987             :        << "]>";                                                               \
    2988             :     break;
    2989             : 
    2990           0 :     TYPED_ARRAYS(TYPED_ARRAY_SHORT_PRINT)
    2991             : #undef TYPED_ARRAY_SHORT_PRINT
    2992             : 
    2993             :     case SHARED_FUNCTION_INFO_TYPE: {
    2994             :       SharedFunctionInfo* shared = SharedFunctionInfo::cast(this);
    2995           0 :       std::unique_ptr<char[]> debug_name = shared->DebugName()->ToCString();
    2996           0 :       if (debug_name[0] != 0) {
    2997           0 :         os << "<SharedFunctionInfo " << debug_name.get() << ">";
    2998             :       } else {
    2999           0 :         os << "<SharedFunctionInfo>";
    3000             :       }
    3001             :       break;
    3002             :     }
    3003             :     case JS_MESSAGE_OBJECT_TYPE:
    3004           0 :       os << "<JSMessageObject>";
    3005           0 :       break;
    3006             : #define MAKE_STRUCT_CASE(NAME, Name, name) \
    3007             :   case NAME##_TYPE:                        \
    3008             :     os << "<" #Name ">";                   \
    3009             :     break;
    3010           0 :   STRUCT_LIST(MAKE_STRUCT_CASE)
    3011             : #undef MAKE_STRUCT_CASE
    3012             :     case CODE_TYPE: {
    3013             :       Code* code = Code::cast(this);
    3014           0 :       os << "<Code " << Code::Kind2String(code->kind()) << ">";
    3015           0 :       break;
    3016             :     }
    3017             :     case ODDBALL_TYPE: {
    3018         122 :       if (IsUndefined(isolate)) {
    3019          75 :         os << "<undefined>";
    3020          47 :       } else if (IsTheHole(isolate)) {
    3021           0 :         os << "<the_hole>";
    3022          47 :       } else if (IsNull(isolate)) {
    3023          17 :         os << "<null>";
    3024          30 :       } else if (IsTrue(isolate)) {
    3025          15 :         os << "<true>";
    3026          15 :       } else if (IsFalse(isolate)) {
    3027          15 :         os << "<false>";
    3028             :       } else {
    3029           0 :         os << "<Odd Oddball: ";
    3030           0 :         os << Oddball::cast(this)->to_string()->ToCString().get();
    3031           0 :         os << ">";
    3032             :       }
    3033             :       break;
    3034             :     }
    3035             :     case SYMBOL_TYPE: {
    3036             :       Symbol* symbol = Symbol::cast(this);
    3037         227 :       symbol->SymbolShortPrint(os);
    3038         227 :       break;
    3039             :     }
    3040             :     case HEAP_NUMBER_TYPE: {
    3041         105 :       os << "<Number ";
    3042             :       HeapNumber::cast(this)->HeapNumberPrint(os);
    3043         105 :       os << ">";
    3044         105 :       break;
    3045             :     }
    3046             :     case MUTABLE_HEAP_NUMBER_TYPE: {
    3047           0 :       os << "<MutableNumber ";
    3048             :       HeapNumber::cast(this)->HeapNumberPrint(os);
    3049             :       os << '>';
    3050             :       break;
    3051             :     }
    3052             :     case JS_PROXY_TYPE:
    3053          15 :       os << "<JSProxy>";
    3054          15 :       break;
    3055             :     case FOREIGN_TYPE:
    3056           0 :       os << "<Foreign>";
    3057           0 :       break;
    3058             :     case CELL_TYPE: {
    3059           0 :       os << "<Cell value= ";
    3060             :       HeapStringAllocator allocator;
    3061             :       StringStream accumulator(&allocator);
    3062           0 :       Cell::cast(this)->value()->ShortPrint(&accumulator);
    3063           0 :       os << accumulator.ToCString().get();
    3064             :       os << '>';
    3065             :       break;
    3066             :     }
    3067             :     case PROPERTY_CELL_TYPE: {
    3068           0 :       os << "<PropertyCell value=";
    3069             :       HeapStringAllocator allocator;
    3070             :       StringStream accumulator(&allocator);
    3071             :       PropertyCell* cell = PropertyCell::cast(this);
    3072           0 :       cell->value()->ShortPrint(&accumulator);
    3073           0 :       os << accumulator.ToCString().get();
    3074             :       os << '>';
    3075             :       break;
    3076             :     }
    3077             :     case WEAK_CELL_TYPE: {
    3078           0 :       os << "<WeakCell value= ";
    3079             :       HeapStringAllocator allocator;
    3080             :       StringStream accumulator(&allocator);
    3081           0 :       WeakCell::cast(this)->value()->ShortPrint(&accumulator);
    3082           0 :       os << accumulator.ToCString().get();
    3083             :       os << '>';
    3084             :       break;
    3085             :     }
    3086             :     default:
    3087           0 :       os << "<Other heap object (" << map()->instance_type() << ")>";
    3088           0 :       break;
    3089             :   }
    3090             : }
    3091             : 
    3092             : 
    3093    33403765 : void HeapObject::Iterate(ObjectVisitor* v) { IterateFast<ObjectVisitor>(v); }
    3094             : 
    3095             : 
    3096         681 : void HeapObject::IterateBody(ObjectVisitor* v) {
    3097             :   Map* m = map();
    3098         681 :   IterateBodyFast<ObjectVisitor>(m->instance_type(), SizeFromMap(m), v);
    3099         681 : }
    3100             : 
    3101             : 
    3102    52411275 : void HeapObject::IterateBody(InstanceType type, int object_size,
    3103             :                              ObjectVisitor* v) {
    3104             :   IterateBodyFast<ObjectVisitor>(type, object_size, v);
    3105    52413359 : }
    3106             : 
    3107             : 
    3108             : struct CallIsValidSlot {
    3109             :   template <typename BodyDescriptor>
    3110             :   static bool apply(HeapObject* obj, int offset, int) {
    3111             :     return BodyDescriptor::IsValidSlot(obj, offset);
    3112             :   }
    3113             : };
    3114             : 
    3115             : 
    3116           0 : bool HeapObject::IsValidSlot(int offset) {
    3117             :   DCHECK_NE(0, offset);
    3118             :   return BodyDescriptorApply<CallIsValidSlot, bool>(map()->instance_type(),
    3119           0 :                                                     this, offset, 0);
    3120             : }
    3121             : 
    3122             : 
    3123           0 : bool HeapNumber::HeapNumberBooleanValue() {
    3124       65455 :   return DoubleToBoolean(value());
    3125             : }
    3126             : 
    3127             : 
    3128       16569 : void HeapNumber::HeapNumberPrint(std::ostream& os) {  // NOLINT
    3129             :   os << value();
    3130       16569 : }
    3131             : 
    3132             : 
    3133             : #define FIELD_ADDR_CONST(p, offset) \
    3134             :   (reinterpret_cast<const byte*>(p) + offset - kHeapObjectTag)
    3135             : 
    3136             : #define READ_INT32_FIELD(p, offset) \
    3137             :   (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset)))
    3138             : 
    3139             : #define READ_INT64_FIELD(p, offset) \
    3140             :   (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset)))
    3141             : 
    3142             : #define READ_BYTE_FIELD(p, offset) \
    3143             :   (*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset)))
    3144             : 
    3145    65530334 : String* JSReceiver::class_name() {
    3146    65530334 :   if (IsFunction()) {
    3147    31014906 :     return GetHeap()->Function_string();
    3148             :   }
    3149    34515428 :   Object* maybe_constructor = map()->GetConstructor();
    3150    34515428 :   if (maybe_constructor->IsJSFunction()) {
    3151             :     JSFunction* constructor = JSFunction::cast(maybe_constructor);
    3152    34515361 :     return String::cast(constructor->shared()->instance_class_name());
    3153          67 :   } else if (maybe_constructor->IsFunctionTemplateInfo()) {
    3154             :     FunctionTemplateInfo* info = FunctionTemplateInfo::cast(maybe_constructor);
    3155             :     return info->class_name()->IsString() ? String::cast(info->class_name())
    3156           1 :                                           : GetHeap()->empty_string();
    3157             :   }
    3158             : 
    3159             :   // If the constructor is not present, return "Object".
    3160          66 :   return GetHeap()->Object_string();
    3161             : }
    3162             : 
    3163             : 
    3164             : // static
    3165     7689049 : Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
    3166             :   Isolate* isolate = receiver->GetIsolate();
    3167             : 
    3168             :   // If the object was instantiated simply with base == new.target, the
    3169             :   // constructor on the map provides the most accurate name.
    3170             :   // Don't provide the info for prototypes, since their constructors are
    3171             :   // reclaimed and replaced by Object in OptimizeAsPrototype.
    3172    23066402 :   if (!receiver->IsJSProxy() && receiver->map()->new_target_is_base() &&
    3173             :       !receiver->map()->is_prototype_map()) {
    3174     7470957 :     Object* maybe_constructor = receiver->map()->GetConstructor();
    3175     7470957 :     if (maybe_constructor->IsJSFunction()) {
    3176             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
    3177             :       String* name = String::cast(constructor->shared()->name());
    3178     5035420 :       if (name->length() == 0) name = constructor->shared()->inferred_name();
    3179     9333199 :       if (name->length() != 0 &&
    3180     4297779 :           !name->Equals(isolate->heap()->Object_string())) {
    3181             :         return handle(name, isolate);
    3182             :       }
    3183     2435537 :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
    3184             :       FunctionTemplateInfo* info =
    3185             :           FunctionTemplateInfo::cast(maybe_constructor);
    3186           0 :       if (info->class_name()->IsString()) {
    3187             :         return handle(String::cast(info->class_name()), isolate);
    3188             :       }
    3189             :     }
    3190             :   }
    3191             : 
    3192             :   Handle<Object> maybe_tag = JSReceiver::GetDataProperty(
    3193     4363353 :       receiver, isolate->factory()->to_string_tag_symbol());
    3194     4363353 :   if (maybe_tag->IsString()) return Handle<String>::cast(maybe_tag);
    3195             : 
    3196     3648871 :   PrototypeIterator iter(isolate, receiver);
    3197     4272896 :   if (iter.IsAtEnd()) return handle(receiver->class_name());
    3198     3024846 :   Handle<JSReceiver> start = PrototypeIterator::GetCurrent<JSReceiver>(iter);
    3199             :   LookupIterator it(receiver, isolate->factory()->constructor_string(), start,
    3200     3024846 :                     LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
    3201     3024846 :   Handle<Object> maybe_constructor = JSReceiver::GetDataProperty(&it);
    3202             :   Handle<String> result = isolate->factory()->Object_string();
    3203     3024846 :   if (maybe_constructor->IsJSFunction()) {
    3204             :     JSFunction* constructor = JSFunction::cast(*maybe_constructor);
    3205             :     String* name = String::cast(constructor->shared()->name());
    3206     3024732 :     if (name->length() == 0) name = constructor->shared()->inferred_name();
    3207     3024732 :     if (name->length() > 0) result = handle(name, isolate);
    3208             :   }
    3209             : 
    3210             :   return result.is_identical_to(isolate->factory()->Object_string())
    3211      476079 :              ? handle(receiver->class_name())
    3212     5573613 :              : result;
    3213             : }
    3214             : 
    3215         491 : Handle<Context> JSReceiver::GetCreationContext() {
    3216             :   JSReceiver* receiver = this;
    3217         996 :   while (receiver->IsJSBoundFunction()) {
    3218             :     receiver = JSBoundFunction::cast(receiver)->bound_target_function();
    3219             :   }
    3220         491 :   Object* constructor = receiver->map()->GetConstructor();
    3221             :   JSFunction* function;
    3222         491 :   if (constructor->IsJSFunction()) {
    3223             :     function = JSFunction::cast(constructor);
    3224          14 :   } else if (constructor->IsFunctionTemplateInfo()) {
    3225             :     // Remote objects don't have a creation context.
    3226           2 :     return Handle<Context>::null();
    3227             :   } else {
    3228             :     // Functions have null as a constructor,
    3229             :     // but any JSFunction knows its context immediately.
    3230          12 :     CHECK(receiver->IsJSFunction());
    3231             :     function = JSFunction::cast(receiver);
    3232             :   }
    3233             : 
    3234         489 :   return function->has_context()
    3235             :              ? Handle<Context>(function->context()->native_context())
    3236         489 :              : Handle<Context>::null();
    3237             : }
    3238             : 
    3239     9704147 : Handle<Object> Map::WrapFieldType(Handle<FieldType> type) {
    3240    10964109 :   if (type->IsClass()) return Map::WeakCellForMap(type->AsClass());
    3241     8444186 :   return type;
    3242             : }
    3243             : 
    3244    67458763 : FieldType* Map::UnwrapFieldType(Object* wrapped_type) {
    3245             :   Object* value = wrapped_type;
    3246    67458763 :   if (value->IsWeakCell()) {
    3247     9716587 :     if (WeakCell::cast(value)->cleared()) return FieldType::None();
    3248             :     value = WeakCell::cast(value)->value();
    3249             :   }
    3250    67458649 :   return FieldType::cast(value);
    3251             : }
    3252             : 
    3253     8779738 : MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, Handle<Name> name,
    3254             :                                     Handle<FieldType> type,
    3255             :                                     PropertyAttributes attributes,
    3256             :                                     PropertyConstness constness,
    3257             :                                     Representation representation,
    3258             :                                     TransitionFlag flag) {
    3259             :   DCHECK(DescriptorArray::kNotFound ==
    3260             :          map->instance_descriptors()->Search(
    3261             :              *name, map->NumberOfOwnDescriptors()));
    3262             : 
    3263             :   // Ensure the descriptor array does not get too big.
    3264     8779738 :   if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
    3265             :     return MaybeHandle<Map>();
    3266             :   }
    3267             : 
    3268             :   Isolate* isolate = map->GetIsolate();
    3269             : 
    3270             :   // Compute the new index for new field.
    3271     8779621 :   int index = map->NextFreePropertyIndex();
    3272             : 
    3273     8779623 :   if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) {
    3274        4197 :     representation = Representation::Tagged();
    3275        4197 :     type = FieldType::Any(isolate);
    3276             :   }
    3277             : 
    3278     8779623 :   Handle<Object> wrapped_type(WrapFieldType(type));
    3279             : 
    3280             :   DCHECK_IMPLIES(!FLAG_track_constant_fields, constness == kMutable);
    3281             :   Descriptor d = Descriptor::DataField(name, index, attributes, constness,
    3282     8779623 :                                        representation, wrapped_type);
    3283     8779623 :   Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag);
    3284     8779625 :   int unused_property_fields = new_map->unused_property_fields() - 1;
    3285     8779625 :   if (unused_property_fields < 0) {
    3286     2328805 :     unused_property_fields += JSObject::kFieldsAdded;
    3287             :   }
    3288             :   new_map->set_unused_property_fields(unused_property_fields);
    3289             :   return new_map;
    3290             : }
    3291             : 
    3292             : 
    3293     6717029 : MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map,
    3294             :                                        Handle<Name> name,
    3295             :                                        Handle<Object> constant,
    3296             :                                        PropertyAttributes attributes,
    3297             :                                        TransitionFlag flag) {
    3298             :   // Ensure the descriptor array does not get too big.
    3299     6717029 :   if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
    3300             :     return MaybeHandle<Map>();
    3301             :   }
    3302             : 
    3303             :   if (FLAG_track_constant_fields) {
    3304             :     Isolate* isolate = map->GetIsolate();
    3305             :     Representation representation = constant->OptimalRepresentation();
    3306             :     Handle<FieldType> type = constant->OptimalType(isolate, representation);
    3307             :     return CopyWithField(map, name, type, attributes, kConst, representation,
    3308             :                          flag);
    3309             :   } else {
    3310             :     // Allocate new instance descriptors with (name, constant) added.
    3311     6717029 :     Descriptor d = Descriptor::DataConstant(name, 0, constant, attributes);
    3312     6717029 :     Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag);
    3313             :     return new_map;
    3314             :   }
    3315             : }
    3316             : 
    3317           0 : const char* Representation::Mnemonic() const {
    3318           0 :   switch (kind_) {
    3319             :     case kNone: return "v";
    3320           0 :     case kTagged: return "t";
    3321           0 :     case kSmi: return "s";
    3322           0 :     case kDouble: return "d";
    3323           0 :     case kInteger32: return "i";
    3324           0 :     case kHeapObject: return "h";
    3325           0 :     case kExternal: return "x";
    3326             :     default:
    3327           0 :       UNREACHABLE();
    3328             :       return NULL;
    3329             :   }
    3330             : }
    3331             : 
    3332           0 : bool Map::TransitionRemovesTaggedField(Map* target) {
    3333             :   int inobject = GetInObjectProperties();
    3334             :   int target_inobject = target->GetInObjectProperties();
    3335           0 :   for (int i = target_inobject; i < inobject; i++) {
    3336           0 :     FieldIndex index = FieldIndex::ForPropertyIndex(this, i);
    3337           0 :     if (!IsUnboxedDoubleField(index)) return true;
    3338             :   }
    3339             :   return false;
    3340             : }
    3341             : 
    3342           0 : bool Map::TransitionChangesTaggedFieldToUntaggedField(Map* target) {
    3343             :   int inobject = GetInObjectProperties();
    3344             :   int target_inobject = target->GetInObjectProperties();
    3345             :   int limit = Min(inobject, target_inobject);
    3346           0 :   for (int i = 0; i < limit; i++) {
    3347           0 :     FieldIndex index = FieldIndex::ForPropertyIndex(target, i);
    3348           0 :     if (!IsUnboxedDoubleField(index) && target->IsUnboxedDoubleField(index)) {
    3349           0 :       return true;
    3350             :     }
    3351             :   }
    3352             :   return false;
    3353             : }
    3354             : 
    3355           0 : bool Map::TransitionRequiresSynchronizationWithGC(Map* target) {
    3356           0 :   return TransitionRemovesTaggedField(target) ||
    3357           0 :          TransitionChangesTaggedFieldToUntaggedField(target);
    3358             : }
    3359             : 
    3360      146633 : bool Map::InstancesNeedRewriting(Map* target) {
    3361      146633 :   int target_number_of_fields = target->NumberOfFields();
    3362             :   int target_inobject = target->GetInObjectProperties();
    3363             :   int target_unused = target->unused_property_fields();
    3364             :   int old_number_of_fields;
    3365             : 
    3366             :   return InstancesNeedRewriting(target, target_number_of_fields,
    3367             :                                 target_inobject, target_unused,
    3368      146633 :                                 &old_number_of_fields);
    3369             : }
    3370             : 
    3371    26131569 : bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
    3372             :                                  int target_inobject, int target_unused,
    3373             :                                  int* old_number_of_fields) {
    3374             :   // If fields were added (or removed), rewrite the instance.
    3375    26131569 :   *old_number_of_fields = NumberOfFields();
    3376             :   DCHECK(target_number_of_fields >= *old_number_of_fields);
    3377    26131569 :   if (target_number_of_fields != *old_number_of_fields) return true;
    3378             : 
    3379             :   // If smi descriptors were replaced by double descriptors, rewrite.
    3380             :   DescriptorArray* old_desc = instance_descriptors();
    3381             :   DescriptorArray* new_desc = target->instance_descriptors();
    3382             :   int limit = NumberOfOwnDescriptors();
    3383    50132130 :   for (int i = 0; i < limit; i++) {
    3384    72750386 :     if (new_desc->GetDetails(i).representation().IsDouble() !=
    3385    72750386 :         old_desc->GetDetails(i).representation().IsDouble()) {
    3386             :       return true;
    3387             :     }
    3388             :   }
    3389             : 
    3390             :   // If no fields were added, and no inobject properties were removed, setting
    3391             :   // the map is sufficient.
    3392    13756937 :   if (target_inobject == GetInObjectProperties()) return false;
    3393             :   // In-object slack tracking may have reduced the object size of the new map.
    3394             :   // In that case, succeed if all existing fields were inobject, and they still
    3395             :   // fit within the new inobject size.
    3396             :   DCHECK(target_inobject < GetInObjectProperties());
    3397         509 :   if (target_number_of_fields <= target_inobject) {
    3398             :     DCHECK(target_number_of_fields + target_unused == target_inobject);
    3399             :     return false;
    3400             :   }
    3401             :   // Otherwise, properties will need to be moved to the backing store.
    3402           0 :   return true;
    3403             : }
    3404             : 
    3405             : 
    3406             : // static
    3407     5497297 : void JSObject::UpdatePrototypeUserRegistration(Handle<Map> old_map,
    3408             :                                                Handle<Map> new_map,
    3409             :                                                Isolate* isolate) {
    3410             :   DCHECK(old_map->is_prototype_map());
    3411             :   DCHECK(new_map->is_prototype_map());
    3412     5497297 :   bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
    3413     5497297 :   new_map->set_prototype_info(old_map->prototype_info());
    3414     5497297 :   old_map->set_prototype_info(Smi::kZero);
    3415     5497296 :   if (FLAG_trace_prototype_users) {
    3416             :     PrintF("Moving prototype_info %p from map %p to map %p.\n",
    3417             :            reinterpret_cast<void*>(new_map->prototype_info()),
    3418             :            reinterpret_cast<void*>(*old_map),
    3419           0 :            reinterpret_cast<void*>(*new_map));
    3420             :   }
    3421     5497296 :   if (was_registered) {
    3422      284402 :     if (new_map->prototype_info()->IsPrototypeInfo()) {
    3423             :       // The new map isn't registered with its prototype yet; reflect this fact
    3424             :       // in the PrototypeInfo it just inherited from the old map.
    3425             :       PrototypeInfo::cast(new_map->prototype_info())
    3426             :           ->set_registry_slot(PrototypeInfo::UNREGISTERED);
    3427             :     }
    3428      284402 :     JSObject::LazyRegisterPrototypeUser(new_map, isolate);
    3429             :   }
    3430     5497296 : }
    3431             : 
    3432             : namespace {
    3433             : // To migrate a fast instance to a fast map:
    3434             : // - First check whether the instance needs to be rewritten. If not, simply
    3435             : //   change the map.
    3436             : // - Otherwise, allocate a fixed array large enough to hold all fields, in
    3437             : //   addition to unused space.
    3438             : // - Copy all existing properties in, in the following order: backing store
    3439             : //   properties, unused fields, inobject properties.
    3440             : // - If all allocation succeeded, commit the state atomically:
    3441             : //   * Copy inobject properties from the backing store back into the object.
    3442             : //   * Trim the difference in instance size of the object. This also cleanly
    3443             : //     frees inobject properties that moved to the backing store.
    3444             : //   * If there are properties left in the backing store, trim of the space used
    3445             : //     to temporarily store the inobject properties.
    3446             : //   * If there are properties left in the backing store, install the backing
    3447             : //     store.
    3448    52815815 : void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
    3449             :   Isolate* isolate = object->GetIsolate();
    3450             :   Handle<Map> old_map(object->map());
    3451             :   // In case of a regular transition.
    3452   105631641 :   if (new_map->GetBackPointer() == *old_map) {
    3453             :     // If the map does not add named properties, simply set the map.
    3454    26830892 :     if (old_map->NumberOfOwnDescriptors() ==
    3455             :         new_map->NumberOfOwnDescriptors()) {
    3456      685894 :       object->synchronized_set_map(*new_map);
    3457      685880 :       return;
    3458             :     }
    3459             : 
    3460             :     PropertyDetails details = new_map->GetLastDescriptorDetails();
    3461    26145005 :     int target_index = details.field_index() - new_map->GetInObjectProperties();
    3462    31502586 :     bool have_space = old_map->unused_property_fields() > 0 ||
    3463     9287038 :                       (details.location() == kField && target_index >= 0 &&
    3464             :                        object->properties()->length() > target_index);
    3465             :     // Either new_map adds an kDescriptor property, or a kField property for
    3466             :     // which there is still space, and which does not require a mutable double
    3467             :     // box (an out-of-object double).
    3468    52290010 :     if (details.location() == kDescriptor ||
    3469    18031342 :         (have_space &&
    3470     5435992 :          ((FLAG_unbox_double_fields && object->properties()->length() == 0) ||
    3471             :           !details.representation().IsDouble()))) {
    3472    21495994 :       object->synchronized_set_map(*new_map);
    3473    21495992 :       return;
    3474             :     }
    3475             : 
    3476             :     // If there is still space in the object, we need to allocate a mutable
    3477             :     // double box.
    3478     4649011 :     if (have_space) {
    3479             :       FieldIndex index =
    3480        5492 :           FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
    3481             :       DCHECK(details.representation().IsDouble());
    3482             :       DCHECK(!new_map->IsUnboxedDoubleField(index));
    3483             :       Handle<Object> value = isolate->factory()->NewMutableHeapNumber();
    3484        5492 :       object->RawFastPropertyAtPut(index, *value);
    3485        5492 :       object->synchronized_set_map(*new_map);
    3486             :       return;
    3487             :     }
    3488             : 
    3489             :     // This migration is a transition from a map that has run out of property
    3490             :     // space. Extend the backing store.
    3491     4643519 :     int grow_by = new_map->unused_property_fields() + 1;
    3492     4643519 :     Handle<FixedArray> old_storage = handle(object->properties(), isolate);
    3493             :     Handle<FixedArray> new_storage =
    3494     4643519 :         isolate->factory()->CopyFixedArrayAndGrow(old_storage, grow_by);
    3495             : 
    3496             :     // Properly initialize newly added property.
    3497             :     Handle<Object> value;
    3498     4643519 :     if (details.representation().IsDouble()) {
    3499             :       value = isolate->factory()->NewMutableHeapNumber();
    3500             :     } else {
    3501             :       value = isolate->factory()->uninitialized_value();
    3502             :     }
    3503             :     DCHECK_EQ(kField, details.location());
    3504             :     DCHECK_EQ(kData, details.kind());
    3505             :     DCHECK(target_index >= 0);  // Must be a backing store index.
    3506     4643519 :     new_storage->set(target_index, *value);
    3507             : 
    3508             :     // From here on we cannot fail and we shouldn't GC anymore.
    3509             :     DisallowHeapAllocation no_allocation;
    3510             : 
    3511             :     // Set the new property value and do the map transition.
    3512     4643519 :     object->set_properties(*new_storage);
    3513     4643519 :     object->synchronized_set_map(*new_map);
    3514     4643519 :     return;
    3515             :   }
    3516             : 
    3517             :   int old_number_of_fields;
    3518    25984937 :   int number_of_fields = new_map->NumberOfFields();
    3519             :   int inobject = new_map->GetInObjectProperties();
    3520             :   int unused = new_map->unused_property_fields();
    3521             : 
    3522             :   // Nothing to do if no functions were converted to fields and no smis were
    3523             :   // converted to doubles.
    3524    25984938 :   if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
    3525    25984937 :                                        unused, &old_number_of_fields)) {
    3526    13610335 :     object->synchronized_set_map(*new_map);
    3527    13610335 :     return;
    3528             :   }
    3529             : 
    3530    12374603 :   int total_size = number_of_fields + unused;
    3531    12374603 :   int external = total_size - inobject;
    3532             : 
    3533    12374603 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size);
    3534             : 
    3535             :   Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
    3536             :   Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors());
    3537             :   int old_nof = old_map->NumberOfOwnDescriptors();
    3538             :   int new_nof = new_map->NumberOfOwnDescriptors();
    3539             : 
    3540             :   // This method only supports generalizing instances to at least the same
    3541             :   // number of properties.
    3542             :   DCHECK(old_nof <= new_nof);
    3543             : 
    3544   105609214 :   for (int i = 0; i < old_nof; i++) {
    3545    93234613 :     PropertyDetails details = new_descriptors->GetDetails(i);
    3546    93234613 :     if (details.location() != kField) continue;
    3547             :     DCHECK_EQ(kData, details.kind());
    3548    63105038 :     PropertyDetails old_details = old_descriptors->GetDetails(i);
    3549             :     Representation old_representation = old_details.representation();
    3550             :     Representation representation = details.representation();
    3551             :     Handle<Object> value;
    3552    63105038 :     if (old_details.location() == kDescriptor) {
    3553     1949152 :       if (old_details.kind() == kAccessor) {
    3554             :         // In case of kAccessor -> kData property reconfiguration, the property
    3555             :         // must already be prepared for data of certain type.
    3556             :         DCHECK(!details.representation().IsNone());
    3557     1512695 :         if (details.representation().IsDouble()) {
    3558             :           value = isolate->factory()->NewMutableHeapNumber();
    3559             :         } else {
    3560             :           value = isolate->factory()->uninitialized_value();
    3561             :         }
    3562             :       } else {
    3563             :         DCHECK_EQ(kData, old_details.kind());
    3564             :         value = handle(old_descriptors->GetValue(i), isolate);
    3565             :         DCHECK(!old_representation.IsDouble() && !representation.IsDouble());
    3566             :       }
    3567             :     } else {
    3568             :       DCHECK_EQ(kField, old_details.location());
    3569    61155886 :       FieldIndex index = FieldIndex::ForDescriptor(*old_map, i);
    3570    61155886 :       if (object->IsUnboxedDoubleField(index)) {
    3571             :         uint64_t old_bits = object->RawFastDoublePropertyAsBitsAt(index);
    3572             :         value = isolate->factory()->NewHeapNumberFromBits(
    3573        4883 :             old_bits, representation.IsDouble() ? MUTABLE : IMMUTABLE);
    3574             : 
    3575             :       } else {
    3576    61151003 :         value = handle(object->RawFastPropertyAt(index), isolate);
    3577    61151003 :         if (!old_representation.IsDouble() && representation.IsDouble()) {
    3578             :           DCHECK_IMPLIES(old_representation.IsNone(),
    3579             :                          value->IsUninitialized(isolate));
    3580        2821 :           value = Object::NewStorageFor(isolate, value, representation);
    3581    61148182 :         } else if (old_representation.IsDouble() &&
    3582             :                    !representation.IsDouble()) {
    3583          19 :           value = Object::WrapForRead(isolate, value, old_representation);
    3584             :         }
    3585             :       }
    3586             :     }
    3587             :     DCHECK(!(representation.IsDouble() && value->IsSmi()));
    3588    63105037 :     int target_index = new_descriptors->GetFieldIndex(i) - inobject;
    3589    63105037 :     if (target_index < 0) target_index += total_size;
    3590    63105037 :     array->set(target_index, *value);
    3591             :   }
    3592             : 
    3593    43615080 :   for (int i = old_nof; i < new_nof; i++) {
    3594    43615080 :     PropertyDetails details = new_descriptors->GetDetails(i);
    3595    43615080 :     if (details.location() != kField) continue;
    3596             :     DCHECK_EQ(kData, details.kind());
    3597             :     Handle<Object> value;
    3598    43615080 :     if (details.representation().IsDouble()) {
    3599             :       value = isolate->factory()->NewMutableHeapNumber();
    3600             :     } else {
    3601             :       value = isolate->factory()->uninitialized_value();
    3602             :     }
    3603    43615080 :     int target_index = new_descriptors->GetFieldIndex(i) - inobject;
    3604    43615080 :     if (target_index < 0) target_index += total_size;
    3605    43615080 :     array->set(target_index, *value);
    3606             :   }
    3607             : 
    3608             :   // From here on we cannot fail and we shouldn't GC anymore.
    3609             :   DisallowHeapAllocation no_allocation;
    3610             : 
    3611    12374601 :   Heap* heap = isolate->heap();
    3612             : 
    3613    12374601 :   heap->NotifyObjectLayoutChange(*object, no_allocation);
    3614             : 
    3615             :   // Copy (real) inobject properties. If necessary, stop at number_of_fields to
    3616             :   // avoid overwriting |one_pointer_filler_map|.
    3617             :   int limit = Min(inobject, number_of_fields);
    3618    47765038 :   for (int i = 0; i < limit; i++) {
    3619    35390435 :     FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
    3620    35390435 :     Object* value = array->get(external + i);
    3621             :     // Can't use JSObject::FastPropertyAtPut() because proper map was not set
    3622             :     // yet.
    3623    35390435 :     if (new_map->IsUnboxedDoubleField(index)) {
    3624             :       DCHECK(value->IsMutableHeapNumber());
    3625             :       // Ensure that all bits of the double value are preserved.
    3626             :       object->RawFastDoublePropertyAsBitsAtPut(
    3627             :           index, HeapNumber::cast(value)->value_as_bits());
    3628       45506 :       if (i < old_number_of_fields && !old_map->IsUnboxedDoubleField(index)) {
    3629             :         // Transition from tagged to untagged slot.
    3630             :         heap->ClearRecordedSlot(*object,
    3631        1875 :                                 HeapObject::RawField(*object, index.offset()));
    3632             :       } else {
    3633             :         DCHECK(!heap->HasRecordedSlot(
    3634             :             *object, HeapObject::RawField(*object, index.offset())));
    3635             :       }
    3636             :     } else {
    3637    35350948 :       object->RawFastPropertyAtPut(index, value);
    3638             :     }
    3639             :   }
    3640             : 
    3641             : 
    3642             :   // If there are properties in the new backing store, trim it to the correct
    3643             :   // size and install the backing store into the object.
    3644    12374603 :   if (external > 0) {
    3645     6738517 :     heap->RightTrimFixedArray(*array, inobject);
    3646     6738516 :     object->set_properties(*array);
    3647             :   }
    3648             : 
    3649             :   // Create filler object past the new instance size.
    3650             :   int new_instance_size = new_map->instance_size();
    3651    12374602 :   int instance_size_delta = old_map->instance_size() - new_instance_size;
    3652             :   DCHECK(instance_size_delta >= 0);
    3653             : 
    3654    12374602 :   if (instance_size_delta > 0) {
    3655          17 :     Address address = object->address();
    3656             :     heap->CreateFillerObjectAt(address + new_instance_size, instance_size_delta,
    3657          17 :                                ClearRecordedSlots::kYes);
    3658          34 :     heap->AdjustLiveBytes(*object, -instance_size_delta);
    3659             :   }
    3660             : 
    3661             :   // We are storing the new map using release store after creating a filler for
    3662             :   // the left-over space to avoid races with the sweeper thread.
    3663    12374602 :   object->synchronized_set_map(*new_map);
    3664             : }
    3665             : 
    3666     1317738 : void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
    3667             :                        int expected_additional_properties) {
    3668             :   // The global object is always normalized.
    3669             :   DCHECK(!object->IsJSGlobalObject());
    3670             :   // JSGlobalProxy must never be normalized
    3671             :   DCHECK(!object->IsJSGlobalProxy());
    3672             : 
    3673     1317738 :   Isolate* isolate = object->GetIsolate();
    3674             :   HandleScope scope(isolate);
    3675             :   Handle<Map> map(object->map());
    3676             : 
    3677             :   // Allocate new content.
    3678             :   int real_size = map->NumberOfOwnDescriptors();
    3679             :   int property_count = real_size;
    3680     1317738 :   if (expected_additional_properties > 0) {
    3681       94767 :     property_count += expected_additional_properties;
    3682             :   } else {
    3683             :     // Make space for two more properties.
    3684     1222971 :     property_count += NameDictionary::kInitialCapacity;
    3685             :   }
    3686             :   Handle<NameDictionary> dictionary =
    3687     1317738 :       NameDictionary::New(isolate, property_count);
    3688             : 
    3689             :   Handle<DescriptorArray> descs(map->instance_descriptors());
    3690     8434361 :   for (int i = 0; i < real_size; i++) {
    3691     5798885 :     PropertyDetails details = descs->GetDetails(i);
    3692             :     Handle<Name> key(descs->GetKey(i));
    3693             :     Handle<Object> value;
    3694     5798885 :     if (details.location() == kField) {
    3695     4466689 :       FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    3696     4466689 :       if (details.kind() == kData) {
    3697     4466689 :         if (object->IsUnboxedDoubleField(index)) {
    3698             :           double old_value = object->RawFastDoublePropertyAt(index);
    3699             :           value = isolate->factory()->NewHeapNumber(old_value);
    3700             :         } else {
    3701     4465793 :           value = handle(object->RawFastPropertyAt(index), isolate);
    3702     4465793 :           if (details.representation().IsDouble()) {
    3703             :             DCHECK(value->IsMutableHeapNumber());
    3704             :             Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
    3705             :             value = isolate->factory()->NewHeapNumber(old->value());
    3706             :           }
    3707             :         }
    3708             :       } else {
    3709             :         DCHECK_EQ(kAccessor, details.kind());
    3710           0 :         value = handle(object->RawFastPropertyAt(index), isolate);
    3711             :       }
    3712             : 
    3713             :     } else {
    3714             :       DCHECK_EQ(kDescriptor, details.location());
    3715             :       value = handle(descs->GetValue(i), isolate);
    3716             :     }
    3717             :     DCHECK(!value.is_null());
    3718             :     PropertyDetails d(details.kind(), details.attributes(), i + 1,
    3719     5798885 :                       PropertyCellType::kNoCell);
    3720     5798885 :     dictionary = NameDictionary::Add(dictionary, key, value, d);
    3721             :   }
    3722             : 
    3723             :   // Copy the next enumeration index from instance descriptor.
    3724     1317738 :   dictionary->SetNextEnumerationIndex(real_size + 1);
    3725             : 
    3726             :   // From here on we cannot fail and we shouldn't GC anymore.
    3727             :   DisallowHeapAllocation no_allocation;
    3728             : 
    3729     1317738 :   Heap* heap = isolate->heap();
    3730     1317738 :   heap->NotifyObjectLayoutChange(*object, no_allocation);
    3731             : 
    3732             :   // Resize the object in the heap if necessary.
    3733             :   int new_instance_size = new_map->instance_size();
    3734     1317738 :   int instance_size_delta = map->instance_size() - new_instance_size;
    3735             :   DCHECK(instance_size_delta >= 0);
    3736             : 
    3737     1317738 :   if (instance_size_delta > 0) {
    3738      452727 :     heap->CreateFillerObjectAt(object->address() + new_instance_size,
    3739      452727 :                                instance_size_delta, ClearRecordedSlots::kYes);
    3740      905454 :     heap->AdjustLiveBytes(*object, -instance_size_delta);
    3741             :   }
    3742             : 
    3743             :   // We are storing the new map using release store after creating a filler for
    3744             :   // the left-over space to avoid races with the sweeper thread.
    3745     1317738 :   object->synchronized_set_map(*new_map);
    3746             : 
    3747     1317738 :   object->set_properties(*dictionary);
    3748             : 
    3749             :   // Ensure that in-object space of slow-mode object does not contain random
    3750             :   // garbage.
    3751             :   int inobject_properties = new_map->GetInObjectProperties();
    3752     1317738 :   if (inobject_properties) {
    3753             :     Heap* heap = isolate->heap();
    3754             :     heap->ClearRecordedSlotRange(
    3755      588032 :         object->address() + map->GetInObjectPropertyOffset(0),
    3756     1176064 :         object->address() + new_instance_size);
    3757             : 
    3758     3467145 :     for (int i = 0; i < inobject_properties; i++) {
    3759     2879113 :       FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
    3760     2879113 :       object->RawFastPropertyAtPut(index, Smi::kZero);
    3761             :     }
    3762             :   }
    3763             : 
    3764     1317738 :   isolate->counters()->props_to_dictionary()->Increment();
    3765             : 
    3766             : #ifdef DEBUG
    3767             :   if (FLAG_trace_normalization) {
    3768             :     OFStream os(stdout);
    3769             :     os << "Object properties have been normalized:\n";
    3770             :     object->Print(os);
    3771             :   }
    3772             : #endif
    3773     1317738 : }
    3774             : 
    3775             : }  // namespace
    3776             : 
    3777             : // static
    3778    55413211 : void JSObject::NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
    3779             :                                Isolate* isolate) {
    3780   110826421 :   if (!old_map->is_prototype_map()) return;
    3781             : 
    3782             :   InvalidatePrototypeChains(*old_map);
    3783             : 
    3784             :   // If the map was registered with its prototype before, ensure that it
    3785             :   // registers with its new prototype now. This preserves the invariant that
    3786             :   // when a map on a prototype chain is registered with its prototype, then
    3787             :   // all prototypes further up the chain are also registered with their
    3788             :   // respective prototypes.
    3789     5497297 :   UpdatePrototypeUserRegistration(old_map, new_map, isolate);
    3790             : }
    3791             : 
    3792    69226741 : void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
    3793             :                             int expected_additional_properties) {
    3794   138453489 :   if (object->map() == *new_map) return;
    3795             :   Handle<Map> old_map(object->map());
    3796    54784093 :   NotifyMapChange(old_map, new_map, new_map->GetIsolate());
    3797             : 
    3798    54784094 :   if (old_map->is_dictionary_map()) {
    3799             :     // For slow-to-fast migrations JSObject::MigrateSlowToFast()
    3800             :     // must be used instead.
    3801      650540 :     CHECK(new_map->is_dictionary_map());
    3802             : 
    3803             :     // Slow-to-slow migration is trivial.
    3804      650540 :     object->set_map(*new_map);
    3805    54133554 :   } else if (!new_map->is_dictionary_map()) {
    3806    52815816 :     MigrateFastToFast(object, new_map);
    3807    52815815 :     if (old_map->is_prototype_map()) {
    3808             :       DCHECK(!old_map->is_stable());
    3809             :       DCHECK(new_map->is_stable());
    3810             :       // Clear out the old descriptor array to avoid problems to sharing
    3811             :       // the descriptor array without using an explicit.
    3812             :       old_map->InitializeDescriptors(
    3813             :           old_map->GetHeap()->empty_descriptor_array(),
    3814     4899217 :           LayoutDescriptor::FastPointerLayout());
    3815             :       // Ensure that no transition was inserted for prototype migrations.
    3816             :       DCHECK_EQ(
    3817             :           0, TransitionArray::NumberOfTransitions(old_map->raw_transitions()));
    3818             :       DCHECK(new_map->GetBackPointer()->IsUndefined(new_map->GetIsolate()));
    3819             :     }
    3820             :   } else {
    3821     1317738 :     MigrateFastToSlow(object, new_map, expected_additional_properties);
    3822             :   }
    3823             : 
    3824             :   // Careful: Don't allocate here!
    3825             :   // For some callers of this method, |object| might be in an inconsistent
    3826             :   // state now: the new map might have a new elements_kind, but the object's
    3827             :   // elements pointer hasn't been updated yet. Callers will fix this, but in
    3828             :   // the meantime, (indirectly) calling JSObjectVerify() must be avoided.
    3829             :   // When adding code here, add a DisallowHeapAllocation too.
    3830             : }
    3831             : 
    3832      237661 : void JSObject::ForceSetPrototype(Handle<JSObject> object,
    3833             :                                  Handle<Object> proto) {
    3834             :   // object.__proto__ = proto;
    3835             :   Handle<Map> old_map = Handle<Map>(object->map());
    3836      237661 :   Handle<Map> new_map = Map::Copy(old_map, "ForceSetPrototype");
    3837      237661 :   Map::SetPrototype(new_map, proto, FAST_PROTOTYPE);
    3838      237661 :   JSObject::MigrateToMap(object, new_map);
    3839      237661 : }
    3840             : 
    3841    56054235 : int Map::NumberOfFields() {
    3842             :   DescriptorArray* descriptors = instance_descriptors();
    3843             :   int result = 0;
    3844   920050224 :   for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
    3845   807941752 :     if (descriptors->GetDetails(i).location() == kField) result++;
    3846             :   }
    3847    56054237 :   return result;
    3848             : }
    3849             : 
    3850     9532631 : void DescriptorArray::GeneralizeAllFields() {
    3851     9532631 :   int length = number_of_descriptors();
    3852    57908793 :   for (int i = 0; i < length; i++) {
    3853    38843529 :     PropertyDetails details = GetDetails(i);
    3854             :     details = details.CopyWithRepresentation(Representation::Tagged());
    3855    38843530 :     if (details.location() == kField) {
    3856             :       DCHECK_EQ(kData, details.kind());
    3857             :       details = details.CopyWithConstness(kMutable);
    3858     5111075 :       SetValue(i, FieldType::Any());
    3859             :     }
    3860             :     set(ToDetailsIndex(i), details.AsSmi());
    3861             :   }
    3862     9532632 : }
    3863             : 
    3864     1946877 : Handle<Map> Map::CopyGeneralizeAllFields(Handle<Map> map,
    3865             :                                          ElementsKind elements_kind,
    3866             :                                          int modify_index, PropertyKind kind,
    3867             :                                          PropertyAttributes attributes,
    3868             :                                          const char* reason) {
    3869             :   Isolate* isolate = map->GetIsolate();
    3870             :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
    3871             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    3872             :   Handle<DescriptorArray> descriptors =
    3873             :       DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors);
    3874     1946878 :   descriptors->GeneralizeAllFields();
    3875             : 
    3876             :   Handle<LayoutDescriptor> new_layout_descriptor(
    3877             :       LayoutDescriptor::FastPointerLayout(), isolate);
    3878             :   Handle<Map> new_map = CopyReplaceDescriptors(
    3879             :       map, descriptors, new_layout_descriptor, OMIT_TRANSITION,
    3880     1946878 :       MaybeHandle<Name>(), reason, SPECIAL_TRANSITION);
    3881             : 
    3882             :   // Unless the instance is being migrated, ensure that modify_index is a field.
    3883     1946878 :   if (modify_index >= 0) {
    3884     1946774 :     PropertyDetails details = descriptors->GetDetails(modify_index);
    3885     1950848 :     if (details.constness() != kMutable || details.location() != kField ||
    3886             :         details.attributes() != attributes) {
    3887             :       int field_index = details.location() == kField
    3888             :                             ? details.field_index()
    3889     3889912 :                             : new_map->NumberOfFields();
    3890             :       Descriptor d = Descriptor::DataField(
    3891             :           handle(descriptors->GetKey(modify_index), isolate), field_index,
    3892     1945174 :           attributes, Representation::Tagged());
    3893     1945174 :       descriptors->Replace(modify_index, &d);
    3894     1945175 :       if (details.location() != kField) {
    3895     1944737 :         int unused_property_fields = new_map->unused_property_fields() - 1;
    3896     1944737 :         if (unused_property_fields < 0) {
    3897     1597063 :           unused_property_fields += JSObject::kFieldsAdded;
    3898             :         }
    3899             :         new_map->set_unused_property_fields(unused_property_fields);
    3900             :       }
    3901             :     } else {
    3902             :       DCHECK(details.attributes() == attributes);
    3903             :     }
    3904             : 
    3905     1946774 :     if (FLAG_trace_generalization) {
    3906           0 :       MaybeHandle<FieldType> field_type = FieldType::None(isolate);
    3907           0 :       if (details.location() == kField) {
    3908             :         field_type = handle(
    3909           0 :             map->instance_descriptors()->GetFieldType(modify_index), isolate);
    3910             :       }
    3911             :       map->PrintGeneralization(
    3912             :           stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(),
    3913             :           new_map->NumberOfOwnDescriptors(), details.location() == kDescriptor,
    3914             :           details.representation(), Representation::Tagged(), field_type,
    3915             :           MaybeHandle<Object>(), FieldType::Any(isolate),
    3916           0 :           MaybeHandle<Object>());
    3917             :     }
    3918             :   }
    3919             :   new_map->set_elements_kind(elements_kind);
    3920     1946878 :   return new_map;
    3921             : }
    3922             : 
    3923             : 
    3924      323702 : void Map::DeprecateTransitionTree() {
    3925      647404 :   if (is_deprecated()) return;
    3926             :   Object* transitions = raw_transitions();
    3927      323702 :   int num_transitions = TransitionArray::NumberOfTransitions(transitions);
    3928      482307 :   for (int i = 0; i < num_transitions; ++i) {
    3929      158605 :     TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree();
    3930             :   }
    3931             :   DCHECK(!constructor_or_backpointer()->IsFunctionTemplateInfo());
    3932             :   deprecate();
    3933             :   dependent_code()->DeoptimizeDependentCodeGroup(
    3934      323702 :       GetIsolate(), DependentCode::kTransitionGroup);
    3935      323702 :   NotifyLeafMapLayoutChange();
    3936             : }
    3937             : 
    3938             : 
    3939             : // Installs |new_descriptors| over the current instance_descriptors to ensure
    3940             : // proper sharing of descriptor arrays.
    3941      167298 : void Map::ReplaceDescriptors(DescriptorArray* new_descriptors,
    3942             :                              LayoutDescriptor* new_layout_descriptor) {
    3943             :   Isolate* isolate = GetIsolate();
    3944             :   // Don't overwrite the empty descriptor array or initial map's descriptors.
    3945      216626 :   if (NumberOfOwnDescriptors() == 0 || GetBackPointer()->IsUndefined(isolate)) {
    3946      167298 :     return;
    3947             :   }
    3948             : 
    3949             :   DescriptorArray* to_replace = instance_descriptors();
    3950       48904 :   isolate->heap()->incremental_marking()->IterateBlackObject(to_replace);
    3951             :   Map* current = this;
    3952      254662 :   while (current->instance_descriptors() == to_replace) {
    3953      157251 :     Object* next = current->GetBackPointer();
    3954      157251 :     if (next->IsUndefined(isolate)) break;  // Stop overwriting at initial map.
    3955             :     current->SetEnumLength(kInvalidEnumCacheSentinel);
    3956      156854 :     current->UpdateDescriptors(new_descriptors, new_layout_descriptor);
    3957             :     current = Map::cast(next);
    3958             :   }
    3959             :   set_owns_descriptors(false);
    3960             : }
    3961             : 
    3962             : 
    3963     2114910 : Map* Map::FindRootMap() {
    3964             :   Map* result = this;
    3965             :   Isolate* isolate = GetIsolate();
    3966             :   while (true) {
    3967     9954574 :     Object* back = result->GetBackPointer();
    3968     9954574 :     if (back->IsUndefined(isolate)) {
    3969             :       // Initial map always owns descriptors and doesn't have unused entries
    3970             :       // in the descriptor array.
    3971             :       DCHECK(result->owns_descriptors());
    3972             :       DCHECK_EQ(result->NumberOfOwnDescriptors(),
    3973             :                 result->instance_descriptors()->number_of_descriptors());
    3974     2114910 :       return result;
    3975             :     }
    3976             :     result = Map::cast(back);
    3977             :   }
    3978             : }
    3979             : 
    3980             : 
    3981      966844 : Map* Map::FindFieldOwner(int descriptor) {
    3982             :   DisallowHeapAllocation no_allocation;
    3983             :   DCHECK_EQ(kField, instance_descriptors()->GetDetails(descriptor).location());
    3984             :   Map* result = this;
    3985             :   Isolate* isolate = GetIsolate();
    3986             :   while (true) {
    3987     3423094 :     Object* back = result->GetBackPointer();
    3988     3423094 :     if (back->IsUndefined(isolate)) break;
    3989             :     Map* parent = Map::cast(back);
    3990     3423094 :     if (parent->NumberOfOwnDescriptors() <= descriptor) break;
    3991             :     result = parent;
    3992             :   }
    3993      966844 :   return result;
    3994             : }
    3995             : 
    3996      550695 : void Map::UpdateFieldType(int descriptor, Handle<Name> name,
    3997             :                           PropertyConstness new_constness,
    3998             :                           Representation new_representation,
    3999             :                           Handle<Object> new_wrapped_type) {
    4000             :   DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell());
    4001             :   // We store raw pointers in the queue, so no allocations are allowed.
    4002             :   DisallowHeapAllocation no_allocation;
    4003      550695 :   PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
    4004      550695 :   if (details.location() != kField) return;
    4005             :   DCHECK_EQ(kData, details.kind());
    4006             : 
    4007      550695 :   Zone zone(GetIsolate()->allocator(), ZONE_NAME);
    4008      550695 :   ZoneQueue<Map*> backlog(&zone);
    4009     1101390 :   backlog.push(this);
    4010             : 
    4011     4101506 :   while (!backlog.empty()) {
    4012     3000116 :     Map* current = backlog.front();
    4013             :     backlog.pop();
    4014             : 
    4015             :     Object* transitions = current->raw_transitions();
    4016     3000116 :     int num_transitions = TransitionArray::NumberOfTransitions(transitions);
    4017     5449537 :     for (int i = 0; i < num_transitions; ++i) {
    4018     2449421 :       Map* target = TransitionArray::GetTarget(transitions, i);
    4019             :       backlog.push(target);
    4020             :     }
    4021             :     DescriptorArray* descriptors = current->instance_descriptors();
    4022     3000116 :     PropertyDetails details = descriptors->GetDetails(descriptor);
    4023             : 
    4024             :     // Currently constness change implies map change.
    4025             :     DCHECK_IMPLIES(new_constness != details.constness(),
    4026             :                    FLAG_modify_map_inplace);
    4027             : 
    4028             :     // It is allowed to change representation here only from None to something.
    4029             :     DCHECK(details.representation().Equals(new_representation) ||
    4030             :            details.representation().IsNone());
    4031             : 
    4032             :     // Skip if already updated the shared descriptor.
    4033     3000116 :     if ((FLAG_modify_map_inplace && new_constness != details.constness()) ||
    4034             :         descriptors->GetValue(descriptor) != *new_wrapped_type) {
    4035             :       DCHECK_IMPLIES(!FLAG_track_constant_fields, new_constness == kMutable);
    4036             :       Descriptor d = Descriptor::DataField(
    4037             :           name, descriptors->GetFieldIndex(descriptor), details.attributes(),
    4038      550747 :           new_constness, new_representation, new_wrapped_type);
    4039      550747 :       descriptors->Replace(descriptor, &d);
    4040             :     }
    4041      550695 :   }
    4042             : }
    4043             : 
    4044           0 : bool FieldTypeIsCleared(Representation rep, FieldType* type) {
    4045     4662342 :   return type->IsNone() && rep.IsHeapObject();
    4046             : }
    4047             : 
    4048             : 
    4049             : // static
    4050     2080752 : Handle<FieldType> Map::GeneralizeFieldType(Representation rep1,
    4051             :                                            Handle<FieldType> type1,
    4052             :                                            Representation rep2,
    4053             :                                            Handle<FieldType> type2,
    4054             :                                            Isolate* isolate) {
    4055             :   // Cleared field types need special treatment. They represent lost knowledge,
    4056             :   // so we must be conservative, so their generalization with any other type
    4057             :   // is "Any".
    4058     4161442 :   if (FieldTypeIsCleared(rep1, *type1) || FieldTypeIsCleared(rep2, *type2)) {
    4059        9569 :     return FieldType::Any(isolate);
    4060             :   }
    4061     2071183 :   if (type1->NowIs(type2)) return type2;
    4062      176992 :   if (type2->NowIs(type1)) return type1;
    4063       99085 :   return FieldType::Any(isolate);
    4064             : }
    4065             : 
    4066             : 
    4067             : // static
    4068      885725 : void Map::GeneralizeField(Handle<Map> map, int modify_index,
    4069             :                           PropertyConstness new_constness,
    4070             :                           Representation new_representation,
    4071             :                           Handle<FieldType> new_field_type) {
    4072             :   Isolate* isolate = map->GetIsolate();
    4073             : 
    4074             :   // Check if we actually need to generalize the field type at all.
    4075             :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
    4076      885725 :   PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
    4077             :   PropertyConstness old_constness = old_details.constness();
    4078             :   Representation old_representation = old_details.representation();
    4079             :   Handle<FieldType> old_field_type(old_descriptors->GetFieldType(modify_index),
    4080      885725 :                                    isolate);
    4081             : 
    4082             :   // Return if the current map is general enough to hold requested contness and
    4083             :   // representation/field type.
    4084      885725 :   if (((FLAG_modify_map_inplace &&
    4085             :         IsGeneralizableTo(new_constness, old_constness)) ||
    4086      885725 :        (!FLAG_modify_map_inplace && (old_constness == new_constness))) &&
    4087      484705 :       old_representation.Equals(new_representation) &&
    4088     1370387 :       !FieldTypeIsCleared(new_representation, *new_field_type) &&
    4089             :       // Checking old_field_type for being cleared is not necessary because
    4090             :       // the NowIs check below would fail anyway in that case.
    4091      484662 :       new_field_type->NowIs(old_field_type)) {
    4092             :     DCHECK(GeneralizeFieldType(old_representation, old_field_type,
    4093             :                                new_representation, new_field_type, isolate)
    4094             :                ->NowIs(old_field_type));
    4095      335030 :     return;
    4096             :   }
    4097             : 
    4098             :   // Determine the field owner.
    4099      550695 :   Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
    4100             :   Handle<DescriptorArray> descriptors(
    4101             :       field_owner->instance_descriptors(), isolate);
    4102             :   DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index));
    4103             : 
    4104             :   new_field_type =
    4105             :       Map::GeneralizeFieldType(old_representation, old_field_type,
    4106      550695 :                                new_representation, new_field_type, isolate);
    4107             :   if (FLAG_modify_map_inplace) {
    4108             :     new_constness = GeneralizeConstness(old_constness, new_constness);
    4109             :   }
    4110             : 
    4111      550695 :   PropertyDetails details = descriptors->GetDetails(modify_index);
    4112             :   Handle<Name> name(descriptors->GetKey(modify_index));
    4113             : 
    4114      550695 :   Handle<Object> wrapped_type(WrapFieldType(new_field_type));
    4115             :   field_owner->UpdateFieldType(modify_index, name, new_constness,
    4116      550695 :                                new_representation, wrapped_type);
    4117             :   field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
    4118      550695 :       isolate, DependentCode::kFieldOwnerGroup);
    4119             : 
    4120      550695 :   if (FLAG_trace_generalization) {
    4121             :     map->PrintGeneralization(
    4122             :         stdout, "field type generalization", modify_index,
    4123             :         map->NumberOfOwnDescriptors(), map->NumberOfOwnDescriptors(), false,
    4124             :         details.representation(), details.representation(), old_field_type,
    4125           0 :         MaybeHandle<Object>(), new_field_type, MaybeHandle<Object>());
    4126             :   }
    4127             : }
    4128             : 
    4129             : // TODO(ishell): remove.
    4130             : // static
    4131         596 : Handle<Map> Map::ReconfigureProperty(Handle<Map> map, int modify_index,
    4132             :                                      PropertyKind new_kind,
    4133             :                                      PropertyAttributes new_attributes,
    4134             :                                      Representation new_representation,
    4135             :                                      Handle<FieldType> new_field_type) {
    4136             :   DCHECK_EQ(kData, new_kind);  // Only kData case is supported.
    4137         596 :   MapUpdater mu(map->GetIsolate(), map);
    4138             :   return mu.ReconfigureToDataField(modify_index, new_attributes, kConst,
    4139         596 :                                    new_representation, new_field_type);
    4140             : }
    4141             : 
    4142             : // TODO(ishell): remove.
    4143             : // static
    4144      652544 : Handle<Map> Map::ReconfigureElementsKind(Handle<Map> map,
    4145             :                                          ElementsKind new_elements_kind) {
    4146      652544 :   MapUpdater mu(map->GetIsolate(), map);
    4147      652544 :   return mu.ReconfigureElementsKind(new_elements_kind);
    4148             : }
    4149             : 
    4150             : // Generalize all fields and update the transition tree.
    4151        1697 : Handle<Map> Map::GeneralizeAllFields(Handle<Map> map) {
    4152             :   Isolate* isolate = map->GetIsolate();
    4153        1697 :   Handle<FieldType> any_type = FieldType::Any(isolate);
    4154             : 
    4155             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    4156        7208 :   for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) {
    4157        1907 :     PropertyDetails details = descriptors->GetDetails(i);
    4158        1907 :     if (details.location() == kField) {
    4159             :       DCHECK_EQ(kData, details.kind());
    4160        1007 :       MapUpdater mu(isolate, map);
    4161             :       map = mu.ReconfigureToDataField(i, details.attributes(), kMutable,
    4162        1007 :                                       Representation::Tagged(), any_type);
    4163             :     }
    4164             :   }
    4165        1697 :   return map;
    4166             : }
    4167             : 
    4168             : 
    4169             : // static
    4170      355240 : MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) {
    4171             :   DisallowHeapAllocation no_allocation;
    4172             :   DisallowDeoptimization no_deoptimization(old_map->GetIsolate());
    4173             : 
    4174      355240 :   if (!old_map->is_deprecated()) return old_map;
    4175             : 
    4176             :   // Check the state of the root map.
    4177        2639 :   Map* root_map = old_map->FindRootMap();
    4178        2639 :   if (root_map->is_deprecated()) {
    4179           0 :     JSFunction* constructor = JSFunction::cast(root_map->GetConstructor());
    4180             :     DCHECK(constructor->has_initial_map());
    4181             :     DCHECK(constructor->initial_map()->is_dictionary_map());
    4182           0 :     if (constructor->initial_map()->elements_kind() !=
    4183             :         old_map->elements_kind()) {
    4184             :       return MaybeHandle<Map>();
    4185             :     }
    4186             :     return handle(constructor->initial_map());
    4187             :   }
    4188        2639 :   if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>();
    4189             : 
    4190             :   ElementsKind from_kind = root_map->elements_kind();
    4191             :   ElementsKind to_kind = old_map->elements_kind();
    4192        2555 :   if (from_kind != to_kind) {
    4193             :     // Try to follow existing elements kind transitions.
    4194             :     root_map = root_map->LookupElementsTransitionMap(to_kind);
    4195          18 :     if (root_map == NULL) return MaybeHandle<Map>();
    4196             :     // From here on, use the map with correct elements kind as root map.
    4197             :   }
    4198        2555 :   Map* new_map = root_map->TryReplayPropertyTransitions(*old_map);
    4199        2555 :   if (new_map == nullptr) return MaybeHandle<Map>();
    4200             :   return handle(new_map);
    4201             : }
    4202             : 
    4203      153711 : Map* Map::TryReplayPropertyTransitions(Map* old_map) {
    4204             :   DisallowHeapAllocation no_allocation;
    4205             :   DisallowDeoptimization no_deoptimization(GetIsolate());
    4206             : 
    4207             :   int root_nof = NumberOfOwnDescriptors();
    4208             : 
    4209             :   int old_nof = old_map->NumberOfOwnDescriptors();
    4210             :   DescriptorArray* old_descriptors = old_map->instance_descriptors();
    4211             : 
    4212             :   Map* new_map = this;
    4213      163037 :   for (int i = root_nof; i < old_nof; ++i) {
    4214       13890 :     PropertyDetails old_details = old_descriptors->GetDetails(i);
    4215             :     Map* transition = TransitionArray::SearchTransition(
    4216             :         new_map, old_details.kind(), old_descriptors->GetKey(i),
    4217       13890 :         old_details.attributes());
    4218       13890 :     if (transition == NULL) return nullptr;
    4219             :     new_map = transition;
    4220             :     DescriptorArray* new_descriptors = new_map->instance_descriptors();
    4221             : 
    4222        9406 :     PropertyDetails new_details = new_descriptors->GetDetails(i);
    4223             :     DCHECK_EQ(old_details.kind(), new_details.kind());
    4224             :     DCHECK_EQ(old_details.attributes(), new_details.attributes());
    4225        9406 :     if (!IsGeneralizableTo(old_details.constness(), new_details.constness())) {
    4226             :       return nullptr;
    4227             :     }
    4228             :     DCHECK(IsGeneralizableTo(old_details.location(), new_details.location()));
    4229       28218 :     if (!old_details.representation().fits_into(new_details.representation())) {
    4230             :       return nullptr;
    4231             :     }
    4232        9354 :     if (new_details.location() == kField) {
    4233        9175 :       if (new_details.kind() == kData) {
    4234        9175 :         FieldType* new_type = new_descriptors->GetFieldType(i);
    4235             :         // Cleared field types need special treatment. They represent lost
    4236             :         // knowledge, so we must first generalize the new_type to "Any".
    4237        9175 :         if (FieldTypeIsCleared(new_details.representation(), new_type)) {
    4238             :           return nullptr;
    4239             :         }
    4240             :         DCHECK_EQ(kData, old_details.kind());
    4241        9175 :         if (old_details.location() == kField) {
    4242        7020 :           FieldType* old_type = old_descriptors->GetFieldType(i);
    4243       14040 :           if (FieldTypeIsCleared(old_details.representation(), old_type) ||
    4244        7020 :               !old_type->NowIs(new_type)) {
    4245             :             return nullptr;
    4246             :           }
    4247             :         } else {
    4248             :           DCHECK_EQ(kDescriptor, old_details.location());
    4249             :           DCHECK(!FLAG_track_constant_fields);
    4250             :           Object* old_value = old_descriptors->GetValue(i);
    4251        2155 :           if (!new_type->NowContains(old_value)) {
    4252             :             return nullptr;
    4253             :           }
    4254             :         }
    4255             : 
    4256             :       } else {
    4257             :         DCHECK_EQ(kAccessor, new_details.kind());
    4258             : #ifdef DEBUG
    4259             :         FieldType* new_type = new_descriptors->GetFieldType(i);
    4260             :         DCHECK(new_type->IsAny());
    4261             : #endif
    4262           0 :         UNREACHABLE();
    4263             :       }
    4264             :     } else {
    4265             :       DCHECK_EQ(kDescriptor, new_details.location());
    4266             :       Object* old_value = old_descriptors->GetValue(i);
    4267             :       Object* new_value = new_descriptors->GetValue(i);
    4268         179 :       if (old_details.location() == kField || old_value != new_value) {
    4269             :         return nullptr;
    4270             :       }
    4271             :     }
    4272             :   }
    4273      149147 :   if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr;
    4274      149147 :   return new_map;
    4275             : }
    4276             : 
    4277             : 
    4278             : // static
    4279    41286527 : Handle<Map> Map::Update(Handle<Map> map) {
    4280    41286527 :   if (!map->is_deprecated()) return map;
    4281       10322 :   MapUpdater mu(map->GetIsolate(), map);
    4282       10322 :   return mu.Update();
    4283             : }
    4284             : 
    4285      225641 : Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
    4286             :                                                  ShouldThrow should_throw,
    4287             :                                                  Handle<Object> value) {
    4288             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    4289             :   return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(),
    4290      225641 :                                             should_throw, value);
    4291             : }
    4292             : 
    4293     4261217 : MaybeHandle<Object> Object::SetProperty(Handle<Object> object,
    4294             :                                         Handle<Name> name, Handle<Object> value,
    4295             :                                         LanguageMode language_mode,
    4296             :                                         StoreFromKeyed store_mode) {
    4297     4261217 :   LookupIterator it(object, name);
    4298     4261217 :   MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode));
    4299             :   return value;
    4300             : }
    4301             : 
    4302             : 
    4303    33956756 : Maybe<bool> Object::SetPropertyInternal(LookupIterator* it,
    4304             :                                         Handle<Object> value,
    4305             :                                         LanguageMode language_mode,
    4306             :                                         StoreFromKeyed store_mode,
    4307             :                                         bool* found) {
    4308    16742905 :   it->UpdateProtector();
    4309             :   DCHECK(it->IsFound());
    4310             :   ShouldThrow should_throw =
    4311    16742905 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    4312             : 
    4313             :   // Make sure that the top context does not change when doing callbacks or
    4314             :   // interceptor calls.
    4315             :   AssertNoContextChange ncc(it->isolate());
    4316             : 
    4317      312937 :   do {
    4318    16900914 :     switch (it->state()) {
    4319             :       case LookupIterator::NOT_FOUND:
    4320           0 :         UNREACHABLE();
    4321             : 
    4322             :       case LookupIterator::ACCESS_CHECK:
    4323       87884 :         if (it->HasAccess()) break;
    4324             :         // Check whether it makes sense to reuse the lookup iterator. Here it
    4325             :         // might still call into setters up the prototype chain.
    4326             :         return JSObject::SetPropertyWithFailedAccessCheck(it, value,
    4327         131 :                                                           should_throw);
    4328             : 
    4329             :       case LookupIterator::JSPROXY:
    4330             :         return JSProxy::SetProperty(it->GetHolder<JSProxy>(), it->GetName(),
    4331       63039 :                                     value, it->GetReceiver(), language_mode);
    4332             : 
    4333             :       case LookupIterator::INTERCEPTOR: {
    4334      225664 :         if (it->HolderIsReceiverOrHiddenPrototype()) {
    4335             :           Maybe<bool> result =
    4336      225382 :               JSObject::SetPropertyWithInterceptor(it, should_throw, value);
    4337      450764 :           if (result.IsNothing() || result.FromJust()) return result;
    4338             :         } else {
    4339             :           Maybe<PropertyAttributes> maybe_attributes =
    4340         282 :               JSObject::GetPropertyAttributesWithInterceptor(it);
    4341         449 :           if (!maybe_attributes.IsJust()) return Nothing<bool>();
    4342         282 :           if ((maybe_attributes.FromJust() & READ_ONLY) != 0) {
    4343           0 :             return WriteToReadOnlyProperty(it, value, should_throw);
    4344             :           }
    4345         282 :           if (maybe_attributes.FromJust() == ABSENT) break;
    4346         167 :           *found = false;
    4347             :           return Nothing<bool>();
    4348             :         }
    4349             :         break;
    4350             :       }
    4351             : 
    4352             :       case LookupIterator::ACCESSOR: {
    4353      411223 :         if (it->IsReadOnly()) {
    4354        2651 :           return WriteToReadOnlyProperty(it, value, should_throw);
    4355             :         }
    4356      408572 :         Handle<Object> accessors = it->GetAccessors();
    4357      619174 :         if (accessors->IsAccessorInfo() &&
    4358      549563 :             !it->HolderIsReceiverOrHiddenPrototype() &&
    4359             :             AccessorInfo::cast(*accessors)->is_special_data_property()) {
    4360         713 :           *found = false;
    4361             :           return Nothing<bool>();
    4362             :         }
    4363      407859 :         return SetPropertyWithAccessor(it, value, should_throw);
    4364             :       }
    4365             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    4366             :         // TODO(verwaest): We should throw an exception if holder is receiver.
    4367             :         return Just(true);
    4368             : 
    4369             :       case LookupIterator::DATA:
    4370    14669663 :         if (it->IsReadOnly()) {
    4371       44336 :           return WriteToReadOnlyProperty(it, value, should_throw);
    4372             :         }
    4373    14625327 :         if (it->HolderIsReceiverOrHiddenPrototype()) {
    4374    14479426 :           return SetDataProperty(it, value);
    4375             :         }
    4376             :       // Fall through.
    4377             :       case LookupIterator::TRANSITION:
    4378     1586531 :         *found = false;
    4379             :         return Nothing<bool>();
    4380             :     }
    4381      312937 :     it->Next();
    4382             :   } while (it->IsFound());
    4383             : 
    4384      154928 :   *found = false;
    4385             :   return Nothing<bool>();
    4386             : }
    4387             : 
    4388             : 
    4389    35771073 : Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
    4390             :                                 LanguageMode language_mode,
    4391             :                                 StoreFromKeyed store_mode) {
    4392    35769223 :   if (it->IsFound()) {
    4393    16675299 :     bool found = true;
    4394             :     Maybe<bool> result =
    4395    16675299 :         SetPropertyInternal(it, value, language_mode, store_mode, &found);
    4396    16675299 :     if (found) return result;
    4397             :   }
    4398             : 
    4399             :   // If the receiver is the JSGlobalObject, the store was contextual. In case
    4400             :   // the property did not exist yet on the global object itself, we have to
    4401             :   // throw a reference error in strict mode.  In sloppy mode, we continue.
    4402    35876037 :   if (is_strict(language_mode) && it->GetReceiver()->IsJSGlobalObject()) {
    4403             :     it->isolate()->Throw(*it->isolate()->factory()->NewReferenceError(
    4404        1850 :         MessageTemplate::kNotDefined, it->name()));
    4405             :     return Nothing<bool>();
    4406             :   }
    4407             : 
    4408             :   ShouldThrow should_throw =
    4409    20832002 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    4410    20832002 :   return AddDataProperty(it, value, NONE, should_throw, store_mode);
    4411             : }
    4412             : 
    4413             : 
    4414       81956 : Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
    4415             :                                      LanguageMode language_mode,
    4416             :                                      StoreFromKeyed store_mode) {
    4417             :   Isolate* isolate = it->isolate();
    4418             : 
    4419       73680 :   if (it->IsFound()) {
    4420       67606 :     bool found = true;
    4421             :     Maybe<bool> result =
    4422       67606 :         SetPropertyInternal(it, value, language_mode, store_mode, &found);
    4423       67606 :     if (found) return result;
    4424             :   }
    4425             : 
    4426        9410 :   it->UpdateProtector();
    4427             : 
    4428             :   // The property either doesn't exist on the holder or exists there as a data
    4429             :   // property.
    4430             : 
    4431             :   ShouldThrow should_throw =
    4432        9410 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    4433             : 
    4434        9410 :   if (!it->GetReceiver()->IsJSReceiver()) {
    4435        1134 :     return WriteToReadOnlyProperty(it, value, should_throw);
    4436             :   }
    4437             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    4438             : 
    4439             :   LookupIterator::Configuration c = LookupIterator::OWN;
    4440             :   LookupIterator own_lookup =
    4441             :       it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
    4442       16552 :                       : LookupIterator(receiver, it->name(), c);
    4443             : 
    4444          28 :   for (; own_lookup.IsFound(); own_lookup.Next()) {
    4445        6162 :     switch (own_lookup.state()) {
    4446             :       case LookupIterator::ACCESS_CHECK:
    4447          34 :         if (!own_lookup.HasAccess()) {
    4448             :           return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value,
    4449           6 :                                                             should_throw);
    4450             :         }
    4451             :         break;
    4452             : 
    4453             :       case LookupIterator::ACCESSOR:
    4454        3052 :         if (own_lookup.GetAccessors()->IsAccessorInfo()) {
    4455          14 :           if (own_lookup.IsReadOnly()) {
    4456           0 :             return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
    4457             :           }
    4458             :           return JSObject::SetPropertyWithAccessor(&own_lookup, value,
    4459          14 :                                                    should_throw);
    4460             :         }
    4461             :       // Fall through.
    4462             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    4463             :         return RedefineIncompatibleProperty(isolate, it->GetName(), value,
    4464        3024 :                                             should_throw);
    4465             : 
    4466             :       case LookupIterator::DATA: {
    4467        1526 :         if (own_lookup.IsReadOnly()) {
    4468         462 :           return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
    4469             :         }
    4470        1064 :         return SetDataProperty(&own_lookup, value);
    4471             :       }
    4472             : 
    4473             :       case LookupIterator::INTERCEPTOR:
    4474             :       case LookupIterator::JSPROXY: {
    4475             :         PropertyDescriptor desc;
    4476             :         Maybe<bool> owned =
    4477        3076 :             JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc);
    4478        3076 :         MAYBE_RETURN(owned, Nothing<bool>());
    4479        2376 :         if (!owned.FromJust()) {
    4480             :           return JSReceiver::CreateDataProperty(&own_lookup, value,
    4481        1057 :                                                 should_throw);
    4482             :         }
    4483        2638 :         if (PropertyDescriptor::IsAccessorDescriptor(&desc) ||
    4484             :             !desc.writable()) {
    4485             :           return RedefineIncompatibleProperty(isolate, it->GetName(), value,
    4486           0 :                                               should_throw);
    4487             :         }
    4488             : 
    4489             :         PropertyDescriptor value_desc;
    4490             :         value_desc.set_value(value);
    4491             :         return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
    4492        2638 :                                              &value_desc, should_throw);
    4493             :       }
    4494             : 
    4495             :       case LookupIterator::NOT_FOUND:
    4496             :       case LookupIterator::TRANSITION:
    4497           0 :         UNREACHABLE();
    4498             :     }
    4499             :   }
    4500             : 
    4501        2142 :   return AddDataProperty(&own_lookup, value, NONE, should_throw, store_mode);
    4502             : }
    4503             : 
    4504        9541 : Maybe<bool> Object::CannotCreateProperty(Isolate* isolate,
    4505             :                                          Handle<Object> receiver,
    4506             :                                          Handle<Object> name,
    4507             :                                          Handle<Object> value,
    4508             :                                          ShouldThrow should_throw) {
    4509        9917 :   RETURN_FAILURE(
    4510             :       isolate, should_throw,
    4511             :       NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name,
    4512             :                    Object::TypeOf(isolate, receiver), receiver));
    4513             : }
    4514             : 
    4515             : 
    4516       97166 : Maybe<bool> Object::WriteToReadOnlyProperty(LookupIterator* it,
    4517             :                                             Handle<Object> value,
    4518             :                                             ShouldThrow should_throw) {
    4519             :   return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
    4520       97166 :                                  it->GetName(), value, should_throw);
    4521             : }
    4522             : 
    4523             : 
    4524       48583 : Maybe<bool> Object::WriteToReadOnlyProperty(Isolate* isolate,
    4525             :                                             Handle<Object> receiver,
    4526             :                                             Handle<Object> name,
    4527             :                                             Handle<Object> value,
    4528             :                                             ShouldThrow should_throw) {
    4529       79245 :   RETURN_FAILURE(isolate, should_throw,
    4530             :                  NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
    4531             :                               Object::TypeOf(isolate, receiver), receiver));
    4532             : }
    4533             : 
    4534             : 
    4535        1527 : Maybe<bool> Object::RedefineIncompatibleProperty(Isolate* isolate,
    4536             :                                                  Handle<Object> name,
    4537             :                                                  Handle<Object> value,
    4538             :                                                  ShouldThrow should_throw) {
    4539        1893 :   RETURN_FAILURE(isolate, should_throw,
    4540             :                  NewTypeError(MessageTemplate::kRedefineDisallowed, name));
    4541             : }
    4542             : 
    4543             : 
    4544    30968522 : Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) {
    4545             :   // Proxies are handled elsewhere. Other non-JSObjects cannot have own
    4546             :   // properties.
    4547             :   Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
    4548             : 
    4549             :   // Store on the holder which may be hidden behind the receiver.
    4550             :   DCHECK(it->HolderIsReceiverOrHiddenPrototype());
    4551             : 
    4552    15480531 :   Handle<Object> to_assign = value;
    4553             :   // Convert the incoming value to a number for storing into typed arrays.
    4554    16806606 :   if (it->IsElement() && receiver->HasFixedTypedArrayElements()) {
    4555     1152847 :     if (!value->IsNumber() && !value->IsUndefined(it->isolate())) {
    4556        5292 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    4557             :           it->isolate(), to_assign, Object::ToNumber(value), Nothing<bool>());
    4558             :       // We have to recheck the length. However, it can only change if the
    4559             :       // underlying buffer was neutered, so just check that.
    4560        2646 :       if (Handle<JSArrayBufferView>::cast(receiver)->WasNeutered()) {
    4561             :         return Just(true);
    4562             :         // TODO(neis): According to the spec, this should throw a TypeError.
    4563             :       }
    4564             :     }
    4565             :   }
    4566             : 
    4567             :   // Possibly migrate to the most up-to-date map that will be able to store
    4568             :   // |value| under it->name().
    4569    15480531 :   it->PrepareForDataProperty(to_assign);
    4570             : 
    4571             :   // Write the property value.
    4572    15480531 :   it->WriteDataValue(to_assign, false);
    4573             : 
    4574             : #if VERIFY_HEAP
    4575             :   if (FLAG_verify_heap) {
    4576             :     receiver->JSObjectVerify();
    4577             :   }
    4578             : #endif
    4579             :   return Just(true);
    4580             : }
    4581             : 
    4582             : 
    4583   172996110 : Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
    4584             :                                     PropertyAttributes attributes,
    4585             :                                     ShouldThrow should_throw,
    4586             :                                     StoreFromKeyed store_mode) {
    4587    55988259 :   if (!it->GetReceiver()->IsJSObject()) {
    4588        9625 :     if (it->GetReceiver()->IsJSProxy() && it->GetName()->IsPrivate()) {
    4589          70 :       RETURN_FAILURE(it->isolate(), should_throw,
    4590             :                      NewTypeError(MessageTemplate::kProxyPrivate));
    4591             :     }
    4592             :     return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
    4593       19082 :                                 value, should_throw);
    4594             :   }
    4595             : 
    4596             :   DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
    4597             : 
    4598    55978676 :   Handle<JSObject> receiver = it->GetStoreTarget();
    4599             : 
    4600             :   // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
    4601             :   // instead. If the prototype is Null, the proxy is detached.
    4602    55978630 :   if (receiver->IsJSGlobalProxy()) return Just(true);
    4603             : 
    4604             :   Isolate* isolate = it->isolate();
    4605             : 
    4606    55978630 :   if (it->ExtendingNonExtensible(receiver)) {
    4607      607516 :     RETURN_FAILURE(
    4608             :         isolate, should_throw,
    4609             :         NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName()));
    4610             :   }
    4611             : 
    4612    55823389 :   if (it->IsElement()) {
    4613     3678050 :     if (receiver->IsJSArray()) {
    4614             :       Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    4615     1518673 :       if (JSArray::WouldChangeReadOnlyLength(array, it->index())) {
    4616        1719 :         RETURN_FAILURE(array->GetIsolate(), should_throw,
    4617             :                        NewTypeError(MessageTemplate::kStrictReadOnlyProperty,
    4618             :                                     isolate->factory()->length_string(),
    4619             :                                     Object::TypeOf(isolate, array), array));
    4620             :       }
    4621             : 
    4622     1518211 :       if (FLAG_trace_external_array_abuse &&
    4623           0 :           array->HasFixedTypedArrayElements()) {
    4624           0 :         CheckArrayAbuse(array, "typed elements write", it->index(), true);
    4625             :       }
    4626             : 
    4627     1518211 :       if (FLAG_trace_js_array_abuse && !array->HasFixedTypedArrayElements()) {
    4628           0 :         CheckArrayAbuse(array, "elements write", it->index(), false);
    4629             :       }
    4630             :     }
    4631             : 
    4632             :     Maybe<bool> result = JSObject::AddDataElement(receiver, it->index(), value,
    4633     3677588 :                                                   attributes, should_throw);
    4634             :     JSObject::ValidateElements(receiver);
    4635     3677588 :     return result;
    4636             :   } else {
    4637    52145339 :     it->UpdateProtector();
    4638             :     // Migrate to the most up-to-date map that will be able to store |value|
    4639             :     // under it->name() with |attributes|.
    4640             :     it->PrepareTransitionToDataProperty(receiver, value, attributes,
    4641    52145351 :                                         store_mode);
    4642             :     DCHECK_EQ(LookupIterator::TRANSITION, it->state());
    4643    52145379 :     it->ApplyTransitionToDataProperty(receiver);
    4644             : 
    4645             :     // Write the property value.
    4646    52145354 :     it->WriteDataValue(value, true);
    4647             : 
    4648             : #if VERIFY_HEAP
    4649             :     if (FLAG_verify_heap) {
    4650             :       receiver->JSObjectVerify();
    4651             :     }
    4652             : #endif
    4653             :   }
    4654             : 
    4655             :   return Just(true);
    4656             : }
    4657             : 
    4658             : 
    4659     5827916 : void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
    4660             :   // Only supports adding slack to owned descriptors.
    4661             :   DCHECK(map->owns_descriptors());
    4662             : 
    4663             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    4664             :   int old_size = map->NumberOfOwnDescriptors();
    4665     5827916 :   if (slack <= descriptors->NumberOfSlackDescriptors()) return;
    4666             : 
    4667             :   Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
    4668             :       descriptors, old_size, slack);
    4669             : 
    4670             :   DisallowHeapAllocation no_allocation;
    4671             :   // The descriptors are still the same, so keep the layout descriptor.
    4672             :   LayoutDescriptor* layout_descriptor = map->GetLayoutDescriptor();
    4673             : 
    4674     5827915 :   if (old_size == 0) {
    4675        2669 :     map->UpdateDescriptors(*new_descriptors, layout_descriptor);
    4676        2669 :     return;
    4677             :   }
    4678             : 
    4679             :   // If the source descriptors had an enum cache we copy it. This ensures
    4680             :   // that the maps to which we push the new descriptor array back can rely
    4681             :   // on a cache always being available once it is set. If the map has more
    4682             :   // enumerated descriptors than available in the original cache, the cache
    4683             :   // will be lazily replaced by the extended cache when needed.
    4684     5825246 :   if (descriptors->HasEnumCache()) {
    4685       36785 :     new_descriptors->CopyEnumCacheFrom(*descriptors);
    4686             :   }
    4687             : 
    4688             :   Isolate* isolate = map->GetIsolate();
    4689             :   // Replace descriptors by new_descriptors in all maps that share it.
    4690     5825246 :   isolate->heap()->incremental_marking()->IterateBlackObject(*descriptors);
    4691             : 
    4692             :   Map* current = *map;
    4693    49662079 :   while (current->instance_descriptors() == *descriptors) {
    4694    38012161 :     Object* next = current->GetBackPointer();
    4695    38012166 :     if (next->IsUndefined(isolate)) break;  // Stop overwriting at initial map.
    4696    38011591 :     current->UpdateDescriptors(*new_descriptors, layout_descriptor);
    4697             :     current = Map::cast(next);
    4698             :   }
    4699     5825246 :   map->UpdateDescriptors(*new_descriptors, layout_descriptor);
    4700             : }
    4701             : 
    4702             : // static
    4703      189387 : Handle<Map> Map::GetObjectCreateMap(Handle<HeapObject> prototype) {
    4704             :   Isolate* isolate = prototype->GetIsolate();
    4705             :   Handle<Map> map(isolate->native_context()->object_function()->initial_map(),
    4706      378774 :                   isolate);
    4707      189387 :   if (map->prototype() == *prototype) return map;
    4708      189358 :   if (prototype->IsNull(isolate)) {
    4709         559 :     return isolate->slow_object_with_null_prototype_map();
    4710             :   }
    4711      188799 :   if (prototype->IsJSObject()) {
    4712             :     Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype);
    4713      187691 :     if (!js_prototype->map()->is_prototype_map()) {
    4714      183660 :       JSObject::OptimizeAsPrototype(js_prototype, FAST_PROTOTYPE);
    4715             :     }
    4716             :     Handle<PrototypeInfo> info =
    4717      187691 :         Map::GetOrCreatePrototypeInfo(js_prototype, isolate);
    4718             :     // TODO(verwaest): Use inobject slack tracking for this map.
    4719      187691 :     if (info->HasObjectCreateMap()) {
    4720             :       map = handle(info->ObjectCreateMap(), isolate);
    4721             :     } else {
    4722      187630 :       map = Map::CopyInitialMap(map);
    4723      187630 :       Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
    4724      187630 :       PrototypeInfo::SetObjectCreateMap(info, map);
    4725             :     }
    4726      187691 :     return map;
    4727             :   }
    4728             : 
    4729        1108 :   return Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE);
    4730             : }
    4731             : 
    4732             : template <class T>
    4733       63263 : static int AppendUniqueCallbacks(Handle<TemplateList> callbacks,
    4734             :                                  Handle<typename T::Array> array,
    4735             :                                  int valid_descriptors) {
    4736             :   int nof_callbacks = callbacks->length();
    4737             : 
    4738             :   Isolate* isolate = array->GetIsolate();
    4739             :   // Ensure the keys are unique names before writing them into the
    4740             :   // instance descriptor. Since it may cause a GC, it has to be done before we
    4741             :   // temporarily put the heap in an invalid state while appending descriptors.
    4742      190118 :   for (int i = 0; i < nof_callbacks; ++i) {
    4743             :     Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)));
    4744       64167 :     if (entry->name()->IsUniqueName()) continue;
    4745             :     Handle<String> key =
    4746             :         isolate->factory()->InternalizeString(
    4747       63017 :             Handle<String>(String::cast(entry->name())));
    4748       63017 :     entry->set_name(*key);
    4749             :   }
    4750             : 
    4751             :   // Fill in new callback descriptors.  Process the callbacks from
    4752             :   // back to front so that the last callback with a given name takes
    4753             :   // precedence over previously added callbacks with that name.
    4754      126855 :   for (int i = nof_callbacks - 1; i >= 0; i--) {
    4755             :     Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)));
    4756             :     Handle<Name> key(Name::cast(entry->name()));
    4757             :     // Check if a descriptor with this name already exists before writing.
    4758       63592 :     if (!T::Contains(key, entry, valid_descriptors, array)) {
    4759           0 :       T::Insert(key, entry, valid_descriptors, array);
    4760       63578 :       valid_descriptors++;
    4761             :     }
    4762             :   }
    4763             : 
    4764       63263 :   return valid_descriptors;
    4765             : }
    4766             : 
    4767             : struct DescriptorArrayAppender {
    4768             :   typedef DescriptorArray Array;
    4769             :   static bool Contains(Handle<Name> key,
    4770             :                        Handle<AccessorInfo> entry,
    4771             :                        int valid_descriptors,
    4772             :                        Handle<DescriptorArray> array) {
    4773             :     DisallowHeapAllocation no_gc;
    4774             :     return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound;
    4775             :   }
    4776           0 :   static void Insert(Handle<Name> key,
    4777             :                      Handle<AccessorInfo> entry,
    4778             :                      int valid_descriptors,
    4779             :                      Handle<DescriptorArray> array) {
    4780             :     DisallowHeapAllocation no_gc;
    4781             :     Descriptor d =
    4782             :         Descriptor::AccessorConstant(key, entry, entry->property_attributes());
    4783           0 :     array->Append(&d);
    4784           0 :   }
    4785             : };
    4786             : 
    4787             : 
    4788             : struct FixedArrayAppender {
    4789             :   typedef FixedArray Array;
    4790       63592 :   static bool Contains(Handle<Name> key,
    4791             :                        Handle<AccessorInfo> entry,
    4792             :                        int valid_descriptors,
    4793             :                        Handle<FixedArray> array) {
    4794         609 :     for (int i = 0; i < valid_descriptors; i++) {
    4795         623 :       if (*key == AccessorInfo::cast(array->get(i))->name()) return true;
    4796             :     }
    4797             :     return false;
    4798             :   }
    4799             :   static void Insert(Handle<Name> key,
    4800             :                      Handle<AccessorInfo> entry,
    4801             :                      int valid_descriptors,
    4802             :                      Handle<FixedArray> array) {
    4803             :     DisallowHeapAllocation no_gc;
    4804       63578 :     array->set(valid_descriptors, *entry);
    4805             :   }
    4806             : };
    4807             : 
    4808             : 
    4809           0 : void Map::AppendCallbackDescriptors(Handle<Map> map,
    4810             :                                     Handle<Object> descriptors) {
    4811             :   int nof = map->NumberOfOwnDescriptors();
    4812             :   Handle<DescriptorArray> array(map->instance_descriptors());
    4813           0 :   Handle<TemplateList> callbacks = Handle<TemplateList>::cast(descriptors);
    4814             :   DCHECK_GE(array->NumberOfSlackDescriptors(), callbacks->length());
    4815           0 :   nof = AppendUniqueCallbacks<DescriptorArrayAppender>(callbacks, array, nof);
    4816             :   map->SetNumberOfOwnDescriptors(nof);
    4817           0 : }
    4818             : 
    4819             : 
    4820       63263 : int AccessorInfo::AppendUnique(Handle<Object> descriptors,
    4821             :                                Handle<FixedArray> array,
    4822             :                                int valid_descriptors) {
    4823       63263 :   Handle<TemplateList> callbacks = Handle<TemplateList>::cast(descriptors);
    4824             :   DCHECK_GE(array->length(), callbacks->length() + valid_descriptors);
    4825             :   return AppendUniqueCallbacks<FixedArrayAppender>(callbacks, array,
    4826       63263 :                                                    valid_descriptors);
    4827             : }
    4828             : 
    4829             : 
    4830      316343 : static bool ContainsMap(MapHandleList* maps, Map* map) {
    4831             :   DCHECK_NOT_NULL(map);
    4832      486083 :   for (int i = 0; i < maps->length(); ++i) {
    4833      391740 :     if (!maps->at(i).is_null() && *maps->at(i) == map) return true;
    4834             :   }
    4835             :   return false;
    4836             : }
    4837             : 
    4838       95612 : Map* Map::FindElementsKindTransitionedMap(MapHandleList* candidates) {
    4839             :   DisallowHeapAllocation no_allocation;
    4840             :   DisallowDeoptimization no_deoptimization(GetIsolate());
    4841             : 
    4842             :   ElementsKind kind = elements_kind();
    4843             :   bool packed = IsFastPackedElementsKind(kind);
    4844             : 
    4845             :   Map* transition = nullptr;
    4846       95612 :   if (IsTransitionableFastElementsKind(kind)) {
    4847             :     // Check the state of the root map.
    4848       47616 :     Map* root_map = FindRootMap();
    4849       47616 :     if (!EquivalentToForTransition(root_map)) return nullptr;
    4850             :     root_map = root_map->LookupElementsTransitionMap(kind);
    4851             :     DCHECK_NOT_NULL(root_map);
    4852             :     // Starting from the next existing elements kind transition try to
    4853             :     // replay the property transitions that does not involve instance rewriting
    4854             :     // (ElementsTransitionAndStoreStub does not support that).
    4855      246388 :     for (root_map = root_map->ElementsTransitionMap();
    4856      352839 :          root_map != nullptr && root_map->has_fast_elements();
    4857             :          root_map = root_map->ElementsTransitionMap()) {
    4858      151156 :       Map* current = root_map->TryReplayPropertyTransitions(this);
    4859      151156 :       if (current == nullptr) continue;
    4860      146633 :       if (InstancesNeedRewriting(current)) continue;
    4861             : 
    4862      293206 :       if (ContainsMap(candidates, current) &&
    4863        5008 :           (packed || !IsFastPackedElementsKind(current->elements_kind()))) {
    4864             :         transition = current;
    4865       46837 :         packed = packed && IsFastPackedElementsKind(current->elements_kind());
    4866             :       }
    4867             :     }
    4868             :   }
    4869       95612 :   return transition;
    4870             : }
    4871             : 
    4872             : 
    4873     1575926 : static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
    4874             :   // Ensure we are requested to search elements kind transition "near the root".
    4875             :   DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(),
    4876             :             map->NumberOfOwnDescriptors());
    4877             :   Map* current_map = map;
    4878             : 
    4879             :   ElementsKind kind = map->elements_kind();
    4880     5510912 :   while (kind != to_kind) {
    4881             :     Map* next_map = current_map->ElementsTransitionMap();
    4882     2620972 :     if (next_map == nullptr) return current_map;
    4883             :     kind = next_map->elements_kind();
    4884             :     current_map = next_map;
    4885             :   }
    4886             : 
    4887             :   DCHECK_EQ(to_kind, current_map->elements_kind());
    4888             :   return current_map;
    4889             : }
    4890             : 
    4891             : 
    4892           0 : Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) {
    4893       47634 :   Map* to_map = FindClosestElementsTransition(this, to_kind);
    4894       47634 :   if (to_map->elements_kind() == to_kind) return to_map;
    4895             :   return nullptr;
    4896             : }
    4897             : 
    4898             : 
    4899      416144 : bool Map::IsMapInArrayPrototypeChain() {
    4900             :   Isolate* isolate = GetIsolate();
    4901      832288 :   if (isolate->initial_array_prototype()->map() == this) {
    4902             :     return true;
    4903             :   }
    4904             : 
    4905      830654 :   if (isolate->initial_object_prototype()->map() == this) {
    4906             :     return true;
    4907             :   }
    4908             : 
    4909      415083 :   return false;
    4910             : }
    4911             : 
    4912             : 
    4913    20613736 : Handle<WeakCell> Map::WeakCellForMap(Handle<Map> map) {
    4914             :   Isolate* isolate = map->GetIsolate();
    4915    20613735 :   if (map->weak_cell_cache()->IsWeakCell()) {
    4916     8402194 :     return Handle<WeakCell>(WeakCell::cast(map->weak_cell_cache()));
    4917             :   }
    4918    12211541 :   Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(map);
    4919    12211541 :   map->set_weak_cell_cache(*weak_cell);
    4920    12211542 :   return weak_cell;
    4921             : }
    4922             : 
    4923             : 
    4924      261912 : static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
    4925             :                                                  ElementsKind to_kind) {
    4926             :   DCHECK(IsTransitionElementsKind(map->elements_kind()));
    4927             : 
    4928             :   Handle<Map> current_map = map;
    4929             : 
    4930             :   ElementsKind kind = map->elements_kind();
    4931             :   TransitionFlag flag;
    4932      261912 :   if (map->is_prototype_map()) {
    4933             :     flag = OMIT_TRANSITION;
    4934             :   } else {
    4935             :     flag = INSERT_TRANSITION;
    4936      259586 :     if (IsFastElementsKind(kind)) {
    4937      536774 :       while (kind != to_kind && !IsTerminalElementsKind(kind)) {
    4938       10207 :         kind = GetNextTransitionElementsKind(kind);
    4939       10207 :         current_map = Map::CopyAsElementsKind(current_map, kind, flag);
    4940             :       }
    4941             :     }
    4942             :   }
    4943             : 
    4944             :   // In case we are exiting the fast elements kind system, just add the map in
    4945             :   // the end.
    4946      261912 :   if (kind != to_kind) {
    4947      259378 :     current_map = Map::CopyAsElementsKind(current_map, to_kind, flag);
    4948             :   }
    4949             : 
    4950             :   DCHECK(current_map->elements_kind() == to_kind);
    4951      261912 :   return current_map;
    4952             : }
    4953             : 
    4954             : 
    4955     2598719 : Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
    4956             :                                       ElementsKind to_kind) {
    4957             :   ElementsKind from_kind = map->elements_kind();
    4958     2598719 :   if (from_kind == to_kind) return map;
    4959             : 
    4960     1504183 :   Isolate* isolate = map->GetIsolate();
    4961             :   Context* native_context = isolate->context()->native_context();
    4962     1504183 :   if (from_kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
    4963         532 :     if (*map == native_context->fast_aliased_arguments_map()) {
    4964             :       DCHECK_EQ(SLOW_SLOPPY_ARGUMENTS_ELEMENTS, to_kind);
    4965             :       return handle(native_context->slow_aliased_arguments_map());
    4966             :     }
    4967     1503651 :   } else if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
    4968          30 :     if (*map == native_context->slow_aliased_arguments_map()) {
    4969             :       DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, to_kind);
    4970             :       return handle(native_context->fast_aliased_arguments_map());
    4971             :     }
    4972     3004009 :   } else if (IsFastElementsKind(from_kind) && IsFastElementsKind(to_kind)) {
    4973             :     // Reuse map transitions for JSArrays.
    4974             :     DisallowHeapAllocation no_gc;
    4975     1037401 :     if (native_context->get(Context::ArrayMapIndex(from_kind)) == *map) {
    4976             :       Object* maybe_transitioned_map =
    4977             :           native_context->get(Context::ArrayMapIndex(to_kind));
    4978      848228 :       if (maybe_transitioned_map->IsMap()) {
    4979             :         return handle(Map::cast(maybe_transitioned_map), isolate);
    4980             :       }
    4981             :     }
    4982             :   }
    4983             : 
    4984             :   DCHECK(!map->IsUndefined(isolate));
    4985             :   // Check if we can go back in the elements kind transition chain.
    4986     1282172 :   if (IsHoleyElementsKind(from_kind) &&
    4987           0 :       to_kind == GetPackedElementsKind(from_kind) &&
    4988      655483 :       map->GetBackPointer()->IsMap() &&
    4989           0 :       Map::cast(map->GetBackPointer())->elements_kind() == to_kind) {
    4990           0 :     return handle(Map::cast(map->GetBackPointer()));
    4991             :   }
    4992             : 
    4993             :   bool allow_store_transition = IsTransitionElementsKind(from_kind);
    4994             :   // Only store fast element maps in ascending generality.
    4995      655483 :   if (IsFastElementsKind(to_kind)) {
    4996             :     allow_store_transition =
    4997      570539 :         allow_store_transition && IsTransitionableFastElementsKind(from_kind) &&
    4998      189173 :         IsMoreGeneralElementsKindTransition(from_kind, to_kind);
    4999             :   }
    5000             : 
    5001      655483 :   if (!allow_store_transition) {
    5002        3035 :     return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION);
    5003             :   }
    5004             : 
    5005      652448 :   return Map::ReconfigureElementsKind(map, to_kind);
    5006             : }
    5007             : 
    5008             : 
    5009             : // static
    5010     1528292 : Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) {
    5011     1528292 :   Handle<Map> closest_map(FindClosestElementsTransition(*map, kind));
    5012             : 
    5013     1528292 :   if (closest_map->elements_kind() == kind) {
    5014     1266380 :     return closest_map;
    5015             :   }
    5016             : 
    5017      261912 :   return AddMissingElementsTransitions(closest_map, kind);
    5018             : }
    5019             : 
    5020             : 
    5021     2521477 : Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
    5022             :                                                ElementsKind to_kind) {
    5023             :   Handle<Map> map(object->map());
    5024     2521477 :   return Map::TransitionElementsTo(map, to_kind);
    5025             : }
    5026             : 
    5027             : 
    5028         188 : void JSProxy::Revoke(Handle<JSProxy> proxy) {
    5029             :   Isolate* isolate = proxy->GetIsolate();
    5030         362 :   if (!proxy->IsRevoked()) proxy->set_handler(isolate->heap()->null_value());
    5031             :   DCHECK(proxy->IsRevoked());
    5032         188 : }
    5033             : 
    5034             : 
    5035       68199 : Maybe<bool> JSProxy::HasProperty(Isolate* isolate, Handle<JSProxy> proxy,
    5036             :                                  Handle<Name> name) {
    5037             :   DCHECK(!name->IsPrivate());
    5038       68199 :   STACK_CHECK(isolate, Nothing<bool>());
    5039             :   // 1. (Assert)
    5040             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    5041             :   Handle<Object> handler(proxy->handler(), isolate);
    5042             :   // 3. If handler is null, throw a TypeError exception.
    5043             :   // 4. Assert: Type(handler) is Object.
    5044       68185 :   if (proxy->IsRevoked()) {
    5045             :     isolate->Throw(*isolate->factory()->NewTypeError(
    5046          56 :         MessageTemplate::kProxyRevoked, isolate->factory()->has_string()));
    5047             :     return Nothing<bool>();
    5048             :   }
    5049             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    5050             :   Handle<JSReceiver> target(proxy->target(), isolate);
    5051             :   // 6. Let trap be ? GetMethod(handler, "has").
    5052             :   Handle<Object> trap;
    5053      136314 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5054             :       isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler),
    5055             :                                        isolate->factory()->has_string()),
    5056             :       Nothing<bool>());
    5057             :   // 7. If trap is undefined, then
    5058       67947 :   if (trap->IsUndefined(isolate)) {
    5059             :     // 7a. Return target.[[HasProperty]](P).
    5060       53258 :     return JSReceiver::HasProperty(target, name);
    5061             :   }
    5062             :   // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, P»)).
    5063             :   Handle<Object> trap_result_obj;
    5064             :   Handle<Object> args[] = {target, name};
    5065       29378 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5066             :       isolate, trap_result_obj,
    5067             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    5068             :       Nothing<bool>());
    5069       14045 :   bool boolean_trap_result = trap_result_obj->BooleanValue();
    5070             :   // 9. If booleanTrapResult is false, then:
    5071       14045 :   if (!boolean_trap_result) {
    5072             :     // 9a. Let targetDesc be ? target.[[GetOwnProperty]](P).
    5073             :     PropertyDescriptor target_desc;
    5074             :     Maybe<bool> target_found = JSReceiver::GetOwnPropertyDescriptor(
    5075        8990 :         isolate, target, name, &target_desc);
    5076        9032 :     MAYBE_RETURN(target_found, Nothing<bool>());
    5077             :     // 9b. If targetDesc is not undefined, then:
    5078        8990 :     if (target_found.FromJust()) {
    5079             :       // 9b i. If targetDesc.[[Configurable]] is false, throw a TypeError
    5080             :       //       exception.
    5081          72 :       if (!target_desc.configurable()) {
    5082             :         isolate->Throw(*isolate->factory()->NewTypeError(
    5083          56 :             MessageTemplate::kProxyHasNonConfigurable, name));
    5084          42 :         return Nothing<bool>();
    5085             :       }
    5086             :       // 9b ii. Let extensibleTarget be ? IsExtensible(target).
    5087          44 :       Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    5088          44 :       MAYBE_RETURN(extensible_target, Nothing<bool>());
    5089             :       // 9b iii. If extensibleTarget is false, throw a TypeError exception.
    5090          44 :       if (!extensible_target.FromJust()) {
    5091             :         isolate->Throw(*isolate->factory()->NewTypeError(
    5092          28 :             MessageTemplate::kProxyHasNonExtensible, name));
    5093             :         return Nothing<bool>();
    5094             :       }
    5095             :     }
    5096             :   }
    5097             :   // 10. Return booleanTrapResult.
    5098             :   return Just(boolean_trap_result);
    5099             : }
    5100             : 
    5101             : 
    5102       63039 : Maybe<bool> JSProxy::SetProperty(Handle<JSProxy> proxy, Handle<Name> name,
    5103             :                                  Handle<Object> value, Handle<Object> receiver,
    5104             :                                  LanguageMode language_mode) {
    5105             :   DCHECK(!name->IsPrivate());
    5106             :   Isolate* isolate = proxy->GetIsolate();
    5107       63039 :   STACK_CHECK(isolate, Nothing<bool>());
    5108             :   Factory* factory = isolate->factory();
    5109             :   Handle<String> trap_name = factory->set_string();
    5110             :   ShouldThrow should_throw =
    5111       63011 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    5112             : 
    5113       63011 :   if (proxy->IsRevoked()) {
    5114             :     isolate->Throw(
    5115          56 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    5116             :     return Nothing<bool>();
    5117             :   }
    5118             :   Handle<JSReceiver> target(proxy->target(), isolate);
    5119             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    5120             : 
    5121             :   Handle<Object> trap;
    5122      125966 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5123             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    5124       62507 :   if (trap->IsUndefined(isolate)) {
    5125             :     LookupIterator it =
    5126       57942 :         LookupIterator::PropertyOrElement(isolate, receiver, name, target);
    5127             :     return Object::SetSuperProperty(&it, value, language_mode,
    5128       57942 :                                     Object::MAY_BE_STORE_FROM_KEYED);
    5129             :   }
    5130             : 
    5131             :   Handle<Object> trap_result;
    5132        4565 :   Handle<Object> args[] = {target, name, value, receiver};
    5133        9130 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5134             :       isolate, trap_result,
    5135             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    5136             :       Nothing<bool>());
    5137        4061 :   if (!trap_result->BooleanValue()) {
    5138         869 :     RETURN_FAILURE(isolate, should_throw,
    5139             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    5140             :                                 trap_name, name));
    5141             :   }
    5142             : 
    5143             :   // Enforce the invariant.
    5144             :   PropertyDescriptor target_desc;
    5145             :   Maybe<bool> owned =
    5146        3332 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    5147        3332 :   MAYBE_RETURN(owned, Nothing<bool>());
    5148        3332 :   if (owned.FromJust()) {
    5149        1526 :     bool inconsistent = PropertyDescriptor::IsDataDescriptor(&target_desc) &&
    5150         840 :                         !target_desc.configurable() &&
    5151        2646 :                         !target_desc.writable() &&
    5152         560 :                         !value->SameValue(*target_desc.value());
    5153        2086 :     if (inconsistent) {
    5154             :       isolate->Throw(*isolate->factory()->NewTypeError(
    5155         560 :           MessageTemplate::kProxySetFrozenData, name));
    5156             :       return Nothing<bool>();
    5157             :     }
    5158         560 :     inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
    5159        2086 :                    !target_desc.configurable() &&
    5160             :                    target_desc.set()->IsUndefined(isolate);
    5161        1806 :     if (inconsistent) {
    5162             :       isolate->Throw(*isolate->factory()->NewTypeError(
    5163         560 :           MessageTemplate::kProxySetFrozenAccessor, name));
    5164             :       return Nothing<bool>();
    5165             :     }
    5166             :   }
    5167             :   return Just(true);
    5168             : }
    5169             : 
    5170             : 
    5171        4817 : Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy,
    5172             :                                              Handle<Name> name,
    5173             :                                              LanguageMode language_mode) {
    5174             :   DCHECK(!name->IsPrivate());
    5175             :   ShouldThrow should_throw =
    5176        4817 :       is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    5177             :   Isolate* isolate = proxy->GetIsolate();
    5178        4817 :   STACK_CHECK(isolate, Nothing<bool>());
    5179             :   Factory* factory = isolate->factory();
    5180             :   Handle<String> trap_name = factory->deleteProperty_string();
    5181             : 
    5182        4817 :   if (proxy->IsRevoked()) {
    5183             :     isolate->Throw(
    5184          56 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    5185             :     return Nothing<bool>();
    5186             :   }
    5187             :   Handle<JSReceiver> target(proxy->target(), isolate);
    5188             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    5189             : 
    5190             :   Handle<Object> trap;
    5191        9578 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5192             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    5193        4579 :   if (trap->IsUndefined(isolate)) {
    5194        1261 :     return JSReceiver::DeletePropertyOrElement(target, name, language_mode);
    5195             :   }
    5196             : 
    5197             :   Handle<Object> trap_result;
    5198             :   Handle<Object> args[] = {target, name};
    5199        6636 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    5200             :       isolate, trap_result,
    5201             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    5202             :       Nothing<bool>());
    5203        2814 :   if (!trap_result->BooleanValue()) {
    5204        1932 :     RETURN_FAILURE(isolate, should_throw,
    5205             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    5206             :                                 trap_name, name));
    5207             :   }
    5208             : 
    5209             :   // Enforce the invariant.
    5210             :   PropertyDescriptor target_desc;
    5211             :   Maybe<bool> owned =
    5212        1638 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    5213        1638 :   MAYBE_RETURN(owned, Nothing<bool>());
    5214        2478 :   if (owned.FromJust() && !target_desc.configurable()) {
    5215             :     isolate->Throw(*factory->NewTypeError(
    5216        1120 :         MessageTemplate::kProxyDeletePropertyNonConfigurable, name));
    5217             :     return Nothing<bool>();
    5218             :   }
    5219             :   return Just(true);
    5220             : }
    5221             : 
    5222             : 
    5223             : // static
    5224       44734 : MaybeHandle<JSProxy> JSProxy::New(Isolate* isolate, Handle<Object> target,
    5225             :                                   Handle<Object> handler) {
    5226       44734 :   if (!target->IsJSReceiver()) {
    5227          30 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject),
    5228             :                     JSProxy);
    5229             :   }
    5230       49761 :   if (target->IsJSProxy() && JSProxy::cast(*target)->IsRevoked()) {
    5231           0 :     THROW_NEW_ERROR(isolate,
    5232             :                     NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
    5233             :                     JSProxy);
    5234             :   }
    5235       44719 :   if (!handler->IsJSReceiver()) {
    5236           0 :     THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject),
    5237             :                     JSProxy);
    5238             :   }
    5239       52139 :   if (handler->IsJSProxy() && JSProxy::cast(*handler)->IsRevoked()) {
    5240           0 :     THROW_NEW_ERROR(isolate,
    5241             :                     NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
    5242             :                     JSProxy);
    5243             :   }
    5244             :   return isolate->factory()->NewJSProxy(Handle<JSReceiver>::cast(target),
    5245       44719 :                                         Handle<JSReceiver>::cast(handler));
    5246             : }
    5247             : 
    5248             : 
    5249             : // static
    5250          29 : MaybeHandle<Context> JSProxy::GetFunctionRealm(Handle<JSProxy> proxy) {
    5251             :   DCHECK(proxy->map()->is_constructor());
    5252          29 :   if (proxy->IsRevoked()) {
    5253           0 :     THROW_NEW_ERROR(proxy->GetIsolate(),
    5254             :                     NewTypeError(MessageTemplate::kProxyRevoked), Context);
    5255             :   }
    5256             :   Handle<JSReceiver> target(JSReceiver::cast(proxy->target()));
    5257          29 :   return JSReceiver::GetFunctionRealm(target);
    5258             : }
    5259             : 
    5260             : 
    5261             : // static
    5262           0 : MaybeHandle<Context> JSBoundFunction::GetFunctionRealm(
    5263             :     Handle<JSBoundFunction> function) {
    5264             :   DCHECK(function->map()->is_constructor());
    5265             :   return JSReceiver::GetFunctionRealm(
    5266           0 :       handle(function->bound_target_function()));
    5267             : }
    5268             : 
    5269             : // static
    5270         341 : MaybeHandle<String> JSBoundFunction::GetName(Isolate* isolate,
    5271             :                                              Handle<JSBoundFunction> function) {
    5272             :   Handle<String> prefix = isolate->factory()->bound__string();
    5273         341 :   if (!function->bound_target_function()->IsJSFunction()) return prefix;
    5274             :   Handle<JSFunction> target(JSFunction::cast(function->bound_target_function()),
    5275             :                             isolate);
    5276         341 :   Handle<Object> target_name = JSFunction::GetName(isolate, target);
    5277         341 :   if (!target_name->IsString()) return prefix;
    5278             :   Factory* factory = isolate->factory();
    5279         341 :   return factory->NewConsString(prefix, Handle<String>::cast(target_name));
    5280             : }
    5281             : 
    5282             : // static
    5283      145679 : Handle<Object> JSFunction::GetName(Isolate* isolate,
    5284             :                                    Handle<JSFunction> function) {
    5285      145679 :   if (function->shared()->name_should_print_as_anonymous()) {
    5286           0 :     return isolate->factory()->anonymous_string();
    5287             :   }
    5288             :   return handle(function->shared()->name(), isolate);
    5289             : }
    5290             : 
    5291             : // static
    5292       24391 : MaybeHandle<Smi> JSFunction::GetLength(Isolate* isolate,
    5293             :                                        Handle<JSFunction> function) {
    5294             :   int length = 0;
    5295       24391 :   if (function->shared()->is_compiled()) {
    5296             :     length = function->shared()->GetLength();
    5297             :   } else {
    5298             :     // If the function isn't compiled yet, the length is not computed
    5299             :     // correctly yet. Compile it now and return the right length.
    5300        2141 :     if (Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) {
    5301             :       length = function->shared()->GetLength();
    5302             :     }
    5303        2141 :     if (isolate->has_pending_exception()) return MaybeHandle<Smi>();
    5304             :   }
    5305             :   DCHECK_GE(length, 0);
    5306             :   return handle(Smi::FromInt(length), isolate);
    5307             : }
    5308             : 
    5309             : // static
    5310        4331 : Handle<Context> JSFunction::GetFunctionRealm(Handle<JSFunction> function) {
    5311             :   DCHECK(function->map()->is_constructor());
    5312        4331 :   return handle(function->context()->native_context());
    5313             : }
    5314             : 
    5315             : 
    5316             : // static
    5317           0 : MaybeHandle<Context> JSObject::GetFunctionRealm(Handle<JSObject> object) {
    5318             :   DCHECK(object->map()->is_constructor());
    5319             :   DCHECK(!object->IsJSFunction());
    5320           0 :   return object->GetCreationContext();
    5321             : }
    5322             : 
    5323             : 
    5324             : // static
    5325        4360 : MaybeHandle<Context> JSReceiver::GetFunctionRealm(Handle<JSReceiver> receiver) {
    5326        4360 :   if (receiver->IsJSProxy()) {
    5327          29 :     return JSProxy::GetFunctionRealm(Handle<JSProxy>::cast(receiver));
    5328             :   }
    5329             : 
    5330        4331 :   if (receiver->IsJSFunction()) {
    5331        4331 :     return JSFunction::GetFunctionRealm(Handle<JSFunction>::cast(receiver));
    5332             :   }
    5333             : 
    5334           0 :   if (receiver->IsJSBoundFunction()) {
    5335             :     return JSBoundFunction::GetFunctionRealm(
    5336           0 :         Handle<JSBoundFunction>::cast(receiver));
    5337             :   }
    5338             : 
    5339             :   return JSObject::GetFunctionRealm(Handle<JSObject>::cast(receiver));
    5340             : }
    5341             : 
    5342             : 
    5343        4940 : Maybe<PropertyAttributes> JSProxy::GetPropertyAttributes(LookupIterator* it) {
    5344             :   PropertyDescriptor desc;
    5345             :   Maybe<bool> found = JSProxy::GetOwnPropertyDescriptor(
    5346        4940 :       it->isolate(), it->GetHolder<JSProxy>(), it->GetName(), &desc);
    5347        2470 :   MAYBE_RETURN(found, Nothing<PropertyAttributes>());
    5348        2005 :   if (!found.FromJust()) return Just(ABSENT);
    5349        1766 :   return Just(desc.ToAttributes());
    5350             : }
    5351             : 
    5352             : 
    5353     9945177 : void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
    5354             :   DCHECK(object->map()->GetInObjectProperties() ==
    5355             :          map->GetInObjectProperties());
    5356             :   ElementsKind obj_kind = object->map()->elements_kind();
    5357             :   ElementsKind map_kind = map->elements_kind();
    5358     9945177 :   if (map_kind != obj_kind) {
    5359             :     ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind);
    5360          60 :     if (IsDictionaryElementsKind(obj_kind)) {
    5361             :       to_kind = obj_kind;
    5362             :     }
    5363          60 :     if (IsDictionaryElementsKind(to_kind)) {
    5364          45 :       NormalizeElements(object);
    5365             :     } else {
    5366          15 :       TransitionElementsKind(object, to_kind);
    5367             :     }
    5368          60 :     map = Map::ReconfigureElementsKind(map, to_kind);
    5369             :   }
    5370     9945177 :   JSObject::MigrateToMap(object, map);
    5371     9945177 : }
    5372             : 
    5373             : 
    5374        9760 : void JSObject::MigrateInstance(Handle<JSObject> object) {
    5375             :   Handle<Map> original_map(object->map());
    5376        9760 :   Handle<Map> map = Map::Update(original_map);
    5377             :   map->set_migration_target(true);
    5378        9760 :   MigrateToMap(object, map);
    5379        9760 :   if (FLAG_trace_migration) {
    5380           0 :     object->PrintInstanceMigration(stdout, *original_map, *map);
    5381             :   }
    5382             : #if VERIFY_HEAP
    5383             :   if (FLAG_verify_heap) {
    5384             :     object->JSObjectVerify();
    5385             :   }
    5386             : #endif
    5387        9760 : }
    5388             : 
    5389             : 
    5390             : // static
    5391        8224 : bool JSObject::TryMigrateInstance(Handle<JSObject> object) {
    5392             :   Isolate* isolate = object->GetIsolate();
    5393             :   DisallowDeoptimization no_deoptimization(isolate);
    5394             :   Handle<Map> original_map(object->map(), isolate);
    5395             :   Handle<Map> new_map;
    5396       16448 :   if (!Map::TryUpdate(original_map).ToHandle(&new_map)) {
    5397             :     return false;
    5398             :   }
    5399        8196 :   JSObject::MigrateToMap(object, new_map);
    5400        8196 :   if (FLAG_trace_migration && *original_map != object->map()) {
    5401           0 :     object->PrintInstanceMigration(stdout, *original_map, object->map());
    5402             :   }
    5403             : #if VERIFY_HEAP
    5404             :   if (FLAG_verify_heap) {
    5405             :     object->JSObjectVerify();
    5406             :   }
    5407             : #endif
    5408             :   return true;
    5409             : }
    5410             : 
    5411             : 
    5412    17973289 : void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name,
    5413             :                            Handle<Object> value,
    5414             :                            PropertyAttributes attributes) {
    5415    17973289 :   LookupIterator it(object, name, object, LookupIterator::OWN_SKIP_INTERCEPTOR);
    5416    17973293 :   CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
    5417             : #ifdef DEBUG
    5418             :   uint32_t index;
    5419             :   DCHECK(!object->IsJSProxy());
    5420             :   DCHECK(!name->AsArrayIndex(&index));
    5421             :   Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
    5422             :   DCHECK(maybe.IsJust());
    5423             :   DCHECK(!it.IsFound());
    5424             :   DCHECK(object->map()->is_extensible() || name->IsPrivate());
    5425             : #endif
    5426    17973293 :   CHECK(AddDataProperty(&it, value, attributes, THROW_ON_ERROR,
    5427             :                         CERTAINLY_NOT_STORE_FROM_KEYED)
    5428             :             .IsJust());
    5429    17973282 : }
    5430             : 
    5431             : 
    5432             : // Reconfigures a property to a data property with attributes, even if it is not
    5433             : // reconfigurable.
    5434             : // Requires a LookupIterator that does not look at the prototype chain beyond
    5435             : // hidden prototypes.
    5436     2305905 : MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
    5437             :     LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
    5438             :     AccessorInfoHandling handling) {
    5439    16414810 :   MAYBE_RETURN_NULL(DefineOwnPropertyIgnoreAttributes(
    5440             :       it, value, attributes, THROW_ON_ERROR, handling));
    5441             :   return value;
    5442             : }
    5443             : 
    5444             : 
    5445    16749027 : Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
    5446    16785146 :     LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
    5447             :     ShouldThrow should_throw, AccessorInfoHandling handling) {
    5448    16749027 :   it->UpdateProtector();
    5449             :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    5450             : 
    5451    33500089 :   for (; it->IsFound(); it->Next()) {
    5452     2608756 :     switch (it->state()) {
    5453             :       case LookupIterator::JSPROXY:
    5454             :       case LookupIterator::NOT_FOUND:
    5455             :       case LookupIterator::TRANSITION:
    5456           0 :         UNREACHABLE();
    5457             : 
    5458             :       case LookupIterator::ACCESS_CHECK:
    5459         771 :         if (!it->HasAccess()) {
    5460           6 :           it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    5461           6 :           RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    5462             :           return Just(true);
    5463             :         }
    5464             :         break;
    5465             : 
    5466             :       // If there's an interceptor, try to store the property with the
    5467             :       // interceptor.
    5468             :       // In case of success, the attributes will have been reset to the default
    5469             :       // attributes of the interceptor, rather than the incoming attributes.
    5470             :       //
    5471             :       // TODO(verwaest): JSProxy afterwards verify the attributes that the
    5472             :       // JSProxy claims it has, and verifies that they are compatible. If not,
    5473             :       // they throw. Here we should do the same.
    5474             :       case LookupIterator::INTERCEPTOR:
    5475         259 :         if (handling == DONT_FORCE_FIELD) {
    5476             :           Maybe<bool> result =
    5477         259 :               JSObject::SetPropertyWithInterceptor(it, should_throw, value);
    5478         518 :           if (result.IsNothing() || result.FromJust()) return result;
    5479             :         }
    5480             :         break;
    5481             : 
    5482             :       case LookupIterator::ACCESSOR: {
    5483     1572594 :         Handle<Object> accessors = it->GetAccessors();
    5484             : 
    5485             :         // Special handling for AccessorInfo, which behaves like a data
    5486             :         // property.
    5487     1572594 :         if (accessors->IsAccessorInfo() && handling == DONT_FORCE_FIELD) {
    5488             :           PropertyAttributes current_attributes = it->property_attributes();
    5489             :           // Ensure the context isn't changed after calling into accessors.
    5490             :           AssertNoContextChange ncc(it->isolate());
    5491             : 
    5492             :           // Update the attributes before calling the setter. The setter may
    5493             :           // later change the shape of the property.
    5494     1571828 :           if (current_attributes != attributes) {
    5495       78644 :             it->TransitionToAccessorPair(accessors, attributes);
    5496             :           }
    5497             : 
    5498     1571828 :           return JSObject::SetPropertyWithAccessor(it, value, should_throw);
    5499             :         }
    5500             : 
    5501         766 :         it->ReconfigureDataProperty(value, attributes);
    5502             :         return Just(true);
    5503             :       }
    5504             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    5505             :         return RedefineIncompatibleProperty(it->isolate(), it->GetName(), value,
    5506          30 :                                             should_throw);
    5507             : 
    5508             :       case LookupIterator::DATA: {
    5509             :         // Regular property update if the attributes match.
    5510     1035116 :         if (it->property_attributes() == attributes) {
    5511     1000041 :           return SetDataProperty(it, value);
    5512             :         }
    5513             : 
    5514             :         // Special case: properties of typed arrays cannot be reconfigured to
    5515             :         // non-writable nor to non-enumerable.
    5516       67243 :         if (it->IsElement() && object->HasFixedTypedArrayElements()) {
    5517             :           return RedefineIncompatibleProperty(it->isolate(), it->GetName(),
    5518           0 :                                               value, should_throw);
    5519             :         }
    5520             : 
    5521             :         // Reconfigure the data property if the attributes mismatch.
    5522       35075 :         it->ReconfigureDataProperty(value, attributes);
    5523             : 
    5524             :         return Just(true);
    5525             :       }
    5526             :     }
    5527             :   }
    5528             : 
    5529             :   return AddDataProperty(it, value, attributes, should_throw,
    5530    14141288 :                          CERTAINLY_NOT_STORE_FROM_KEYED);
    5531             : }
    5532             : 
    5533    10946720 : MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
    5534             :     Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
    5535             :     PropertyAttributes attributes) {
    5536             :   DCHECK(!value->IsTheHole(object->GetIsolate()));
    5537    10946720 :   LookupIterator it(object, name, object, LookupIterator::OWN);
    5538    10946718 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    5539             : }
    5540             : 
    5541      295008 : MaybeHandle<Object> JSObject::SetOwnElementIgnoreAttributes(
    5542             :     Handle<JSObject> object, uint32_t index, Handle<Object> value,
    5543             :     PropertyAttributes attributes) {
    5544             :   Isolate* isolate = object->GetIsolate();
    5545             :   LookupIterator it(isolate, object, index, object, LookupIterator::OWN);
    5546      295008 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    5547             : }
    5548             : 
    5549     2016815 : MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes(
    5550             :     Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
    5551             :     PropertyAttributes attributes) {
    5552             :   Isolate* isolate = object->GetIsolate();
    5553             :   LookupIterator it = LookupIterator::PropertyOrElement(
    5554     2016815 :       isolate, object, name, object, LookupIterator::OWN);
    5555     2016815 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    5556             : }
    5557             : 
    5558      281223 : Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
    5559             :     LookupIterator* it) {
    5560      281223 :   return GetPropertyAttributesWithInterceptorInternal(it, it->GetInterceptor());
    5561             : }
    5562             : 
    5563    10832660 : Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
    5564    13995614 :     LookupIterator* it) {
    5565    27991228 :   for (; it->IsFound(); it->Next()) {
    5566    10148160 :     switch (it->state()) {
    5567             :       case LookupIterator::NOT_FOUND:
    5568             :       case LookupIterator::TRANSITION:
    5569           0 :         UNREACHABLE();
    5570             :       case LookupIterator::JSPROXY:
    5571        1304 :         return JSProxy::GetPropertyAttributes(it);
    5572             :       case LookupIterator::INTERCEPTOR: {
    5573             :         Maybe<PropertyAttributes> result =
    5574         411 :             JSObject::GetPropertyAttributesWithInterceptor(it);
    5575         466 :         if (!result.IsJust()) return result;
    5576         411 :         if (result.FromJust() != ABSENT) return result;
    5577         356 :         break;
    5578             :       }
    5579             :       case LookupIterator::ACCESS_CHECK:
    5580     3162695 :         if (it->HasAccess()) break;
    5581          97 :         return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
    5582             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    5583             :         return Just(ABSENT);
    5584             :       case LookupIterator::ACCESSOR:
    5585             :       case LookupIterator::DATA:
    5586             :         return Just(it->property_attributes());
    5587             :     }
    5588             :   }
    5589             :   return Just(ABSENT);
    5590             : }
    5591             : 
    5592             : 
    5593          79 : Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) {
    5594             :   Handle<FixedArray> array(
    5595          79 :       isolate->factory()->NewFixedArray(kEntries, TENURED));
    5596          79 :   return Handle<NormalizedMapCache>::cast(array);
    5597             : }
    5598             : 
    5599             : 
    5600     1082763 : MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
    5601             :                                          PropertyNormalizationMode mode) {
    5602             :   DisallowHeapAllocation no_gc;
    5603             :   Object* value = FixedArray::get(GetIndex(fast_map));
    5604     2049898 :   if (!value->IsMap() ||
    5605      967135 :       !Map::cast(value)->EquivalentToForNormalization(*fast_map, mode)) {
    5606             :     return MaybeHandle<Map>();
    5607             :   }
    5608             :   return handle(Map::cast(value));
    5609             : }
    5610             : 
    5611             : 
    5612      329339 : void NormalizedMapCache::Set(Handle<Map> fast_map,
    5613             :                              Handle<Map> normalized_map) {
    5614             :   DisallowHeapAllocation no_gc;
    5615             :   DCHECK(normalized_map->is_dictionary_map());
    5616      329339 :   FixedArray::set(GetIndex(fast_map), *normalized_map);
    5617      329339 : }
    5618             : 
    5619             : 
    5620       76392 : void NormalizedMapCache::Clear() {
    5621             :   int entries = length();
    5622     4965480 :   for (int i = 0; i != entries; i++) {
    5623     4889088 :     set_undefined(i);
    5624             :   }
    5625       76392 : }
    5626             : 
    5627             : 
    5628           0 : void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object,
    5629             :                                     Handle<Name> name,
    5630             :                                     Handle<Code> code) {
    5631             :   Handle<Map> map(object->map());
    5632           0 :   Map::UpdateCodeCache(map, name, code);
    5633           0 : }
    5634             : 
    5635             : 
    5636     1306883 : void JSObject::NormalizeProperties(Handle<JSObject> object,
    5637             :                                    PropertyNormalizationMode mode,
    5638             :                                    int expected_additional_properties,
    5639             :                                    const char* reason) {
    5640     1572995 :   if (!object->HasFastProperties()) return;
    5641             : 
    5642             :   Handle<Map> map(object->map());
    5643     1040771 :   Handle<Map> new_map = Map::Normalize(map, mode, reason);
    5644             : 
    5645     1040771 :   MigrateToMap(object, new_map, expected_additional_properties);
    5646             : }
    5647             : 
    5648             : 
    5649      791176 : void JSObject::MigrateSlowToFast(Handle<JSObject> object,
    5650             :                                  int unused_property_fields,
    5651             :                                  const char* reason) {
    5652     1188993 :   if (object->HasFastProperties()) return;
    5653             :   DCHECK(!object->IsJSGlobalObject());
    5654             :   Isolate* isolate = object->GetIsolate();
    5655             :   Factory* factory = isolate->factory();
    5656             :   Handle<NameDictionary> dictionary(object->property_dictionary());
    5657             : 
    5658             :   // Make sure we preserve dictionary representation if there are too many
    5659             :   // descriptors.
    5660             :   int number_of_elements = dictionary->NumberOfElements();
    5661      522846 :   if (number_of_elements > kMaxNumberOfDescriptors) return;
    5662             : 
    5663             :   Handle<FixedArray> iteration_order =
    5664      522263 :       NameDictionary::IterationIndices(dictionary);
    5665             : 
    5666             :   int instance_descriptor_length = iteration_order->length();
    5667             :   int number_of_fields = 0;
    5668             : 
    5669             :   // Compute the length of the instance descriptor.
    5670     3719095 :   for (int i = 0; i < instance_descriptor_length; i++) {
    5671             :     int index = Smi::cast(iteration_order->get(i))->value();
    5672             :     DCHECK(dictionary->IsKey(isolate, dictionary->KeyAt(index)));
    5673             : 
    5674             :     PropertyKind kind = dictionary->DetailsAt(index).kind();
    5675     3196832 :     if (kind == kData) {
    5676             :       if (FLAG_track_constant_fields) {
    5677             :         number_of_fields += 1;
    5678             :       } else {
    5679     2745428 :         Object* value = dictionary->ValueAt(index);
    5680     2745428 :         if (!value->IsJSFunction()) {
    5681      904111 :           number_of_fields += 1;
    5682             :         }
    5683             :       }
    5684             :     }
    5685             :   }
    5686             : 
    5687             :   Handle<Map> old_map(object->map(), isolate);
    5688             : 
    5689             :   int inobject_props = old_map->GetInObjectProperties();
    5690             : 
    5691             :   // Allocate new map.
    5692      522263 :   Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
    5693             :   new_map->set_dictionary_map(false);
    5694             : 
    5695      522263 :   NotifyMapChange(old_map, new_map, isolate);
    5696             : 
    5697             : #if TRACE_MAPS
    5698             :   if (FLAG_trace_maps) {
    5699             :     PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n",
    5700             :            reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map),
    5701             :            reason);
    5702             :   }
    5703             : #endif
    5704             : 
    5705      522263 :   if (instance_descriptor_length == 0) {
    5706             :     DisallowHeapAllocation no_gc;
    5707             :     DCHECK_LE(unused_property_fields, inobject_props);
    5708             :     // Transform the object.
    5709             :     new_map->set_unused_property_fields(inobject_props);
    5710      128904 :     object->synchronized_set_map(*new_map);
    5711      257808 :     object->set_properties(isolate->heap()->empty_fixed_array());
    5712             :     // Check that it really works.
    5713             :     DCHECK(object->HasFastProperties());
    5714             :     return;
    5715             :   }
    5716             : 
    5717             :   // Allocate the instance descriptor.
    5718             :   Handle<DescriptorArray> descriptors = DescriptorArray::Allocate(
    5719      393359 :       isolate, instance_descriptor_length, 0, TENURED);
    5720             : 
    5721             :   int number_of_allocated_fields =
    5722      393359 :       number_of_fields + unused_property_fields - inobject_props;
    5723      393359 :   if (number_of_allocated_fields < 0) {
    5724             :     // There is enough inobject space for all fields (including unused).
    5725             :     number_of_allocated_fields = 0;
    5726      121825 :     unused_property_fields = inobject_props - number_of_fields;
    5727             :   }
    5728             : 
    5729             :   // Allocate the fixed array for the fields.
    5730             :   Handle<FixedArray> fields = factory->NewFixedArray(
    5731      393359 :       number_of_allocated_fields);
    5732             : 
    5733             :   // Fill in the instance descriptor and the fields.
    5734             :   int current_offset = 0;
    5735     3590191 :   for (int i = 0; i < instance_descriptor_length; i++) {
    5736             :     int index = Smi::cast(iteration_order->get(i))->value();
    5737             :     Object* k = dictionary->KeyAt(index);
    5738             :     DCHECK(dictionary->IsKey(isolate, k));
    5739             :     // Dictionary keys are internalized upon insertion.
    5740             :     // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild.
    5741     3196832 :     CHECK(k->IsUniqueName());
    5742             :     Handle<Name> key(Name::cast(k), isolate);
    5743             : 
    5744     3196832 :     Object* value = dictionary->ValueAt(index);
    5745             : 
    5746             :     PropertyDetails details = dictionary->DetailsAt(index);
    5747             :     DCHECK_EQ(kField, details.location());
    5748             :     DCHECK_EQ(kMutable, details.constness());
    5749             : 
    5750             :     Descriptor d;
    5751     3196832 :     if (details.kind() == kData) {
    5752     2745428 :       if (!FLAG_track_constant_fields && value->IsJSFunction()) {
    5753             :         d = Descriptor::DataConstant(key, handle(value, isolate),
    5754     1841317 :                                      details.attributes());
    5755             :       } else {
    5756             :         d = Descriptor::DataField(
    5757             :             key, current_offset, details.attributes(), kDefaultFieldConstness,
    5758             :             // TODO(verwaest): value->OptimalRepresentation();
    5759     1808222 :             Representation::Tagged(), FieldType::Any(isolate));
    5760             :       }
    5761             :     } else {
    5762             :       DCHECK_EQ(kAccessor, details.kind());
    5763             :       d = Descriptor::AccessorConstant(key, handle(value, isolate),
    5764      451404 :                                        details.attributes());
    5765             :     }
    5766             :     details = d.GetDetails();
    5767     3196832 :     if (details.location() == kField) {
    5768      904111 :       if (current_offset < inobject_props) {
    5769             :         object->InObjectPropertyAtPut(current_offset, value,
    5770      493645 :                                       UPDATE_WRITE_BARRIER);
    5771             :       } else {
    5772      410466 :         int offset = current_offset - inobject_props;
    5773      410466 :         fields->set(offset, value);
    5774             :       }
    5775      904111 :       current_offset += details.field_width_in_words();
    5776             :     }
    5777     3196832 :     descriptors->Set(i, &d);
    5778             :   }
    5779             :   DCHECK(current_offset == number_of_fields);
    5780             : 
    5781      393359 :   descriptors->Sort();
    5782             : 
    5783             :   Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New(
    5784      393359 :       new_map, descriptors, descriptors->number_of_descriptors());
    5785             : 
    5786             :   DisallowHeapAllocation no_gc;
    5787      393359 :   new_map->InitializeDescriptors(*descriptors, *layout_descriptor);
    5788             :   new_map->set_unused_property_fields(unused_property_fields);
    5789             : 
    5790             :   // Transform the object.
    5791      393359 :   object->synchronized_set_map(*new_map);
    5792             : 
    5793      393359 :   object->set_properties(*fields);
    5794             :   DCHECK(object->IsJSObject());
    5795             : 
    5796             :   // Check that it really works.
    5797             :   DCHECK(object->HasFastProperties());
    5798             : }
    5799             : 
    5800             : 
    5801        5432 : void JSObject::ResetElements(Handle<JSObject> object) {
    5802             :   Isolate* isolate = object->GetIsolate();
    5803        5432 :   CHECK(object->map() != isolate->heap()->sloppy_arguments_elements_map());
    5804        5432 :   if (object->map()->has_dictionary_elements()) {
    5805             :     Handle<SeededNumberDictionary> new_elements =
    5806        3444 :         SeededNumberDictionary::New(isolate, 0);
    5807        3444 :     object->set_elements(*new_elements);
    5808             :   } else {
    5809        3976 :     object->set_elements(object->map()->GetInitialElements());
    5810             :   }
    5811        5432 : }
    5812             : 
    5813             : 
    5814      126525 : void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) {
    5815      253050 :   if (dictionary->requires_slow_elements()) return;
    5816             :   dictionary->set_requires_slow_elements();
    5817       75374 :   if (map()->is_prototype_map()) {
    5818             :     // If this object is a prototype (the callee will check), invalidate any
    5819             :     // prototype chains involving it.
    5820             :     InvalidatePrototypeChains(map());
    5821             :   }
    5822             : }
    5823             : 
    5824             : 
    5825      466454 : Handle<SeededNumberDictionary> JSObject::NormalizeElements(
    5826             :     Handle<JSObject> object) {
    5827             :   DCHECK(!object->HasFixedTypedArrayElements());
    5828      458557 :   Isolate* isolate = object->GetIsolate();
    5829      466454 :   bool is_arguments = object->HasSloppyArgumentsElements();
    5830             :   {
    5831             :     DisallowHeapAllocation no_gc;
    5832             :     FixedArrayBase* elements = object->elements();
    5833             : 
    5834      466454 :     if (is_arguments) {
    5835             :       FixedArray* parameter_map = FixedArray::cast(elements);
    5836             :       elements = FixedArrayBase::cast(parameter_map->get(1));
    5837             :     }
    5838             : 
    5839      466454 :     if (elements->IsDictionary()) {
    5840             :       return handle(SeededNumberDictionary::cast(elements), isolate);
    5841             :     }
    5842             :   }
    5843             : 
    5844             :   DCHECK(object->HasFastSmiOrObjectElements() ||
    5845             :          object->HasFastDoubleElements() ||
    5846             :          object->HasFastArgumentsElements() ||
    5847             :          object->HasFastStringWrapperElements());
    5848             : 
    5849             :   Handle<SeededNumberDictionary> dictionary =
    5850      458557 :       object->GetElementsAccessor()->Normalize(object);
    5851             : 
    5852             :   // Switch to using the dictionary as the backing storage for elements.
    5853             :   ElementsKind target_kind = is_arguments
    5854             :                                  ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS
    5855      458025 :                                  : object->HasFastStringWrapperElements()
    5856             :                                        ? SLOW_STRING_WRAPPER_ELEMENTS
    5857      916582 :                                        : DICTIONARY_ELEMENTS;
    5858      458557 :   Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind);
    5859             :   // Set the new map first to satify the elements type assert in set_elements().
    5860      458557 :   JSObject::MigrateToMap(object, new_map);
    5861             : 
    5862      458557 :   if (is_arguments) {
    5863         532 :     FixedArray::cast(object->elements())->set(1, *dictionary);
    5864             :   } else {
    5865      458025 :     object->set_elements(*dictionary);
    5866             :   }
    5867             : 
    5868      458557 :   isolate->counters()->elements_to_dictionary()->Increment();
    5869             : 
    5870             : #ifdef DEBUG
    5871             :   if (FLAG_trace_normalization) {
    5872             :     OFStream os(stdout);
    5873             :     os << "Object elements have been normalized:\n";
    5874             :     object->Print(os);
    5875             :   }
    5876             : #endif
    5877             : 
    5878             :   DCHECK(object->HasDictionaryElements() ||
    5879             :          object->HasSlowArgumentsElements() ||
    5880             :          object->HasSlowStringWrapperElements());
    5881      458557 :   return dictionary;
    5882             : }
    5883             : 
    5884             : 
    5885             : template <typename ProxyType>
    5886        3181 : static Smi* GetOrCreateIdentityHashHelper(Isolate* isolate,
    5887             :                                           Handle<ProxyType> proxy) {
    5888             :   Object* maybe_hash = proxy->hash();
    5889        3181 :   if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash);
    5890             : 
    5891         687 :   Smi* hash = Smi::FromInt(isolate->GenerateIdentityHash(Smi::kMaxValue));
    5892         687 :   proxy->set_hash(hash);
    5893         687 :   return hash;
    5894             : }
    5895             : 
    5896             : // static
    5897       20925 : Object* JSObject::GetIdentityHash(Isolate* isolate, Handle<JSObject> object) {
    5898       20925 :   if (object->IsJSGlobalProxy()) {
    5899          82 :     return JSGlobalProxy::cast(*object)->hash();
    5900             :   }
    5901             :   Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol();
    5902       41686 :   return *JSReceiver::GetDataProperty(object, hash_code_symbol);
    5903             : }
    5904             : 
    5905             : // static
    5906        3952 : Smi* JSObject::GetOrCreateIdentityHash(Isolate* isolate,
    5907             :                                        Handle<JSObject> object) {
    5908        3952 :   if (object->IsJSGlobalProxy()) {
    5909             :     return GetOrCreateIdentityHashHelper(isolate,
    5910          87 :                                          Handle<JSGlobalProxy>::cast(object));
    5911             :   }
    5912             : 
    5913             :   Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol();
    5914        3865 :   LookupIterator it(object, hash_code_symbol, object, LookupIterator::OWN);
    5915        3865 :   if (it.IsFound()) {
    5916             :     DCHECK_EQ(LookupIterator::DATA, it.state());
    5917         962 :     Object* maybe_hash = *it.GetDataValue();
    5918         481 :     if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash);
    5919             :   }
    5920             : 
    5921        3384 :   Smi* hash = Smi::FromInt(isolate->GenerateIdentityHash(Smi::kMaxValue));
    5922        3384 :   CHECK(AddDataProperty(&it, handle(hash, isolate), NONE, THROW_ON_ERROR,
    5923             :                         CERTAINLY_NOT_STORE_FROM_KEYED)
    5924             :             .IsJust());
    5925             :   return hash;
    5926             : }
    5927             : 
    5928             : // static
    5929           0 : Object* JSProxy::GetIdentityHash(Handle<JSProxy> proxy) {
    5930           0 :   return proxy->hash();
    5931             : }
    5932             : 
    5933           0 : Smi* JSProxy::GetOrCreateIdentityHash(Isolate* isolate, Handle<JSProxy> proxy) {
    5934        3094 :   return GetOrCreateIdentityHashHelper(isolate, proxy);
    5935             : }
    5936             : 
    5937             : 
    5938         185 : Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
    5939             :                                                     ShouldThrow should_throw) {
    5940             :   Isolate* isolate = it->isolate();
    5941             :   // Make sure that the top context does not change when doing callbacks or
    5942             :   // interceptor calls.
    5943             :   AssertNoContextChange ncc(isolate);
    5944             : 
    5945             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    5946         117 :   Handle<InterceptorInfo> interceptor(it->GetInterceptor());
    5947         117 :   if (interceptor->deleter()->IsUndefined(isolate)) return Nothing<bool>();
    5948             : 
    5949             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    5950             :   Handle<Object> receiver = it->GetReceiver();
    5951          68 :   if (!receiver->IsJSReceiver()) {
    5952           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    5953             :                                      Object::ConvertReceiver(isolate, receiver),
    5954             :                                      Nothing<bool>());
    5955             :   }
    5956             : 
    5957             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    5958             :                                  *holder, should_throw);
    5959             :   Handle<Object> result;
    5960          68 :   if (it->IsElement()) {
    5961             :     uint32_t index = it->index();
    5962             :     v8::IndexedPropertyDeleterCallback deleter =
    5963             :         v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
    5964          27 :     result = args.Call(deleter, index);
    5965             :   } else {
    5966             :     DCHECK_IMPLIES(it->name()->IsSymbol(),
    5967             :                    interceptor->can_intercept_symbols());
    5968          41 :     Handle<Name> name = it->name();
    5969             :     DCHECK(!name->IsPrivate());
    5970             :     v8::GenericNamedPropertyDeleterCallback deleter =
    5971             :         v8::ToCData<v8::GenericNamedPropertyDeleterCallback>(
    5972             :             interceptor->deleter());
    5973          41 :     result = args.Call(deleter, name);
    5974             :   }
    5975             : 
    5976          68 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    5977          68 :   if (result.is_null()) return Nothing<bool>();
    5978             : 
    5979             :   DCHECK(result->IsBoolean());
    5980             :   // Rebox CustomArguments::kReturnValueOffset before returning.
    5981             :   return Just(result->IsTrue(isolate));
    5982             : }
    5983             : 
    5984             : 
    5985     6177375 : void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object,
    5986             :                                           Handle<Name> name, int entry) {
    5987             :   DCHECK(!object->HasFastProperties());
    5988             :   Isolate* isolate = object->GetIsolate();
    5989             : 
    5990     6177375 :   if (object->IsJSGlobalObject()) {
    5991             :     // If we have a global object, invalidate the cell and swap in a new one.
    5992             :     Handle<GlobalDictionary> dictionary(
    5993             :         JSObject::cast(*object)->global_dictionary());
    5994             :     DCHECK_NE(GlobalDictionary::kNotFound, entry);
    5995             : 
    5996       12243 :     auto cell = PropertyCell::InvalidateEntry(dictionary, entry);
    5997       24486 :     cell->set_value(isolate->heap()->the_hole_value());
    5998             :     cell->set_property_details(
    5999             :         PropertyDetails::Empty(PropertyCellType::kUninitialized));
    6000             :   } else {
    6001             :     Handle<NameDictionary> dictionary(object->property_dictionary());
    6002             :     DCHECK_NE(NameDictionary::kNotFound, entry);
    6003             : 
    6004     6165132 :     NameDictionary::DeleteProperty(dictionary, entry);
    6005             :     Handle<NameDictionary> new_properties =
    6006             :         NameDictionary::Shrink(dictionary, name);
    6007     6165132 :     object->set_properties(*new_properties);
    6008             :   }
    6009     6177375 : }
    6010             : 
    6011             : 
    6012    27147935 : Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it,
    6013             :                                        LanguageMode language_mode) {
    6014     9045871 :   it->UpdateProtector();
    6015             : 
    6016             :   Isolate* isolate = it->isolate();
    6017             : 
    6018     9045871 :   if (it->state() == LookupIterator::JSPROXY) {
    6019             :     return JSProxy::DeletePropertyOrElement(it->GetHolder<JSProxy>(),
    6020        4817 :                                             it->GetName(), language_mode);
    6021             :   }
    6022             : 
    6023     9041054 :   if (it->GetReceiver()->IsJSProxy()) {
    6024          56 :     if (it->state() != LookupIterator::NOT_FOUND) {
    6025             :       DCHECK_EQ(LookupIterator::DATA, it->state());
    6026             :       DCHECK(it->name()->IsPrivate());
    6027           7 :       it->Delete();
    6028             :     }
    6029             :     return Just(true);
    6030             :   }
    6031             :   Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
    6032             : 
    6033    18112274 :   for (; it->IsFound(); it->Next()) {
    6034     6360279 :     switch (it->state()) {
    6035             :       case LookupIterator::JSPROXY:
    6036             :       case LookupIterator::NOT_FOUND:
    6037             :       case LookupIterator::TRANSITION:
    6038           0 :         UNREACHABLE();
    6039             :       case LookupIterator::ACCESS_CHECK:
    6040       15093 :         if (it->HasAccess()) break;
    6041          43 :         isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    6042          43 :         RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    6043             :         return Just(false);
    6044             :       case LookupIterator::INTERCEPTOR: {
    6045             :         ShouldThrow should_throw =
    6046         117 :             is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
    6047             :         Maybe<bool> result =
    6048         117 :             JSObject::DeletePropertyWithInterceptor(it, should_throw);
    6049             :         // An exception was thrown in the interceptor. Propagate.
    6050         145 :         if (isolate->has_pending_exception()) return Nothing<bool>();
    6051             :         // Delete with interceptor succeeded. Return result.
    6052             :         // TODO(neis): In strict mode, we should probably throw if the
    6053             :         // interceptor returns false.
    6054         117 :         if (result.IsJust()) return result;
    6055          89 :         break;
    6056             :       }
    6057             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    6058             :         return Just(true);
    6059             :       case LookupIterator::DATA:
    6060             :       case LookupIterator::ACCESSOR: {
    6061     6344999 :         if (!it->IsConfigurable()) {
    6062             :           // Fail if the property is not configurable.
    6063        3502 :           if (is_strict(language_mode)) {
    6064             :             isolate->Throw(*isolate->factory()->NewTypeError(
    6065             :                 MessageTemplate::kStrictDeleteProperty, it->GetName(),
    6066        2517 :                 receiver));
    6067             :             return Nothing<bool>();
    6068             :           }
    6069             :           return Just(false);
    6070             :         }
    6071             : 
    6072     6341497 :         it->Delete();
    6073             : 
    6074             :         return Just(true);
    6075             :       }
    6076             :     }
    6077             :   }
    6078             : 
    6079             :   return Just(true);
    6080             : }
    6081             : 
    6082             : 
    6083          12 : Maybe<bool> JSReceiver::DeleteElement(Handle<JSReceiver> object, uint32_t index,
    6084             :                                       LanguageMode language_mode) {
    6085             :   LookupIterator it(object->GetIsolate(), object, index, object,
    6086             :                     LookupIterator::OWN);
    6087          12 :   return DeleteProperty(&it, language_mode);
    6088             : }
    6089             : 
    6090             : 
    6091         468 : Maybe<bool> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
    6092             :                                        Handle<Name> name,
    6093             :                                        LanguageMode language_mode) {
    6094         468 :   LookupIterator it(object, name, object, LookupIterator::OWN);
    6095         468 :   return DeleteProperty(&it, language_mode);
    6096             : }
    6097             : 
    6098             : 
    6099        5843 : Maybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object,
    6100             :                                                 Handle<Name> name,
    6101             :                                                 LanguageMode language_mode) {
    6102             :   LookupIterator it = LookupIterator::PropertyOrElement(
    6103        5843 :       name->GetIsolate(), object, name, object, LookupIterator::OWN);
    6104        5843 :   return DeleteProperty(&it, language_mode);
    6105             : }
    6106             : 
    6107             : // ES6 19.1.2.4
    6108             : // static
    6109      285828 : Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object,
    6110             :                                    Handle<Object> key,
    6111             :                                    Handle<Object> attributes) {
    6112             :   // 1. If Type(O) is not Object, throw a TypeError exception.
    6113      285828 :   if (!object->IsJSReceiver()) {
    6114             :     Handle<String> fun_name =
    6115         102 :         isolate->factory()->InternalizeUtf8String("Object.defineProperty");
    6116         204 :     THROW_NEW_ERROR_RETURN_FAILURE(
    6117             :         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name));
    6118             :   }
    6119             :   // 2. Let key be ToPropertyKey(P).
    6120             :   // 3. ReturnIfAbrupt(key).
    6121      571452 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, ToPropertyKey(isolate, key));
    6122             :   // 4. Let desc be ToPropertyDescriptor(Attributes).
    6123             :   // 5. ReturnIfAbrupt(desc).
    6124             :   PropertyDescriptor desc;
    6125      285726 :   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
    6126         215 :     return isolate->heap()->exception();
    6127             :   }
    6128             :   // 6. Let success be DefinePropertyOrThrow(O,key, desc).
    6129             :   Maybe<bool> success = DefineOwnProperty(
    6130      285511 :       isolate, Handle<JSReceiver>::cast(object), key, &desc, THROW_ON_ERROR);
    6131             :   // 7. ReturnIfAbrupt(success).
    6132      285511 :   MAYBE_RETURN(success, isolate->heap()->exception());
    6133      283836 :   CHECK(success.FromJust());
    6134             :   // 8. Return O.
    6135      283836 :   return *object;
    6136             : }
    6137             : 
    6138             : 
    6139             : // ES6 19.1.2.3.1
    6140             : // static
    6141       19975 : MaybeHandle<Object> JSReceiver::DefineProperties(Isolate* isolate,
    6142             :                                                  Handle<Object> object,
    6143             :                                                  Handle<Object> properties) {
    6144             :   // 1. If Type(O) is not Object, throw a TypeError exception.
    6145       19975 :   if (!object->IsJSReceiver()) {
    6146             :     Handle<String> fun_name =
    6147          43 :         isolate->factory()->InternalizeUtf8String("Object.defineProperties");
    6148          86 :     THROW_NEW_ERROR(isolate,
    6149             :                     NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name),
    6150             :                     Object);
    6151             :   }
    6152             :   // 2. Let props be ToObject(Properties).
    6153             :   // 3. ReturnIfAbrupt(props).
    6154             :   Handle<JSReceiver> props;
    6155       39864 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, props,
    6156             :                              Object::ToObject(isolate, properties), Object);
    6157             : 
    6158             :   // 4. Let keys be props.[[OwnPropertyKeys]]().
    6159             :   // 5. ReturnIfAbrupt(keys).
    6160             :   Handle<FixedArray> keys;
    6161       39834 :   ASSIGN_RETURN_ON_EXCEPTION(
    6162             :       isolate, keys, KeyAccumulator::GetKeys(props, KeyCollectionMode::kOwnOnly,
    6163             :                                              ALL_PROPERTIES),
    6164             :       Object);
    6165             :   // 6. Let descriptors be an empty List.
    6166             :   int capacity = keys->length();
    6167       19917 :   std::vector<PropertyDescriptor> descriptors(capacity);
    6168             :   size_t descriptors_index = 0;
    6169             :   // 7. Repeat for each element nextKey of keys in List order,
    6170      379204 :   for (int i = 0; i < keys->length(); ++i) {
    6171             :     Handle<Object> next_key(keys->get(i), isolate);
    6172             :     // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey).
    6173             :     // 7b. ReturnIfAbrupt(propDesc).
    6174      170044 :     bool success = false;
    6175             :     LookupIterator it = LookupIterator::PropertyOrElement(
    6176      170044 :         isolate, props, next_key, &success, LookupIterator::OWN);
    6177             :     DCHECK(success);
    6178      170044 :     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
    6179      170403 :     if (!maybe.IsJust()) return MaybeHandle<Object>();
    6180             :     PropertyAttributes attrs = maybe.FromJust();
    6181             :     // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true:
    6182      171765 :     if (attrs == ABSENT) continue;
    6183      170044 :     if (attrs & DONT_ENUM) continue;
    6184             :     // 7c i. Let descObj be Get(props, nextKey).
    6185             :     // 7c ii. ReturnIfAbrupt(descObj).
    6186             :     Handle<Object> desc_obj;
    6187      336646 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, desc_obj, Object::GetProperty(&it),
    6188             :                                Object);
    6189             :     // 7c iii. Let desc be ToPropertyDescriptor(descObj).
    6190             :     success = PropertyDescriptor::ToPropertyDescriptor(
    6191      336646 :         isolate, desc_obj, &descriptors[descriptors_index]);
    6192             :     // 7c iv. ReturnIfAbrupt(desc).
    6193      168323 :     if (!success) return MaybeHandle<Object>();
    6194             :     // 7c v. Append the pair (a two element List) consisting of nextKey and
    6195             :     //       desc to the end of descriptors.
    6196      167964 :     descriptors[descriptors_index].set_name(next_key);
    6197      167964 :     descriptors_index++;
    6198             :   }
    6199             :   // 8. For each pair from descriptors in list order,
    6200      167290 :   for (size_t i = 0; i < descriptors_index; ++i) {
    6201      167290 :     PropertyDescriptor* desc = &descriptors[i];
    6202             :     // 8a. Let P be the first element of pair.
    6203             :     // 8b. Let desc be the second element of pair.
    6204             :     // 8c. Let status be DefinePropertyOrThrow(O, P, desc).
    6205             :     Maybe<bool> status =
    6206             :         DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object),
    6207      167290 :                           desc->name(), desc, THROW_ON_ERROR);
    6208             :     // 8d. ReturnIfAbrupt(status).
    6209      167290 :     if (!status.IsJust()) return MaybeHandle<Object>();
    6210      167290 :     CHECK(status.FromJust());
    6211             :   }
    6212             :   // 9. Return o.
    6213             :   return object;
    6214             : }
    6215             : 
    6216             : 
    6217             : // static
    6218      647720 : Maybe<bool> JSReceiver::DefineOwnProperty(Isolate* isolate,
    6219             :                                           Handle<JSReceiver> object,
    6220             :                                           Handle<Object> key,
    6221             :                                           PropertyDescriptor* desc,
    6222             :                                           ShouldThrow should_throw) {
    6223      647720 :   if (object->IsJSArray()) {
    6224             :     return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object),
    6225       80543 :                                       key, desc, should_throw);
    6226             :   }
    6227      567177 :   if (object->IsJSProxy()) {
    6228             :     return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object),
    6229        5822 :                                       key, desc, should_throw);
    6230             :   }
    6231      561355 :   if (object->IsJSTypedArray()) {
    6232             :     return JSTypedArray::DefineOwnProperty(
    6233        4786 :         isolate, Handle<JSTypedArray>::cast(object), key, desc, should_throw);
    6234             :   }
    6235             :   // TODO(neis): Special case for JSModuleNamespace?
    6236             : 
    6237             :   // OrdinaryDefineOwnProperty, by virtue of calling
    6238             :   // DefineOwnPropertyIgnoreAttributes, can handle arguments
    6239             :   // (ES#sec-arguments-exotic-objects-defineownproperty-p-desc).
    6240             :   return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key,
    6241      556569 :                                    desc, should_throw);
    6242             : }
    6243             : 
    6244             : 
    6245             : // static
    6246      662084 : Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate,
    6247             :                                                   Handle<JSObject> object,
    6248             :                                                   Handle<Object> key,
    6249             :                                                   PropertyDescriptor* desc,
    6250             :                                                   ShouldThrow should_throw) {
    6251      662084 :   bool success = false;
    6252             :   DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey...
    6253             :   LookupIterator it = LookupIterator::PropertyOrElement(
    6254      662084 :       isolate, object, key, &success, LookupIterator::OWN);
    6255             :   DCHECK(success);  // ...so creating a LookupIterator can't fail.
    6256             : 
    6257             :   // Deal with access checks first.
    6258      662084 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    6259        3716 :     if (!it.HasAccess()) {
    6260          36 :       isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
    6261          36 :       RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    6262             :       return Just(true);
    6263             :     }
    6264        3680 :     it.Next();
    6265             :   }
    6266             : 
    6267             :   // Handle interceptor
    6268      662048 :   if (it.state() == LookupIterator::INTERCEPTOR) {
    6269         208 :     if (it.HolderIsReceiverOrHiddenPrototype()) {
    6270             :       Maybe<bool> result = DefinePropertyWithInterceptorInternal(
    6271         208 :           &it, it.GetInterceptor(), should_throw, *desc);
    6272         416 :       if (result.IsNothing() || result.FromJust()) {
    6273          63 :         return result;
    6274             :       }
    6275             :     }
    6276             :   }
    6277             : 
    6278      661985 :   return OrdinaryDefineOwnProperty(&it, desc, should_throw);
    6279             : }
    6280             : 
    6281             : 
    6282             : // ES6 9.1.6.1
    6283             : // static
    6284      661985 : Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it,
    6285             :                                                   PropertyDescriptor* desc,
    6286             :                                                   ShouldThrow should_throw) {
    6287             :   Isolate* isolate = it->isolate();
    6288             :   // 1. Let current be O.[[GetOwnProperty]](P).
    6289             :   // 2. ReturnIfAbrupt(current).
    6290             :   PropertyDescriptor current;
    6291      661985 :   MAYBE_RETURN(GetOwnPropertyDescriptor(it, &current), Nothing<bool>());
    6292             : 
    6293             :   // TODO(jkummerow/verwaest): It would be nice if we didn't have to reset
    6294             :   // the iterator every time. Currently, the reasons why we need it are:
    6295             :   // - handle interceptors correctly
    6296             :   // - handle accessors correctly (which might change the holder's map)
    6297      661985 :   it->Restart();
    6298             :   // 3. Let extensible be the value of the [[Extensible]] internal slot of O.
    6299      661985 :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    6300      661985 :   bool extensible = JSObject::IsExtensible(object);
    6301             : 
    6302             :   return ValidateAndApplyPropertyDescriptor(isolate, it, extensible, desc,
    6303      661985 :                                             &current, should_throw);
    6304             : }
    6305             : 
    6306             : 
    6307             : // ES6 9.1.6.2
    6308             : // static
    6309           0 : Maybe<bool> JSReceiver::IsCompatiblePropertyDescriptor(
    6310             :     Isolate* isolate, bool extensible, PropertyDescriptor* desc,
    6311             :     PropertyDescriptor* current, Handle<Name> property_name,
    6312             :     ShouldThrow should_throw) {
    6313             :   // 1. Return ValidateAndApplyPropertyDescriptor(undefined, undefined,
    6314             :   //    Extensible, Desc, Current).
    6315             :   return ValidateAndApplyPropertyDescriptor(
    6316        6987 :       isolate, NULL, extensible, desc, current, should_throw, property_name);
    6317             : }
    6318             : 
    6319             : 
    6320             : // ES6 9.1.6.3
    6321             : // static
    6322      668972 : Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
    6323             :     Isolate* isolate, LookupIterator* it, bool extensible,
    6324             :     PropertyDescriptor* desc, PropertyDescriptor* current,
    6325             :     ShouldThrow should_throw, Handle<Name> property_name) {
    6326             :   // We either need a LookupIterator, or a property name.
    6327             :   DCHECK((it == NULL) != property_name.is_null());
    6328             :   Handle<JSObject> object;
    6329             :   if (it != NULL) object = Handle<JSObject>::cast(it->GetReceiver());
    6330             :   bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc);
    6331             :   bool desc_is_accessor_descriptor =
    6332             :       PropertyDescriptor::IsAccessorDescriptor(desc);
    6333             :   bool desc_is_generic_descriptor =
    6334             :       PropertyDescriptor::IsGenericDescriptor(desc);
    6335             :   // 1. (Assert)
    6336             :   // 2. If current is undefined, then
    6337      668972 :   if (current->is_empty()) {
    6338             :     // 2a. If extensible is false, return false.
    6339      522728 :     if (!extensible) {
    6340         667 :       RETURN_FAILURE(isolate, should_throw,
    6341             :                      NewTypeError(MessageTemplate::kDefineDisallowed,
    6342             :                                   it != NULL ? it->GetName() : property_name));
    6343             :     }
    6344             :     // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then:
    6345             :     // (This is equivalent to !IsAccessorDescriptor(desc).)
    6346             :     DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) ==
    6347             :            !desc_is_accessor_descriptor);
    6348      522508 :     if (!desc_is_accessor_descriptor) {
    6349             :       // 2c i. If O is not undefined, create an own data property named P of
    6350             :       // object O whose [[Value]], [[Writable]], [[Enumerable]] and
    6351             :       // [[Configurable]] attribute values are described by Desc. If the value
    6352             :       // of an attribute field of Desc is absent, the attribute of the newly
    6353             :       // created property is set to its default value.
    6354      420571 :       if (it != NULL) {
    6355      416679 :         if (!desc->has_writable()) desc->set_writable(false);
    6356      416679 :         if (!desc->has_enumerable()) desc->set_enumerable(false);
    6357      416679 :         if (!desc->has_configurable()) desc->set_configurable(false);
    6358             :         Handle<Object> value(
    6359             :             desc->has_value()
    6360             :                 ? desc->value()
    6361      416679 :                 : Handle<Object>::cast(isolate->factory()->undefined_value()));
    6362             :         MaybeHandle<Object> result =
    6363             :             JSObject::DefineOwnPropertyIgnoreAttributes(it, value,
    6364      416679 :                                                         desc->ToAttributes());
    6365      416679 :         if (result.is_null()) return Nothing<bool>();
    6366             :       }
    6367             :     } else {
    6368             :       // 2d. Else Desc must be an accessor Property Descriptor,
    6369             :       DCHECK(desc_is_accessor_descriptor);
    6370             :       // 2d i. If O is not undefined, create an own accessor property named P
    6371             :       // of object O whose [[Get]], [[Set]], [[Enumerable]] and
    6372             :       // [[Configurable]] attribute values are described by Desc. If the value
    6373             :       // of an attribute field of Desc is absent, the attribute of the newly
    6374             :       // created property is set to its default value.
    6375      101937 :       if (it != NULL) {
    6376      101713 :         if (!desc->has_enumerable()) desc->set_enumerable(false);
    6377      101713 :         if (!desc->has_configurable()) desc->set_configurable(false);
    6378             :         Handle<Object> getter(
    6379             :             desc->has_get()
    6380             :                 ? desc->get()
    6381      120469 :                 : Handle<Object>::cast(isolate->factory()->null_value()));
    6382             :         Handle<Object> setter(
    6383             :             desc->has_set()
    6384             :                 ? desc->set()
    6385      165985 :                 : Handle<Object>::cast(isolate->factory()->null_value()));
    6386             :         MaybeHandle<Object> result =
    6387      101713 :             JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes());
    6388      101713 :         if (result.is_null()) return Nothing<bool>();
    6389             :       }
    6390             :     }
    6391             :     // 2e. Return true.
    6392             :     return Just(true);
    6393             :   }
    6394             :   // 3. Return true, if every field in Desc is absent.
    6395             :   // 4. Return true, if every field in Desc also occurs in current and the
    6396             :   // value of every field in Desc is the same value as the corresponding field
    6397             :   // in current when compared using the SameValue algorithm.
    6398      209039 :   if ((!desc->has_enumerable() ||
    6399      144781 :        desc->enumerable() == current->enumerable()) &&
    6400       90221 :       (!desc->has_configurable() ||
    6401      141031 :        desc->configurable() == current->configurable()) &&
    6402      114814 :       (!desc->has_value() ||
    6403      216686 :        (current->has_value() && current->value()->SameValue(*desc->value()))) &&
    6404       77568 :       (!desc->has_writable() ||
    6405      160599 :        (current->has_writable() && current->writable() == desc->writable())) &&
    6406        8224 :       (!desc->has_get() ||
    6407      227503 :        (current->has_get() && current->get()->SameValue(*desc->get()))) &&
    6408       11182 :       (!desc->has_set() ||
    6409       10889 :        (current->has_set() && current->set()->SameValue(*desc->set())))) {
    6410             :     return Just(true);
    6411             :   }
    6412             :   // 5. If the [[Configurable]] field of current is false, then
    6413       82141 :   if (!current->configurable()) {
    6414             :     // 5a. Return false, if the [[Configurable]] field of Desc is true.
    6415       28431 :     if (desc->has_configurable() && desc->configurable()) {
    6416         809 :       RETURN_FAILURE(isolate, should_throw,
    6417             :                      NewTypeError(MessageTemplate::kRedefineDisallowed,
    6418             :                                   it != NULL ? it->GetName() : property_name));
    6419             :     }
    6420             :     // 5b. Return false, if the [[Enumerable]] field of Desc is present and the
    6421             :     // [[Enumerable]] fields of current and Desc are the Boolean negation of
    6422             :     // each other.
    6423       27434 :     if (desc->has_enumerable() && desc->enumerable() != current->enumerable()) {
    6424         452 :       RETURN_FAILURE(isolate, should_throw,
    6425             :                      NewTypeError(MessageTemplate::kRedefineDisallowed,
    6426             :                                   it != NULL ? it->GetName() : property_name));
    6427             :     }
    6428             :   }
    6429             : 
    6430             :   bool current_is_data_descriptor =
    6431             :       PropertyDescriptor::IsDataDescriptor(current);
    6432             :   // 6. If IsGenericDescriptor(Desc) is true, no further validation is required.
    6433       81663 :   if (desc_is_generic_descriptor) {
    6434             :     // Nothing to see here.
    6435             : 
    6436             :     // 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) have
    6437             :     // different results, then:
    6438       80244 :   } else if (current_is_data_descriptor != desc_is_data_descriptor) {
    6439             :     // 7a. Return false, if the [[Configurable]] field of current is false.
    6440        3552 :     if (!current->configurable()) {
    6441         671 :       RETURN_FAILURE(isolate, should_throw,
    6442             :                      NewTypeError(MessageTemplate::kRedefineDisallowed,
    6443             :                                   it != NULL ? it->GetName() : property_name));
    6444             :     }
    6445             :     // 7b. If IsDataDescriptor(current) is true, then:
    6446             :     if (current_is_data_descriptor) {
    6447             :       // 7b i. If O is not undefined, convert the property named P of object O
    6448             :       // from a data property to an accessor property. Preserve the existing
    6449             :       // values of the converted property's [[Configurable]] and [[Enumerable]]
    6450             :       // attributes and set the rest of the property's attributes to their
    6451             :       // default values.
    6452             :       // --> Folded into step 10.
    6453             :     } else {
    6454             :       // 7c i. If O is not undefined, convert the property named P of object O
    6455             :       // from an accessor property to a data property. Preserve the existing
    6456             :       // values of the converted property’s [[Configurable]] and [[Enumerable]]
    6457             :       // attributes and set the rest of the property’s attributes to their
    6458             :       // default values.
    6459             :       // --> Folded into step 10.
    6460             :     }
    6461             : 
    6462             :     // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both
    6463             :     // true, then:
    6464       76692 :   } else if (current_is_data_descriptor && desc_is_data_descriptor) {
    6465             :     // 8a. If the [[Configurable]] field of current is false, then:
    6466       59626 :     if (!current->configurable()) {
    6467             :       // 8a i. Return false, if the [[Writable]] field of current is false and
    6468             :       // the [[Writable]] field of Desc is true.
    6469       23582 :       if (!current->writable() && desc->has_writable() && desc->writable()) {
    6470         298 :         RETURN_FAILURE(
    6471             :             isolate, should_throw,
    6472             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    6473             :                          it != NULL ? it->GetName() : property_name));
    6474             :       }
    6475             :       // 8a ii. If the [[Writable]] field of current is false, then:
    6476       22941 :       if (!current->writable()) {
    6477             :         // 8a ii 1. Return false, if the [[Value]] field of Desc is present and
    6478             :         // SameValue(Desc.[[Value]], current.[[Value]]) is false.
    6479         714 :         if (desc->has_value() && !desc->value()->SameValue(*current->value())) {
    6480        1224 :           RETURN_FAILURE(
    6481             :               isolate, should_throw,
    6482             :               NewTypeError(MessageTemplate::kRedefineDisallowed,
    6483             :                            it != NULL ? it->GetName() : property_name));
    6484             :         }
    6485             :       }
    6486             :     }
    6487             :   } else {
    6488             :     // 9. Else IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc)
    6489             :     // are both true,
    6490             :     DCHECK(PropertyDescriptor::IsAccessorDescriptor(current) &&
    6491             :            desc_is_accessor_descriptor);
    6492             :     // 9a. If the [[Configurable]] field of current is false, then:
    6493       17066 :     if (!current->configurable()) {
    6494             :       // 9a i. Return false, if the [[Set]] field of Desc is present and
    6495             :       // SameValue(Desc.[[Set]], current.[[Set]]) is false.
    6496         220 :       if (desc->has_set() && !desc->set()->SameValue(*current->set())) {
    6497         186 :         RETURN_FAILURE(
    6498             :             isolate, should_throw,
    6499             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    6500             :                          it != NULL ? it->GetName() : property_name));
    6501             :       }
    6502             :       // 9a ii. Return false, if the [[Get]] field of Desc is present and
    6503             :       // SameValue(Desc.[[Get]], current.[[Get]]) is false.
    6504         154 :       if (desc->has_get() && !desc->get()->SameValue(*current->get())) {
    6505         248 :         RETURN_FAILURE(
    6506             :             isolate, should_throw,
    6507             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    6508             :                          it != NULL ? it->GetName() : property_name));
    6509             :       }
    6510             :     }
    6511             :   }
    6512             : 
    6513             :   // 10. If O is not undefined, then:
    6514       80887 :   if (it != NULL) {
    6515             :     // 10a. For each field of Desc that is present, set the corresponding
    6516             :     // attribute of the property named P of object O to the value of the field.
    6517             :     PropertyAttributes attrs = NONE;
    6518             : 
    6519       80523 :     if (desc->has_enumerable()) {
    6520             :       attrs = static_cast<PropertyAttributes>(
    6521        8748 :           attrs | (desc->enumerable() ? NONE : DONT_ENUM));
    6522             :     } else {
    6523             :       attrs = static_cast<PropertyAttributes>(
    6524       71775 :           attrs | (current->enumerable() ? NONE : DONT_ENUM));
    6525             :     }
    6526       80523 :     if (desc->has_configurable()) {
    6527             :       attrs = static_cast<PropertyAttributes>(
    6528       27231 :           attrs | (desc->configurable() ? NONE : DONT_DELETE));
    6529             :     } else {
    6530             :       attrs = static_cast<PropertyAttributes>(
    6531       53292 :           attrs | (current->configurable() ? NONE : DONT_DELETE));
    6532             :     }
    6533      101550 :     if (desc_is_data_descriptor ||
    6534       21027 :         (desc_is_generic_descriptor && current_is_data_descriptor)) {
    6535       60755 :       if (desc->has_writable()) {
    6536             :         attrs = static_cast<PropertyAttributes>(
    6537       56375 :             attrs | (desc->writable() ? NONE : READ_ONLY));
    6538             :       } else {
    6539             :         attrs = static_cast<PropertyAttributes>(
    6540        4380 :             attrs | (current->writable() ? NONE : READ_ONLY));
    6541             :       }
    6542             :       Handle<Object> value(
    6543             :           desc->has_value() ? desc->value()
    6544             :                             : current->has_value()
    6545             :                                   ? current->value()
    6546             :                                   : Handle<Object>::cast(
    6547       64918 :                                         isolate->factory()->undefined_value()));
    6548             :       MaybeHandle<Object> result =
    6549             :           JSObject::DefineOwnPropertyIgnoreAttributes(it, value, attrs);
    6550       60755 :       if (result.is_null()) return Nothing<bool>();
    6551             :     } else {
    6552             :       DCHECK(desc_is_accessor_descriptor ||
    6553             :              (desc_is_generic_descriptor &&
    6554             :               PropertyDescriptor::IsAccessorDescriptor(current)));
    6555             :       Handle<Object> getter(
    6556             :           desc->has_get()
    6557             :               ? desc->get()
    6558             :               : current->has_get()
    6559             :                     ? current->get()
    6560       31444 :                     : Handle<Object>::cast(isolate->factory()->null_value()));
    6561             :       Handle<Object> setter(
    6562             :           desc->has_set()
    6563             :               ? desc->set()
    6564             :               : current->has_set()
    6565             :                     ? current->set()
    6566       29360 :                     : Handle<Object>::cast(isolate->factory()->null_value()));
    6567             :       MaybeHandle<Object> result =
    6568       19768 :           JSObject::DefineAccessor(it, getter, setter, attrs);
    6569       19768 :       if (result.is_null()) return Nothing<bool>();
    6570             :     }
    6571             :   }
    6572             : 
    6573             :   // 11. Return true.
    6574             :   return Just(true);
    6575             : }
    6576             : 
    6577             : 
    6578             : // static
    6579      370734 : Maybe<bool> JSReceiver::CreateDataProperty(LookupIterator* it,
    6580             :                                            Handle<Object> value,
    6581             :                                            ShouldThrow should_throw) {
    6582             :   DCHECK(!it->check_prototype_chain());
    6583             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    6584             :   Isolate* isolate = receiver->GetIsolate();
    6585             : 
    6586      370734 :   if (receiver->IsJSObject()) {
    6587      369647 :     return JSObject::CreateDataProperty(it, value, should_throw);  // Shortcut.
    6588             :   }
    6589             : 
    6590             :   PropertyDescriptor new_desc;
    6591             :   new_desc.set_value(value);
    6592             :   new_desc.set_writable(true);
    6593             :   new_desc.set_enumerable(true);
    6594             :   new_desc.set_configurable(true);
    6595             : 
    6596             :   return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
    6597        2174 :                                        &new_desc, should_throw);
    6598             : }
    6599             : 
    6600      746148 : Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
    6601             :                                          Handle<Object> value,
    6602             :                                          ShouldThrow should_throw) {
    6603             :   DCHECK(it->GetReceiver()->IsJSObject());
    6604      373077 :   MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
    6605             :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    6606             :   Isolate* isolate = receiver->GetIsolate();
    6607             : 
    6608      373071 :   if (it->IsFound()) {
    6609      200346 :     Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
    6610      200401 :     MAYBE_RETURN(attributes, Nothing<bool>());
    6611      200346 :     if ((attributes.FromJust() & DONT_DELETE) != 0) {
    6612         184 :       RETURN_FAILURE(
    6613             :           isolate, should_throw,
    6614             :           NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
    6615             :     }
    6616             :   } else {
    6617      172725 :     if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) {
    6618         350 :       RETURN_FAILURE(
    6619             :           isolate, should_throw,
    6620             :           NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
    6621             :     }
    6622             :   }
    6623             : 
    6624      372924 :   RETURN_ON_EXCEPTION_VALUE(it->isolate(),
    6625             :                             DefineOwnPropertyIgnoreAttributes(it, value, NONE),
    6626             :                             Nothing<bool>());
    6627             : 
    6628             :   return Just(true);
    6629             : }
    6630             : 
    6631             : 
    6632             : // TODO(jkummerow): Consider unification with FastAsArrayLength() in
    6633             : // accessors.cc.
    6634       62305 : bool PropertyKeyToArrayLength(Handle<Object> value, uint32_t* length) {
    6635             :   DCHECK(value->IsNumber() || value->IsName());
    6636       62305 :   if (value->ToArrayLength(length)) return true;
    6637       83258 :   if (value->IsString()) return String::cast(*value)->AsArrayIndex(length);
    6638             :   return false;
    6639             : }
    6640             : 
    6641           0 : bool PropertyKeyToArrayIndex(Handle<Object> index_obj, uint32_t* output) {
    6642       62305 :   return PropertyKeyToArrayLength(index_obj, output) && *output != kMaxUInt32;
    6643             : }
    6644             : 
    6645             : 
    6646             : // ES6 9.4.2.1
    6647             : // static
    6648       80543 : Maybe<bool> JSArray::DefineOwnProperty(Isolate* isolate, Handle<JSArray> o,
    6649             :                                        Handle<Object> name,
    6650             :                                        PropertyDescriptor* desc,
    6651             :                                        ShouldThrow should_throw) {
    6652             :   // 1. Assert: IsPropertyKey(P) is true. ("P" is |name|.)
    6653             :   // 2. If P is "length", then:
    6654             :   // TODO(jkummerow): Check if we need slow string comparison.
    6655       80543 :   if (*name == isolate->heap()->length_string()) {
    6656             :     // 2a. Return ArraySetLength(A, Desc).
    6657       18238 :     return ArraySetLength(isolate, o, desc, should_throw);
    6658             :   }
    6659             :   // 3. Else if P is an array index, then:
    6660       62305 :   uint32_t index = 0;
    6661       62305 :   if (PropertyKeyToArrayIndex(name, &index)) {
    6662             :     // 3a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    6663             :     PropertyDescriptor old_len_desc;
    6664             :     Maybe<bool> success = GetOwnPropertyDescriptor(
    6665       59166 :         isolate, o, isolate->factory()->length_string(), &old_len_desc);
    6666             :     // 3b. (Assert)
    6667             :     DCHECK(success.FromJust());
    6668             :     USE(success);
    6669             :     // 3c. Let oldLen be oldLenDesc.[[Value]].
    6670       59166 :     uint32_t old_len = 0;
    6671       59166 :     CHECK(old_len_desc.value()->ToArrayLength(&old_len));
    6672             :     // 3d. Let index be ToUint32(P).
    6673             :     // (Already done above.)
    6674             :     // 3e. (Assert)
    6675             :     // 3f. If index >= oldLen and oldLenDesc.[[Writable]] is false,
    6676             :     //     return false.
    6677      100146 :     if (index >= old_len && old_len_desc.has_writable() &&
    6678             :         !old_len_desc.writable()) {
    6679           0 :       RETURN_FAILURE(isolate, should_throw,
    6680             :                      NewTypeError(MessageTemplate::kDefineDisallowed, name));
    6681             :     }
    6682             :     // 3g. Let succeeded be OrdinaryDefineOwnProperty(A, P, Desc).
    6683             :     Maybe<bool> succeeded =
    6684       59166 :         OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
    6685             :     // 3h. Assert: succeeded is not an abrupt completion.
    6686             :     //     In our case, if should_throw == THROW_ON_ERROR, it can be!
    6687             :     // 3i. If succeeded is false, return false.
    6688      118205 :     if (succeeded.IsNothing() || !succeeded.FromJust()) return succeeded;
    6689             :     // 3j. If index >= oldLen, then:
    6690       59025 :     if (index >= old_len) {
    6691             :       // 3j i. Set oldLenDesc.[[Value]] to index + 1.
    6692       20490 :       old_len_desc.set_value(isolate->factory()->NewNumberFromUint(index + 1));
    6693             :       // 3j ii. Let succeeded be
    6694             :       //        OrdinaryDefineOwnProperty(A, "length", oldLenDesc).
    6695             :       succeeded = OrdinaryDefineOwnProperty(isolate, o,
    6696             :                                             isolate->factory()->length_string(),
    6697       20490 :                                             &old_len_desc, should_throw);
    6698             :       // 3j iii. Assert: succeeded is true.
    6699             :       DCHECK(succeeded.FromJust());
    6700             :       USE(succeeded);
    6701             :     }
    6702             :     // 3k. Return true.
    6703             :     return Just(true);
    6704             :   }
    6705             : 
    6706             :   // 4. Return OrdinaryDefineOwnProperty(A, P, Desc).
    6707        3139 :   return OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
    6708             : }
    6709             : 
    6710             : 
    6711             : // Part of ES6 9.4.2.4 ArraySetLength.
    6712             : // static
    6713     1020711 : bool JSArray::AnythingToArrayLength(Isolate* isolate,
    6714             :                                     Handle<Object> length_object,
    6715             :                                     uint32_t* output) {
    6716             :   // Fast path: check numbers and strings that can be converted directly
    6717             :   // and unobservably.
    6718     1020711 :   if (length_object->ToArrayLength(output)) return true;
    6719      533158 :   if (length_object->IsString() &&
    6720          30 :       Handle<String>::cast(length_object)->AsArrayIndex(output)) {
    6721             :     return true;
    6722             :   }
    6723             :   // Slow path: follow steps in ES6 9.4.2.4 "ArraySetLength".
    6724             :   // 3. Let newLen be ToUint32(Desc.[[Value]]).
    6725             :   Handle<Object> uint32_v;
    6726     1066226 :   if (!Object::ToUint32(isolate, length_object).ToHandle(&uint32_v)) {
    6727             :     // 4. ReturnIfAbrupt(newLen).
    6728             :     return false;
    6729             :   }
    6730             :   // 5. Let numberLen be ToNumber(Desc.[[Value]]).
    6731             :   Handle<Object> number_v;
    6732     1066196 :   if (!Object::ToNumber(length_object).ToHandle(&number_v)) {
    6733             :     // 6. ReturnIfAbrupt(newLen).
    6734             :     return false;
    6735             :   }
    6736             :   // 7. If newLen != numberLen, throw a RangeError exception.
    6737      533098 :   if (uint32_v->Number() != number_v->Number()) {
    6738             :     Handle<Object> exception =
    6739         386 :         isolate->factory()->NewRangeError(MessageTemplate::kInvalidArrayLength);
    6740         386 :     isolate->Throw(*exception);
    6741             :     return false;
    6742             :   }
    6743      532712 :   CHECK(uint32_v->ToArrayLength(output));
    6744             :   return true;
    6745             : }
    6746             : 
    6747             : 
    6748             : // ES6 9.4.2.4
    6749             : // static
    6750       18238 : Maybe<bool> JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a,
    6751             :                                     PropertyDescriptor* desc,
    6752             :                                     ShouldThrow should_throw) {
    6753             :   // 1. If the [[Value]] field of Desc is absent, then
    6754       18238 :   if (!desc->has_value()) {
    6755             :     // 1a. Return OrdinaryDefineOwnProperty(A, "length", Desc).
    6756             :     return OrdinaryDefineOwnProperty(
    6757         400 :         isolate, a, isolate->factory()->length_string(), desc, should_throw);
    6758             :   }
    6759             :   // 2. Let newLenDesc be a copy of Desc.
    6760             :   // (Actual copying is not necessary.)
    6761             :   PropertyDescriptor* new_len_desc = desc;
    6762             :   // 3. - 7. Convert Desc.[[Value]] to newLen.
    6763       17838 :   uint32_t new_len = 0;
    6764       17838 :   if (!AnythingToArrayLength(isolate, desc->value(), &new_len)) {
    6765             :     DCHECK(isolate->has_pending_exception());
    6766             :     return Nothing<bool>();
    6767             :   }
    6768             :   // 8. Set newLenDesc.[[Value]] to newLen.
    6769             :   // (Done below, if needed.)
    6770             :   // 9. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    6771             :   PropertyDescriptor old_len_desc;
    6772             :   Maybe<bool> success = GetOwnPropertyDescriptor(
    6773       17823 :       isolate, a, isolate->factory()->length_string(), &old_len_desc);
    6774             :   // 10. (Assert)
    6775             :   DCHECK(success.FromJust());
    6776             :   USE(success);
    6777             :   // 11. Let oldLen be oldLenDesc.[[Value]].
    6778       17823 :   uint32_t old_len = 0;
    6779       17823 :   CHECK(old_len_desc.value()->ToArrayLength(&old_len));
    6780             :   // 12. If newLen >= oldLen, then
    6781       17823 :   if (new_len >= old_len) {
    6782             :     // 8. Set newLenDesc.[[Value]] to newLen.
    6783             :     // 12a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc).
    6784       17809 :     new_len_desc->set_value(isolate->factory()->NewNumberFromUint(new_len));
    6785             :     return OrdinaryDefineOwnProperty(isolate, a,
    6786             :                                      isolate->factory()->length_string(),
    6787       17809 :                                      new_len_desc, should_throw);
    6788             :   }
    6789             :   // 13. If oldLenDesc.[[Writable]] is false, return false.
    6790          14 :   if (!old_len_desc.writable()) {
    6791           0 :     RETURN_FAILURE(isolate, should_throw,
    6792             :                    NewTypeError(MessageTemplate::kRedefineDisallowed,
    6793             :                                 isolate->factory()->length_string()));
    6794             :   }
    6795             :   // 14. If newLenDesc.[[Writable]] is absent or has the value true,
    6796             :   // let newWritable be true.
    6797             :   bool new_writable = false;
    6798          14 :   if (!new_len_desc->has_writable() || new_len_desc->writable()) {
    6799             :     new_writable = true;
    6800             :   } else {
    6801             :     // 15. Else,
    6802             :     // 15a. Need to defer setting the [[Writable]] attribute to false in case
    6803             :     //      any elements cannot be deleted.
    6804             :     // 15b. Let newWritable be false. (It's initialized as "false" anyway.)
    6805             :     // 15c. Set newLenDesc.[[Writable]] to true.
    6806             :     // (Not needed.)
    6807             :   }
    6808             :   // Most of steps 16 through 19 is implemented by JSArray::SetLength.
    6809          14 :   JSArray::SetLength(a, new_len);
    6810             :   // Steps 19d-ii, 20.
    6811          14 :   if (!new_writable) {
    6812             :     PropertyDescriptor readonly;
    6813             :     readonly.set_writable(false);
    6814             :     Maybe<bool> success = OrdinaryDefineOwnProperty(
    6815             :         isolate, a, isolate->factory()->length_string(), &readonly,
    6816           0 :         should_throw);
    6817             :     DCHECK(success.FromJust());
    6818             :     USE(success);
    6819             :   }
    6820          14 :   uint32_t actual_new_len = 0;
    6821          14 :   CHECK(a->length()->ToArrayLength(&actual_new_len));
    6822             :   // Steps 19d-v, 21. Return false if there were non-deletable elements.
    6823          14 :   bool result = actual_new_len == new_len;
    6824          14 :   if (!result) {
    6825          14 :     RETURN_FAILURE(
    6826             :         isolate, should_throw,
    6827             :         NewTypeError(MessageTemplate::kStrictDeleteProperty,
    6828             :                      isolate->factory()->NewNumberFromUint(actual_new_len - 1),
    6829             :                      a));
    6830             :   }
    6831             :   return Just(result);
    6832             : }
    6833             : 
    6834             : 
    6835             : // ES6 9.5.6
    6836             : // static
    6837        5822 : Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy,
    6838             :                                        Handle<Object> key,
    6839             :                                        PropertyDescriptor* desc,
    6840             :                                        ShouldThrow should_throw) {
    6841        5822 :   STACK_CHECK(isolate, Nothing<bool>());
    6842        6214 :   if (key->IsSymbol() && Handle<Symbol>::cast(key)->IsPrivate()) {
    6843             :     return SetPrivateProperty(isolate, proxy, Handle<Symbol>::cast(key), desc,
    6844          28 :                               should_throw);
    6845             :   }
    6846             :   Handle<String> trap_name = isolate->factory()->defineProperty_string();
    6847             :   // 1. Assert: IsPropertyKey(P) is true.
    6848             :   DCHECK(key->IsName() || key->IsNumber());
    6849             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    6850             :   Handle<Object> handler(proxy->handler(), isolate);
    6851             :   // 3. If handler is null, throw a TypeError exception.
    6852             :   // 4. Assert: Type(handler) is Object.
    6853        5794 :   if (proxy->IsRevoked()) {
    6854             :     isolate->Throw(*isolate->factory()->NewTypeError(
    6855          28 :         MessageTemplate::kProxyRevoked, trap_name));
    6856             :     return Nothing<bool>();
    6857             :   }
    6858             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    6859             :   Handle<JSReceiver> target(proxy->target(), isolate);
    6860             :   // 6. Let trap be ? GetMethod(handler, "defineProperty").
    6861             :   Handle<Object> trap;
    6862       11560 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    6863             :       isolate, trap,
    6864             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    6865             :       Nothing<bool>());
    6866             :   // 7. If trap is undefined, then:
    6867        5640 :   if (trap->IsUndefined(isolate)) {
    6868             :     // 7a. Return target.[[DefineOwnProperty]](P, Desc).
    6869             :     return JSReceiver::DefineOwnProperty(isolate, target, key, desc,
    6870        2810 :                                          should_throw);
    6871             :   }
    6872             :   // 8. Let descObj be FromPropertyDescriptor(Desc).
    6873        2830 :   Handle<Object> desc_obj = desc->ToObject(isolate);
    6874             :   // 9. Let booleanTrapResult be
    6875             :   //    ToBoolean(? Call(trap, handler, «target, P, descObj»)).
    6876             :   Handle<Name> property_name =
    6877             :       key->IsName()
    6878             :           ? Handle<Name>::cast(key)
    6879        2830 :           : Handle<Name>::cast(isolate->factory()->NumberToString(key));
    6880             :   // Do not leak private property names.
    6881             :   DCHECK(!property_name->IsPrivate());
    6882             :   Handle<Object> trap_result_obj;
    6883        2830 :   Handle<Object> args[] = {target, property_name, desc_obj};
    6884        5660 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    6885             :       isolate, trap_result_obj,
    6886             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    6887             :       Nothing<bool>());
    6888             :   // 10. If booleanTrapResult is false, return false.
    6889        2017 :   if (!trap_result_obj->BooleanValue()) {
    6890         154 :     RETURN_FAILURE(isolate, should_throw,
    6891             :                    NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
    6892             :                                 trap_name, property_name));
    6893             :   }
    6894             :   // 11. Let targetDesc be ? target.[[GetOwnProperty]](P).
    6895             :   PropertyDescriptor target_desc;
    6896             :   Maybe<bool> target_found =
    6897        1891 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, key, &target_desc);
    6898        1891 :   MAYBE_RETURN(target_found, Nothing<bool>());
    6899             :   // 12. Let extensibleTarget be ? IsExtensible(target).
    6900        1891 :   Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target);
    6901        1891 :   MAYBE_RETURN(maybe_extensible, Nothing<bool>());
    6902             :   bool extensible_target = maybe_extensible.FromJust();
    6903             :   // 13. If Desc has a [[Configurable]] field and if Desc.[[Configurable]]
    6904             :   //     is false, then:
    6905             :   // 13a. Let settingConfigFalse be true.
    6906             :   // 14. Else let settingConfigFalse be false.
    6907        2956 :   bool setting_config_false = desc->has_configurable() && !desc->configurable();
    6908             :   // 15. If targetDesc is undefined, then
    6909        1891 :   if (!target_found.FromJust()) {
    6910             :     // 15a. If extensibleTarget is false, throw a TypeError exception.
    6911         966 :     if (!extensible_target) {
    6912             :       isolate->Throw(*isolate->factory()->NewTypeError(
    6913          28 :           MessageTemplate::kProxyDefinePropertyNonExtensible, property_name));
    6914             :       return Nothing<bool>();
    6915             :     }
    6916             :     // 15b. If settingConfigFalse is true, throw a TypeError exception.
    6917         952 :     if (setting_config_false) {
    6918             :       isolate->Throw(*isolate->factory()->NewTypeError(
    6919          28 :           MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
    6920             :       return Nothing<bool>();
    6921             :     }
    6922             :   } else {
    6923             :     // 16. Else targetDesc is not undefined,
    6924             :     // 16a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc,
    6925             :     //      targetDesc) is false, throw a TypeError exception.
    6926             :     Maybe<bool> valid =
    6927             :         IsCompatiblePropertyDescriptor(isolate, extensible_target, desc,
    6928             :                                        &target_desc, property_name, DONT_THROW);
    6929         925 :     MAYBE_RETURN(valid, Nothing<bool>());
    6930         925 :     if (!valid.FromJust()) {
    6931             :       isolate->Throw(*isolate->factory()->NewTypeError(
    6932          28 :           MessageTemplate::kProxyDefinePropertyIncompatible, property_name));
    6933             :       return Nothing<bool>();
    6934             :     }
    6935             :     // 16b. If settingConfigFalse is true and targetDesc.[[Configurable]] is
    6936             :     //      true, throw a TypeError exception.
    6937        1051 :     if (setting_config_false && target_desc.configurable()) {
    6938             :       isolate->Throw(*isolate->factory()->NewTypeError(
    6939          28 :           MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
    6940             :       return Nothing<bool>();
    6941             :     }
    6942             :   }
    6943             :   // 17. Return true.
    6944             :   return Just(true);
    6945             : }
    6946             : 
    6947             : 
    6948             : // static
    6949          49 : Maybe<bool> JSProxy::SetPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy,
    6950             :                                         Handle<Symbol> private_name,
    6951             :                                         PropertyDescriptor* desc,
    6952             :                                         ShouldThrow should_throw) {
    6953             :   // Despite the generic name, this can only add private data properties.
    6954          70 :   if (!PropertyDescriptor::IsDataDescriptor(desc) ||
    6955          21 :       desc->ToAttributes() != DONT_ENUM) {
    6956          56 :     RETURN_FAILURE(isolate, should_throw,
    6957             :                    NewTypeError(MessageTemplate::kProxyPrivate));
    6958             :   }
    6959             :   DCHECK(proxy->map()->is_dictionary_map());
    6960             :   Handle<Object> value =
    6961             :       desc->has_value()
    6962             :           ? desc->value()
    6963          21 :           : Handle<Object>::cast(isolate->factory()->undefined_value());
    6964             : 
    6965          21 :   LookupIterator it(proxy, private_name, proxy);
    6966             : 
    6967          21 :   if (it.IsFound()) {
    6968             :     DCHECK_EQ(LookupIterator::DATA, it.state());
    6969             :     DCHECK_EQ(DONT_ENUM, it.property_attributes());
    6970           7 :     it.WriteDataValue(value, false);
    6971             :     return Just(true);
    6972             :   }
    6973             : 
    6974             :   Handle<NameDictionary> dict(proxy->property_dictionary());
    6975             :   PropertyDetails details(kData, DONT_ENUM, 0, PropertyCellType::kNoCell);
    6976             :   Handle<NameDictionary> result =
    6977          14 :       NameDictionary::Add(dict, private_name, value, details);
    6978          21 :   if (!dict.is_identical_to(result)) proxy->set_properties(*result);
    6979             :   return Just(true);
    6980             : }
    6981             : 
    6982             : 
    6983             : // static
    6984     3690215 : Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate,
    6985             :                                                  Handle<JSReceiver> object,
    6986             :                                                  Handle<Object> key,
    6987             :                                                  PropertyDescriptor* desc) {
    6988     3690215 :   bool success = false;
    6989             :   DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey...
    6990             :   LookupIterator it = LookupIterator::PropertyOrElement(
    6991     3690215 :       isolate, object, key, &success, LookupIterator::OWN);
    6992             :   DCHECK(success);  // ...so creating a LookupIterator can't fail.
    6993     3690215 :   return GetOwnPropertyDescriptor(&it, desc);
    6994             : }
    6995             : 
    6996             : namespace {
    6997             : 
    6998     8692690 : Maybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
    6999             :                                                  PropertyDescriptor* desc) {
    7000             :   bool has_access = true;
    7001     4346236 :   if (it->state() == LookupIterator::ACCESS_CHECK) {
    7002     3156992 :     has_access = it->HasAccess() || JSObject::AllCanRead(it);
    7003     3156992 :     it->Next();
    7004             :   }
    7005             : 
    7006     8692418 :   if (has_access && it->state() == LookupIterator::INTERCEPTOR) {
    7007             :     Isolate* isolate = it->isolate();
    7008         213 :     Handle<InterceptorInfo> interceptor = it->GetInterceptor();
    7009         213 :     if (!interceptor->descriptor()->IsUndefined(isolate)) {
    7010             :       Handle<Object> result;
    7011             :       Handle<JSObject> holder = it->GetHolder<JSObject>();
    7012             : 
    7013             :       Handle<Object> receiver = it->GetReceiver();
    7014          45 :       if (!receiver->IsJSReceiver()) {
    7015          14 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7016             :             isolate, receiver, Object::ConvertReceiver(isolate, receiver),
    7017             :             Nothing<bool>());
    7018             :       }
    7019             : 
    7020             :       PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    7021             :                                      *holder, Object::DONT_THROW);
    7022          45 :       if (it->IsElement()) {
    7023             :         uint32_t index = it->index();
    7024             :         v8::IndexedPropertyDescriptorCallback descriptorCallback =
    7025             :             v8::ToCData<v8::IndexedPropertyDescriptorCallback>(
    7026             :                 interceptor->descriptor());
    7027             : 
    7028          12 :         result = args.Call(descriptorCallback, index);
    7029             :       } else {
    7030          33 :         Handle<Name> name = it->name();
    7031             :         DCHECK(!name->IsPrivate());
    7032             :         v8::GenericNamedPropertyDescriptorCallback descriptorCallback =
    7033             :             v8::ToCData<v8::GenericNamedPropertyDescriptorCallback>(
    7034             :                 interceptor->descriptor());
    7035          33 :         result = args.Call(descriptorCallback, name);
    7036             :       }
    7037          45 :       if (!result.is_null()) {
    7038             :         // Request successfully intercepted, try to set the property
    7039             :         // descriptor.
    7040             :         Utils::ApiCheck(
    7041          14 :             PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
    7042             :             it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
    7043             :                             : "v8::NamedPropertyDescriptorCallback",
    7044          14 :             "Invalid property descriptor.");
    7045             : 
    7046             :         return Just(true);
    7047             :       }
    7048             :     }
    7049             :   }
    7050     4346222 :   it->Restart();
    7051             :   return Just(false);
    7052             : }
    7053             : }  // namespace
    7054             : 
    7055             : // ES6 9.1.5.1
    7056             : // Returns true on success, false if the property didn't exist, nothing if
    7057             : // an exception was thrown.
    7058             : // static
    7059     8088101 : Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it,
    7060             :                                                  PropertyDescriptor* desc) {
    7061             :   Isolate* isolate = it->isolate();
    7062             :   // "Virtual" dispatch.
    7063     8097717 :   if (it->IsFound() && it->GetHolder<JSReceiver>()->IsJSProxy()) {
    7064             :     return JSProxy::GetOwnPropertyDescriptor(isolate, it->GetHolder<JSProxy>(),
    7065        9040 :                                              it->GetName(), desc);
    7066             :   }
    7067             : 
    7068     4346236 :   Maybe<bool> intercepted = GetPropertyDescriptorWithInterceptor(it, desc);
    7069     4346236 :   MAYBE_RETURN(intercepted, Nothing<bool>());
    7070     4346236 :   if (intercepted.FromJust()) {
    7071             :     return Just(true);
    7072             :   }
    7073             : 
    7074             :   // Request was not intercepted, continue as normal.
    7075             :   // 1. (Assert)
    7076             :   // 2. If O does not have an own property with key P, return undefined.
    7077     4346222 :   Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it);
    7078     4346222 :   MAYBE_RETURN(maybe, Nothing<bool>());
    7079             :   PropertyAttributes attrs = maybe.FromJust();
    7080     4346168 :   if (attrs == ABSENT) return Just(false);
    7081             :   DCHECK(!isolate->has_pending_exception());
    7082             : 
    7083             :   // 3. Let D be a newly created Property Descriptor with no fields.
    7084             :   DCHECK(desc->is_empty());
    7085             :   // 4. Let X be O's own property whose key is P.
    7086             :   // 5. If X is a data property, then
    7087     3900922 :   bool is_accessor_pair = it->state() == LookupIterator::ACCESSOR &&
    7088     3900922 :                           it->GetAccessors()->IsAccessorPair();
    7089     3732825 :   if (!is_accessor_pair) {
    7090             :     // 5a. Set D.[[Value]] to the value of X's [[Value]] attribute.
    7091             :     Handle<Object> value;
    7092     7394420 :     if (!Object::GetProperty(it).ToHandle(&value)) {
    7093             :       DCHECK(isolate->has_pending_exception());
    7094             :       return Nothing<bool>();
    7095             :     }
    7096             :     desc->set_value(value);
    7097             :     // 5b. Set D.[[Writable]] to the value of X's [[Writable]] attribute
    7098     3697210 :     desc->set_writable((attrs & READ_ONLY) == 0);
    7099             :   } else {
    7100             :     // 6. Else X is an accessor property, so
    7101             :     Handle<AccessorPair> accessors =
    7102       35615 :         Handle<AccessorPair>::cast(it->GetAccessors());
    7103             :     // 6a. Set D.[[Get]] to the value of X's [[Get]] attribute.
    7104       35615 :     desc->set_get(AccessorPair::GetComponent(accessors, ACCESSOR_GETTER));
    7105             :     // 6b. Set D.[[Set]] to the value of X's [[Set]] attribute.
    7106       35615 :     desc->set_set(AccessorPair::GetComponent(accessors, ACCESSOR_SETTER));
    7107             :   }
    7108             : 
    7109             :   // 7. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
    7110     3732825 :   desc->set_enumerable((attrs & DONT_ENUM) == 0);
    7111             :   // 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
    7112     3732825 :   desc->set_configurable((attrs & DONT_DELETE) == 0);
    7113             :   // 9. Return D.
    7114             :   DCHECK(PropertyDescriptor::IsAccessorDescriptor(desc) !=
    7115             :          PropertyDescriptor::IsDataDescriptor(desc));
    7116             :   return Just(true);
    7117             : }
    7118             : 
    7119             : 
    7120             : // ES6 9.5.5
    7121             : // static
    7122       13932 : Maybe<bool> JSProxy::GetOwnPropertyDescriptor(Isolate* isolate,
    7123             :                                               Handle<JSProxy> proxy,
    7124             :                                               Handle<Name> name,
    7125             :                                               PropertyDescriptor* desc) {
    7126             :   DCHECK(!name->IsPrivate());
    7127       13932 :   STACK_CHECK(isolate, Nothing<bool>());
    7128             : 
    7129             :   Handle<String> trap_name =
    7130             :       isolate->factory()->getOwnPropertyDescriptor_string();
    7131             :   // 1. (Assert)
    7132             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
    7133             :   Handle<Object> handler(proxy->handler(), isolate);
    7134             :   // 3. If handler is null, throw a TypeError exception.
    7135             :   // 4. Assert: Type(handler) is Object.
    7136       13932 :   if (proxy->IsRevoked()) {
    7137             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7138          56 :         MessageTemplate::kProxyRevoked, trap_name));
    7139             :     return Nothing<bool>();
    7140             :   }
    7141             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
    7142             :   Handle<JSReceiver> target(proxy->target(), isolate);
    7143             :   // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor").
    7144             :   Handle<Object> trap;
    7145       27808 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7146             :       isolate, trap,
    7147             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
    7148             :       Nothing<bool>());
    7149             :   // 7. If trap is undefined, then
    7150       13820 :   if (trap->IsUndefined(isolate)) {
    7151             :     // 7a. Return target.[[GetOwnProperty]](P).
    7152        4983 :     return JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, desc);
    7153             :   }
    7154             :   // 8. Let trapResultObj be ? Call(trap, handler, «target, P»).
    7155             :   Handle<Object> trap_result_obj;
    7156             :   Handle<Object> args[] = {target, name};
    7157       17674 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7158             :       isolate, trap_result_obj,
    7159             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    7160             :       Nothing<bool>());
    7161             :   // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a
    7162             :   //    TypeError exception.
    7163        8694 :   if (!trap_result_obj->IsJSReceiver() &&
    7164             :       !trap_result_obj->IsUndefined(isolate)) {
    7165             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7166          56 :         MessageTemplate::kProxyGetOwnPropertyDescriptorInvalid, name));
    7167             :     return Nothing<bool>();
    7168             :   }
    7169             :   // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
    7170             :   PropertyDescriptor target_desc;
    7171             :   Maybe<bool> found =
    7172        7406 :       JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
    7173        7406 :   MAYBE_RETURN(found, Nothing<bool>());
    7174             :   // 11. If trapResultObj is undefined, then
    7175        7406 :   if (trap_result_obj->IsUndefined(isolate)) {
    7176             :     // 11a. If targetDesc is undefined, return undefined.
    7177        1232 :     if (!found.FromJust()) return Just(false);
    7178             :     // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError
    7179             :     //      exception.
    7180          70 :     if (!target_desc.configurable()) {
    7181             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7182          84 :           MessageTemplate::kProxyGetOwnPropertyDescriptorUndefined, name));
    7183             :       return Nothing<bool>();
    7184             :     }
    7185             :     // 11c. Let extensibleTarget be ? IsExtensible(target).
    7186          28 :     Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    7187          28 :     MAYBE_RETURN(extensible_target, Nothing<bool>());
    7188             :     // 11d. (Assert)
    7189             :     // 11e. If extensibleTarget is false, throw a TypeError exception.
    7190          28 :     if (!extensible_target.FromJust()) {
    7191             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7192           0 :           MessageTemplate::kProxyGetOwnPropertyDescriptorNonExtensible, name));
    7193             :       return Nothing<bool>();
    7194             :     }
    7195             :     // 11f. Return undefined.
    7196             :     return Just(false);
    7197             :   }
    7198             :   // 12. Let extensibleTarget be ? IsExtensible(target).
    7199        6174 :   Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
    7200        6174 :   MAYBE_RETURN(extensible_target, Nothing<bool>());
    7201             :   // 13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj).
    7202        6174 :   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj,
    7203        6174 :                                                 desc)) {
    7204             :     DCHECK(isolate->has_pending_exception());
    7205             :     return Nothing<bool>();
    7206             :   }
    7207             :   // 14. Call CompletePropertyDescriptor(resultDesc).
    7208        6062 :   PropertyDescriptor::CompletePropertyDescriptor(isolate, desc);
    7209             :   // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget,
    7210             :   //     resultDesc, targetDesc).
    7211             :   Maybe<bool> valid =
    7212             :       IsCompatiblePropertyDescriptor(isolate, extensible_target.FromJust(),
    7213             :                                      desc, &target_desc, name, DONT_THROW);
    7214        6062 :   MAYBE_RETURN(valid, Nothing<bool>());
    7215             :   // 16. If valid is false, throw a TypeError exception.
    7216        6062 :   if (!valid.FromJust()) {
    7217             :     isolate->Throw(*isolate->factory()->NewTypeError(
    7218          56 :         MessageTemplate::kProxyGetOwnPropertyDescriptorIncompatible, name));
    7219             :     return Nothing<bool>();
    7220             :   }
    7221             :   // 17. If resultDesc.[[Configurable]] is false, then
    7222        6034 :   if (!desc->configurable()) {
    7223             :     // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true:
    7224         742 :     if (target_desc.is_empty() || target_desc.configurable()) {
    7225             :       // 17a i. Throw a TypeError exception.
    7226             :       isolate->Throw(*isolate->factory()->NewTypeError(
    7227             :           MessageTemplate::kProxyGetOwnPropertyDescriptorNonConfigurable,
    7228          56 :           name));
    7229             :       return Nothing<bool>();
    7230             :     }
    7231             :   }
    7232             :   // 18. Return resultDesc.
    7233             :   return Just(true);
    7234             : }
    7235             : 
    7236             : 
    7237           0 : bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
    7238             :                                             ElementsKind kind,
    7239             :                                             Object* object) {
    7240             :   Isolate* isolate = elements->GetIsolate();
    7241           0 :   if (IsFastObjectElementsKind(kind) || kind == FAST_STRING_WRAPPER_ELEMENTS) {
    7242             :     int length = IsJSArray()
    7243             :         ? Smi::cast(JSArray::cast(this)->length())->value()
    7244           0 :         : elements->length();
    7245           0 :     for (int i = 0; i < length; ++i) {
    7246             :       Object* element = elements->get(i);
    7247           0 :       if (!element->IsTheHole(isolate) && element == object) return true;
    7248             :     }
    7249             :   } else {
    7250             :     DCHECK(kind == DICTIONARY_ELEMENTS || kind == SLOW_STRING_WRAPPER_ELEMENTS);
    7251             :     Object* key =
    7252           0 :         SeededNumberDictionary::cast(elements)->SlowReverseLookup(object);
    7253           0 :     if (!key->IsUndefined(isolate)) return true;
    7254             :   }
    7255             :   return false;
    7256             : }
    7257             : 
    7258             : 
    7259             : // Check whether this object references another object.
    7260           0 : bool JSObject::ReferencesObject(Object* obj) {
    7261             :   Map* map_of_this = map();
    7262             :   Heap* heap = GetHeap();
    7263             :   DisallowHeapAllocation no_allocation;
    7264             : 
    7265             :   // Is the object the constructor for this object?
    7266           0 :   if (map_of_this->GetConstructor() == obj) {
    7267             :     return true;
    7268             :   }
    7269             : 
    7270             :   // Is the object the prototype for this object?
    7271           0 :   if (map_of_this->prototype() == obj) {
    7272             :     return true;
    7273             :   }
    7274             : 
    7275             :   // Check if the object is among the named properties.
    7276           0 :   Object* key = SlowReverseLookup(obj);
    7277           0 :   if (!key->IsUndefined(heap->isolate())) {
    7278             :     return true;
    7279             :   }
    7280             : 
    7281             :   // Check if the object is among the indexed properties.
    7282             :   ElementsKind kind = GetElementsKind();
    7283           0 :   switch (kind) {
    7284             :     // Raw pixels and external arrays do not reference other
    7285             :     // objects.
    7286             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
    7287             :     case TYPE##_ELEMENTS:                                                      \
    7288             :       break;
    7289             : 
    7290             :     TYPED_ARRAYS(TYPED_ARRAY_CASE)
    7291             : #undef TYPED_ARRAY_CASE
    7292             : 
    7293             :     case FAST_DOUBLE_ELEMENTS:
    7294             :     case FAST_HOLEY_DOUBLE_ELEMENTS:
    7295             :       break;
    7296             :     case FAST_SMI_ELEMENTS:
    7297             :     case FAST_HOLEY_SMI_ELEMENTS:
    7298             :       break;
    7299             :     case FAST_ELEMENTS:
    7300             :     case FAST_HOLEY_ELEMENTS:
    7301             :     case DICTIONARY_ELEMENTS:
    7302             :     case FAST_STRING_WRAPPER_ELEMENTS:
    7303             :     case SLOW_STRING_WRAPPER_ELEMENTS: {
    7304             :       FixedArray* elements = FixedArray::cast(this->elements());
    7305           0 :       if (ReferencesObjectFromElements(elements, kind, obj)) return true;
    7306             :       break;
    7307             :     }
    7308             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    7309             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
    7310             :       SloppyArgumentsElements* elements =
    7311             :           SloppyArgumentsElements::cast(this->elements());
    7312             :       // Check the mapped parameters.
    7313           0 :       for (uint32_t i = 0; i < elements->parameter_map_length(); ++i) {
    7314             :         Object* value = elements->get_mapped_entry(i);
    7315           0 :         if (!value->IsTheHole(heap->isolate()) && value == obj) return true;
    7316             :       }
    7317             :       // Check the arguments.
    7318             :       FixedArray* arguments = elements->arguments();
    7319             :       kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS :
    7320           0 :           FAST_HOLEY_ELEMENTS;
    7321           0 :       if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
    7322             :       break;
    7323             :     }
    7324             :     case NO_ELEMENTS:
    7325             :       break;
    7326             :   }
    7327             : 
    7328             :   // For functions check the context.
    7329           0 :   if (IsJSFunction()) {
    7330             :     // Get the constructor function for arguments array.
    7331             :     Map* arguments_map =
    7332           0 :         heap->isolate()->context()->native_context()->sloppy_arguments_map();
    7333             :     JSFunction* arguments_function =
    7334           0 :         JSFunction::cast(arguments_map->GetConstructor());
    7335             : 
    7336             :     // Get the context and don't check if it is the native context.
    7337             :     JSFunction* f = JSFunction::cast(this);
    7338             :     Context* context = f->context();
    7339           0 :     if (context->IsNativeContext()) {
    7340             :       return false;
    7341             :     }
    7342             : 
    7343             :     // Check the non-special context slots.
    7344           0 :     for (int i = Context::MIN_CONTEXT_SLOTS; i < context->length(); i++) {
    7345             :       // Only check JS objects.
    7346           0 :       if (context->get(i)->IsJSObject()) {
    7347             :         JSObject* ctxobj = JSObject::cast(context->get(i));
    7348             :         // If it is an arguments array check the content.
    7349           0 :         if (ctxobj->map()->GetConstructor() == arguments_function) {
    7350           0 :           if (ctxobj->ReferencesObject(obj)) {
    7351             :             return true;
    7352             :           }
    7353           0 :         } else if (ctxobj == obj) {
    7354             :           return true;
    7355             :         }
    7356             :       }
    7357             :     }
    7358             : 
    7359             :     // Check the context extension (if any) if it can have references.
    7360           0 :     if (context->has_extension() && !context->IsCatchContext()) {
    7361             :       // With harmony scoping, a JSFunction may have a script context.
    7362             :       // TODO(mvstanton): walk into the ScopeInfo.
    7363           0 :       if (context->IsScriptContext()) {
    7364             :         return false;
    7365             :       }
    7366             : 
    7367           0 :       return context->extension_object()->ReferencesObject(obj);
    7368             :     }
    7369             :   }
    7370             : 
    7371             :   // No references to object.
    7372             :   return false;
    7373             : }
    7374             : 
    7375             : 
    7376      206214 : Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver,
    7377             :                                           IntegrityLevel level,
    7378             :                                           ShouldThrow should_throw) {
    7379             :   DCHECK(level == SEALED || level == FROZEN);
    7380             : 
    7381      206214 :   if (receiver->IsJSObject()) {
    7382             :     Handle<JSObject> object = Handle<JSObject>::cast(receiver);
    7383      205570 :     if (!object->HasSloppyArgumentsElements()) {  // Fast path.
    7384      205496 :       if (level == SEALED) {
    7385             :         return JSObject::PreventExtensionsWithTransition<SEALED>(object,
    7386         409 :                                                                  should_throw);
    7387             :       } else {
    7388             :         return JSObject::PreventExtensionsWithTransition<FROZEN>(object,
    7389      205087 :                                                                  should_throw);
    7390             :       }
    7391             :     }
    7392             :   }
    7393             : 
    7394             :   Isolate* isolate = receiver->GetIsolate();
    7395             : 
    7396         718 :   MAYBE_RETURN(JSReceiver::PreventExtensions(receiver, should_throw),
    7397             :                Nothing<bool>());
    7398             : 
    7399             :   Handle<FixedArray> keys;
    7400         718 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7401             :       isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
    7402             : 
    7403             :   PropertyDescriptor no_conf;
    7404             :   no_conf.set_configurable(false);
    7405             : 
    7406             :   PropertyDescriptor no_conf_no_write;
    7407             :   no_conf_no_write.set_configurable(false);
    7408             :   no_conf_no_write.set_writable(false);
    7409             : 
    7410         718 :   if (level == SEALED) {
    7411         406 :     for (int i = 0; i < keys->length(); ++i) {
    7412             :       Handle<Object> key(keys->get(i), isolate);
    7413         126 :       MAYBE_RETURN(
    7414             :           DefineOwnProperty(isolate, receiver, key, &no_conf, THROW_ON_ERROR),
    7415             :           Nothing<bool>());
    7416             :     }
    7417             :     return Just(true);
    7418             :   }
    7419             : 
    7420        4498 :   for (int i = 0; i < keys->length(); ++i) {
    7421             :     Handle<Object> key(keys->get(i), isolate);
    7422             :     PropertyDescriptor current_desc;
    7423             :     Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
    7424        1967 :         isolate, receiver, key, &current_desc);
    7425        1967 :     MAYBE_RETURN(owned, Nothing<bool>());
    7426        1967 :     if (owned.FromJust()) {
    7427             :       PropertyDescriptor desc =
    7428             :           PropertyDescriptor::IsAccessorDescriptor(&current_desc)
    7429             :               ? no_conf
    7430        1967 :               : no_conf_no_write;
    7431        1967 :       MAYBE_RETURN(
    7432             :           DefineOwnProperty(isolate, receiver, key, &desc, THROW_ON_ERROR),
    7433             :           Nothing<bool>());
    7434             :     }
    7435             :   }
    7436             :   return Just(true);
    7437             : }
    7438             : 
    7439             : 
    7440        7712 : Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> object,
    7441             :                                            IntegrityLevel level) {
    7442             :   DCHECK(level == SEALED || level == FROZEN);
    7443             :   Isolate* isolate = object->GetIsolate();
    7444             : 
    7445        7712 :   Maybe<bool> extensible = JSReceiver::IsExtensible(object);
    7446        7712 :   MAYBE_RETURN(extensible, Nothing<bool>());
    7447        7712 :   if (extensible.FromJust()) return Just(false);
    7448             : 
    7449             :   Handle<FixedArray> keys;
    7450        1585 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7451             :       isolate, keys, JSReceiver::OwnPropertyKeys(object), Nothing<bool>());
    7452             : 
    7453       19213 :   for (int i = 0; i < keys->length(); ++i) {
    7454             :     Handle<Object> key(keys->get(i), isolate);
    7455             :     PropertyDescriptor current_desc;
    7456             :     Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
    7457        9314 :         isolate, object, key, &current_desc);
    7458        9814 :     MAYBE_RETURN(owned, Nothing<bool>());
    7459        9314 :     if (owned.FromJust()) {
    7460        9314 :       if (current_desc.configurable()) return Just(false);
    7461       14809 :       if (level == FROZEN &&
    7462       14699 :           PropertyDescriptor::IsDataDescriptor(&current_desc) &&
    7463             :           current_desc.writable()) {
    7464             :         return Just(false);
    7465             :       }
    7466             :     }
    7467             :   }
    7468             :   return Just(true);
    7469             : }
    7470             : 
    7471             : 
    7472        7126 : Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object,
    7473             :                                           ShouldThrow should_throw) {
    7474        7126 :   if (object->IsJSProxy()) {
    7475             :     return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object),
    7476         952 :                                       should_throw);
    7477             :   }
    7478             :   DCHECK(object->IsJSObject());
    7479             :   return JSObject::PreventExtensions(Handle<JSObject>::cast(object),
    7480        6174 :                                      should_throw);
    7481             : }
    7482             : 
    7483             : 
    7484         952 : Maybe<bool> JSProxy::PreventExtensions(Handle<JSProxy> proxy,
    7485             :                                        ShouldThrow should_throw) {
    7486             :   Isolate* isolate = proxy->GetIsolate();
    7487         952 :   STACK_CHECK(isolate, Nothing<bool>());
    7488             :   Factory* factory = isolate->factory();
    7489             :   Handle<String> trap_name = factory->preventExtensions_string();
    7490             : 
    7491         952 :   if (proxy->IsRevoked()) {
    7492             :     isolate->Throw(
    7493          56 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    7494             :     return Nothing<bool>();
    7495             :   }
    7496             :   Handle<JSReceiver> target(proxy->target(), isolate);
    7497             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    7498             : 
    7499             :   Handle<Object> trap;
    7500        1848 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7501             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    7502         896 :   if (trap->IsUndefined(isolate)) {
    7503         812 :     return JSReceiver::PreventExtensions(target, should_throw);
    7504             :   }
    7505             : 
    7506             :   Handle<Object> trap_result;
    7507             :   Handle<Object> args[] = {target};
    7508         168 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7509             :       isolate, trap_result,
    7510             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    7511             :       Nothing<bool>());
    7512          84 :   if (!trap_result->BooleanValue()) {
    7513          28 :     RETURN_FAILURE(
    7514             :         isolate, should_throw,
    7515             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
    7516             :   }
    7517             : 
    7518             :   // Enforce the invariant.
    7519          56 :   Maybe<bool> target_result = JSReceiver::IsExtensible(target);
    7520          56 :   MAYBE_RETURN(target_result, Nothing<bool>());
    7521          56 :   if (target_result.FromJust()) {
    7522             :     isolate->Throw(*factory->NewTypeError(
    7523          28 :         MessageTemplate::kProxyPreventExtensionsExtensible));
    7524             :     return Nothing<bool>();
    7525             :   }
    7526             :   return Just(true);
    7527             : }
    7528             : 
    7529             : 
    7530        6632 : Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
    7531             :                                         ShouldThrow should_throw) {
    7532           0 :   Isolate* isolate = object->GetIsolate();
    7533             : 
    7534        6632 :   if (!object->HasSloppyArgumentsElements()) {
    7535        6543 :     return PreventExtensionsWithTransition<NONE>(object, should_throw);
    7536             :   }
    7537             : 
    7538          89 :   if (object->IsAccessCheckNeeded() &&
    7539           0 :       !isolate->MayAccess(handle(isolate->context()), object)) {
    7540           0 :     isolate->ReportFailedAccessCheck(object);
    7541           0 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    7542           0 :     RETURN_FAILURE(isolate, should_throw,
    7543             :                    NewTypeError(MessageTemplate::kNoAccess));
    7544             :   }
    7545             : 
    7546          89 :   if (!object->map()->is_extensible()) return Just(true);
    7547             : 
    7548          89 :   if (object->IsJSGlobalProxy()) {
    7549           0 :     PrototypeIterator iter(isolate, object);
    7550           0 :     if (iter.IsAtEnd()) return Just(true);
    7551             :     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
    7552             :     return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter),
    7553           0 :                              should_throw);
    7554             :   }
    7555             : 
    7556         178 :   if (object->map()->has_named_interceptor() ||
    7557             :       object->map()->has_indexed_interceptor()) {
    7558           0 :     RETURN_FAILURE(isolate, should_throw,
    7559             :                    NewTypeError(MessageTemplate::kCannotPreventExt));
    7560             :   }
    7561             : 
    7562          89 :   if (!object->HasFixedTypedArrayElements()) {
    7563             :     // If there are fast elements we normalize.
    7564          89 :     Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
    7565             :     DCHECK(object->HasDictionaryElements() ||
    7566             :            object->HasSlowArgumentsElements());
    7567             : 
    7568             :     // Make sure that we never go back to fast case.
    7569          89 :     object->RequireSlowElements(*dictionary);
    7570             :   }
    7571             : 
    7572             :   // Do a map transition, other objects with this map may still
    7573             :   // be extensible.
    7574             :   // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
    7575          89 :   Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions");
    7576             : 
    7577             :   new_map->set_is_extensible(false);
    7578          89 :   JSObject::MigrateToMap(object, new_map);
    7579             :   DCHECK(!object->map()->is_extensible());
    7580             : 
    7581             :   return Just(true);
    7582             : }
    7583             : 
    7584             : 
    7585     1520952 : Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) {
    7586     1520952 :   if (object->IsJSProxy()) {
    7587         910 :     return JSProxy::IsExtensible(Handle<JSProxy>::cast(object));
    7588             :   }
    7589     1520042 :   return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object)));
    7590             : }
    7591             : 
    7592             : 
    7593         910 : Maybe<bool> JSProxy::IsExtensible(Handle<JSProxy> proxy) {
    7594             :   Isolate* isolate = proxy->GetIsolate();
    7595         910 :   STACK_CHECK(isolate, Nothing<bool>());
    7596             :   Factory* factory = isolate->factory();
    7597             :   Handle<String> trap_name = factory->isExtensible_string();
    7598             : 
    7599         910 :   if (proxy->IsRevoked()) {
    7600             :     isolate->Throw(
    7601          56 :         *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
    7602             :     return Nothing<bool>();
    7603             :   }
    7604             :   Handle<JSReceiver> target(proxy->target(), isolate);
    7605             :   Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
    7606             : 
    7607             :   Handle<Object> trap;
    7608        1764 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7609             :       isolate, trap, Object::GetMethod(handler, trap_name), Nothing<bool>());
    7610         854 :   if (trap->IsUndefined(isolate)) {
    7611         196 :     return JSReceiver::IsExtensible(target);
    7612             :   }
    7613             : 
    7614             :   Handle<Object> trap_result;
    7615             :   Handle<Object> args[] = {target};
    7616        1316 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    7617             :       isolate, trap_result,
    7618             :       Execution::Call(isolate, trap, handler, arraysize(args), args),
    7619             :       Nothing<bool>());
    7620             : 
    7621             :   // Enforce the invariant.
    7622         658 :   Maybe<bool> target_result = JSReceiver::IsExtensible(target);
    7623         658 :   MAYBE_RETURN(target_result, Nothing<bool>());
    7624         658 :   if (target_result.FromJust() != trap_result->BooleanValue()) {
    7625             :     isolate->Throw(
    7626             :         *factory->NewTypeError(MessageTemplate::kProxyIsExtensibleInconsistent,
    7627          84 :                                factory->ToBoolean(target_result.FromJust())));
    7628             :     return Nothing<bool>();
    7629             :   }
    7630         616 :   return target_result;
    7631             : }
    7632             : 
    7633             : 
    7634     2354752 : bool JSObject::IsExtensible(Handle<JSObject> object) {
    7635          36 :   Isolate* isolate = object->GetIsolate();
    7636     2354788 :   if (object->IsAccessCheckNeeded() &&
    7637          36 :       !isolate->MayAccess(handle(isolate->context()), object)) {
    7638             :     return true;
    7639             :   }
    7640     2354728 :   if (object->IsJSGlobalProxy()) {
    7641             :     PrototypeIterator iter(isolate, *object);
    7642        3969 :     if (iter.IsAtEnd()) return false;
    7643             :     DCHECK(iter.GetCurrent()->IsJSGlobalObject());
    7644        7938 :     return iter.GetCurrent<JSObject>()->map()->is_extensible();
    7645             :   }
    7646     2350759 :   return object->map()->is_extensible();
    7647             : }
    7648             : 
    7649             : namespace {
    7650             : 
    7651             : template <typename Dictionary>
    7652             : void DictionaryDetailsAtPut(Isolate* isolate, Handle<Dictionary> dictionary,
    7653             :                             int entry, PropertyDetails details) {
    7654             :   dictionary->DetailsAtPut(entry, details);
    7655             : }
    7656             : 
    7657             : template <>
    7658       13229 : void DictionaryDetailsAtPut<GlobalDictionary>(
    7659             :     Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry,
    7660             :     PropertyDetails details) {
    7661       13229 :   Object* value = dictionary->ValueAt(entry);
    7662             :   DCHECK(value->IsPropertyCell());
    7663             :   value = PropertyCell::cast(value)->value();
    7664       26458 :   if (value->IsTheHole(isolate)) return;
    7665             :   PropertyCell::PrepareForValue(dictionary, entry, handle(value, isolate),
    7666       13214 :                                 details);
    7667             : }
    7668             : 
    7669             : template <typename Dictionary>
    7670        5991 : void ApplyAttributesToDictionary(Isolate* isolate,
    7671             :                                  Handle<Dictionary> dictionary,
    7672             :                                  const PropertyAttributes attributes) {
    7673             :   int capacity = dictionary->Capacity();
    7674       70583 :   for (int i = 0; i < capacity; i++) {
    7675             :     Object* k = dictionary->KeyAt(i);
    7676       90851 :     if (dictionary->IsKey(isolate, k) &&
    7677             :         !(k->IsSymbol() && Symbol::cast(k)->is_private())) {
    7678             :       PropertyDetails details = dictionary->DetailsAt(i);
    7679       26125 :       int attrs = attributes;
    7680             :       // READ_ONLY is an invalid attribute for JS setters/getters.
    7681       49718 :       if ((attributes & READ_ONLY) && details.kind() == kAccessor) {
    7682          44 :         Object* v = dictionary->ValueAt(i);
    7683          44 :         if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value();
    7684          44 :         if (v->IsAccessorPair()) attrs &= ~READ_ONLY;
    7685             :       }
    7686             :       details = details.CopyAddAttributes(
    7687             :           static_cast<PropertyAttributes>(attrs));
    7688       13229 :       DictionaryDetailsAtPut<Dictionary>(isolate, dictionary, i, details);
    7689             :     }
    7690             :   }
    7691        5991 : }
    7692             : 
    7693             : }  // namespace
    7694             : 
    7695             : template <PropertyAttributes attrs>
    7696      212187 : Maybe<bool> JSObject::PreventExtensionsWithTransition(
    7697             :     Handle<JSObject> object, ShouldThrow should_throw) {
    7698             :   STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN);
    7699             : 
    7700             :   // Sealing/freezing sloppy arguments should be handled elsewhere.
    7701             :   DCHECK(!object->HasSloppyArgumentsElements());
    7702             : 
    7703          30 :   Isolate* isolate = object->GetIsolate();
    7704      212217 :   if (object->IsAccessCheckNeeded() &&
    7705          30 :       !isolate->MayAccess(handle(isolate->context()), object)) {
    7706          24 :     isolate->ReportFailedAccessCheck(object);
    7707          24 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    7708           0 :     RETURN_FAILURE(isolate, should_throw,
    7709             :                    NewTypeError(MessageTemplate::kNoAccess));
    7710             :   }
    7711             : 
    7712        6545 :   if (attrs == NONE && !object->map()->is_extensible()) return Just(true);
    7713             : 
    7714      212148 :   if (object->IsJSGlobalProxy()) {
    7715         148 :     PrototypeIterator iter(isolate, object);
    7716         148 :     if (iter.IsAtEnd()) return Just(true);
    7717             :     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
    7718             :     return PreventExtensionsWithTransition<attrs>(
    7719         148 :         PrototypeIterator::GetCurrent<JSObject>(iter), should_throw);
    7720             :   }
    7721             : 
    7722      423999 :   if (object->map()->has_named_interceptor() ||
    7723             :       object->map()->has_indexed_interceptor()) {
    7724             :     MessageTemplate::Template message = MessageTemplate::kNone;
    7725             :     switch (attrs) {
    7726             :       case NONE:
    7727             :         message = MessageTemplate::kCannotPreventExt;
    7728             :         break;
    7729             : 
    7730             :       case SEALED:
    7731             :         message = MessageTemplate::kCannotSeal;
    7732             :         break;
    7733             : 
    7734             :       case FROZEN:
    7735             :         message = MessageTemplate::kCannotFreeze;
    7736             :         break;
    7737             :     }
    7738           3 :     RETURN_FAILURE(isolate, should_throw, NewTypeError(message));
    7739             :   }
    7740             : 
    7741             :   Handle<SeededNumberDictionary> new_element_dictionary;
    7742      635500 :   if (!object->HasFixedTypedArrayElements() &&
    7743      211910 :       !object->HasDictionaryElements() &&
    7744      211591 :       !object->HasSlowStringWrapperElements()) {
    7745             :     int length =
    7746             :         object->IsJSArray()
    7747             :             ? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
    7748      211591 :             : object->elements()->length();
    7749      217870 :     new_element_dictionary =
    7750             :         length == 0 ? isolate->factory()->empty_slow_element_dictionary()
    7751        6279 :                     : object->GetElementsAccessor()->Normalize(object);
    7752             :   }
    7753             : 
    7754             :   Handle<Symbol> transition_marker;
    7755             :   if (attrs == NONE) {
    7756             :     transition_marker = isolate->factory()->nonextensible_symbol();
    7757             :   } else if (attrs == SEALED) {
    7758             :     transition_marker = isolate->factory()->sealed_symbol();
    7759             :   } else {
    7760             :     DCHECK(attrs == FROZEN);
    7761             :     transition_marker = isolate->factory()->frozen_symbol();
    7762             :   }
    7763             : 
    7764             :   Handle<Map> old_map(object->map(), isolate);
    7765             :   Map* transition =
    7766      211999 :       TransitionArray::SearchSpecial(*old_map, *transition_marker);
    7767      211999 :   if (transition != NULL) {
    7768             :     Handle<Map> transition_map(transition, isolate);
    7769             :     DCHECK(transition_map->has_dictionary_elements() ||
    7770             :            transition_map->has_fixed_typed_array_elements() ||
    7771             :            transition_map->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
    7772             :     DCHECK(!transition_map->is_extensible());
    7773      159859 :     JSObject::MigrateToMap(object, transition_map);
    7774       52140 :   } else if (TransitionArray::CanHaveMoreTransitions(old_map)) {
    7775             :     // Create a new descriptor array with the appropriate property attributes
    7776             :     Handle<Map> new_map = Map::CopyForPreventExtensions(
    7777       51203 :         old_map, attrs, transition_marker, "CopyForPreventExtensions");
    7778       51203 :     JSObject::MigrateToMap(object, new_map);
    7779             :   } else {
    7780             :     DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map());
    7781             :     // Slow path: need to normalize properties for safety
    7782         937 :     NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0,
    7783             :                         "SlowPreventExtensions");
    7784             : 
    7785             :     // Create a new map, since other objects with this map may be extensible.
    7786             :     // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
    7787             :     Handle<Map> new_map =
    7788         937 :         Map::Copy(handle(object->map()), "SlowCopyForPreventExtensions");
    7789             :     new_map->set_is_extensible(false);
    7790         937 :     if (!new_element_dictionary.is_null()) {
    7791             :       ElementsKind new_kind =
    7792             :           IsStringWrapperElementsKind(old_map->elements_kind())
    7793             :               ? SLOW_STRING_WRAPPER_ELEMENTS
    7794         937 :               : DICTIONARY_ELEMENTS;
    7795             :       new_map->set_elements_kind(new_kind);
    7796             :     }
    7797         937 :     JSObject::MigrateToMap(object, new_map);
    7798             : 
    7799             :     if (attrs != NONE) {
    7800         213 :       if (object->IsJSGlobalObject()) {
    7801             :         Handle<GlobalDictionary> dictionary(object->global_dictionary(),
    7802             :                                             isolate);
    7803         134 :         ApplyAttributesToDictionary(isolate, dictionary, attrs);
    7804             :       } else {
    7805             :         Handle<NameDictionary> dictionary(object->property_dictionary(),
    7806             :                                           isolate);
    7807          79 :         ApplyAttributesToDictionary(isolate, dictionary, attrs);
    7808             :       }
    7809             :     }
    7810             :   }
    7811             : 
    7812             :   // Both seal and preventExtensions always go through without modifications to
    7813             :   // typed array elements. Freeze works only if there are no actual elements.
    7814      211999 :   if (object->HasFixedTypedArrayElements()) {
    7815          59 :     if (attrs == FROZEN &&
    7816             :         JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) {
    7817          44 :       isolate->Throw(*isolate->factory()->NewTypeError(
    7818          88 :           MessageTemplate::kCannotFreezeArrayBufferView));
    7819             :       return Nothing<bool>();
    7820             :     }
    7821             :     return Just(true);
    7822             :   }
    7823             : 
    7824             :   DCHECK(object->map()->has_dictionary_elements() ||
    7825             :          object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
    7826      211910 :   if (!new_element_dictionary.is_null()) {
    7827      211591 :     object->set_elements(*new_element_dictionary);
    7828             :   }
    7829             : 
    7830      211910 :   if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
    7831             :     Handle<SeededNumberDictionary> dictionary(object->element_dictionary(),
    7832             :                                               isolate);
    7833             :     // Make sure we never go back to the fast case
    7834        6510 :     object->RequireSlowElements(*dictionary);
    7835             :     if (attrs != NONE) {
    7836        5778 :       ApplyAttributesToDictionary(isolate, dictionary, attrs);
    7837             :     }
    7838             :   }
    7839             : 
    7840             :   return Just(true);
    7841             : }
    7842             : 
    7843             : 
    7844    58218049 : Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
    7845             :                                         Representation representation,
    7846             :                                         FieldIndex index) {
    7847             :   Isolate* isolate = object->GetIsolate();
    7848    58218049 :   if (object->IsUnboxedDoubleField(index)) {
    7849             :     double value = object->RawFastDoublePropertyAt(index);
    7850       78231 :     return isolate->factory()->NewHeapNumber(value);
    7851             :   }
    7852    58139818 :   Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
    7853    58139818 :   return Object::WrapForRead(isolate, raw_value, representation);
    7854             : }
    7855             : 
    7856             : template <class ContextObject>
    7857             : class JSObjectWalkVisitor {
    7858             :  public:
    7859             :   JSObjectWalkVisitor(ContextObject* site_context, bool copying,
    7860             :                       JSObject::DeepCopyHints hints)
    7861             :     : site_context_(site_context),
    7862             :       copying_(copying),
    7863     8247456 :       hints_(hints) {}
    7864             : 
    7865             :   MUST_USE_RESULT MaybeHandle<JSObject> StructureWalk(Handle<JSObject> object);
    7866             : 
    7867             :  protected:
    7868     1897610 :   MUST_USE_RESULT inline MaybeHandle<JSObject> VisitElementOrProperty(
    7869             :       Handle<JSObject> object,
    7870     2201171 :       Handle<JSObject> value) {
    7871     1897610 :     Handle<AllocationSite> current_site = site_context()->EnterNewScope();
    7872     1897610 :     MaybeHandle<JSObject> copy_of_value = StructureWalk(value);
    7873      303561 :     site_context()->ExitScope(current_site, value);
    7874     1897610 :     return copy_of_value;
    7875             :   }
    7876             : 
    7877             :   inline ContextObject* site_context() { return site_context_; }
    7878    10145062 :   inline Isolate* isolate() { return site_context()->isolate(); }
    7879             : 
    7880             :   inline bool copying() const { return copying_; }
    7881             : 
    7882             :  private:
    7883             :   ContextObject* site_context_;
    7884             :   const bool copying_;
    7885             :   const JSObject::DeepCopyHints hints_;
    7886             : };
    7887             : 
    7888             : template <class ContextObject>
    7889    10145062 : MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
    7890    26183410 :     Handle<JSObject> object) {
    7891      641009 :   Isolate* isolate = this->isolate();
    7892             :   bool copying = this->copying();
    7893    10145062 :   bool shallow = hints_ == JSObject::kObjectIsShallow;
    7894             : 
    7895    10145062 :   if (!shallow) {
    7896             :     StackLimitCheck check(isolate);
    7897             : 
    7898     8796677 :     if (check.HasOverflowed()) {
    7899         165 :       isolate->StackOverflow();
    7900             :       return MaybeHandle<JSObject>();
    7901             :     }
    7902             :   }
    7903             : 
    7904    10144897 :   if (object->map()->is_deprecated()) {
    7905        2303 :     JSObject::MigrateInstance(object);
    7906             :   }
    7907             : 
    7908             :   Handle<JSObject> copy;
    7909    10144898 :   if (copying) {
    7910             :     // JSFunction objects are not allowed to be in normal boilerplates at all.
    7911             :     DCHECK(!object->IsJSFunction());
    7912             :     Handle<AllocationSite> site_to_pass;
    7913     8922587 :     if (site_context()->ShouldCreateMemento(object)) {
    7914     7115761 :       site_to_pass = site_context()->current();
    7915             :     }
    7916     8922588 :     copy = isolate->factory()->CopyJSObjectWithAllocationSite(
    7917             :         object, site_to_pass);
    7918             :   } else {
    7919             :     copy = object;
    7920             :   }
    7921             : 
    7922             :   DCHECK(copying || copy.is_identical_to(object));
    7923             : 
    7924             :   ElementsKind kind = copy->GetElementsKind();
    7925    18757388 :   if (copying && IsFastSmiOrObjectElementsKind(kind) &&
    7926             :       FixedArray::cast(copy->elements())->map() ==
    7927     8612488 :         isolate->heap()->fixed_cow_array_map()) {
    7928      641009 :     isolate->counters()->cow_arrays_created_runtime()->Increment();
    7929             :   }
    7930             : 
    7931    10144900 :   if (!shallow) {
    7932             :     HandleScope scope(isolate);
    7933             : 
    7934             :     // Deep copy own properties.
    7935     8796514 :     if (copy->HasFastProperties()) {
    7936             :       Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
    7937             :       int limit = copy->map()->NumberOfOwnDescriptors();
    7938    29933368 :       for (int i = 0; i < limit; i++) {
    7939    21137049 :         PropertyDetails details = descriptors->GetDetails(i);
    7940    23106187 :         if (details.location() != kField) continue;
    7941             :         DCHECK_EQ(kData, details.kind());
    7942    19167911 :         FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i);
    7943    19167909 :         if (object->IsUnboxedDoubleField(index)) {
    7944      160513 :           if (copying) {
    7945             :             // Ensure that all bits of the double value are preserved.
    7946             :             uint64_t value = object->RawFastDoublePropertyAsBitsAt(index);
    7947             :             copy->RawFastDoublePropertyAsBitsAtPut(index, value);
    7948             :           }
    7949             :         } else {
    7950    19007397 :           Handle<Object> value(object->RawFastPropertyAt(index), isolate);
    7951    19007402 :           if (value->IsJSObject()) {
    7952     1693952 :             ASSIGN_RETURN_ON_EXCEPTION(
    7953             :                 isolate, value,
    7954             :                 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
    7955             :                 JSObject);
    7956      846961 :             if (copying) {
    7957      645365 :               copy->FastPropertyAtPut(index, *value);
    7958             :             }
    7959             :           } else {
    7960    18160426 :             if (copying) {
    7961    15742937 :               Representation representation = details.representation();
    7962    15742937 :               value = Object::NewStorageFor(isolate, value, representation);
    7963    15742937 :               copy->FastPropertyAtPut(index, *value);
    7964             :             }
    7965             :           }
    7966             :         }
    7967             :       }
    7968             :     } else {
    7969             :       // Only deep copy fields from the object literal expression.
    7970             :       // In particular, don't try to copy the length attribute of
    7971             :       // an array.
    7972             :       PropertyFilter filter = static_cast<PropertyFilter>(
    7973             :           ONLY_WRITABLE | ONLY_ENUMERABLE | ONLY_CONFIGURABLE);
    7974             :       KeyAccumulator accumulator(isolate, KeyCollectionMode::kOwnOnly, filter);
    7975         182 :       accumulator.CollectOwnPropertyNames(copy, copy);
    7976         182 :       Handle<FixedArray> names = accumulator.GetKeys();
    7977      593688 :       for (int i = 0; i < names->length(); i++) {
    7978             :         DCHECK(names->get(i)->IsName());
    7979             :         Handle<Name> name(Name::cast(names->get(i)));
    7980             :         Handle<Object> value =
    7981      593324 :             JSObject::GetProperty(copy, name).ToHandleChecked();
    7982      296662 :         if (value->IsJSObject()) {
    7983             :           Handle<JSObject> result;
    7984           0 :           ASSIGN_RETURN_ON_EXCEPTION(
    7985             :               isolate, result,
    7986             :               VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
    7987             :               JSObject);
    7988           0 :           if (copying) {
    7989             :             // Creating object copy for literals. No strict mode needed.
    7990           0 :             JSObject::SetProperty(copy, name, result, SLOPPY).Assert();
    7991             :           }
    7992             :         }
    7993         182 :       }
    7994             :     }
    7995             : 
    7996             :     // Deep copy own elements.
    7997     8796501 :     switch (kind) {
    7998             :       case FAST_ELEMENTS:
    7999             :       case FAST_HOLEY_ELEMENTS: {
    8000             :         Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
    8001     7716301 :         if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
    8002             : #ifdef DEBUG
    8003             :           for (int i = 0; i < elements->length(); i++) {
    8004             :             DCHECK(!elements->get(i)->IsJSObject());
    8005             :           }
    8006             : #endif
    8007             :         } else {
    8008    14127124 :           for (int i = 0; i < elements->length(); i++) {
    8009             :             Handle<Object> value(elements->get(i), isolate);
    8010     3252017 :             if (value->IsJSObject()) {
    8011             :               Handle<JSObject> result;
    8012     2100528 :               ASSIGN_RETURN_ON_EXCEPTION(
    8013             :                   isolate, result,
    8014             :                   VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
    8015             :                   JSObject);
    8016     1050234 :               if (copying) {
    8017      948439 :                 elements->set(i, *result);
    8018             :               }
    8019             :             }
    8020             :           }
    8021             :         }
    8022             :         break;
    8023             :       }
    8024             :       case DICTIONARY_ELEMENTS: {
    8025             :         Handle<SeededNumberDictionary> element_dictionary(
    8026             :             copy->element_dictionary());
    8027             :         int capacity = element_dictionary->Capacity();
    8028       28179 :         for (int i = 0; i < capacity; i++) {
    8029             :           Object* k = element_dictionary->KeyAt(i);
    8030       26276 :           if (element_dictionary->IsKey(isolate, k)) {
    8031        9826 :             Handle<Object> value(element_dictionary->ValueAt(i), isolate);
    8032        9826 :             if (value->IsJSObject()) {
    8033             :               Handle<JSObject> result;
    8034         740 :               ASSIGN_RETURN_ON_EXCEPTION(
    8035             :                   isolate, result,
    8036             :                   VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
    8037             :                   JSObject);
    8038         370 :               if (copying) {
    8039             :                 element_dictionary->ValueAtPut(i, *result);
    8040             :               }
    8041             :             }
    8042             :           }
    8043             :         }
    8044             :         break;
    8045             :       }
    8046             :       case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    8047             :       case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    8048           0 :         UNIMPLEMENTED();
    8049             :         break;
    8050             :       case FAST_STRING_WRAPPER_ELEMENTS:
    8051             :       case SLOW_STRING_WRAPPER_ELEMENTS:
    8052           0 :         UNREACHABLE();
    8053             :         break;
    8054             : 
    8055             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
    8056             :       case TYPE##_ELEMENTS:                                                    \
    8057             : 
    8058             :       TYPED_ARRAYS(TYPED_ARRAY_CASE)
    8059             : #undef TYPED_ARRAY_CASE
    8060             :       // Typed elements cannot be created using an object literal.
    8061           0 :       UNREACHABLE();
    8062             :       break;
    8063             : 
    8064             :       case FAST_SMI_ELEMENTS:
    8065             :       case FAST_HOLEY_SMI_ELEMENTS:
    8066             :       case FAST_DOUBLE_ELEMENTS:
    8067             :       case FAST_HOLEY_DOUBLE_ELEMENTS:
    8068             :       case NO_ELEMENTS:
    8069             :         // No contained objects, nothing to do.
    8070             :         break;
    8071             :     }
    8072             :   }
    8073             : 
    8074             :   return copy;
    8075             : }
    8076             : 
    8077             : 
    8078      918881 : MaybeHandle<JSObject> JSObject::DeepWalk(
    8079             :     Handle<JSObject> object,
    8080             :     AllocationSiteCreationContext* site_context) {
    8081             :   JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, false,
    8082             :                                                        kNoHints);
    8083      918881 :   MaybeHandle<JSObject> result = v.StructureWalk(object);
    8084             :   Handle<JSObject> for_assert;
    8085             :   DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object));
    8086      918881 :   return result;
    8087             : }
    8088             : 
    8089             : 
    8090     7328575 : MaybeHandle<JSObject> JSObject::DeepCopy(
    8091             :     Handle<JSObject> object,
    8092             :     AllocationSiteUsageContext* site_context,
    8093             :     DeepCopyHints hints) {
    8094             :   JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints);
    8095     7328575 :   MaybeHandle<JSObject> copy = v.StructureWalk(object);
    8096             :   Handle<JSObject> for_assert;
    8097             :   DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object));
    8098     7328575 :   return copy;
    8099             : }
    8100             : 
    8101             : // static
    8102    10353260 : MaybeHandle<Object> JSReceiver::ToPrimitive(Handle<JSReceiver> receiver,
    8103             :                                             ToPrimitiveHint hint) {
    8104             :   Isolate* const isolate = receiver->GetIsolate();
    8105             :   Handle<Object> exotic_to_prim;
    8106    20706520 :   ASSIGN_RETURN_ON_EXCEPTION(
    8107             :       isolate, exotic_to_prim,
    8108             :       GetMethod(receiver, isolate->factory()->to_primitive_symbol()), Object);
    8109    10353254 :   if (!exotic_to_prim->IsUndefined(isolate)) {
    8110             :     Handle<Object> hint_string =
    8111        6539 :         isolate->factory()->ToPrimitiveHintString(hint);
    8112             :     Handle<Object> result;
    8113       13078 :     ASSIGN_RETURN_ON_EXCEPTION(
    8114             :         isolate, result,
    8115             :         Execution::Call(isolate, exotic_to_prim, receiver, 1, &hint_string),
    8116             :         Object);
    8117        6410 :     if (result->IsPrimitive()) return result;
    8118           0 :     THROW_NEW_ERROR(isolate,
    8119             :                     NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
    8120             :                     Object);
    8121             :   }
    8122             :   return OrdinaryToPrimitive(receiver, (hint == ToPrimitiveHint::kString)
    8123             :                                            ? OrdinaryToPrimitiveHint::kString
    8124    10346715 :                                            : OrdinaryToPrimitiveHint::kNumber);
    8125             : }
    8126             : 
    8127             : 
    8128             : // static
    8129    10346715 : MaybeHandle<Object> JSReceiver::OrdinaryToPrimitive(
    8130             :     Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint) {
    8131             :   Isolate* const isolate = receiver->GetIsolate();
    8132    31040145 :   Handle<String> method_names[2];
    8133    10346715 :   switch (hint) {
    8134             :     case OrdinaryToPrimitiveHint::kNumber:
    8135       11879 :       method_names[0] = isolate->factory()->valueOf_string();
    8136       11879 :       method_names[1] = isolate->factory()->toString_string();
    8137       11879 :       break;
    8138             :     case OrdinaryToPrimitiveHint::kString:
    8139    10334836 :       method_names[0] = isolate->factory()->toString_string();
    8140    10334836 :       method_names[1] = isolate->factory()->valueOf_string();
    8141    10334836 :       break;
    8142             :   }
    8143    10363512 :   for (Handle<String> name : method_names) {
    8144             :     Handle<Object> method;
    8145    20710008 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, method,
    8146             :                                JSReceiver::GetProperty(receiver, name), Object);
    8147    10354976 :     if (method->IsCallable()) {
    8148             :       Handle<Object> result;
    8149    20708438 :       ASSIGN_RETURN_ON_EXCEPTION(
    8150             :           isolate, result, Execution::Call(isolate, method, receiver, 0, NULL),
    8151             :           Object);
    8152    10333679 :       if (result->IsPrimitive()) return result;
    8153             :     }
    8154             :   }
    8155         438 :   THROW_NEW_ERROR(isolate,
    8156             :                   NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
    8157             :                   Object);
    8158             : }
    8159             : 
    8160             : 
    8161             : // TODO(cbruni/jkummerow): Consider moving this into elements.cc.
    8162      222954 : bool JSObject::HasEnumerableElements() {
    8163             :   // TODO(cbruni): cleanup
    8164             :   JSObject* object = this;
    8165      222954 :   switch (object->GetElementsKind()) {
    8166             :     case FAST_SMI_ELEMENTS:
    8167             :     case FAST_ELEMENTS:
    8168             :     case FAST_DOUBLE_ELEMENTS: {
    8169             :       int length = object->IsJSArray()
    8170             :                        ? Smi::cast(JSArray::cast(object)->length())->value()
    8171       89170 :                        : object->elements()->length();
    8172       89170 :       return length > 0;
    8173             :     }
    8174             :     case FAST_HOLEY_SMI_ELEMENTS:
    8175             :     case FAST_HOLEY_ELEMENTS: {
    8176             :       FixedArray* elements = FixedArray::cast(object->elements());
    8177             :       int length = object->IsJSArray()
    8178             :                        ? Smi::cast(JSArray::cast(object)->length())->value()
    8179      133339 :                        : elements->length();
    8180             :       Isolate* isolate = GetIsolate();
    8181     4028504 :       for (int i = 0; i < length; i++) {
    8182     3934375 :         if (!elements->is_the_hole(isolate, i)) return true;
    8183             :       }
    8184             :       return false;
    8185             :     }
    8186             :     case FAST_HOLEY_DOUBLE_ELEMENTS: {
    8187             :       int length = object->IsJSArray()
    8188             :                        ? Smi::cast(JSArray::cast(object)->length())->value()
    8189          75 :                        : object->elements()->length();
    8190             :       // Zero-length arrays would use the empty FixedArray...
    8191          75 :       if (length == 0) return false;
    8192             :       // ...so only cast to FixedDoubleArray otherwise.
    8193             :       FixedDoubleArray* elements = FixedDoubleArray::cast(object->elements());
    8194          75 :       for (int i = 0; i < length; i++) {
    8195          75 :         if (!elements->is_the_hole(i)) return true;
    8196             :       }
    8197             :       return false;
    8198             :     }
    8199             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
    8200             :     case TYPE##_ELEMENTS:
    8201             : 
    8202             :       TYPED_ARRAYS(TYPED_ARRAY_CASE)
    8203             : #undef TYPED_ARRAY_CASE
    8204             :       {
    8205             :         int length = object->elements()->length();
    8206           0 :         return length > 0;
    8207             :       }
    8208             :     case DICTIONARY_ELEMENTS: {
    8209             :       SeededNumberDictionary* elements =
    8210             :           SeededNumberDictionary::cast(object->elements());
    8211         280 :       return elements->NumberOfElementsFilterAttributes(ONLY_ENUMERABLE) > 0;
    8212             :     }
    8213             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    8214             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    8215             :       // We're approximating non-empty arguments objects here.
    8216             :       return true;
    8217             :     case FAST_STRING_WRAPPER_ELEMENTS:
    8218             :     case SLOW_STRING_WRAPPER_ELEMENTS:
    8219           0 :       if (String::cast(JSValue::cast(object)->value())->length() > 0) {
    8220             :         return true;
    8221             :       }
    8222           0 :       return object->elements()->length() > 0;
    8223             :     case NO_ELEMENTS:
    8224           0 :       return false;
    8225             :   }
    8226           0 :   UNREACHABLE();
    8227             :   return true;
    8228             : }
    8229             : 
    8230             : 
    8231      175278 : int Map::NumberOfDescribedProperties(DescriptorFlag which,
    8232             :                                      PropertyFilter filter) {
    8233             :   int result = 0;
    8234             :   DescriptorArray* descs = instance_descriptors();
    8235             :   int limit = which == ALL_DESCRIPTORS
    8236             :       ? descs->number_of_descriptors()
    8237      175278 :       : NumberOfOwnDescriptors();
    8238     1120023 :   for (int i = 0; i < limit; i++) {
    8239     2603766 :     if ((descs->GetDetails(i).attributes() & filter) == 0 &&
    8240      714276 :         !descs->GetKey(i)->FilterKey(filter)) {
    8241      711549 :       result++;
    8242             :     }
    8243             :   }
    8244      175278 :   return result;
    8245             : }
    8246             : 
    8247             : 
    8248     8779880 : int Map::NextFreePropertyIndex() {
    8249             :   int free_index = 0;
    8250             :   int number_of_own_descriptors = NumberOfOwnDescriptors();
    8251             :   DescriptorArray* descs = instance_descriptors();
    8252   289287866 :   for (int i = 0; i < number_of_own_descriptors; i++) {
    8253   280507986 :     PropertyDetails details = descs->GetDetails(i);
    8254   280507986 :     if (details.location() == kField) {
    8255   271066829 :       int candidate = details.field_index() + details.field_width_in_words();
    8256   271066829 :       if (candidate > free_index) free_index = candidate;
    8257             :     }
    8258             :   }
    8259     8779880 :   return free_index;
    8260             : }
    8261             : 
    8262             : 
    8263    16080831 : bool Map::OnlyHasSimpleProperties() {
    8264             :   // Wrapped string elements aren't explicitly stored in the elements backing
    8265             :   // store, but are loaded indirectly from the underlying string.
    8266    16076322 :   return !IsStringWrapperElementsKind(elements_kind()) &&
    8267    48174479 :          !IsSpecialReceiverMap() && !has_hidden_prototype() &&
    8268    16080831 :          !is_dictionary_map();
    8269             : }
    8270             : 
    8271        1064 : MUST_USE_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
    8272             :     Isolate* isolate, Handle<JSReceiver> receiver, bool get_entries,
    8273             :     Handle<FixedArray>* result) {
    8274             :   Handle<Map> map(JSReceiver::cast(*receiver)->map(), isolate);
    8275             : 
    8276        1064 :   if (!map->IsJSObjectMap()) return Just(false);
    8277         616 :   if (!map->OnlyHasSimpleProperties()) return Just(false);
    8278             : 
    8279             :   Handle<JSObject> object(JSObject::cast(*receiver));
    8280             : 
    8281             :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    8282             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    8283             :   int number_of_own_elements =
    8284         952 :       object->GetElementsAccessor()->GetCapacity(*object, object->elements());
    8285             :   Handle<FixedArray> values_or_entries = isolate->factory()->NewFixedArray(
    8286         476 :       number_of_own_descriptors + number_of_own_elements);
    8287         476 :   int count = 0;
    8288             : 
    8289         476 :   if (object->elements() != isolate->heap()->empty_fixed_array()) {
    8290         336 :     MAYBE_RETURN(object->GetElementsAccessor()->CollectValuesOrEntries(
    8291             :                      isolate, object, values_or_entries, get_entries, &count,
    8292             :                      ENUMERABLE_STRINGS),
    8293             :                  Nothing<bool>());
    8294             :   }
    8295             : 
    8296         476 :   bool stable = object->map() == *map;
    8297             : 
    8298        1792 :   for (int index = 0; index < number_of_own_descriptors; index++) {
    8299             :     Handle<Name> next_key(descriptors->GetKey(index), isolate);
    8300        1316 :     if (!next_key->IsString()) continue;
    8301             :     Handle<Object> prop_value;
    8302             : 
    8303             :     // Directly decode from the descriptor array if |from| did not change shape.
    8304        1176 :     if (stable) {
    8305        1148 :       PropertyDetails details = descriptors->GetDetails(index);
    8306        1148 :       if (!details.IsEnumerable()) continue;
    8307         784 :       if (details.kind() == kData) {
    8308         728 :         if (details.location() == kDescriptor) {
    8309             :           prop_value = handle(descriptors->GetValue(index), isolate);
    8310             :         } else {
    8311         728 :           Representation representation = details.representation();
    8312         728 :           FieldIndex field_index = FieldIndex::ForDescriptor(*map, index);
    8313             :           prop_value =
    8314         728 :               JSObject::FastPropertyAt(object, representation, field_index);
    8315             :         }
    8316             :       } else {
    8317         112 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8318             :             isolate, prop_value, JSReceiver::GetProperty(object, next_key),
    8319             :             Nothing<bool>());
    8320          56 :         stable = object->map() == *map;
    8321             :       }
    8322             :     } else {
    8323             :       // If the map did change, do a slower lookup. We are still guaranteed that
    8324             :       // the object has a simple shape, and that the key is a name.
    8325          28 :       LookupIterator it(object, next_key, LookupIterator::OWN_SKIP_INTERCEPTOR);
    8326          28 :       if (!it.IsFound()) continue;
    8327             :       DCHECK(it.state() == LookupIterator::DATA ||
    8328             :              it.state() == LookupIterator::ACCESSOR);
    8329          28 :       if (!it.IsEnumerable()) continue;
    8330          56 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8331             :           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
    8332             :     }
    8333             : 
    8334         812 :     if (get_entries) {
    8335         560 :       prop_value = MakeEntryPair(isolate, next_key, prop_value);
    8336             :     }
    8337             : 
    8338        1624 :     values_or_entries->set(count, *prop_value);
    8339         812 :     count++;
    8340             :   }
    8341             : 
    8342         476 :   if (count < values_or_entries->length()) values_or_entries->Shrink(count);
    8343         476 :   *result = values_or_entries;
    8344             :   return Just(true);
    8345             : }
    8346             : 
    8347        1064 : MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
    8348             :                                               Handle<JSReceiver> object,
    8349             :                                               PropertyFilter filter,
    8350             :                                               bool get_entries) {
    8351             :   Handle<FixedArray> values_or_entries;
    8352        1064 :   if (filter == ENUMERABLE_STRINGS) {
    8353             :     Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries(
    8354        1064 :         isolate, object, get_entries, &values_or_entries);
    8355        1540 :     if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>();
    8356        1064 :     if (fast_values_or_entries.FromJust()) return values_or_entries;
    8357             :   }
    8358             : 
    8359             :   PropertyFilter key_filter =
    8360         588 :       static_cast<PropertyFilter>(filter & ~ONLY_ENUMERABLE);
    8361             : 
    8362             :   Handle<FixedArray> keys;
    8363        1176 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8364             :       isolate, keys,
    8365             :       KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, key_filter,
    8366             :                               GetKeysConversion::kConvertToString),
    8367             :       MaybeHandle<FixedArray>());
    8368             : 
    8369         588 :   values_or_entries = isolate->factory()->NewFixedArray(keys->length());
    8370             :   int length = 0;
    8371             : 
    8372        5152 :   for (int i = 0; i < keys->length(); ++i) {
    8373             :     Handle<Name> key = Handle<Name>::cast(handle(keys->get(i), isolate));
    8374             : 
    8375        1988 :     if (filter & ONLY_ENUMERABLE) {
    8376             :       PropertyDescriptor descriptor;
    8377             :       Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
    8378        1988 :           isolate, object, key, &descriptor);
    8379        1988 :       MAYBE_RETURN(did_get_descriptor, MaybeHandle<FixedArray>());
    8380        3948 :       if (!did_get_descriptor.FromJust() || !descriptor.enumerable()) continue;
    8381             :     }
    8382             : 
    8383             :     Handle<Object> value;
    8384        2744 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    8385             :         isolate, value, JSReceiver::GetPropertyOrElement(object, key),
    8386             :         MaybeHandle<FixedArray>());
    8387             : 
    8388        1372 :     if (get_entries) {
    8389             :       Handle<FixedArray> entry_storage =
    8390         686 :           isolate->factory()->NewUninitializedFixedArray(2);
    8391         686 :       entry_storage->set(0, *key);
    8392         686 :       entry_storage->set(1, *value);
    8393             :       value = isolate->factory()->NewJSArrayWithElements(entry_storage,
    8394         686 :                                                          FAST_ELEMENTS, 2);
    8395             :     }
    8396             : 
    8397        1372 :     values_or_entries->set(length, *value);
    8398        1372 :     length++;
    8399             :   }
    8400         588 :   if (length < values_or_entries->length()) values_or_entries->Shrink(length);
    8401             :   return values_or_entries;
    8402             : }
    8403             : 
    8404         518 : MaybeHandle<FixedArray> JSReceiver::GetOwnValues(Handle<JSReceiver> object,
    8405             :                                                  PropertyFilter filter) {
    8406         518 :   return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, false);
    8407             : }
    8408             : 
    8409         546 : MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object,
    8410             :                                                   PropertyFilter filter) {
    8411         546 :   return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, true);
    8412             : }
    8413             : 
    8414      301849 : bool Map::DictionaryElementsInPrototypeChainOnly() {
    8415      301849 :   if (IsDictionaryElementsKind(elements_kind())) {
    8416             :     return false;
    8417             :   }
    8418             : 
    8419      887039 :   for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) {
    8420             :     // Be conservative, don't walk into proxies.
    8421     1199116 :     if (iter.GetCurrent()->IsJSProxy()) return true;
    8422             :     // String wrappers have non-configurable, non-writable elements.
    8423     1199116 :     if (iter.GetCurrent()->IsStringWrapper()) return true;
    8424      599513 :     JSObject* current = iter.GetCurrent<JSObject>();
    8425             : 
    8426      610730 :     if (current->HasDictionaryElements() &&
    8427       11217 :         current->element_dictionary()->requires_slow_elements()) {
    8428             :       return true;
    8429             :     }
    8430             : 
    8431      588615 :     if (current->HasSlowArgumentsElements()) {
    8432             :       FixedArray* parameter_map = FixedArray::cast(current->elements());
    8433             :       Object* arguments = parameter_map->get(1);
    8434           0 :       if (SeededNumberDictionary::cast(arguments)->requires_slow_elements()) {
    8435             :         return true;
    8436             :       }
    8437             :     }
    8438             :   }
    8439             : 
    8440      287481 :   return false;
    8441             : }
    8442             : 
    8443             : 
    8444      386449 : MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
    8445             :                                              Handle<Name> name,
    8446             :                                              Handle<Object> getter,
    8447             :                                              Handle<Object> setter,
    8448             :                                              PropertyAttributes attributes) {
    8449             :   Isolate* isolate = object->GetIsolate();
    8450             : 
    8451             :   LookupIterator it = LookupIterator::PropertyOrElement(
    8452      386449 :       isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    8453      386449 :   return DefineAccessor(&it, getter, setter, attributes);
    8454             : }
    8455             : 
    8456             : 
    8457     1523784 : MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
    8458             :                                              Handle<Object> getter,
    8459             :                                              Handle<Object> setter,
    8460             :                                              PropertyAttributes attributes) {
    8461             :   Isolate* isolate = it->isolate();
    8462             : 
    8463      507930 :   it->UpdateProtector();
    8464             : 
    8465      507930 :   if (it->state() == LookupIterator::ACCESS_CHECK) {
    8466        2657 :     if (!it->HasAccess()) {
    8467           6 :       isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    8468           6 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    8469             :       return isolate->factory()->undefined_value();
    8470             :     }
    8471        2651 :     it->Next();
    8472             :   }
    8473             : 
    8474             :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    8475             :   // Ignore accessors on typed arrays.
    8476      547112 :   if (it->IsElement() && object->HasFixedTypedArrayElements()) {
    8477             :     return it->factory()->undefined_value();
    8478             :   }
    8479             : 
    8480             :   DCHECK(getter->IsCallable() || getter->IsUndefined(isolate) ||
    8481             :          getter->IsNull(isolate) || getter->IsFunctionTemplateInfo());
    8482             :   DCHECK(setter->IsCallable() || setter->IsUndefined(isolate) ||
    8483             :          setter->IsNull(isolate) || setter->IsFunctionTemplateInfo());
    8484      507924 :   it->TransitionToAccessorProperty(getter, setter, attributes);
    8485             : 
    8486             :   return isolate->factory()->undefined_value();
    8487             : }
    8488             : 
    8489             : 
    8490      118150 : MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
    8491             :                                           Handle<AccessorInfo> info) {
    8492             :   Isolate* isolate = object->GetIsolate();
    8493             :   Handle<Name> name(Name::cast(info->name()), isolate);
    8494             : 
    8495             :   LookupIterator it = LookupIterator::PropertyOrElement(
    8496      118150 :       isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    8497             : 
    8498             :   // Duplicate ACCESS_CHECK outside of GetPropertyAttributes for the case that
    8499             :   // the FailedAccessCheckCallbackFunction doesn't throw an exception.
    8500             :   //
    8501             :   // TODO(verwaest): Force throw an exception if the callback doesn't, so we can
    8502             :   // remove reliance on default return values.
    8503      118150 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    8504        6955 :     if (!it.HasAccess()) {
    8505           6 :       isolate->ReportFailedAccessCheck(object);
    8506           6 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    8507           0 :       return it.factory()->undefined_value();
    8508             :     }
    8509        6949 :     it.Next();
    8510             :   }
    8511             : 
    8512             :   // Ignore accessors on typed arrays.
    8513      118158 :   if (it.IsElement() && object->HasFixedTypedArrayElements()) {
    8514           0 :     return it.factory()->undefined_value();
    8515             :   }
    8516             : 
    8517      118144 :   CHECK(GetPropertyAttributes(&it).IsJust());
    8518             : 
    8519             :   // ES5 forbids turning a property into an accessor if it's not
    8520             :   // configurable. See 8.6.1 (Table 5).
    8521      118187 :   if (it.IsFound() && !it.IsConfigurable()) {
    8522          29 :     return it.factory()->undefined_value();
    8523             :   }
    8524             : 
    8525      118115 :   it.TransitionToAccessorPair(info, info->property_attributes());
    8526             : 
    8527             :   return object;
    8528             : }
    8529             : 
    8530          84 : Object* JSObject::SlowReverseLookup(Object* value) {
    8531          84 :   if (HasFastProperties()) {
    8532             :     int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
    8533             :     DescriptorArray* descs = map()->instance_descriptors();
    8534             :     bool value_is_number = value->IsNumber();
    8535         252 :     for (int i = 0; i < number_of_own_descriptors; i++) {
    8536         210 :       PropertyDetails details = descs->GetDetails(i);
    8537         210 :       if (details.location() == kField) {
    8538             :         DCHECK_EQ(kData, details.kind());
    8539          28 :         FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
    8540          28 :         if (IsUnboxedDoubleField(field_index)) {
    8541           0 :           if (value_is_number) {
    8542             :             double property = RawFastDoublePropertyAt(field_index);
    8543           0 :             if (property == value->Number()) {
    8544          28 :               return descs->GetKey(i);
    8545             :             }
    8546             :           }
    8547             :         } else {
    8548          28 :           Object* property = RawFastPropertyAt(field_index);
    8549          28 :           if (field_index.is_double()) {
    8550             :             DCHECK(property->IsMutableHeapNumber());
    8551           0 :             if (value_is_number && property->Number() == value->Number()) {
    8552           0 :               return descs->GetKey(i);
    8553             :             }
    8554          28 :           } else if (property == value) {
    8555          28 :             return descs->GetKey(i);
    8556             :           }
    8557             :         }
    8558             :       } else {
    8559             :         DCHECK_EQ(kDescriptor, details.location());
    8560         182 :         if (details.kind() == kData) {
    8561         168 :           if (descs->GetValue(i) == value) {
    8562           0 :             return descs->GetKey(i);
    8563             :           }
    8564             :         }
    8565             :       }
    8566             :     }
    8567          42 :     return GetHeap()->undefined_value();
    8568          14 :   } else if (IsJSGlobalObject()) {
    8569          14 :     return global_dictionary()->SlowReverseLookup(value);
    8570             :   } else {
    8571           0 :     return property_dictionary()->SlowReverseLookup(value);
    8572             :   }
    8573             : }
    8574             : 
    8575             : 
    8576    25904759 : Handle<Map> Map::RawCopy(Handle<Map> map, int instance_size) {
    8577             :   Isolate* isolate = map->GetIsolate();
    8578             :   Handle<Map> result =
    8579    25904759 :       isolate->factory()->NewMap(map->instance_type(), instance_size);
    8580             :   Handle<Object> prototype(map->prototype(), isolate);
    8581    25904748 :   Map::SetPrototype(result, prototype);
    8582    51809497 :   result->set_constructor_or_backpointer(map->GetConstructor());
    8583             :   result->set_bit_field(map->bit_field());
    8584             :   result->set_bit_field2(map->bit_field2());
    8585             :   int new_bit_field3 = map->bit_field3();
    8586             :   new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
    8587             :   new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
    8588             :   new_bit_field3 = EnumLengthBits::update(new_bit_field3,
    8589             :                                           kInvalidEnumCacheSentinel);
    8590    25904750 :   new_bit_field3 = Deprecated::update(new_bit_field3, false);
    8591    25904750 :   if (!map->is_dictionary_map()) {
    8592    24624742 :     new_bit_field3 = IsUnstable::update(new_bit_field3, false);
    8593             :   }
    8594    25904750 :   result->set_bit_field3(new_bit_field3);
    8595    25904750 :   return result;
    8596             : }
    8597             : 
    8598             : 
    8599     1317738 : Handle<Map> Map::Normalize(Handle<Map> fast_map, PropertyNormalizationMode mode,
    8600             :                            const char* reason) {
    8601             :   DCHECK(!fast_map->is_dictionary_map());
    8602             : 
    8603      329339 :   Isolate* isolate = fast_map->GetIsolate();
    8604             :   Handle<Object> maybe_cache(isolate->native_context()->normalized_map_cache(),
    8605     2635476 :                              isolate);
    8606             :   bool use_cache =
    8607     2400975 :       !fast_map->is_prototype_map() && !maybe_cache->IsUndefined(isolate);
    8608             :   Handle<NormalizedMapCache> cache;
    8609     1317738 :   if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache);
    8610             : 
    8611             :   Handle<Map> new_map;
    8612     3483264 :   if (use_cache && cache->Get(fast_map, mode).ToHandle(&new_map)) {
    8613             : #ifdef VERIFY_HEAP
    8614             :     if (FLAG_verify_heap) new_map->DictionaryMapVerify();
    8615             : #endif
    8616             : #ifdef ENABLE_SLOW_DCHECKS
    8617             :     if (FLAG_enable_slow_asserts) {
    8618             :       // The cached map should match newly created normalized map bit-by-bit,
    8619             :       // except for the code cache, which can contain some ics which can be
    8620             :       // applied to the shared map, dependent code and weak cell cache.
    8621             :       Handle<Map> fresh = Map::CopyNormalized(fast_map, mode);
    8622             : 
    8623             :       if (new_map->is_prototype_map()) {
    8624             :         // For prototype maps, the PrototypeInfo is not copied.
    8625             :         DCHECK(memcmp(fresh->address(), new_map->address(),
    8626             :                       kTransitionsOrPrototypeInfoOffset) == 0);
    8627             :         DCHECK(fresh->raw_transitions() == Smi::kZero);
    8628             :         STATIC_ASSERT(kDescriptorsOffset ==
    8629             :                       kTransitionsOrPrototypeInfoOffset + kPointerSize);
    8630             :         DCHECK(memcmp(HeapObject::RawField(*fresh, kDescriptorsOffset),
    8631             :                       HeapObject::RawField(*new_map, kDescriptorsOffset),
    8632             :                       kCodeCacheOffset - kDescriptorsOffset) == 0);
    8633             :       } else {
    8634             :         DCHECK(memcmp(fresh->address(), new_map->address(),
    8635             :                       Map::kCodeCacheOffset) == 0);
    8636             :       }
    8637             :       STATIC_ASSERT(Map::kDependentCodeOffset ==
    8638             :                     Map::kCodeCacheOffset + kPointerSize);
    8639             :       STATIC_ASSERT(Map::kWeakCellCacheOffset ==
    8640             :                     Map::kDependentCodeOffset + kPointerSize);
    8641             :       int offset = Map::kWeakCellCacheOffset + kPointerSize;
    8642             :       DCHECK(memcmp(fresh->address() + offset,
    8643             :                     new_map->address() + offset,
    8644             :                     Map::kSize - offset) == 0);
    8645             :     }
    8646             : #endif
    8647             :   } else {
    8648      564314 :     new_map = Map::CopyNormalized(fast_map, mode);
    8649      564314 :     if (use_cache) {
    8650      329339 :       cache->Set(fast_map, new_map);
    8651      329339 :       isolate->counters()->maps_normalized()->Increment();
    8652             :     }
    8653             : #if TRACE_MAPS
    8654             :     if (FLAG_trace_maps) {
    8655             :       PrintF("[TraceMaps: Normalize from= %p to= %p reason= %s ]\n",
    8656             :              reinterpret_cast<void*>(*fast_map),
    8657             :              reinterpret_cast<void*>(*new_map), reason);
    8658             :     }
    8659             : #endif
    8660             :   }
    8661     1317738 :   fast_map->NotifyLeafMapLayoutChange();
    8662     1317738 :   return new_map;
    8663             : }
    8664             : 
    8665             : 
    8666      564314 : Handle<Map> Map::CopyNormalized(Handle<Map> map,
    8667             :                                 PropertyNormalizationMode mode) {
    8668             :   int new_instance_size = map->instance_size();
    8669      564314 :   if (mode == CLEAR_INOBJECT_PROPERTIES) {
    8670      109803 :     new_instance_size -= map->GetInObjectProperties() * kPointerSize;
    8671             :   }
    8672             : 
    8673      564314 :   Handle<Map> result = RawCopy(map, new_instance_size);
    8674             : 
    8675      564314 :   if (mode != CLEAR_INOBJECT_PROPERTIES) {
    8676             :     result->SetInObjectProperties(map->GetInObjectProperties());
    8677             :   }
    8678             : 
    8679             :   result->set_dictionary_map(true);
    8680             :   result->set_migration_target(false);
    8681             :   result->set_construction_counter(kNoSlackTracking);
    8682             : 
    8683             : #ifdef VERIFY_HEAP
    8684             :   if (FLAG_verify_heap) result->DictionaryMapVerify();
    8685             : #endif
    8686             : 
    8687      564314 :   return result;
    8688             : }
    8689             : 
    8690             : // Return an immutable prototype exotic object version of the input map.
    8691             : // Never even try to cache it in the transition tree, as it is intended
    8692             : // for the global object and its prototype chain, and excluding it saves
    8693             : // memory on the map transition tree.
    8694             : 
    8695             : // static
    8696           7 : Handle<Map> Map::TransitionToImmutableProto(Handle<Map> map) {
    8697           7 :   Handle<Map> new_map = Map::Copy(map, "ImmutablePrototype");
    8698             :   new_map->set_immutable_proto(true);
    8699           7 :   return new_map;
    8700             : }
    8701             : 
    8702      410220 : Handle<Map> Map::CopyInitialMap(Handle<Map> map, int instance_size,
    8703             :                                 int in_object_properties,
    8704             :                                 int unused_property_fields) {
    8705             : #ifdef DEBUG
    8706             :   Isolate* isolate = map->GetIsolate();
    8707             :   // Strict function maps have Function as a constructor but the
    8708             :   // Function's initial map is a sloppy function map. Same holds for
    8709             :   // GeneratorFunction / AsyncFunction and its initial map.
    8710             :   Object* constructor = map->GetConstructor();
    8711             :   DCHECK(constructor->IsJSFunction());
    8712             :   DCHECK(*map == JSFunction::cast(constructor)->initial_map() ||
    8713             :          *map == *isolate->strict_function_map() ||
    8714             :          *map == *isolate->generator_function_map() ||
    8715             :          *map == *isolate->async_function_map());
    8716             : #endif
    8717             :   // Initial maps must always own their descriptors and it's descriptor array
    8718             :   // does not contain descriptors that do not belong to the map.
    8719             :   DCHECK(map->owns_descriptors());
    8720             :   DCHECK_EQ(map->NumberOfOwnDescriptors(),
    8721             :             map->instance_descriptors()->number_of_descriptors());
    8722             : 
    8723      410220 :   Handle<Map> result = RawCopy(map, instance_size);
    8724             : 
    8725             :   // Please note instance_type and instance_size are set when allocated.
    8726             :   result->SetInObjectProperties(in_object_properties);
    8727             :   result->set_unused_property_fields(unused_property_fields);
    8728             : 
    8729             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    8730      410220 :   if (number_of_own_descriptors > 0) {
    8731             :     // The copy will use the same descriptors array.
    8732             :     result->UpdateDescriptors(map->instance_descriptors(),
    8733      214003 :                               map->GetLayoutDescriptor());
    8734             :     result->SetNumberOfOwnDescriptors(number_of_own_descriptors);
    8735             : 
    8736             :     DCHECK_EQ(result->NumberOfFields(),
    8737             :               in_object_properties - unused_property_fields);
    8738             :   }
    8739             : 
    8740      410220 :   return result;
    8741             : }
    8742             : 
    8743             : 
    8744    24930225 : Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) {
    8745    24930225 :   Handle<Map> result = RawCopy(map, map->instance_size());
    8746             : 
    8747             :   // Please note instance_type and instance_size are set when allocated.
    8748    24930219 :   if (map->IsJSObjectMap()) {
    8749             :     result->SetInObjectProperties(map->GetInObjectProperties());
    8750             :     result->set_unused_property_fields(map->unused_property_fields());
    8751             :   }
    8752             :   result->ClearCodeCache(map->GetHeap());
    8753    24930219 :   map->NotifyLeafMapLayoutChange();
    8754    24930225 :   return result;
    8755             : }
    8756             : 
    8757             : 
    8758     9525533 : Handle<Map> Map::ShareDescriptor(Handle<Map> map,
    8759             :                                  Handle<DescriptorArray> descriptors,
    8760             :                                  Descriptor* descriptor) {
    8761             :   // Sanity check. This path is only to be taken if the map owns its descriptor
    8762             :   // array, implying that its NumberOfOwnDescriptors equals the number of
    8763             :   // descriptors in the descriptor array.
    8764             :   DCHECK_EQ(map->NumberOfOwnDescriptors(),
    8765             :             map->instance_descriptors()->number_of_descriptors());
    8766             : 
    8767     9525533 :   Handle<Map> result = CopyDropDescriptors(map);
    8768     9525533 :   Handle<Name> name = descriptor->GetKey();
    8769             : 
    8770             :   // Ensure there's space for the new descriptor in the shared descriptor array.
    8771     9525533 :   if (descriptors->NumberOfSlackDescriptors() == 0) {
    8772     5825462 :     int old_size = descriptors->number_of_descriptors();
    8773     5825462 :     if (old_size == 0) {
    8774         531 :       descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1);
    8775             :     } else {
    8776     5824931 :       int slack = SlackForArraySize(old_size, kMaxNumberOfDescriptors);
    8777     5824931 :       EnsureDescriptorSlack(map, slack);
    8778             :       descriptors = handle(map->instance_descriptors());
    8779             :     }
    8780             :   }
    8781             : 
    8782             :   Handle<LayoutDescriptor> layout_descriptor =
    8783             :       FLAG_unbox_double_fields
    8784             :           ? LayoutDescriptor::ShareAppend(map, descriptor->GetDetails())
    8785     9525533 :           : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate());
    8786             : 
    8787             :   {
    8788             :     DisallowHeapAllocation no_gc;
    8789     9525532 :     descriptors->Append(descriptor);
    8790     9525533 :     result->InitializeDescriptors(*descriptors, *layout_descriptor);
    8791             :   }
    8792             : 
    8793             :   DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
    8794     9525531 :   ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION);
    8795             : 
    8796     9525533 :   return result;
    8797             : }
    8798             : 
    8799             : 
    8800             : #if TRACE_MAPS
    8801             : 
    8802             : // static
    8803             : void Map::TraceTransition(const char* what, Map* from, Map* to, Name* name) {
    8804             :   if (FLAG_trace_maps) {
    8805             :     PrintF("[TraceMaps: %s from= %p to= %p name= ", what,
    8806             :            reinterpret_cast<void*>(from), reinterpret_cast<void*>(to));
    8807             :     name->NameShortPrint();
    8808             :     PrintF(" ]\n");
    8809             :   }
    8810             : }
    8811             : 
    8812             : 
    8813             : // static
    8814             : void Map::TraceAllTransitions(Map* map) {
    8815             :   Object* transitions = map->raw_transitions();
    8816             :   int num_transitions = TransitionArray::NumberOfTransitions(transitions);
    8817             :   for (int i = -0; i < num_transitions; ++i) {
    8818             :     Map* target = TransitionArray::GetTarget(transitions, i);
    8819             :     Name* key = TransitionArray::GetKey(transitions, i);
    8820             :     Map::TraceTransition("Transition", map, target, key);
    8821             :     Map::TraceAllTransitions(target);
    8822             :   }
    8823             : }
    8824             : 
    8825             : #endif  // TRACE_MAPS
    8826             : 
    8827             : 
    8828    11747190 : void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child,
    8829             :                             Handle<Name> name, SimpleTransitionFlag flag) {
    8830    23494380 :   if (!parent->GetBackPointer()->IsUndefined(parent->GetIsolate())) {
    8831             :     parent->set_owns_descriptors(false);
    8832             :   } else {
    8833             :     // |parent| is initial map and it must keep the ownership, there must be no
    8834             :     // descriptors in the descriptors array that do not belong to the map.
    8835             :     DCHECK(parent->owns_descriptors());
    8836             :     DCHECK_EQ(parent->NumberOfOwnDescriptors(),
    8837             :               parent->instance_descriptors()->number_of_descriptors());
    8838             :   }
    8839    11747190 :   if (parent->is_prototype_map()) {
    8840             :     DCHECK(child->is_prototype_map());
    8841             : #if TRACE_MAPS
    8842             :     Map::TraceTransition("NoTransition", *parent, *child, *name);
    8843             : #endif
    8844             :   } else {
    8845    11747190 :     TransitionArray::Insert(parent, name, child, flag);
    8846             : #if TRACE_MAPS
    8847             :     Map::TraceTransition("Transition", *parent, *child, *name);
    8848             : #endif
    8849             :   }
    8850    11747192 : }
    8851             : 
    8852             : 
    8853    14384997 : Handle<Map> Map::CopyReplaceDescriptors(
    8854             :     Handle<Map> map, Handle<DescriptorArray> descriptors,
    8855             :     Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
    8856             :     MaybeHandle<Name> maybe_name, const char* reason,
    8857             :     SimpleTransitionFlag simple_flag) {
    8858             :   DCHECK(descriptors->IsSortedNoDuplicates());
    8859             : 
    8860    14384997 :   Handle<Map> result = CopyDropDescriptors(map);
    8861             : 
    8862    14384993 :   if (!map->is_prototype_map()) {
    8863    11247526 :     if (flag == INSERT_TRANSITION &&
    8864     1830886 :         TransitionArray::CanHaveMoreTransitions(map)) {
    8865     1830886 :       result->InitializeDescriptors(*descriptors, *layout_descriptor);
    8866             : 
    8867             :       Handle<Name> name;
    8868     1830886 :       CHECK(maybe_name.ToHandle(&name));
    8869     1830886 :       ConnectTransition(map, result, name, simple_flag);
    8870             :     } else {
    8871     7585754 :       descriptors->GeneralizeAllFields();
    8872             :       result->InitializeDescriptors(*descriptors,
    8873     7585755 :                                     LayoutDescriptor::FastPointerLayout());
    8874             :     }
    8875             :   } else {
    8876     4968353 :     result->InitializeDescriptors(*descriptors, *layout_descriptor);
    8877             :   }
    8878             : #if TRACE_MAPS
    8879             :   if (FLAG_trace_maps &&
    8880             :       // Mirror conditions above that did not call ConnectTransition().
    8881             :       (map->is_prototype_map() ||
    8882             :        !(flag == INSERT_TRANSITION &&
    8883             :          TransitionArray::CanHaveMoreTransitions(map)))) {
    8884             :     PrintF("[TraceMaps: ReplaceDescriptors from= %p to= %p reason= %s ]\n",
    8885             :            reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*result),
    8886             :            reason);
    8887             :   }
    8888             : #endif
    8889             : 
    8890    14384994 :   return result;
    8891             : }
    8892             : 
    8893             : 
    8894             : // Creates transition tree starting from |split_map| and adding all descriptors
    8895             : // starting from descriptor with index |split_map|.NumberOfOwnDescriptors().
    8896             : // The way how it is done is tricky because of GC and special descriptors
    8897             : // marking logic.
    8898      167389 : Handle<Map> Map::AddMissingTransitions(
    8899             :     Handle<Map> split_map, Handle<DescriptorArray> descriptors,
    8900             :     Handle<LayoutDescriptor> full_layout_descriptor) {
    8901             :   DCHECK(descriptors->IsSortedNoDuplicates());
    8902             :   int split_nof = split_map->NumberOfOwnDescriptors();
    8903      167389 :   int nof_descriptors = descriptors->number_of_descriptors();
    8904             :   DCHECK_LT(split_nof, nof_descriptors);
    8905             : 
    8906             :   // Start with creating last map which will own full descriptors array.
    8907             :   // This is necessary to guarantee that GC will mark the whole descriptor
    8908             :   // array if any of the allocations happening below fail.
    8909             :   // Number of unused properties is temporarily incorrect and the layout
    8910             :   // descriptor could unnecessarily be in slow mode but we will fix after
    8911             :   // all the other intermediate maps are created.
    8912      167389 :   Handle<Map> last_map = CopyDropDescriptors(split_map);
    8913      167389 :   last_map->InitializeDescriptors(*descriptors, *full_layout_descriptor);
    8914             :   last_map->set_unused_property_fields(0);
    8915             : 
    8916             :   // During creation of intermediate maps we violate descriptors sharing
    8917             :   // invariant since the last map is not yet connected to the transition tree
    8918             :   // we create here. But it is safe because GC never trims map's descriptors
    8919             :   // if there are no dead transitions from that map and this is exactly the
    8920             :   // case for all the intermediate maps we create here.
    8921             :   Handle<Map> map = split_map;
    8922      248739 :   for (int i = split_nof; i < nof_descriptors - 1; ++i) {
    8923       81350 :     Handle<Map> new_map = CopyDropDescriptors(map);
    8924       81350 :     InstallDescriptors(map, new_map, i, descriptors, full_layout_descriptor);
    8925       81350 :     map = new_map;
    8926             :   }
    8927      167389 :   map->NotifyLeafMapLayoutChange();
    8928             :   InstallDescriptors(map, last_map, nof_descriptors - 1, descriptors,
    8929      167389 :                      full_layout_descriptor);
    8930      167389 :   return last_map;
    8931             : }
    8932             : 
    8933             : 
    8934             : // Since this method is used to rewrite an existing transition tree, it can
    8935             : // always insert transitions without checking.
    8936      248739 : void Map::InstallDescriptors(Handle<Map> parent, Handle<Map> child,
    8937             :                              int new_descriptor,
    8938             :                              Handle<DescriptorArray> descriptors,
    8939             :                              Handle<LayoutDescriptor> full_layout_descriptor) {
    8940             :   DCHECK(descriptors->IsSortedNoDuplicates());
    8941             : 
    8942      248739 :   child->set_instance_descriptors(*descriptors);
    8943      248739 :   child->SetNumberOfOwnDescriptors(new_descriptor + 1);
    8944             : 
    8945             :   int unused_property_fields = parent->unused_property_fields();
    8946      248739 :   PropertyDetails details = descriptors->GetDetails(new_descriptor);
    8947      248739 :   if (details.location() == kField) {
    8948      231304 :     unused_property_fields = parent->unused_property_fields() - 1;
    8949      231304 :     if (unused_property_fields < 0) {
    8950       21507 :       unused_property_fields += JSObject::kFieldsAdded;
    8951             :     }
    8952             :   }
    8953             :   child->set_unused_property_fields(unused_property_fields);
    8954             : 
    8955             :   if (FLAG_unbox_double_fields) {
    8956             :     Handle<LayoutDescriptor> layout_descriptor =
    8957             :         LayoutDescriptor::AppendIfFastOrUseFull(parent, details,
    8958      248739 :                                                 full_layout_descriptor);
    8959      248739 :     child->set_layout_descriptor(*layout_descriptor);
    8960             : #ifdef VERIFY_HEAP
    8961             :     // TODO(ishell): remove these checks from VERIFY_HEAP mode.
    8962             :     if (FLAG_verify_heap) {
    8963             :       CHECK(child->layout_descriptor()->IsConsistentWithMap(*child));
    8964             :     }
    8965             : #else
    8966             :     SLOW_DCHECK(child->layout_descriptor()->IsConsistentWithMap(*child));
    8967             : #endif
    8968      248739 :     child->set_visitor_id(Heap::GetStaticVisitorIdForMap(*child));
    8969             :   }
    8970             : 
    8971      248739 :   Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
    8972      248739 :   ConnectTransition(parent, child, name, SIMPLE_PROPERTY_TRANSITION);
    8973      248739 : }
    8974             : 
    8975             : 
    8976      273410 : Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
    8977             :                                     TransitionFlag flag) {
    8978             :   Map* maybe_elements_transition_map = NULL;
    8979      273410 :   if (flag == INSERT_TRANSITION) {
    8980             :     // Ensure we are requested to add elements kind transition "near the root".
    8981             :     DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(),
    8982             :               map->NumberOfOwnDescriptors());
    8983             : 
    8984             :     maybe_elements_transition_map = map->ElementsTransitionMap();
    8985             :     DCHECK(maybe_elements_transition_map == NULL ||
    8986             :            (maybe_elements_transition_map->elements_kind() ==
    8987             :                 DICTIONARY_ELEMENTS &&
    8988             :             kind == DICTIONARY_ELEMENTS));
    8989             :     DCHECK(!IsFastElementsKind(kind) ||
    8990             :            IsMoreGeneralElementsKindTransition(map->elements_kind(), kind));
    8991             :     DCHECK(kind != map->elements_kind());
    8992             :   }
    8993             : 
    8994      268049 :   bool insert_transition = flag == INSERT_TRANSITION &&
    8995      415275 :                            TransitionArray::CanHaveMoreTransitions(map) &&
    8996             :                            maybe_elements_transition_map == NULL;
    8997             : 
    8998      273410 :   if (insert_transition) {
    8999      141865 :     Handle<Map> new_map = CopyForTransition(map, "CopyAsElementsKind");
    9000             :     new_map->set_elements_kind(kind);
    9001             : 
    9002             :     Isolate* isolate = map->GetIsolate();
    9003             :     Handle<Name> name = isolate->factory()->elements_transition_symbol();
    9004      141865 :     ConnectTransition(map, new_map, name, SPECIAL_TRANSITION);
    9005      141865 :     return new_map;
    9006             :   }
    9007             : 
    9008             :   // Create a new free-floating map only if we are not allowed to store it.
    9009      131545 :   Handle<Map> new_map = Copy(map, "CopyAsElementsKind");
    9010             :   new_map->set_elements_kind(kind);
    9011      131545 :   return new_map;
    9012             : }
    9013             : 
    9014             : 
    9015         731 : Handle<Map> Map::AsLanguageMode(Handle<Map> initial_map,
    9016             :                                 LanguageMode language_mode, FunctionKind kind) {
    9017             :   DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
    9018             :   // Initial map for sloppy mode function is stored in the function
    9019             :   // constructor. Initial maps for strict mode are cached as special transitions
    9020             :   // using |strict_function_transition_symbol| as a key.
    9021         731 :   if (language_mode == SLOPPY) return initial_map;
    9022             :   Isolate* isolate = initial_map->GetIsolate();
    9023             : 
    9024         226 :   int map_index = Context::FunctionMapIndex(language_mode, kind);
    9025             :   Handle<Map> function_map(
    9026         452 :       Map::cast(isolate->native_context()->get(map_index)));
    9027             : 
    9028             :   STATIC_ASSERT(LANGUAGE_END == 2);
    9029             :   DCHECK_EQ(STRICT, language_mode);
    9030             :   Handle<Symbol> transition_symbol =
    9031             :       isolate->factory()->strict_function_transition_symbol();
    9032             :   Map* maybe_transition =
    9033         226 :       TransitionArray::SearchSpecial(*initial_map, *transition_symbol);
    9034         226 :   if (maybe_transition != NULL) {
    9035             :     return handle(maybe_transition, isolate);
    9036             :   }
    9037         170 :   initial_map->NotifyLeafMapLayoutChange();
    9038             : 
    9039             :   // Create new map taking descriptors from the |function_map| and all
    9040             :   // the other details from the |initial_map|.
    9041             :   Handle<Map> map =
    9042             :       Map::CopyInitialMap(function_map, initial_map->instance_size(),
    9043             :                           initial_map->GetInObjectProperties(),
    9044         170 :                           initial_map->unused_property_fields());
    9045         170 :   map->SetConstructor(initial_map->GetConstructor());
    9046         170 :   map->set_prototype(initial_map->prototype());
    9047             : 
    9048         170 :   if (TransitionArray::CanHaveMoreTransitions(initial_map)) {
    9049             :     Map::ConnectTransition(initial_map, map, transition_symbol,
    9050         170 :                            SPECIAL_TRANSITION);
    9051             :   }
    9052         170 :   return map;
    9053             : }
    9054             : 
    9055             : 
    9056      141865 : Handle<Map> Map::CopyForTransition(Handle<Map> map, const char* reason) {
    9057             :   DCHECK(!map->is_prototype_map());
    9058      141865 :   Handle<Map> new_map = CopyDropDescriptors(map);
    9059             : 
    9060      141865 :   if (map->owns_descriptors()) {
    9061             :     // In case the map owned its own descriptors, share the descriptors and
    9062             :     // transfer ownership to the new map.
    9063             :     // The properties did not change, so reuse descriptors.
    9064             :     new_map->InitializeDescriptors(map->instance_descriptors(),
    9065      141863 :                                    map->GetLayoutDescriptor());
    9066             :   } else {
    9067             :     // In case the map did not own its own descriptors, a split is forced by
    9068             :     // copying the map; creating a new descriptor array cell.
    9069             :     Handle<DescriptorArray> descriptors(map->instance_descriptors());
    9070             :     int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9071             :     Handle<DescriptorArray> new_descriptors =
    9072             :         DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
    9073             :     Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9074             :                                                    map->GetIsolate());
    9075           2 :     new_map->InitializeDescriptors(*new_descriptors, *new_layout_descriptor);
    9076             :   }
    9077             : 
    9078             : #if TRACE_MAPS
    9079             :   if (FLAG_trace_maps) {
    9080             :     PrintF("[TraceMaps: CopyForTransition from= %p to= %p reason= %s ]\n",
    9081             :            reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*new_map),
    9082             :            reason);
    9083             :   }
    9084             : #endif
    9085             : 
    9086      141865 :   return new_map;
    9087             : }
    9088             : 
    9089             : 
    9090     6157609 : Handle<Map> Map::Copy(Handle<Map> map, const char* reason) {
    9091             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    9092             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    9093             :   Handle<DescriptorArray> new_descriptors =
    9094     6157610 :       DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
    9095             :   Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9096             :                                                  map->GetIsolate());
    9097             :   return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
    9098             :                                 OMIT_TRANSITION, MaybeHandle<Name>(), reason,
    9099     6157610 :                                 SPECIAL_TRANSITION);
    9100             : }
    9101             : 
    9102             : 
    9103      250434 : Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
    9104             :   Handle<Map> copy =
    9105      500868 :       Copy(handle(isolate->object_function()->initial_map()), "MapCreate");
    9106             : 
    9107             :   // Check that we do not overflow the instance size when adding the extra
    9108             :   // inobject properties. If the instance size overflows, we allocate as many
    9109             :   // properties as we can as inobject properties.
    9110             :   int max_extra_properties =
    9111             :       (JSObject::kMaxInstanceSize - JSObject::kHeaderSize) >> kPointerSizeLog2;
    9112             : 
    9113      250434 :   if (inobject_properties > max_extra_properties) {
    9114             :     inobject_properties = max_extra_properties;
    9115             :   }
    9116             : 
    9117             :   int new_instance_size =
    9118      250434 :       JSObject::kHeaderSize + kPointerSize * inobject_properties;
    9119             : 
    9120             :   // Adjust the map with the extra inobject properties.
    9121             :   copy->SetInObjectProperties(inobject_properties);
    9122             :   copy->set_unused_property_fields(inobject_properties);
    9123             :   copy->set_instance_size(new_instance_size);
    9124      250434 :   copy->set_visitor_id(Heap::GetStaticVisitorIdForMap(*copy));
    9125      250434 :   return copy;
    9126             : }
    9127             : 
    9128             : 
    9129       51215 : Handle<Map> Map::CopyForPreventExtensions(Handle<Map> map,
    9130             :                                           PropertyAttributes attrs_to_add,
    9131             :                                           Handle<Symbol> transition_marker,
    9132             :                                           const char* reason) {
    9133             :   int num_descriptors = map->NumberOfOwnDescriptors();
    9134             :   Isolate* isolate = map->GetIsolate();
    9135             :   Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
    9136             :       handle(map->instance_descriptors(), isolate), num_descriptors,
    9137       51215 :       attrs_to_add);
    9138             :   Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
    9139             :                                                  isolate);
    9140             :   Handle<Map> new_map = CopyReplaceDescriptors(
    9141             :       map, new_desc, new_layout_descriptor, INSERT_TRANSITION,
    9142       51215 :       transition_marker, reason, SPECIAL_TRANSITION);
    9143             :   new_map->set_is_extensible(false);
    9144       51215 :   if (!IsFixedTypedArrayElementsKind(map->elements_kind())) {
    9145             :     ElementsKind new_kind = IsStringWrapperElementsKind(map->elements_kind())
    9146             :                                 ? SLOW_STRING_WRAPPER_ELEMENTS
    9147       51141 :                                 : DICTIONARY_ELEMENTS;
    9148             :     new_map->set_elements_kind(new_kind);
    9149             :   }
    9150       51215 :   return new_map;
    9151             : }
    9152             : 
    9153             : namespace {
    9154             : 
    9155    25258440 : bool CanHoldValue(DescriptorArray* descriptors, int descriptor,
    9156             :                   PropertyConstness constness, Object* value) {
    9157    25258440 :   PropertyDetails details = descriptors->GetDetails(descriptor);
    9158    25258441 :   if (details.location() == kField) {
    9159    24683063 :     if (details.kind() == kData) {
    9160    24683062 :       return IsGeneralizableTo(constness, details.constness()) &&
    9161    73593902 :              value->FitsRepresentation(details.representation()) &&
    9162    48910836 :              descriptors->GetFieldType(descriptor)->NowContains(value);
    9163             :     } else {
    9164             :       DCHECK_EQ(kAccessor, details.kind());
    9165             :       return false;
    9166             :     }
    9167             : 
    9168             :   } else {
    9169             :     DCHECK_EQ(kDescriptor, details.location());
    9170             :     DCHECK_EQ(kConst, details.constness());
    9171      575378 :     if (details.kind() == kData) {
    9172             :       DCHECK(!FLAG_track_constant_fields);
    9173             :       DCHECK(descriptors->GetValue(descriptor) != value ||
    9174             :              value->FitsRepresentation(details.representation()));
    9175      575378 :       return descriptors->GetValue(descriptor) == value;
    9176             :     } else {
    9177             :       DCHECK_EQ(kAccessor, details.kind());
    9178             :       return false;
    9179             :     }
    9180             :   }
    9181             :   UNREACHABLE();
    9182             :   return false;
    9183             : }
    9184             : 
    9185    25258439 : Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor,
    9186             :                                      PropertyConstness constness,
    9187             :                                      Handle<Object> value) {
    9188    25258439 :   if (CanHoldValue(map->instance_descriptors(), descriptor, constness,
    9189             :                    *value)) {
    9190    24102815 :     return map;
    9191             :   }
    9192             : 
    9193             :   Isolate* isolate = map->GetIsolate();
    9194             :   PropertyAttributes attributes =
    9195     2311252 :       map->instance_descriptors()->GetDetails(descriptor).attributes();
    9196     1155626 :   Representation representation = value->OptimalRepresentation();
    9197     1155626 :   Handle<FieldType> type = value->OptimalType(isolate, representation);
    9198             : 
    9199     1155626 :   MapUpdater mu(isolate, map);
    9200             :   return mu.ReconfigureToDataField(descriptor, attributes, constness,
    9201     1155626 :                                    representation, type);
    9202             : }
    9203             : 
    9204             : }  // namespace
    9205             : 
    9206             : // static
    9207    10658805 : Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor,
    9208             :                                         PropertyConstness constness,
    9209             :                                         Handle<Object> value) {
    9210             :   // Dictionaries can store any property value.
    9211             :   DCHECK(!map->is_dictionary_map());
    9212             :   // Update to the newest map before storing the property.
    9213    10658805 :   return UpdateDescriptorForValue(Update(map), descriptor, constness, value);
    9214             : }
    9215             : 
    9216    30182367 : Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
    9217             :                                           Handle<Object> value,
    9218             :                                           PropertyAttributes attributes,
    9219             :                                           PropertyConstness constness,
    9220             :                                           StoreFromKeyed store_mode) {
    9221             :   RuntimeCallTimerScope stats_scope(
    9222             :       *map, map->is_prototype_map()
    9223             :                 ? &RuntimeCallStats::PrototypeMap_TransitionToDataProperty
    9224    30182367 :                 : &RuntimeCallStats::Map_TransitionToDataProperty);
    9225             : 
    9226             :   DCHECK(name->IsUniqueName());
    9227             :   DCHECK(!map->is_dictionary_map());
    9228             : 
    9229             :   // Migrate to the newest map before storing the property.
    9230    30182382 :   map = Update(map);
    9231             : 
    9232             :   Map* maybe_transition =
    9233    30182378 :       TransitionArray::SearchTransition(*map, kData, *name, attributes);
    9234    30182370 :   if (maybe_transition != NULL) {
    9235             :     Handle<Map> transition(maybe_transition);
    9236             :     int descriptor = transition->LastAdded();
    9237             : 
    9238             :     DCHECK_EQ(attributes, transition->instance_descriptors()
    9239             :                               ->GetDetails(descriptor)
    9240             :                               .attributes());
    9241             : 
    9242    14599631 :     return UpdateDescriptorForValue(transition, descriptor, constness, value);
    9243             :   }
    9244             : 
    9245             :   TransitionFlag flag = INSERT_TRANSITION;
    9246             :   MaybeHandle<Map> maybe_map;
    9247    15582740 :   if (!FLAG_track_constant_fields && value->IsJSFunction()) {
    9248     6716985 :     maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag);
    9249     8865755 :   } else if (!map->TooManyFastProperties(store_mode)) {
    9250             :     Isolate* isolate = name->GetIsolate();
    9251     8764661 :     Representation representation = value->OptimalRepresentation();
    9252     8764659 :     Handle<FieldType> type = value->OptimalType(isolate, representation);
    9253             :     maybe_map = Map::CopyWithField(map, name, type, attributes, constness,
    9254     8764661 :                                    representation, flag);
    9255             :   }
    9256             : 
    9257             :   Handle<Map> result;
    9258    15582741 :   if (!maybe_map.ToHandle(&result)) {
    9259             :     Isolate* isolate = name->GetIsolate();
    9260             :     const char* reason = "TooManyFastProperties";
    9261             : #if TRACE_MAPS
    9262             :     std::unique_ptr<ScopedVector<char>> buffer;
    9263             :     if (FLAG_trace_maps) {
    9264             :       ScopedVector<char> name_buffer(100);
    9265             :       name->NameShortPrint(name_buffer);
    9266             :       buffer.reset(new ScopedVector<char>(128));
    9267             :       SNPrintF(*buffer, "TooManyFastProperties %s", name_buffer.start());
    9268             :       reason = buffer->start();
    9269             :     }
    9270             : #endif
    9271      101209 :     Handle<Object> maybe_constructor(map->GetConstructor(), isolate);
    9272      101209 :     if (FLAG_feedback_normalization && map->new_target_is_base() &&
    9273      101209 :         maybe_constructor->IsJSFunction() &&
    9274             :         !JSFunction::cast(*maybe_constructor)->shared()->native()) {
    9275             :       Handle<JSFunction> constructor =
    9276             :           Handle<JSFunction>::cast(maybe_constructor);
    9277             :       DCHECK_NE(*constructor,
    9278             :                 constructor->context()->native_context()->object_function());
    9279             :       Handle<Map> initial_map(constructor->initial_map(), isolate);
    9280           0 :       result = Map::Normalize(initial_map, CLEAR_INOBJECT_PROPERTIES, reason);
    9281           0 :       initial_map->DeprecateTransitionTree();
    9282             :       Handle<Object> prototype(result->prototype(), isolate);
    9283           0 :       JSFunction::SetInitialMap(constructor, result, prototype);
    9284             : 
    9285             :       // Deoptimize all code that embeds the previous initial map.
    9286             :       initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
    9287           0 :           isolate, DependentCode::kInitialMapChangedGroup);
    9288           0 :       if (!result->EquivalentToForNormalization(*map,
    9289           0 :                                                 CLEAR_INOBJECT_PROPERTIES)) {
    9290           0 :         result = Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, reason);
    9291             :       }
    9292             :     } else {
    9293      101209 :       result = Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, reason);
    9294             :     }
    9295             :   }
    9296             : 
    9297    15582741 :   return result;
    9298             : }
    9299             : 
    9300             : 
    9301     1515099 : Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor,
    9302             :                                              PropertyKind kind,
    9303             :                                              PropertyAttributes attributes) {
    9304             :   // Dictionaries have to be reconfigured in-place.
    9305             :   DCHECK(!map->is_dictionary_map());
    9306             : 
    9307     3030199 :   if (!map->GetBackPointer()->IsMap()) {
    9308             :     // There is no benefit from reconstructing transition tree for maps without
    9309             :     // back pointers.
    9310             :     return CopyGeneralizeAllFields(map, map->elements_kind(), descriptor, kind,
    9311             :                                    attributes,
    9312     1489827 :                                    "GenAll_AttributesMismatchProtoMap");
    9313             :   }
    9314             : 
    9315       25273 :   if (FLAG_trace_generalization) {
    9316           0 :     map->PrintReconfiguration(stdout, descriptor, kind, attributes);
    9317             :   }
    9318             : 
    9319             :   Isolate* isolate = map->GetIsolate();
    9320             : 
    9321       25273 :   MapUpdater mu(isolate, map);
    9322             :   DCHECK_EQ(kData, kind);  // Only kData case is supported so far.
    9323             :   Handle<Map> new_map = mu.ReconfigureToDataField(
    9324             :       descriptor, attributes, kDefaultFieldConstness, Representation::None(),
    9325       25273 :       FieldType::None(isolate));
    9326       25273 :   return new_map;
    9327             : }
    9328             : 
    9329      434778 : Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
    9330             :                                               Handle<Name> name, int descriptor,
    9331             :                                               Handle<Object> getter,
    9332             :                                               Handle<Object> setter,
    9333             :                                               PropertyAttributes attributes) {
    9334             :   RuntimeCallTimerScope stats_scope(
    9335             :       isolate,
    9336             :       map->is_prototype_map()
    9337             :           ? &RuntimeCallStats::PrototypeMap_TransitionToAccessorProperty
    9338      434778 :           : &RuntimeCallStats::Map_TransitionToAccessorProperty);
    9339             : 
    9340             :   // At least one of the accessors needs to be a new value.
    9341             :   DCHECK(!getter->IsNull(isolate) || !setter->IsNull(isolate));
    9342             :   DCHECK(name->IsUniqueName());
    9343             : 
    9344             :   // Dictionary maps can always have additional data properties.
    9345      434778 :   if (map->is_dictionary_map()) return map;
    9346             : 
    9347             :   // Migrate to the newest map before transitioning to the new property.
    9348      434778 :   map = Update(map);
    9349             : 
    9350             :   PropertyNormalizationMode mode = map->is_prototype_map()
    9351             :                                        ? KEEP_INOBJECT_PROPERTIES
    9352      434778 :                                        : CLEAR_INOBJECT_PROPERTIES;
    9353             : 
    9354             :   Map* maybe_transition =
    9355      434778 :       TransitionArray::SearchTransition(*map, kAccessor, *name, attributes);
    9356      434778 :   if (maybe_transition != NULL) {
    9357             :     Handle<Map> transition(maybe_transition, isolate);
    9358             :     DescriptorArray* descriptors = transition->instance_descriptors();
    9359             :     int descriptor = transition->LastAdded();
    9360             :     DCHECK(descriptors->GetKey(descriptor)->Equals(*name));
    9361             : 
    9362             :     DCHECK_EQ(kAccessor, descriptors->GetDetails(descriptor).kind());
    9363             :     DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes());
    9364             : 
    9365             :     Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
    9366       18809 :     if (!maybe_pair->IsAccessorPair()) {
    9367           0 :       return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair");
    9368             :     }
    9369             : 
    9370             :     Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair);
    9371       18809 :     if (!pair->Equals(*getter, *setter)) {
    9372       17908 :       return Map::Normalize(map, mode, "TransitionToDifferentAccessor");
    9373             :     }
    9374             : 
    9375         901 :     return transition;
    9376             :   }
    9377             : 
    9378             :   Handle<AccessorPair> pair;
    9379             :   DescriptorArray* old_descriptors = map->instance_descriptors();
    9380      415969 :   if (descriptor != DescriptorArray::kNotFound) {
    9381      158119 :     if (descriptor != map->LastAdded()) {
    9382        3251 :       return Map::Normalize(map, mode, "AccessorsOverwritingNonLast");
    9383             :     }
    9384      154868 :     PropertyDetails old_details = old_descriptors->GetDetails(descriptor);
    9385      154868 :     if (old_details.kind() != kAccessor) {
    9386      152339 :       return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors");
    9387             :     }
    9388             : 
    9389        2529 :     if (old_details.attributes() != attributes) {
    9390         131 :       return Map::Normalize(map, mode, "AccessorsWithAttributes");
    9391             :     }
    9392             : 
    9393             :     Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate);
    9394        2398 :     if (!maybe_pair->IsAccessorPair()) {
    9395          28 :       return Map::Normalize(map, mode, "AccessorsOverwritingNonPair");
    9396             :     }
    9397             : 
    9398             :     Handle<AccessorPair> current_pair = Handle<AccessorPair>::cast(maybe_pair);
    9399        2370 :     if (current_pair->Equals(*getter, *setter)) return map;
    9400             : 
    9401             :     bool overwriting_accessor = false;
    9402        4733 :     if (!getter->IsNull(isolate) &&
    9403        4589 :         !current_pair->get(ACCESSOR_GETTER)->IsNull(isolate) &&
    9404             :         current_pair->get(ACCESSOR_GETTER) != *getter) {
    9405             :       overwriting_accessor = true;
    9406             :     }
    9407        4726 :     if (!setter->IsNull(isolate) &&
    9408        4185 :         !current_pair->get(ACCESSOR_SETTER)->IsNull(isolate) &&
    9409             :         current_pair->get(ACCESSOR_SETTER) != *setter) {
    9410             :       overwriting_accessor = true;
    9411             :     }
    9412        2370 :     if (overwriting_accessor) {
    9413        2094 :       return Map::Normalize(map, mode, "AccessorsOverwritingAccessors");
    9414             :     }
    9415             : 
    9416         276 :     pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair));
    9417      515700 :   } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors ||
    9418      257850 :              map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) {
    9419           0 :     return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors");
    9420             :   } else {
    9421      257850 :     pair = isolate->factory()->NewAccessorPair();
    9422             :   }
    9423             : 
    9424      258126 :   pair->SetComponents(*getter, *setter);
    9425             : 
    9426             :   TransitionFlag flag = INSERT_TRANSITION;
    9427             :   Descriptor d = Descriptor::AccessorConstant(name, pair, attributes);
    9428      258126 :   return Map::CopyInsertDescriptor(map, &d, flag);
    9429             : }
    9430             : 
    9431             : 
    9432    15754549 : Handle<Map> Map::CopyAddDescriptor(Handle<Map> map,
    9433             :                                    Descriptor* descriptor,
    9434             :                                    TransitionFlag flag) {
    9435             :   Handle<DescriptorArray> descriptors(map->instance_descriptors());
    9436             : 
    9437             :   // Share descriptors only if map owns descriptors and it not an initial map.
    9438    47178457 :   if (flag == INSERT_TRANSITION && map->owns_descriptors() &&
    9439    40949727 :       !map->GetBackPointer()->IsUndefined(map->GetIsolate()) &&
    9440     9525533 :       TransitionArray::CanHaveMoreTransitions(map)) {
    9441     9525533 :     return ShareDescriptor(map, descriptors, descriptor);
    9442             :   }
    9443             : 
    9444             :   int nof = map->NumberOfOwnDescriptors();
    9445             :   Handle<DescriptorArray> new_descriptors =
    9446             :       DescriptorArray::CopyUpTo(descriptors, nof, 1);
    9447     6229017 :   new_descriptors->Append(descriptor);
    9448             : 
    9449             :   Handle<LayoutDescriptor> new_layout_descriptor =
    9450             :       FLAG_unbox_double_fields
    9451     6229018 :           ? LayoutDescriptor::New(map, new_descriptors, nof + 1)
    9452     6229018 :           : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate());
    9453             : 
    9454             :   return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
    9455             :                                 flag, descriptor->GetKey(), "CopyAddDescriptor",
    9456     6229018 :                                 SIMPLE_PROPERTY_TRANSITION);
    9457             : }
    9458             : 
    9459             : 
    9460      258174 : Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map,
    9461             :                                       Descriptor* descriptor,
    9462             :                                       TransitionFlag flag) {
    9463             :   Handle<DescriptorArray> old_descriptors(map->instance_descriptors());
    9464             : 
    9465             :   // We replace the key if it is already present.
    9466             :   int index = old_descriptors->SearchWithCache(map->GetIsolate(),
    9467             :                                                *descriptor->GetKey(), *map);
    9468      258174 :   if (index != DescriptorArray::kNotFound) {
    9469         276 :     return CopyReplaceDescriptor(map, old_descriptors, descriptor, index, flag);
    9470             :   }
    9471      257898 :   return CopyAddDescriptor(map, descriptor, flag);
    9472             : }
    9473             : 
    9474             : 
    9475           0 : Handle<DescriptorArray> DescriptorArray::CopyUpTo(
    9476             :     Handle<DescriptorArray> desc,
    9477             :     int enumeration_index,
    9478             :     int slack) {
    9479             :   return DescriptorArray::CopyUpToAddAttributes(
    9480    20161700 :       desc, enumeration_index, NONE, slack);
    9481             : }
    9482             : 
    9483             : 
    9484    20212910 : Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
    9485             :     Handle<DescriptorArray> desc,
    9486             :     int enumeration_index,
    9487             :     PropertyAttributes attributes,
    9488             :     int slack) {
    9489    20212910 :   if (enumeration_index + slack == 0) {
    9490             :     return desc->GetIsolate()->factory()->empty_descriptor_array();
    9491             :   }
    9492             : 
    9493             :   int size = enumeration_index;
    9494             : 
    9495             :   Handle<DescriptorArray> descriptors =
    9496    18015316 :       DescriptorArray::Allocate(desc->GetIsolate(), size, slack);
    9497             : 
    9498    18015316 :   if (attributes != NONE) {
    9499       78469 :     for (int i = 0; i < size; ++i) {
    9500             :       Object* value = desc->GetValue(i);
    9501             :       Name* key = desc->GetKey(i);
    9502       78469 :       PropertyDetails details = desc->GetDetails(i);
    9503             :       // Bulk attribute changes never affect private properties.
    9504       78469 :       if (!key->IsPrivate()) {
    9505             :         int mask = DONT_DELETE | DONT_ENUM;
    9506             :         // READ_ONLY is an invalid attribute for JS setters/getters.
    9507       79854 :         if (details.kind() != kAccessor || !value->IsAccessorPair()) {
    9508             :           mask |= READ_ONLY;
    9509             :         }
    9510             :         details = details.CopyAddAttributes(
    9511       78413 :             static_cast<PropertyAttributes>(attributes & mask));
    9512             :       }
    9513       78469 :       descriptors->Set(i, key, value, details);
    9514             :     }
    9515             :   } else {
    9516   154691642 :     for (int i = 0; i < size; ++i) {
    9517   154691633 :       descriptors->CopyFrom(i, *desc);
    9518             :     }
    9519             :   }
    9520             : 
    9521    18113086 :   if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort();
    9522             : 
    9523    18015317 :   return descriptors;
    9524             : }
    9525             : 
    9526             : 
    9527        8607 : bool DescriptorArray::IsEqualUpTo(DescriptorArray* desc, int nof_descriptors) {
    9528       56569 :   for (int i = 0; i < nof_descriptors; i++) {
    9529       95924 :     if (GetKey(i) != desc->GetKey(i) || GetValue(i) != desc->GetValue(i)) {
    9530             :       return false;
    9531             :     }
    9532       47962 :     PropertyDetails details = GetDetails(i);
    9533       47962 :     PropertyDetails other_details = desc->GetDetails(i);
    9534       95924 :     if (details.kind() != other_details.kind() ||
    9535       95924 :         details.location() != other_details.location() ||
    9536             :         !details.representation().Equals(other_details.representation())) {
    9537             :       return false;
    9538             :     }
    9539             :   }
    9540             :   return true;
    9541             : }
    9542             : 
    9543             : 
    9544         276 : Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map,
    9545             :                                        Handle<DescriptorArray> descriptors,
    9546             :                                        Descriptor* descriptor,
    9547             :                                        int insertion_index,
    9548             :                                        TransitionFlag flag) {
    9549             :   Handle<Name> key = descriptor->GetKey();
    9550             :   DCHECK(*key == descriptors->GetKey(insertion_index));
    9551             : 
    9552             :   Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
    9553             :       descriptors, map->NumberOfOwnDescriptors());
    9554             : 
    9555         276 :   new_descriptors->Replace(insertion_index, descriptor);
    9556             :   Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New(
    9557         276 :       map, new_descriptors, new_descriptors->number_of_descriptors());
    9558             : 
    9559             :   SimpleTransitionFlag simple_flag =
    9560         276 :       (insertion_index == descriptors->number_of_descriptors() - 1)
    9561             :           ? SIMPLE_PROPERTY_TRANSITION
    9562         276 :           : PROPERTY_TRANSITION;
    9563             :   return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
    9564             :                                 flag, key, "CopyReplaceDescriptor",
    9565         276 :                                 simple_flag);
    9566             : }
    9567             : 
    9568             : // Helper class to manage a Map's code cache. The layout depends on the number
    9569             : // of entries; this is worthwhile because most code caches are very small,
    9570             : // but some are huge (thousands of entries).
    9571             : // For zero entries, the EmptyFixedArray is used.
    9572             : // For one entry, we use a 2-element FixedArray containing [name, code].
    9573             : // For 2..100 entries, we use a FixedArray with linear lookups, the layout is:
    9574             : //   [0] - number of slots that are currently in use
    9575             : //   [1] - first name
    9576             : //   [2] - first code
    9577             : //   [3] - second name
    9578             : //   [4] - second code
    9579             : //   etc.
    9580             : // For more than 128 entries, we use a CodeCacheHashTable.
    9581             : class CodeCache : public AllStatic {
    9582             :  public:
    9583             :   // Returns the new cache, to be stored on the map.
    9584       39712 :   static Handle<FixedArray> Put(Isolate* isolate, Handle<FixedArray> cache,
    9585             :                                 Handle<Name> name, Handle<Code> code) {
    9586             :     int length = cache->length();
    9587       39712 :     if (length == 0) return PutFirstElement(isolate, name, code);
    9588        2387 :     if (length == kEntrySize) {
    9589         577 :       return PutSecondElement(isolate, cache, name, code);
    9590             :     }
    9591        1810 :     if (length <= kLinearMaxSize) {
    9592        1663 :       Handle<FixedArray> result = PutLinearElement(isolate, cache, name, code);
    9593        1663 :       if (!result.is_null()) return result;
    9594             :       // Fall through if linear storage is getting too large.
    9595             :     }
    9596         154 :     return PutHashTableElement(isolate, cache, name, code);
    9597             :   }
    9598             : 
    9599       43561 :   static Code* Lookup(FixedArray* cache, Name* name, Code::Flags flags) {
    9600             :     int length = cache->length();
    9601       43561 :     if (length == 0) return nullptr;
    9602        6243 :     if (length == kEntrySize) return OneElementLookup(cache, name, flags);
    9603        3701 :     if (!cache->IsCodeCacheHashTable()) {
    9604        2490 :       return LinearLookup(cache, name, flags);
    9605             :     } else {
    9606        1211 :       return CodeCacheHashTable::cast(cache)->Lookup(name, flags);
    9607             :     }
    9608             :   }
    9609             : 
    9610             :  private:
    9611             :   static const int kNameIndex = 0;
    9612             :   static const int kCodeIndex = 1;
    9613             :   static const int kEntrySize = 2;
    9614             : 
    9615             :   static const int kLinearUsageIndex = 0;
    9616             :   static const int kLinearReservedSlots = 1;
    9617             :   static const int kLinearInitialCapacity = 2;
    9618             :   static const int kLinearMaxSize = 257;  // == LinearSizeFor(128);
    9619             : 
    9620             :   static const int kHashTableInitialCapacity = 200;  // Number of entries.
    9621             : 
    9622             :   static int LinearSizeFor(int entries) {
    9623         164 :     return kLinearReservedSlots + kEntrySize * entries;
    9624             :   }
    9625             : 
    9626             :   static int LinearNewSize(int old_size) {
    9627         164 :     int old_entries = (old_size - kLinearReservedSlots) / kEntrySize;
    9628         164 :     return LinearSizeFor(old_entries * 2);
    9629             :   }
    9630             : 
    9631        2542 :   static Code* OneElementLookup(FixedArray* cache, Name* name,
    9632             :                                 Code::Flags flags) {
    9633             :     DCHECK_EQ(cache->length(), kEntrySize);
    9634        2542 :     if (cache->get(kNameIndex) != name) return nullptr;
    9635             :     Code* maybe_code = Code::cast(cache->get(kCodeIndex));
    9636        2239 :     if (maybe_code->flags() != flags) return nullptr;
    9637        2192 :     return maybe_code;
    9638             :   }
    9639             : 
    9640        2490 :   static Code* LinearLookup(FixedArray* cache, Name* name, Code::Flags flags) {
    9641             :     DCHECK_GE(cache->length(), kEntrySize);
    9642             :     DCHECK(!cache->IsCodeCacheHashTable());
    9643             :     int usage = GetLinearUsage(cache);
    9644       59584 :     for (int i = kLinearReservedSlots; i < usage; i += kEntrySize) {
    9645       59544 :       if (cache->get(i + kNameIndex) != name) continue;
    9646        2501 :       Code* code = Code::cast(cache->get(i + kCodeIndex));
    9647        2501 :       if (code->flags() == flags) return code;
    9648             :     }
    9649             :     return nullptr;
    9650             :   }
    9651             : 
    9652       37325 :   static Handle<FixedArray> PutFirstElement(Isolate* isolate, Handle<Name> name,
    9653             :                                             Handle<Code> code) {
    9654       37325 :     Handle<FixedArray> cache = isolate->factory()->NewFixedArray(kEntrySize);
    9655       37325 :     cache->set(kNameIndex, *name);
    9656       37325 :     cache->set(kCodeIndex, *code);
    9657       37325 :     return cache;
    9658             :   }
    9659             : 
    9660         577 :   static Handle<FixedArray> PutSecondElement(Isolate* isolate,
    9661             :                                              Handle<FixedArray> cache,
    9662             :                                              Handle<Name> name,
    9663             :                                              Handle<Code> code) {
    9664             :     DCHECK_EQ(cache->length(), kEntrySize);
    9665             :     Handle<FixedArray> new_cache = isolate->factory()->NewFixedArray(
    9666         577 :         LinearSizeFor(kLinearInitialCapacity));
    9667         577 :     new_cache->set(kLinearReservedSlots + kNameIndex, cache->get(kNameIndex));
    9668         577 :     new_cache->set(kLinearReservedSlots + kCodeIndex, cache->get(kCodeIndex));
    9669         577 :     new_cache->set(LinearSizeFor(1) + kNameIndex, *name);
    9670         577 :     new_cache->set(LinearSizeFor(1) + kCodeIndex, *code);
    9671             :     new_cache->set(kLinearUsageIndex, Smi::FromInt(LinearSizeFor(2)));
    9672         577 :     return new_cache;
    9673             :   }
    9674             : 
    9675        1663 :   static Handle<FixedArray> PutLinearElement(Isolate* isolate,
    9676             :                                              Handle<FixedArray> cache,
    9677             :                                              Handle<Name> name,
    9678             :                                              Handle<Code> code) {
    9679             :     int length = cache->length();
    9680             :     int usage = GetLinearUsage(*cache);
    9681             :     DCHECK_LE(usage, length);
    9682             :     // Check if we need to grow.
    9683        1663 :     if (usage == length) {
    9684             :       int new_length = LinearNewSize(length);
    9685         164 :       if (new_length > kLinearMaxSize) return Handle<FixedArray>::null();
    9686             :       Handle<FixedArray> new_cache =
    9687         157 :           isolate->factory()->NewFixedArray(new_length);
    9688        3841 :       for (int i = kLinearReservedSlots; i < length; i++) {
    9689        3684 :         new_cache->set(i, cache->get(i));
    9690             :       }
    9691         157 :       cache = new_cache;
    9692             :     }
    9693             :     // Store new entry.
    9694             :     DCHECK_GE(cache->length(), usage + kEntrySize);
    9695        1656 :     cache->set(usage + kNameIndex, *name);
    9696        3312 :     cache->set(usage + kCodeIndex, *code);
    9697        1656 :     cache->set(kLinearUsageIndex, Smi::FromInt(usage + kEntrySize));
    9698        1656 :     return cache;
    9699             :   }
    9700             : 
    9701         154 :   static Handle<FixedArray> PutHashTableElement(Isolate* isolate,
    9702             :                                                 Handle<FixedArray> cache,
    9703             :                                                 Handle<Name> name,
    9704             :                                                 Handle<Code> code) {
    9705             :     // Check if we need to transition from linear to hash table storage.
    9706         154 :     if (!cache->IsCodeCacheHashTable()) {
    9707             :       // Check that the initial hash table capacity is large enough.
    9708             :       DCHECK_EQ(kLinearMaxSize, LinearSizeFor(128));
    9709             :       STATIC_ASSERT(kHashTableInitialCapacity > 128);
    9710             : 
    9711             :       int length = cache->length();
    9712             :       // Only migrate from linear storage when it's full.
    9713             :       DCHECK_EQ(length, GetLinearUsage(*cache));
    9714             :       DCHECK_EQ(length, kLinearMaxSize);
    9715             :       Handle<CodeCacheHashTable> table =
    9716           7 :           CodeCacheHashTable::New(isolate, kHashTableInitialCapacity);
    9717             :       HandleScope scope(isolate);
    9718         903 :       for (int i = kLinearReservedSlots; i < length; i += kEntrySize) {
    9719             :         Handle<Name> old_name(Name::cast(cache->get(i + kNameIndex)), isolate);
    9720         896 :         Handle<Code> old_code(Code::cast(cache->get(i + kCodeIndex)), isolate);
    9721         896 :         CodeCacheHashTable::Put(table, old_name, old_code);
    9722             :       }
    9723             :       cache = table;
    9724             :     }
    9725             :     // Store new entry.
    9726             :     DCHECK(cache->IsCodeCacheHashTable());
    9727             :     return CodeCacheHashTable::Put(Handle<CodeCacheHashTable>::cast(cache),
    9728         154 :                                    name, code);
    9729             :   }
    9730             : 
    9731             :   static inline int GetLinearUsage(FixedArray* linear_cache) {
    9732             :     DCHECK_GT(linear_cache->length(), kEntrySize);
    9733             :     return Smi::cast(linear_cache->get(kLinearUsageIndex))->value();
    9734             :   }
    9735             : };
    9736             : 
    9737       39712 : void Map::UpdateCodeCache(Handle<Map> map,
    9738             :                           Handle<Name> name,
    9739             :                           Handle<Code> code) {
    9740             :   Isolate* isolate = map->GetIsolate();
    9741             :   Handle<FixedArray> cache(map->code_cache(), isolate);
    9742       39712 :   Handle<FixedArray> new_cache = CodeCache::Put(isolate, cache, name, code);
    9743       39712 :   map->set_code_cache(*new_cache);
    9744       39712 : }
    9745             : 
    9746       43561 : Code* Map::LookupInCodeCache(Name* name, Code::Flags flags) {
    9747       43561 :   return CodeCache::Lookup(code_cache(), name, flags);
    9748             : }
    9749             : 
    9750             : 
    9751             : // The key in the code cache hash table consists of the property name and the
    9752             : // code object. The actual match is on the name and the code flags. If a key
    9753             : // is created using the flags and not a code object it can only be used for
    9754             : // lookup not to create a new entry.
    9755           0 : class CodeCacheHashTableKey : public HashTableKey {
    9756             :  public:
    9757             :   CodeCacheHashTableKey(Handle<Name> name, Code::Flags flags)
    9758        1211 :       : name_(name), flags_(flags), code_() {
    9759             :     DCHECK(name_->IsUniqueName());
    9760             :   }
    9761             : 
    9762             :   CodeCacheHashTableKey(Handle<Name> name, Handle<Code> code)
    9763        2100 :       : name_(name), flags_(code->flags()), code_(code) {
    9764             :     DCHECK(name_->IsUniqueName());
    9765             :   }
    9766             : 
    9767        1505 :   bool IsMatch(Object* other) override {
    9768             :     DCHECK(other->IsFixedArray());
    9769             :     FixedArray* pair = FixedArray::cast(other);
    9770             :     Name* name = Name::cast(pair->get(0));
    9771             :     Code::Flags flags = Code::cast(pair->get(1))->flags();
    9772        1505 :     if (flags != flags_) return false;
    9773             :     DCHECK(name->IsUniqueName());
    9774        1505 :     return *name_ == name;
    9775             :   }
    9776             : 
    9777             :   static uint32_t NameFlagsHashHelper(Name* name, Code::Flags flags) {
    9778        2261 :     return name->Hash() ^ flags;
    9779             :   }
    9780             : 
    9781        4522 :   uint32_t Hash() override { return NameFlagsHashHelper(*name_, flags_); }
    9782             : 
    9783           0 :   uint32_t HashForObject(Object* obj) override {
    9784             :     FixedArray* pair = FixedArray::cast(obj);
    9785             :     Name* name = Name::cast(pair->get(0));
    9786             :     Code* code = Code::cast(pair->get(1));
    9787           0 :     return NameFlagsHashHelper(name, code->flags());
    9788             :   }
    9789             : 
    9790        1050 :   MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) override {
    9791             :     Handle<Code> code = code_.ToHandleChecked();
    9792        1050 :     Handle<FixedArray> pair = isolate->factory()->NewFixedArray(2);
    9793        1050 :     pair->set(0, *name_);
    9794        1050 :     pair->set(1, *code);
    9795        1050 :     return pair;
    9796             :   }
    9797             : 
    9798             :  private:
    9799             :   Handle<Name> name_;
    9800             :   Code::Flags flags_;
    9801             :   // TODO(jkummerow): We should be able to get by without this.
    9802             :   MaybeHandle<Code> code_;
    9803             : };
    9804             : 
    9805             : 
    9806        1050 : Handle<CodeCacheHashTable> CodeCacheHashTable::Put(
    9807             :     Handle<CodeCacheHashTable> cache, Handle<Name> name, Handle<Code> code) {
    9808             :   CodeCacheHashTableKey key(name, code);
    9809             : 
    9810        1050 :   Handle<CodeCacheHashTable> new_cache = EnsureCapacity(cache, 1, &key);
    9811             : 
    9812        2100 :   int entry = new_cache->FindInsertionEntry(key.Hash());
    9813        1050 :   Handle<Object> k = key.AsHandle(cache->GetIsolate());
    9814             : 
    9815        1050 :   new_cache->set(EntryToIndex(entry), *k);
    9816        1050 :   new_cache->ElementAdded();
    9817        1050 :   return new_cache;
    9818             : }
    9819             : 
    9820        1211 : Code* CodeCacheHashTable::Lookup(Name* name, Code::Flags flags) {
    9821             :   DisallowHeapAllocation no_alloc;
    9822             :   CodeCacheHashTableKey key(handle(name), flags);
    9823             :   int entry = FindEntry(&key);
    9824        1211 :   if (entry == kNotFound) return nullptr;
    9825        1204 :   return Code::cast(FixedArray::cast(get(EntryToIndex(entry)))->get(1));
    9826             : }
    9827             : 
    9828    10501010 : Handle<FixedArray> FixedArray::SetAndGrow(Handle<FixedArray> array, int index,
    9829             :                                           Handle<Object> value) {
    9830    10501010 :   if (index < array->length()) {
    9831     9931652 :     array->set(index, *value);
    9832     9931652 :     return array;
    9833             :   }
    9834             :   int capacity = array->length();
    9835      569358 :   do {
    9836     1138716 :     capacity = JSObject::NewElementsCapacity(capacity);
    9837             :   } while (capacity <= index);
    9838             :   Handle<FixedArray> new_array =
    9839      569358 :       array->GetIsolate()->factory()->NewUninitializedFixedArray(capacity);
    9840      569358 :   array->CopyTo(0, *new_array, 0, array->length());
    9841      569358 :   new_array->FillWithHoles(array->length(), new_array->length());
    9842      569358 :   new_array->set(index, *value);
    9843      569358 :   return new_array;
    9844             : }
    9845             : 
    9846    12880503 : void FixedArray::Shrink(int new_length) {
    9847             :   DCHECK(0 <= new_length && new_length <= length());
    9848    12880503 :   if (new_length < length()) {
    9849    21159266 :     GetHeap()->RightTrimFixedArray(this, length() - new_length);
    9850             :   }
    9851    12880503 : }
    9852             : 
    9853      618954 : void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos,
    9854             :                         int len) const {
    9855             :   DisallowHeapAllocation no_gc;
    9856      618954 :   WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
    9857    27218618 :   for (int index = 0; index < len; index++) {
    9858    53199326 :     dest->set(dest_pos+index, get(pos+index), mode);
    9859             :   }
    9860      618955 : }
    9861             : 
    9862             : #ifdef DEBUG
    9863             : bool FixedArray::IsEqualTo(FixedArray* other) {
    9864             :   if (length() != other->length()) return false;
    9865             :   for (int i = 0 ; i < length(); ++i) {
    9866             :     if (get(i) != other->get(i)) return false;
    9867             :   }
    9868             :   return true;
    9869             : }
    9870             : #endif
    9871             : 
    9872             : 
    9873             : // static
    9874    13248769 : void WeakFixedArray::Set(Handle<WeakFixedArray> array, int index,
    9875             :                          Handle<HeapObject> value) {
    9876             :   DCHECK(array->IsEmptySlot(index));  // Don't overwrite anything.
    9877             :   Handle<WeakCell> cell =
    9878             :       value->IsMap() ? Map::WeakCellForMap(Handle<Map>::cast(value))
    9879    25999395 :                      : array->GetIsolate()->factory()->NewWeakCell(value);
    9880    26497534 :   Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell);
    9881    13248768 :   if (FLAG_trace_weak_arrays) {
    9882           0 :     PrintF("[WeakFixedArray: storing at index %d ]\n", index);
    9883             :   }
    9884             :   array->set_last_used_index(index);
    9885    13248768 : }
    9886             : 
    9887             : 
    9888             : // static
    9889    13248762 : Handle<WeakFixedArray> WeakFixedArray::Add(Handle<Object> maybe_array,
    9890             :                                            Handle<HeapObject> value,
    9891             :                                            int* assigned_index) {
    9892             :   Handle<WeakFixedArray> array =
    9893    13248766 :       (maybe_array.is_null() || !maybe_array->IsWeakFixedArray())
    9894             :           ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null())
    9895    13345052 :           : Handle<WeakFixedArray>::cast(maybe_array);
    9896             :   // Try to store the new entry if there's room. Optimize for consecutive
    9897             :   // accesses.
    9898             :   int first_index = array->last_used_index();
    9899             :   int length = array->Length();
    9900    13248770 :   if (length > 0) {
    9901             :     for (int i = first_index;;) {
    9902    57546249 :       if (array->IsEmptySlot((i))) {
    9903    13061489 :         WeakFixedArray::Set(array, i, value);
    9904    13061487 :         if (assigned_index != NULL) *assigned_index = i;
    9905    13061487 :         return array;
    9906             :       }
    9907    44484760 :       if (FLAG_trace_weak_arrays) {
    9908           0 :         PrintF("[WeakFixedArray: searching for free slot]\n");
    9909             :       }
    9910    44484761 :       i = (i + 1) % length;
    9911    44484761 :       if (i == first_index) break;
    9912             :     }
    9913             :   }
    9914             : 
    9915             :   // No usable slot found, grow the array.
    9916      187281 :   int new_length = length == 0 ? 1 : length + (length >> 1) + 4;
    9917             :   Handle<WeakFixedArray> new_array =
    9918      187281 :       Allocate(array->GetIsolate(), new_length, array);
    9919      187281 :   if (FLAG_trace_weak_arrays) {
    9920           0 :     PrintF("[WeakFixedArray: growing to size %d ]\n", new_length);
    9921             :   }
    9922      187281 :   WeakFixedArray::Set(new_array, length, value);
    9923      187281 :   if (assigned_index != NULL) *assigned_index = length;
    9924      187281 :   return new_array;
    9925             : }
    9926             : 
    9927             : 
    9928             : template <class CompactionCallback>
    9929         303 : void WeakFixedArray::Compact() {
    9930             :   FixedArray* array = FixedArray::cast(this);
    9931             :   int new_length = kFirstIndex;
    9932      131248 :   for (int i = kFirstIndex; i < array->length(); i++) {
    9933             :     Object* element = array->get(i);
    9934       65321 :     if (element->IsSmi()) continue;
    9935       43807 :     if (WeakCell::cast(element)->cleared()) continue;
    9936             :     Object* value = WeakCell::cast(element)->value();
    9937             :     CompactionCallback::Callback(value, i - kFirstIndex,
    9938         230 :                                  new_length - kFirstIndex);
    9939       43688 :     array->set(new_length++, element);
    9940             :   }
    9941         303 :   array->Shrink(new_length);
    9942             :   set_last_used_index(0);
    9943         303 : }
    9944             : 
    9945             : 
    9946     1068370 : void WeakFixedArray::Iterator::Reset(Object* maybe_array) {
    9947     1068370 :   if (maybe_array->IsWeakFixedArray()) {
    9948      425549 :     list_ = WeakFixedArray::cast(maybe_array);
    9949      425549 :     index_ = 0;
    9950             : #ifdef DEBUG
    9951             :     last_used_index_ = list_->last_used_index();
    9952             : #endif  // DEBUG
    9953             :   }
    9954     1068370 : }
    9955             : 
    9956             : 
    9957           0 : void JSObject::PrototypeRegistryCompactionCallback::Callback(Object* value,
    9958             :                                                              int old_index,
    9959             :                                                              int new_index) {
    9960             :   DCHECK(value->IsMap() && Map::cast(value)->is_prototype_map());
    9961             :   Map* map = Map::cast(value);
    9962             :   DCHECK(map->prototype_info()->IsPrototypeInfo());
    9963             :   PrototypeInfo* proto_info = PrototypeInfo::cast(map->prototype_info());
    9964             :   DCHECK_EQ(old_index, proto_info->registry_slot());
    9965             :   proto_info->set_registry_slot(new_index);
    9966           0 : }
    9967             : 
    9968             : 
    9969             : template void WeakFixedArray::Compact<WeakFixedArray::NullCallback>();
    9970             : template void
    9971             : WeakFixedArray::Compact<JSObject::PrototypeRegistryCompactionCallback>();
    9972             : 
    9973             : 
    9974     6234878 : bool WeakFixedArray::Remove(Handle<HeapObject> value) {
    9975     6234878 :   if (Length() == 0) return false;
    9976             :   // Optimize for the most recently added element to be removed again.
    9977             :   int first_index = last_used_index();
    9978             :   for (int i = first_index;;) {
    9979    13662549 :     if (Get(i) == *value) {
    9980             :       Clear(i);
    9981             :       // Users of WeakFixedArray should make sure that there are no duplicates.
    9982     6234879 :       return true;
    9983             :     }
    9984     1192792 :     i = (i + 1) % Length();
    9985      596396 :     if (i == first_index) return false;
    9986             :   }
    9987             :   UNREACHABLE();
    9988             : }
    9989             : 
    9990             : 
    9991             : // static
    9992      283574 : Handle<WeakFixedArray> WeakFixedArray::Allocate(
    9993             :     Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from) {
    9994             :   DCHECK(0 <= size);
    9995             :   Handle<FixedArray> result =
    9996      283574 :       isolate->factory()->NewUninitializedFixedArray(size + kFirstIndex);
    9997             :   int index = 0;
    9998      283574 :   if (!initialize_from.is_null()) {
    9999             :     DCHECK(initialize_from->Length() <= size);
   10000             :     Handle<FixedArray> raw_source = Handle<FixedArray>::cast(initialize_from);
   10001             :     // Copy the entries without compacting, since the PrototypeInfo relies on
   10002             :     // the index of the entries not to change.
   10003    37610254 :     while (index < raw_source->length()) {
   10004    37422973 :       result->set(index, raw_source->get(index));
   10005    37422973 :       index++;
   10006             :     }
   10007             :   }
   10008    19826681 :   while (index < result->length()) {
   10009             :     result->set(index, Smi::kZero);
   10010    19543107 :     index++;
   10011             :   }
   10012      283574 :   return Handle<WeakFixedArray>::cast(result);
   10013             : }
   10014             : 
   10015             : // static
   10016        2215 : Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj,
   10017             :                                  AddMode mode) {
   10018        2215 :   int length = array->Length();
   10019        2215 :   array = EnsureSpace(array, length + 1);
   10020        2215 :   if (mode == kReloadLengthAfterAllocation) {
   10021             :     DCHECK(array->Length() <= length);
   10022           0 :     length = array->Length();
   10023             :   }
   10024             :   array->Set(length, *obj);
   10025             :   array->SetLength(length + 1);
   10026        2215 :   return array;
   10027             : }
   10028             : 
   10029             : // static
   10030      962182 : Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj1,
   10031             :                                  Handle<Object> obj2, AddMode mode) {
   10032      962182 :   int length = array->Length();
   10033      962182 :   array = EnsureSpace(array, length + 2);
   10034      962182 :   if (mode == kReloadLengthAfterAllocation) {
   10035       38125 :     length = array->Length();
   10036             :   }
   10037             :   array->Set(length, *obj1);
   10038             :   array->Set(length + 1, *obj2);
   10039             :   array->SetLength(length + 2);
   10040      962182 :   return array;
   10041             : }
   10042             : 
   10043             : // static
   10044         472 : Handle<ArrayList> ArrayList::New(Isolate* isolate, int size) {
   10045             :   Handle<ArrayList> result = Handle<ArrayList>::cast(
   10046         472 :       isolate->factory()->NewFixedArray(size + kFirstIndex));
   10047             :   result->SetLength(0);
   10048         472 :   return result;
   10049             : }
   10050             : 
   10051         210 : Handle<FixedArray> ArrayList::Elements() const {
   10052         420 :   Handle<FixedArray> result = GetIsolate()->factory()->NewFixedArray(Length());
   10053             :   // Do not copy the first entry, i.e., the length.
   10054         420 :   CopyTo(kFirstIndex, *result, 0, Length());
   10055         210 :   return result;
   10056             : }
   10057             : 
   10058       38125 : bool ArrayList::IsFull() {
   10059             :   int capacity = length();
   10060       38125 :   return kFirstIndex + Length() == capacity;
   10061             : }
   10062             : 
   10063             : namespace {
   10064             : 
   10065     5988436 : Handle<FixedArray> EnsureSpaceInFixedArray(Handle<FixedArray> array,
   10066             :                                            int length) {
   10067             :   int capacity = array->length();
   10068     5988436 :   if (capacity < length) {
   10069             :     Isolate* isolate = array->GetIsolate();
   10070             :     int new_capacity = length;
   10071       97822 :     new_capacity = new_capacity + Max(new_capacity / 2, 2);
   10072       48911 :     int grow_by = new_capacity - capacity;
   10073       48911 :     array = isolate->factory()->CopyFixedArrayAndGrow(array, grow_by);
   10074             :   }
   10075     5988436 :   return array;
   10076             : }
   10077             : 
   10078             : }  // namespace
   10079             : 
   10080             : // static
   10081      964397 : Handle<ArrayList> ArrayList::EnsureSpace(Handle<ArrayList> array, int length) {
   10082             :   const bool empty = (array->length() == 0);
   10083             :   auto ret = Handle<ArrayList>::cast(
   10084     1928794 :       EnsureSpaceInFixedArray(array, kFirstIndex + length));
   10085      964397 :   if (empty) ret->SetLength(0);
   10086      964397 :   return ret;
   10087             : }
   10088             : 
   10089      259822 : Handle<RegExpMatchInfo> RegExpMatchInfo::ReserveCaptures(
   10090             :     Handle<RegExpMatchInfo> match_info, int capture_count) {
   10091             :   DCHECK_GE(match_info->length(), kLastMatchOverhead);
   10092      259822 :   const int required_length = kFirstCaptureIndex + capture_count;
   10093             :   Handle<FixedArray> result =
   10094      259822 :       EnsureSpaceInFixedArray(match_info, required_length);
   10095      259822 :   return Handle<RegExpMatchInfo>::cast(result);
   10096             : }
   10097             : 
   10098             : // static
   10099     4726137 : Handle<FrameArray> FrameArray::AppendJSFrame(Handle<FrameArray> in,
   10100             :                                              Handle<Object> receiver,
   10101             :                                              Handle<JSFunction> function,
   10102             :                                              Handle<AbstractCode> code,
   10103             :                                              int offset, int flags) {
   10104             :   const int frame_count = in->FrameCount();
   10105     4726137 :   const int new_length = LengthFor(frame_count + 1);
   10106             :   Handle<FrameArray> array = EnsureSpace(in, new_length);
   10107             :   array->SetReceiver(frame_count, *receiver);
   10108             :   array->SetFunction(frame_count, *function);
   10109             :   array->SetCode(frame_count, *code);
   10110             :   array->SetOffset(frame_count, Smi::FromInt(offset));
   10111     4726137 :   array->SetFlags(frame_count, Smi::FromInt(flags));
   10112             :   array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1));
   10113     4726137 :   return array;
   10114             : }
   10115             : 
   10116             : // static
   10117       38080 : Handle<FrameArray> FrameArray::AppendWasmFrame(Handle<FrameArray> in,
   10118             :                                                Handle<Object> wasm_instance,
   10119             :                                                int wasm_function_index,
   10120             :                                                Handle<AbstractCode> code,
   10121             :                                                int offset, int flags) {
   10122             :   const int frame_count = in->FrameCount();
   10123       38080 :   const int new_length = LengthFor(frame_count + 1);
   10124             :   Handle<FrameArray> array = EnsureSpace(in, new_length);
   10125             :   array->SetWasmInstance(frame_count, *wasm_instance);
   10126             :   array->SetWasmFunctionIndex(frame_count, Smi::FromInt(wasm_function_index));
   10127             :   // code will be a null handle for interpreted wasm frames.
   10128       38080 :   if (!code.is_null()) array->SetCode(frame_count, *code);
   10129             :   array->SetOffset(frame_count, Smi::FromInt(offset));
   10130       38080 :   array->SetFlags(frame_count, Smi::FromInt(flags));
   10131             :   array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1));
   10132       38080 :   return array;
   10133             : }
   10134             : 
   10135     2419438 : void FrameArray::ShrinkToFit() { Shrink(LengthFor(FrameCount())); }
   10136             : 
   10137             : // static
   10138           0 : Handle<FrameArray> FrameArray::EnsureSpace(Handle<FrameArray> array,
   10139             :                                            int length) {
   10140     4764217 :   return Handle<FrameArray>::cast(EnsureSpaceInFixedArray(array, length));
   10141             : }
   10142             : 
   10143    18576670 : Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
   10144             :                                                   int number_of_descriptors,
   10145             :                                                   int slack,
   10146             :                                                   PretenureFlag pretenure) {
   10147             :   DCHECK(0 <= number_of_descriptors);
   10148             :   Factory* factory = isolate->factory();
   10149             :   // Do not use DescriptorArray::cast on incomplete object.
   10150    18576670 :   int size = number_of_descriptors + slack;
   10151    18576670 :   if (size == 0) return factory->empty_descriptor_array();
   10152             :   // Allocate the array of keys.
   10153             :   Handle<FixedArray> result =
   10154    18576670 :       factory->NewFixedArray(LengthFor(size), pretenure);
   10155             : 
   10156             :   result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
   10157             :   result->set(kEnumCacheIndex, Smi::kZero);
   10158             :   return Handle<DescriptorArray>::cast(result);
   10159             : }
   10160             : 
   10161          12 : void DescriptorArray::ClearEnumCache() { set(kEnumCacheIndex, Smi::kZero); }
   10162             : 
   10163     2496355 : void DescriptorArray::Replace(int index, Descriptor* descriptor) {
   10164             :   descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index));
   10165     2496355 :   Set(index, descriptor);
   10166     2496356 : }
   10167             : 
   10168             : 
   10169             : // static
   10170      114863 : void DescriptorArray::SetEnumCache(Handle<DescriptorArray> descriptors,
   10171             :                                    Isolate* isolate,
   10172             :                                    Handle<FixedArray> new_cache,
   10173             :                                    Handle<FixedArray> new_index_cache) {
   10174             :   DCHECK(!descriptors->IsEmpty());
   10175             :   FixedArray* bridge_storage;
   10176      114863 :   bool needs_new_enum_cache = !descriptors->HasEnumCache();
   10177      114863 :   if (needs_new_enum_cache) {
   10178             :     bridge_storage = *isolate->factory()->NewFixedArray(
   10179      189764 :         DescriptorArray::kEnumCacheBridgeLength);
   10180             :   } else {
   10181             :     bridge_storage = FixedArray::cast(descriptors->get(kEnumCacheIndex));
   10182             :   }
   10183      114863 :   bridge_storage->set(kEnumCacheBridgeCacheIndex, *new_cache);
   10184             :   bridge_storage->set(
   10185             :       kEnumCacheBridgeIndicesCacheIndex,
   10186      229726 :       new_index_cache.is_null() ? Object::cast(Smi::kZero) : *new_index_cache);
   10187      114863 :   if (needs_new_enum_cache) {
   10188       94882 :     descriptors->set(kEnumCacheIndex, bridge_storage);
   10189             :   }
   10190      114863 : }
   10191             : 
   10192   154691632 : void DescriptorArray::CopyFrom(int index, DescriptorArray* src) {
   10193   154691632 :   PropertyDetails details = src->GetDetails(index);
   10194   154691635 :   Set(index, src->GetKey(index), src->GetValue(index), details);
   10195   154691646 : }
   10196             : 
   10197      672987 : void DescriptorArray::Sort() {
   10198             :   // In-place heap sort.
   10199      672987 :   int len = number_of_descriptors();
   10200             :   // Reset sorting since the descriptor array might contain invalid pointers.
   10201      672987 :   for (int i = 0; i < len; ++i) SetSortedKey(i, i);
   10202             :   // Bottom-up max-heap construction.
   10203             :   // Index of the last node with children
   10204      672987 :   const int max_parent_index = (len / 2) - 1;
   10205     2377018 :   for (int i = max_parent_index; i >= 0; --i) {
   10206             :     int parent_index = i;
   10207     1704031 :     const uint32_t parent_hash = GetSortedKey(i)->Hash();
   10208     5030286 :     while (parent_index <= max_parent_index) {
   10209     2445606 :       int child_index = 2 * parent_index + 1;
   10210     2445606 :       uint32_t child_hash = GetSortedKey(child_index)->Hash();
   10211     2445606 :       if (child_index + 1 < len) {
   10212     2078141 :         uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
   10213     2078141 :         if (right_child_hash > child_hash) {
   10214             :           child_index++;
   10215             :           child_hash = right_child_hash;
   10216             :         }
   10217             :       }
   10218     2445606 :       if (child_hash <= parent_hash) break;
   10219     1622224 :       SwapSortedKeys(parent_index, child_index);
   10220             :       // Now element at child_index could be < its children.
   10221             :       parent_index = child_index;  // parent_hash remains correct.
   10222             :     }
   10223             :   }
   10224             : 
   10225             :   // Extract elements and create sorted array.
   10226     3823641 :   for (int i = len - 1; i > 0; --i) {
   10227             :     // Put max element at the back of the array.
   10228     3150654 :     SwapSortedKeys(0, i);
   10229             :     // Shift down the new top element.
   10230             :     int parent_index = 0;
   10231     3150654 :     const uint32_t parent_hash = GetSortedKey(parent_index)->Hash();
   10232     3150654 :     const int max_parent_index = (i / 2) - 1;
   10233    12639607 :     while (parent_index <= max_parent_index) {
   10234     6810081 :       int child_index = parent_index * 2 + 1;
   10235     6810081 :       uint32_t child_hash = GetSortedKey(child_index)->Hash();
   10236     6810081 :       if (child_index + 1 < i) {
   10237     6147622 :         uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
   10238     6147622 :         if (right_child_hash > child_hash) {
   10239             :           child_index++;
   10240             :           child_hash = right_child_hash;
   10241             :         }
   10242             :       }
   10243     6810081 :       if (child_hash <= parent_hash) break;
   10244     6338299 :       SwapSortedKeys(parent_index, child_index);
   10245             :       parent_index = child_index;
   10246             :     }
   10247             :   }
   10248             :   DCHECK(IsSortedNoDuplicates());
   10249      672987 : }
   10250             : 
   10251             : 
   10252       17523 : Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) {
   10253       17523 :   Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair();
   10254       17523 :   copy->set_getter(pair->getter());
   10255       17523 :   copy->set_setter(pair->setter());
   10256       17523 :   return copy;
   10257             : }
   10258             : 
   10259       71561 : Handle<Object> AccessorPair::GetComponent(Handle<AccessorPair> accessor_pair,
   10260             :                                           AccessorComponent component) {
   10261             :   Object* accessor = accessor_pair->get(component);
   10262       71561 :   if (accessor->IsFunctionTemplateInfo()) {
   10263             :     return ApiNatives::InstantiateFunction(
   10264             :                handle(FunctionTemplateInfo::cast(accessor)))
   10265         184 :         .ToHandleChecked();
   10266             :   }
   10267             :   Isolate* isolate = accessor_pair->GetIsolate();
   10268       71469 :   if (accessor->IsNull(isolate)) {
   10269        6815 :     return isolate->factory()->undefined_value();
   10270             :   }
   10271             :   return handle(accessor, isolate);
   10272             : }
   10273             : 
   10274      670319 : Handle<DeoptimizationInputData> DeoptimizationInputData::New(
   10275             :     Isolate* isolate, int deopt_entry_count, PretenureFlag pretenure) {
   10276             :   return Handle<DeoptimizationInputData>::cast(
   10277             :       isolate->factory()->NewFixedArray(LengthFor(deopt_entry_count),
   10278      670319 :                                         pretenure));
   10279             : }
   10280             : 
   10281             : 
   10282      236326 : Handle<DeoptimizationOutputData> DeoptimizationOutputData::New(
   10283             :     Isolate* isolate,
   10284             :     int number_of_deopt_points,
   10285             :     PretenureFlag pretenure) {
   10286             :   Handle<FixedArray> result;
   10287      236326 :   if (number_of_deopt_points == 0) {
   10288             :     result = isolate->factory()->empty_fixed_array();
   10289             :   } else {
   10290             :     result = isolate->factory()->NewFixedArray(
   10291      236326 :         LengthOfFixedArray(number_of_deopt_points), pretenure);
   10292             :   }
   10293      236326 :   return Handle<DeoptimizationOutputData>::cast(result);
   10294             : }
   10295             : 
   10296          48 : SharedFunctionInfo* DeoptimizationInputData::GetInlinedFunction(int index) {
   10297          48 :   if (index == -1) {
   10298           0 :     return SharedFunctionInfo::cast(SharedFunctionInfo());
   10299             :   } else {
   10300          48 :     return SharedFunctionInfo::cast(LiteralArray()->get(index));
   10301             :   }
   10302             : }
   10303             : 
   10304    10643411 : int HandlerTable::LookupRange(int pc_offset, int* data_out,
   10305             :                               CatchPrediction* prediction_out) {
   10306             :   int innermost_handler = -1;
   10307             : #ifdef DEBUG
   10308             :   // Assuming that ranges are well nested, we don't need to track the innermost
   10309             :   // offsets. This is just to verify that the table is actually well nested.
   10310             :   int innermost_start = std::numeric_limits<int>::min();
   10311             :   int innermost_end = std::numeric_limits<int>::max();
   10312             : #endif
   10313    51034236 :   for (int i = 0; i < length(); i += kRangeEntrySize) {
   10314             :     int start_offset = Smi::cast(get(i + kRangeStartIndex))->value();
   10315    14873707 :     int end_offset = Smi::cast(get(i + kRangeEndIndex))->value();
   10316    14873707 :     int handler_field = Smi::cast(get(i + kRangeHandlerIndex))->value();
   10317    14873707 :     int handler_offset = HandlerOffsetField::decode(handler_field);
   10318             :     CatchPrediction prediction = HandlerPredictionField::decode(handler_field);
   10319    14873707 :     int handler_data = Smi::cast(get(i + kRangeDataIndex))->value();
   10320    14873707 :     if (pc_offset >= start_offset && pc_offset < end_offset) {
   10321             :       DCHECK_GE(start_offset, innermost_start);
   10322             :       DCHECK_LT(end_offset, innermost_end);
   10323             :       innermost_handler = handler_offset;
   10324             : #ifdef DEBUG
   10325             :       innermost_start = start_offset;
   10326             :       innermost_end = end_offset;
   10327             : #endif
   10328     2174972 :       if (data_out) *data_out = handler_data;
   10329     2174972 :       if (prediction_out) *prediction_out = prediction;
   10330             :     }
   10331             :   }
   10332    10643411 :   return innermost_handler;
   10333             : }
   10334             : 
   10335             : 
   10336             : // TODO(turbofan): Make sure table is sorted and use binary search.
   10337     2088275 : int HandlerTable::LookupReturn(int pc_offset) {
   10338     6636452 :   for (int i = 0; i < length(); i += kReturnEntrySize) {
   10339             :     int return_offset = Smi::cast(get(i + kReturnOffsetIndex))->value();
   10340     1555528 :     int handler_field = Smi::cast(get(i + kReturnHandlerIndex))->value();
   10341     1555528 :     if (pc_offset == return_offset) {
   10342      651154 :       return HandlerOffsetField::decode(handler_field);
   10343             :     }
   10344             :   }
   10345             :   return -1;
   10346             : }
   10347             : 
   10348             : 
   10349             : #ifdef DEBUG
   10350             : bool DescriptorArray::IsEqualTo(DescriptorArray* other) {
   10351             :   if (IsEmpty()) return other->IsEmpty();
   10352             :   if (other->IsEmpty()) return false;
   10353             :   if (length() != other->length()) return false;
   10354             :   for (int i = 0; i < length(); ++i) {
   10355             :     if (get(i) != other->get(i)) return false;
   10356             :   }
   10357             :   return true;
   10358             : }
   10359             : #endif
   10360             : 
   10361             : // static
   10362     1838054 : Handle<String> String::Trim(Handle<String> string, TrimMode mode) {
   10363     1838054 :   Isolate* const isolate = string->GetIsolate();
   10364     1838054 :   string = String::Flatten(string);
   10365             :   int const length = string->length();
   10366             : 
   10367             :   // Perform left trimming if requested.
   10368             :   int left = 0;
   10369             :   UnicodeCache* unicode_cache = isolate->unicode_cache();
   10370     1838054 :   if (mode == kTrim || mode == kTrimLeft) {
   10371     3693504 :     while (left < length &&
   10372     1846458 :            unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
   10373        9496 :       left++;
   10374             :     }
   10375             :   }
   10376             : 
   10377             :   // Perform right trimming if requested.
   10378             :   int right = length;
   10379     1838054 :   if (mode == kTrim || mode == kTrimRight) {
   10380     1838222 :     while (
   10381     3675856 :         right > left &&
   10382     3675268 :         unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(right - 1))) {
   10383        1050 :       right--;
   10384             :     }
   10385             :   }
   10386             : 
   10387     1838054 :   return isolate->factory()->NewSubString(string, left, right);
   10388             : }
   10389             : 
   10390     3124575 : bool String::LooksValid() { return GetIsolate()->heap()->Contains(this); }
   10391             : 
   10392             : // static
   10393     1532984 : MaybeHandle<String> Name::ToFunctionName(Handle<Name> name) {
   10394     1532985 :   if (name->IsString()) return Handle<String>::cast(name);
   10395             :   // ES6 section 9.2.11 SetFunctionName, step 4.
   10396             :   Isolate* const isolate = name->GetIsolate();
   10397             :   Handle<Object> description(Handle<Symbol>::cast(name)->name(), isolate);
   10398       11319 :   if (description->IsUndefined(isolate)) {
   10399             :     return isolate->factory()->empty_string();
   10400             :   }
   10401       11193 :   IncrementalStringBuilder builder(isolate);
   10402             :   builder.AppendCharacter('[');
   10403       11193 :   builder.AppendString(Handle<String>::cast(description));
   10404             :   builder.AppendCharacter(']');
   10405       11193 :   return builder.Finish();
   10406             : }
   10407             : 
   10408             : // static
   10409        6814 : MaybeHandle<String> Name::ToFunctionName(Handle<Name> name,
   10410             :                                          Handle<String> prefix) {
   10411             :   Handle<String> name_string;
   10412             :   Isolate* const isolate = name->GetIsolate();
   10413       13628 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, name_string, ToFunctionName(name),
   10414             :                              String);
   10415        6814 :   IncrementalStringBuilder builder(isolate);
   10416        6814 :   builder.AppendString(prefix);
   10417             :   builder.AppendCharacter(' ');
   10418        6814 :   builder.AppendString(name_string);
   10419        6814 :   return builder.Finish();
   10420             : }
   10421             : 
   10422             : namespace {
   10423             : 
   10424             : bool AreDigits(const uint8_t* s, int from, int to) {
   10425       46568 :   for (int i = from; i < to; i++) {
   10426      108861 :     if (s[i] < '0' || s[i] > '9') return false;
   10427             :   }
   10428             : 
   10429             :   return true;
   10430             : }
   10431             : 
   10432             : 
   10433             : int ParseDecimalInteger(const uint8_t* s, int from, int to) {
   10434             :   DCHECK(to - from < 10);  // Overflow is not possible.
   10435             :   DCHECK(from < to);
   10436        2619 :   int d = s[from] - '0';
   10437             : 
   10438        3198 :   for (int i = from + 1; i < to; i++) {
   10439         579 :     d = 10 * d + (s[i] - '0');
   10440             :   }
   10441             : 
   10442             :   return d;
   10443             : }
   10444             : 
   10445             : }  // namespace
   10446             : 
   10447             : 
   10448             : // static
   10449    12609845 : Handle<Object> String::ToNumber(Handle<String> subject) {
   10450     2726891 :   Isolate* const isolate = subject->GetIsolate();
   10451             : 
   10452             :   // Flatten {subject} string first.
   10453    12609845 :   subject = String::Flatten(subject);
   10454             : 
   10455             :   // Fast array index case.
   10456             :   uint32_t index;
   10457    12609845 :   if (subject->AsArrayIndex(&index)) {
   10458     6002725 :     return isolate->factory()->NewNumberFromUint(index);
   10459             :   }
   10460             : 
   10461             :   // Fast case: short integer or some sorts of junk values.
   10462     6607120 :   if (subject->IsSeqOneByteString()) {
   10463             :     int len = subject->length();
   10464     4153631 :     if (len == 0) return handle(Smi::kZero, isolate);
   10465             : 
   10466             :     DisallowHeapAllocation no_gc;
   10467     4087193 :     uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
   10468     4087193 :     bool minus = (data[0] == '-');
   10469     4087193 :     int start_pos = (minus ? 1 : 0);
   10470             : 
   10471     4087193 :     if (start_pos == len) {
   10472           0 :       return isolate->factory()->nan_value();
   10473     4087193 :     } else if (data[start_pos] > '9') {
   10474             :       // Fast check for a junk value. A valid string may start from a
   10475             :       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
   10476             :       // or the 'I' character ('Infinity'). All of that have codes not greater
   10477             :       // than '9' except 'I' and &nbsp;.
   10478     3854314 :       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
   10479     3844391 :         return isolate->factory()->nan_value();
   10480             :       }
   10481      297791 :     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
   10482             :       // The maximal/minimal smi has 10 digits. If the string has less digits
   10483             :       // we know it will fit into the smi-data type.
   10484             :       int d = ParseDecimalInteger(data, start_pos, len);
   10485        2619 :       if (minus) {
   10486        2933 :         if (d == 0) return isolate->factory()->minus_zero_value();
   10487        2125 :         d = -d;
   10488         180 :       } else if (!subject->HasHashCode() && len <= String::kMaxArrayIndexSize &&
   10489           0 :                  (len == 1 || data[0] != '0')) {
   10490             :         // String hash is not calculated yet but all the data are present.
   10491             :         // Update the hash field to speed up sequential convertions.
   10492           0 :         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
   10493             : #ifdef DEBUG
   10494             :         subject->Hash();  // Force hash calculation.
   10495             :         DCHECK_EQ(static_cast<int>(subject->hash_field()),
   10496             :                   static_cast<int>(hash));
   10497             : #endif
   10498             :         subject->set_hash_field(hash);
   10499             :       }
   10500        2215 :       return handle(Smi::FromInt(d), isolate);
   10501             :     }
   10502             :   }
   10503             : 
   10504             :   // Slower case.
   10505             :   int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
   10506             :   return isolate->factory()->NewNumber(
   10507     2726891 :       StringToDouble(isolate->unicode_cache(), subject, flags));
   10508             : }
   10509             : 
   10510             : 
   10511   125831565 : String::FlatContent String::GetFlatContent() {
   10512             :   DCHECK(!AllowHeapAllocation::IsAllowed());
   10513             :   int length = this->length();
   10514             :   StringShape shape(this);
   10515             :   String* string = this;
   10516             :   int offset = 0;
   10517   125831565 :   if (shape.representation_tag() == kConsStringTag) {
   10518             :     ConsString* cons = ConsString::cast(string);
   10519           0 :     if (cons->second()->length() != 0) {
   10520           0 :       return FlatContent();
   10521             :     }
   10522             :     string = cons->first();
   10523             :     shape = StringShape(string);
   10524   125831565 :   } else if (shape.representation_tag() == kSlicedStringTag) {
   10525             :     SlicedString* slice = SlicedString::cast(string);
   10526             :     offset = slice->offset();
   10527             :     string = slice->parent();
   10528             :     shape = StringShape(string);
   10529             :     DCHECK(shape.representation_tag() != kConsStringTag &&
   10530             :            shape.representation_tag() != kSlicedStringTag);
   10531             :   }
   10532   125831565 :   if (shape.representation_tag() == kThinStringTag) {
   10533             :     ThinString* thin = ThinString::cast(string);
   10534             :     string = thin->actual();
   10535             :     shape = StringShape(string);
   10536             :     DCHECK(!shape.IsCons());
   10537             :     DCHECK(!shape.IsSliced());
   10538             :   }
   10539   125831565 :   if (shape.encoding_tag() == kOneByteStringTag) {
   10540             :     const uint8_t* start;
   10541   113713019 :     if (shape.representation_tag() == kSeqStringTag) {
   10542   113709868 :       start = SeqOneByteString::cast(string)->GetChars();
   10543             :     } else {
   10544             :       start = ExternalOneByteString::cast(string)->GetChars();
   10545             :     }
   10546   113713021 :     return FlatContent(start + offset, length);
   10547             :   } else {
   10548             :     DCHECK(shape.encoding_tag() == kTwoByteStringTag);
   10549             :     const uc16* start;
   10550    12118546 :     if (shape.representation_tag() == kSeqStringTag) {
   10551    12115756 :       start = SeqTwoByteString::cast(string)->GetChars();
   10552             :     } else {
   10553             :       start = ExternalTwoByteString::cast(string)->GetChars();
   10554             :     }
   10555    12118546 :     return FlatContent(start + offset, length);
   10556             :   }
   10557             : }
   10558             : 
   10559     3734839 : std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls,
   10560             :                                           RobustnessFlag robust_flag,
   10561             :                                           int offset, int length,
   10562             :                                           int* length_return) {
   10563     6859306 :   if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
   10564             :     return std::unique_ptr<char[]>();
   10565             :   }
   10566             :   // Negative length means the to the end of the string.
   10567     3734839 :   if (length < 0) length = kMaxInt - offset;
   10568             : 
   10569             :   // Compute the size of the UTF-8 string. Start at the specified offset.
   10570             :   StringCharacterStream stream(this, offset);
   10571             :   int character_position = offset;
   10572             :   int utf8_bytes = 0;
   10573             :   int last = unibrow::Utf16::kNoPreviousCharacter;
   10574    42635139 :   while (stream.HasMore() && character_position++ < offset + length) {
   10575    35165461 :     uint16_t character = stream.GetNext();
   10576    35165461 :     utf8_bytes += unibrow::Utf8::Length(character, last);
   10577    35165461 :     last = character;
   10578             :   }
   10579             : 
   10580     3734839 :   if (length_return) {
   10581     3085127 :     *length_return = utf8_bytes;
   10582             :   }
   10583             : 
   10584     3734839 :   char* result = NewArray<char>(utf8_bytes + 1);
   10585             : 
   10586             :   // Convert the UTF-16 string to a UTF-8 buffer. Start at the specified offset.
   10587     3734839 :   stream.Reset(this, offset);
   10588             :   character_position = offset;
   10589             :   int utf8_byte_position = 0;
   10590             :   last = unibrow::Utf16::kNoPreviousCharacter;
   10591    42635139 :   while (stream.HasMore() && character_position++ < offset + length) {
   10592    35165461 :     uint16_t character = stream.GetNext();
   10593    35165461 :     if (allow_nulls == DISALLOW_NULLS && character == 0) {
   10594             :       character = ' ';
   10595             :     }
   10596             :     utf8_byte_position +=
   10597    35165461 :         unibrow::Utf8::Encode(result + utf8_byte_position, character, last);
   10598    35165461 :     last = character;
   10599             :   }
   10600     3734839 :   result[utf8_byte_position] = 0;
   10601             :   return std::unique_ptr<char[]>(result);
   10602             : }
   10603             : 
   10604      654070 : std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls,
   10605             :                                           RobustnessFlag robust_flag,
   10606             :                                           int* length_return) {
   10607      654070 :   return ToCString(allow_nulls, robust_flag, 0, -1, length_return);
   10608             : }
   10609             : 
   10610             : 
   10611          82 : const uc16* String::GetTwoByteData(unsigned start) {
   10612             :   DCHECK(!IsOneByteRepresentationUnderneath());
   10613          82 :   switch (StringShape(this).representation_tag()) {
   10614             :     case kSeqStringTag:
   10615           0 :       return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start);
   10616             :     case kExternalStringTag:
   10617             :       return ExternalTwoByteString::cast(this)->
   10618          82 :         ExternalTwoByteStringGetData(start);
   10619             :     case kSlicedStringTag: {
   10620             :       SlicedString* slice = SlicedString::cast(this);
   10621           0 :       return slice->parent()->GetTwoByteData(start + slice->offset());
   10622             :     }
   10623             :     case kConsStringTag:
   10624             :     case kThinStringTag:
   10625           0 :       UNREACHABLE();
   10626             :       return NULL;
   10627             :   }
   10628           0 :   UNREACHABLE();
   10629             :   return NULL;
   10630             : }
   10631             : 
   10632             : 
   10633           0 : const uc16* SeqTwoByteString::SeqTwoByteStringGetData(unsigned start) {
   10634             :   return reinterpret_cast<uc16*>(
   10635           0 :       reinterpret_cast<char*>(this) - kHeapObjectTag + kHeaderSize) + start;
   10636             : }
   10637             : 
   10638             : 
   10639      122039 : void Relocatable::PostGarbageCollectionProcessing(Isolate* isolate) {
   10640             :   Relocatable* current = isolate->relocatable_top();
   10641      265715 :   while (current != NULL) {
   10642       21637 :     current->PostGarbageCollection();
   10643       21637 :     current = current->prev_;
   10644             :   }
   10645      122039 : }
   10646             : 
   10647             : 
   10648             : // Reserve space for statics needing saving and restoring.
   10649        1313 : int Relocatable::ArchiveSpacePerThread() {
   10650        1313 :   return sizeof(Relocatable*);  // NOLINT
   10651             : }
   10652             : 
   10653             : 
   10654             : // Archive statics that are thread-local.
   10655       22597 : char* Relocatable::ArchiveState(Isolate* isolate, char* to) {
   10656       22597 :   *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top();
   10657             :   isolate->set_relocatable_top(NULL);
   10658       22597 :   return to + ArchiveSpacePerThread();
   10659             : }
   10660             : 
   10661             : 
   10662             : // Restore statics that are thread-local.
   10663       22597 : char* Relocatable::RestoreState(Isolate* isolate, char* from) {
   10664       22597 :   isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from));
   10665       22597 :   return from + ArchiveSpacePerThread();
   10666             : }
   10667             : 
   10668        4066 : char* Relocatable::Iterate(RootVisitor* v, char* thread_storage) {
   10669        4066 :   Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage);
   10670             :   Iterate(v, top);
   10671        4066 :   return thread_storage + ArchiveSpacePerThread();
   10672             : }
   10673             : 
   10674      240983 : void Relocatable::Iterate(Isolate* isolate, RootVisitor* v) {
   10675             :   Iterate(v, isolate->relocatable_top());
   10676      240983 : }
   10677             : 
   10678           0 : void Relocatable::Iterate(RootVisitor* v, Relocatable* top) {
   10679             :   Relocatable* current = top;
   10680      287038 :   while (current != NULL) {
   10681       41989 :     current->IterateInstance(v);
   10682       41989 :     current = current->prev_;
   10683             :   }
   10684           0 : }
   10685             : 
   10686             : 
   10687     1491694 : FlatStringReader::FlatStringReader(Isolate* isolate, Handle<String> str)
   10688             :     : Relocatable(isolate),
   10689             :       str_(str.location()),
   10690     4475082 :       length_(str->length()) {
   10691     1491694 :   PostGarbageCollection();
   10692     1491694 : }
   10693             : 
   10694             : 
   10695        3584 : FlatStringReader::FlatStringReader(Isolate* isolate, Vector<const char> input)
   10696             :     : Relocatable(isolate),
   10697             :       str_(0),
   10698             :       is_one_byte_(true),
   10699        3584 :       length_(input.length()),
   10700       10752 :       start_(input.start()) {}
   10701             : 
   10702             : 
   10703     1491783 : void FlatStringReader::PostGarbageCollection() {
   10704     1491783 :   if (str_ == NULL) return;
   10705             :   Handle<String> str(str_);
   10706             :   DCHECK(str->IsFlat());
   10707             :   DisallowHeapAllocation no_gc;
   10708             :   // This does not actually prevent the vector from being relocated later.
   10709     1491783 :   String::FlatContent content = str->GetFlatContent();
   10710             :   DCHECK(content.IsFlat());
   10711     2983566 :   is_one_byte_ = content.IsOneByte();
   10712     1491783 :   if (is_one_byte_) {
   10713     1352397 :     start_ = content.ToOneByteVector().start();
   10714             :   } else {
   10715      139386 :     start_ = content.ToUC16Vector().start();
   10716             :   }
   10717             : }
   10718             : 
   10719             : 
   10720       60578 : void ConsStringIterator::Initialize(ConsString* cons_string, int offset) {
   10721             :   DCHECK(cons_string != NULL);
   10722     6034467 :   root_ = cons_string;
   10723     6034467 :   consumed_ = offset;
   10724             :   // Force stack blown condition to trigger restart.
   10725     6034467 :   depth_ = 1;
   10726     6034467 :   maximum_depth_ = kStackSize + depth_;
   10727             :   DCHECK(StackBlown());
   10728       60578 : }
   10729             : 
   10730             : 
   10731    75784580 : String* ConsStringIterator::Continue(int* offset_out) {
   10732             :   DCHECK(depth_ != 0);
   10733             :   DCHECK_EQ(0, *offset_out);
   10734    75784580 :   bool blew_stack = StackBlown();
   10735             :   String* string = NULL;
   10736             :   // Get the next leaf if there is one.
   10737    75784580 :   if (!blew_stack) string = NextLeaf(&blew_stack);
   10738             :   // Restart search from root.
   10739    75784580 :   if (blew_stack) {
   10740             :     DCHECK(string == NULL);
   10741     6840741 :     string = Search(offset_out);
   10742             :   }
   10743             :   // Ensure future calls return null immediately.
   10744    75784580 :   if (string == NULL) Reset(NULL);
   10745    75784580 :   return string;
   10746             : }
   10747             : 
   10748             : 
   10749    13681308 : String* ConsStringIterator::Search(int* offset_out) {
   10750     6840741 :   ConsString* cons_string = root_;
   10751             :   // Reset the stack, pushing the root string.
   10752     6840741 :   depth_ = 1;
   10753     6840741 :   maximum_depth_ = 1;
   10754     6840741 :   frames_[0] = cons_string;
   10755     6840741 :   const int consumed = consumed_;
   10756             :   int offset = 0;
   10757             :   while (true) {
   10758             :     // Loop until the string is found which contains the target offset.
   10759             :     String* string = cons_string->first();
   10760             :     int length = string->length();
   10761             :     int32_t type;
   10762 23686761841 :     if (consumed < offset + length) {
   10763             :       // Target offset is in the left branch.
   10764             :       // Keep going if we're still in a ConString.
   10765             :       type = string->map()->instance_type();
   10766 23684386707 :       if ((type & kStringRepresentationMask) == kConsStringTag) {
   10767             :         cons_string = ConsString::cast(string);
   10768             :         PushLeft(cons_string);
   10769             :         continue;
   10770             :       }
   10771             :       // Tell the stack we're done descending.
   10772             :       AdjustMaximumDepth();
   10773             :     } else {
   10774             :       // Descend right.
   10775             :       // Update progress through the string.
   10776             :       offset += length;
   10777             :       // Keep going if we're still in a ConString.
   10778             :       string = cons_string->second();
   10779             :       type = string->map()->instance_type();
   10780     2375134 :       if ((type & kStringRepresentationMask) == kConsStringTag) {
   10781             :         cons_string = ConsString::cast(string);
   10782             :         PushRight(cons_string);
   10783             :         continue;
   10784             :       }
   10785             :       // Need this to be updated for the current string.
   10786             :       length = string->length();
   10787             :       // Account for the possibility of an empty right leaf.
   10788             :       // This happens only if we have asked for an offset outside the string.
   10789      770020 :       if (length == 0) {
   10790             :         // Reset so future operations will return null immediately.
   10791             :         Reset(NULL);
   10792         174 :         return NULL;
   10793             :       }
   10794             :       // Tell the stack we're done descending.
   10795             :       AdjustMaximumDepth();
   10796             :       // Pop stack so next iteration is in correct place.
   10797             :       Pop();
   10798             :     }
   10799             :     DCHECK(length != 0);
   10800             :     // Adjust return values and exit.
   10801     6840567 :     consumed_ = offset + length;
   10802     6840567 :     *offset_out = consumed - offset;
   10803     6840567 :     return string;
   10804             :   }
   10805             :   UNREACHABLE();
   10806             :   return NULL;
   10807             : }
   10808             : 
   10809             : 
   10810   152826869 : String* ConsStringIterator::NextLeaf(bool* blew_stack) {
   10811             :   while (true) {
   10812             :     // Tree traversal complete.
   10813    69537660 :     if (depth_ == 0) {
   10814        6995 :       *blew_stack = false;
   10815        6995 :       return NULL;
   10816             :     }
   10817             :     // We've lost track of higher nodes.
   10818    69530665 :     if (StackBlown()) {
   10819         834 :       *blew_stack = true;
   10820         834 :       return NULL;
   10821             :     }
   10822             :     // Go right.
   10823   139059662 :     ConsString* cons_string = frames_[OffsetForDepth(depth_ - 1)];
   10824             :     String* string = cons_string->second();
   10825             :     int32_t type = string->map()->instance_type();
   10826    69529831 :     if ((type & kStringRepresentationMask) != kConsStringTag) {
   10827             :       // Pop stack so next iteration is in correct place.
   10828             :       Pop();
   10829             :       int length = string->length();
   10830             :       // Could be a flattened ConsString.
   10831    55178300 :       if (length == 0) continue;
   10832    54585313 :       consumed_ += length;
   10833    54585313 :       return string;
   10834             :     }
   10835             :     cons_string = ConsString::cast(string);
   10836             :     PushRight(cons_string);
   10837             :     // Need to traverse all the way left.
   10838             :     while (true) {
   10839             :       // Continue left.
   10840             :       string = cons_string->first();
   10841             :       type = string->map()->instance_type();
   10842    23762821 :       if ((type & kStringRepresentationMask) != kConsStringTag) {
   10843             :         AdjustMaximumDepth();
   10844             :         int length = string->length();
   10845    14351531 :         if (length == 0) break;  // Skip empty left-hand sides of ConsStrings.
   10846    14351531 :         consumed_ += length;
   10847    14351531 :         return string;
   10848             :       }
   10849             :       cons_string = ConsString::cast(string);
   10850             :       PushLeft(cons_string);
   10851             :     }
   10852             :   }
   10853             :   UNREACHABLE();
   10854             :   return NULL;
   10855             : }
   10856             : 
   10857             : 
   10858     4320981 : uint16_t ConsString::ConsStringGet(int index) {
   10859             :   DCHECK(index >= 0 && index < this->length());
   10860             : 
   10861             :   // Check for a flattened cons string
   10862     4320981 :   if (second()->length() == 0) {
   10863             :     String* left = first();
   10864      374002 :     return left->Get(index);
   10865             :   }
   10866             : 
   10867             :   String* string = String::cast(this);
   10868             : 
   10869             :   while (true) {
   10870    42982425 :     if (StringShape(string).IsCons()) {
   10871             :       ConsString* cons_string = ConsString::cast(string);
   10872             :       String* left = cons_string->first();
   10873    39035446 :       if (left->length() > index) {
   10874             :         string = left;
   10875             :       } else {
   10876      488981 :         index -= left->length();
   10877             :         string = cons_string->second();
   10878             :       }
   10879             :     } else {
   10880     3946979 :       return string->Get(index);
   10881             :     }
   10882             :   }
   10883             : 
   10884             :   UNREACHABLE();
   10885             :   return 0;
   10886             : }
   10887             : 
   10888         516 : uint16_t ThinString::ThinStringGet(int index) { return actual()->Get(index); }
   10889             : 
   10890     1816864 : uint16_t SlicedString::SlicedStringGet(int index) {
   10891     3633728 :   return parent()->Get(offset() + index);
   10892             : }
   10893             : 
   10894             : 
   10895             : template <typename sinkchar>
   10896   277422127 : void String::WriteToFlat(String* src,
   10897             :                          sinkchar* sink,
   10898             :                          int f,
   10899             :                          int t) {
   10900             :   String* source = src;
   10901             :   int from = f;
   10902             :   int to = t;
   10903             :   while (true) {
   10904             :     DCHECK(0 <= from && from <= to && to <= source->length());
   10905   372456848 :     switch (StringShape(source).full_representation_tag()) {
   10906             :       case kOneByteStringTag | kExternalStringTag: {
   10907             :         CopyChars(sink, ExternalOneByteString::cast(source)->GetChars() + from,
   10908      996924 :                   to - from);
   10909             :         return;
   10910             :       }
   10911             :       case kTwoByteStringTag | kExternalStringTag: {
   10912             :         const uc16* data =
   10913             :             ExternalTwoByteString::cast(source)->GetChars();
   10914             :         CopyChars(sink,
   10915             :                   data + from,
   10916      340890 :                   to - from);
   10917             :         return;
   10918             :       }
   10919             :       case kOneByteStringTag | kSeqStringTag: {
   10920             :         CopyChars(sink,
   10921   244915746 :                   SeqOneByteString::cast(source)->GetChars() + from,
   10922   489831492 :                   to - from);
   10923             :         return;
   10924             :       }
   10925             :       case kTwoByteStringTag | kSeqStringTag: {
   10926             :         CopyChars(sink,
   10927    12055638 :                   SeqTwoByteString::cast(source)->GetChars() + from,
   10928    24111276 :                   to - from);
   10929             :         return;
   10930             :       }
   10931             :       case kOneByteStringTag | kConsStringTag:
   10932             :       case kTwoByteStringTag | kConsStringTag: {
   10933             :         ConsString* cons_string = ConsString::cast(source);
   10934             :         String* first = cons_string->first();
   10935             :         int boundary = first->length();
   10936   112533580 :         if (to - boundary >= boundary - from) {
   10937             :           // Right hand side is longer.  Recurse over left.
   10938    30928445 :           if (from < boundary) {
   10939    30928445 :             WriteToFlat(first, sink, from, boundary);
   10940    61856890 :             if (from == 0 && cons_string->second() == first) {
   10941    17531267 :               CopyChars(sink + boundary, sink, boundary);
   10942             :               return;
   10943             :             }
   10944    13397178 :             sink += boundary - from;
   10945             :             from = 0;
   10946             :           } else {
   10947           0 :             from -= boundary;
   10948             :           }
   10949             :           to -= boundary;
   10950             :           source = cons_string->second();
   10951             :         } else {
   10952             :           // Left hand side is longer.  Recurse over right.
   10953    81605135 :           if (to > boundary) {
   10954             :             String* second = cons_string->second();
   10955             :             // When repeatedly appending to a string, we get a cons string that
   10956             :             // is unbalanced to the left, a list, essentially.  We inline the
   10957             :             // common case of sequential one-byte right child.
   10958    81036711 :             if (to - boundary == 1) {
   10959    72450806 :               sink[boundary - from] = static_cast<sinkchar>(second->Get(0));
   10960    44811308 :             } else if (second->IsSeqOneByteString()) {
   10961    38379751 :               CopyChars(sink + boundary - from,
   10962    38379751 :                         SeqOneByteString::cast(second)->GetChars(),
   10963    76759502 :                         to - boundary);
   10964             :             } else {
   10965     6431557 :               WriteToFlat(second,
   10966     6431557 :                           sink + boundary - from,
   10967             :                           0,
   10968     6431557 :                           to - boundary);
   10969             :             }
   10970             :             to = boundary;
   10971             :           }
   10972             :           source = first;
   10973             :         }
   10974             :         break;
   10975             :       }
   10976             :       case kOneByteStringTag | kSlicedStringTag:
   10977             :       case kTwoByteStringTag | kSlicedStringTag: {
   10978             :         SlicedString* slice = SlicedString::cast(source);
   10979     2080123 :         unsigned offset = slice->offset();
   10980     4160246 :         WriteToFlat(slice->parent(), sink, from + offset, to + offset);
   10981     2080123 :         return;
   10982             :       }
   10983             :       case kOneByteStringTag | kThinStringTag:
   10984             :       case kTwoByteStringTag | kThinStringTag:
   10985             :         source = ThinString::cast(source)->actual();
   10986       32409 :         break;
   10987             :     }
   10988             :   }
   10989             : }
   10990             : 
   10991             : 
   10992             : 
   10993             : template <typename SourceChar>
   10994      129928 : static void CalculateLineEndsImpl(Isolate* isolate,
   10995             :                                   List<int>* line_ends,
   10996             :                                   Vector<const SourceChar> src,
   10997             :                                   bool include_ending_line) {
   10998       64964 :   const int src_len = src.length();
   10999             :   UnicodeCache* cache = isolate->unicode_cache();
   11000   330207931 :   for (int i = 0; i < src_len - 1; i++) {
   11001   330142967 :     SourceChar current = src[i];
   11002   660285934 :     SourceChar next = src[i + 1];
   11003   330142967 :     if (cache->IsLineTerminatorSequence(current, next)) line_ends->Add(i);
   11004             :   }
   11005             : 
   11006      129438 :   if (src_len > 0 && cache->IsLineTerminatorSequence(src[src_len - 1], 0)) {
   11007       23333 :     line_ends->Add(src_len - 1);
   11008             :   }
   11009       64964 :   if (include_ending_line) {
   11010             :     // Include one character beyond the end of script. The rewriter uses that
   11011             :     // position for the implicit return statement.
   11012       63124 :     line_ends->Add(src_len);
   11013             :   }
   11014       64964 : }
   11015             : 
   11016             : 
   11017       64964 : Handle<FixedArray> String::CalculateLineEnds(Handle<String> src,
   11018             :                                              bool include_ending_line) {
   11019       64964 :   src = Flatten(src);
   11020             :   // Rough estimate of line count based on a roughly estimated average
   11021             :   // length of (unpacked) code.
   11022       64964 :   int line_count_estimate = src->length() >> 4;
   11023             :   List<int> line_ends(line_count_estimate);
   11024             :   Isolate* isolate = src->GetIsolate();
   11025             :   { DisallowHeapAllocation no_allocation;  // ensure vectors stay valid.
   11026             :     // Dispatch on type of strings.
   11027       64964 :     String::FlatContent content = src->GetFlatContent();
   11028             :     DCHECK(content.IsFlat());
   11029       64964 :     if (content.IsOneByte()) {
   11030             :       CalculateLineEndsImpl(isolate,
   11031             :                             &line_ends,
   11032             :                             content.ToOneByteVector(),
   11033       64358 :                             include_ending_line);
   11034             :     } else {
   11035             :       CalculateLineEndsImpl(isolate,
   11036             :                             &line_ends,
   11037             :                             content.ToUC16Vector(),
   11038         606 :                             include_ending_line);
   11039             :     }
   11040             :   }
   11041       64964 :   int line_count = line_ends.length();
   11042       64964 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
   11043    14930848 :   for (int i = 0; i < line_count; i++) {
   11044    29731768 :     array->set(i, Smi::FromInt(line_ends[i]));
   11045             :   }
   11046      129928 :   return array;
   11047             : }
   11048             : 
   11049             : 
   11050             : // Compares the contents of two strings by reading and comparing
   11051             : // int-sized blocks of characters.
   11052             : template <typename Char>
   11053             : static inline bool CompareRawStringContents(const Char* const a,
   11054             :                                             const Char* const b,
   11055             :                                             int length) {
   11056   106096322 :   return CompareChars(a, b, length) == 0;
   11057             : }
   11058             : 
   11059             : 
   11060             : template<typename Chars1, typename Chars2>
   11061             : class RawStringComparator : public AllStatic {
   11062             :  public:
   11063             :   static inline bool compare(const Chars1* a, const Chars2* b, int len) {
   11064             :     DCHECK(sizeof(Chars1) != sizeof(Chars2));
   11065     1322694 :     for (int i = 0; i < len; i++) {
   11066     1322738 :       if (a[i] != b[i]) {
   11067             :         return false;
   11068             :       }
   11069             :     }
   11070             :     return true;
   11071             :   }
   11072             : };
   11073             : 
   11074             : 
   11075             : template<>
   11076             : class RawStringComparator<uint16_t, uint16_t> {
   11077             :  public:
   11078             :   static inline bool compare(const uint16_t* a, const uint16_t* b, int len) {
   11079             :     return CompareRawStringContents(a, b, len);
   11080             :   }
   11081             : };
   11082             : 
   11083             : 
   11084             : template<>
   11085             : class RawStringComparator<uint8_t, uint8_t> {
   11086             :  public:
   11087             :   static inline bool compare(const uint8_t* a, const uint8_t* b, int len) {
   11088             :     return CompareRawStringContents(a, b, len);
   11089             :   }
   11090             : };
   11091             : 
   11092             : 
   11093             : class StringComparator {
   11094             :   class State {
   11095             :    public:
   11096     6157820 :     State() : is_one_byte_(true), length_(0), buffer8_(NULL) {}
   11097             : 
   11098    12315640 :     void Init(String* string) {
   11099    12315640 :       ConsString* cons_string = String::VisitFlat(this, string);
   11100             :       iter_.Reset(cons_string);
   11101    12315640 :       if (cons_string != NULL) {
   11102             :         int offset;
   11103     3741594 :         string = iter_.Next(&offset);
   11104     3741594 :         String::VisitFlat(this, string, offset);
   11105             :       }
   11106    12315640 :     }
   11107             : 
   11108             :     inline void VisitOneByteString(const uint8_t* chars, int length) {
   11109    50970706 :       is_one_byte_ = true;
   11110    50970706 :       buffer8_ = chars;
   11111    50970706 :       length_ = length;
   11112             :     }
   11113             : 
   11114             :     inline void VisitTwoByteString(const uint16_t* chars, int length) {
   11115     7882781 :       is_one_byte_ = false;
   11116     7882781 :       buffer16_ = chars;
   11117     7882781 :       length_ = length;
   11118             :     }
   11119             : 
   11120    56481012 :     void Advance(int consumed) {
   11121             :       DCHECK(consumed <= length_);
   11122             :       // Still in buffer.
   11123    56481012 :       if (length_ != consumed) {
   11124     9943165 :         if (is_one_byte_) {
   11125     9858799 :           buffer8_ += consumed;
   11126             :         } else {
   11127       84366 :           buffer16_ += consumed;
   11128             :         }
   11129     9943165 :         length_ -= consumed;
   11130    66424177 :         return;
   11131             :       }
   11132             :       // Advance state.
   11133             :       int offset;
   11134    46537847 :       String* next = iter_.Next(&offset);
   11135             :       DCHECK_EQ(0, offset);
   11136             :       DCHECK(next != NULL);
   11137    46537847 :       String::VisitFlat(this, next);
   11138             :     }
   11139             : 
   11140             :     ConsStringIterator iter_;
   11141             :     bool is_one_byte_;
   11142             :     int length_;
   11143             :     union {
   11144             :       const uint8_t* buffer8_;
   11145             :       const uint16_t* buffer16_;
   11146             :     };
   11147             : 
   11148             :    private:
   11149             :     DISALLOW_COPY_AND_ASSIGN(State);
   11150             :   };
   11151             : 
   11152             :  public:
   11153             :   inline StringComparator() {}
   11154             : 
   11155             :   template<typename Chars1, typename Chars2>
   11156             :   static inline bool Equals(State* state_1, State* state_2, int to_check) {
   11157             :     const Chars1* a = reinterpret_cast<const Chars1*>(state_1->buffer8_);
   11158             :     const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_);
   11159             :     return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check);
   11160             :   }
   11161             : 
   11162     6157820 :   bool Equals(String* string_1, String* string_2) {
   11163             :     int length = string_1->length();
   11164    40556146 :     state_1_.Init(string_1);
   11165    40556146 :     state_2_.Init(string_2);
   11166             :     while (true) {
   11167    34398326 :       int to_check = Min(state_1_.length_, state_2_.length_);
   11168             :       DCHECK(to_check > 0 && to_check <= length);
   11169             :       bool is_equal;
   11170    34398326 :       if (state_1_.is_one_byte_) {
   11171    30367390 :         if (state_2_.is_one_byte_) {
   11172             :           is_equal = Equals<uint8_t, uint8_t>(&state_1_, &state_2_, to_check);
   11173             :         } else {
   11174             :           is_equal = Equals<uint8_t, uint16_t>(&state_1_, &state_2_, to_check);
   11175             :         }
   11176             :       } else {
   11177     4030936 :         if (state_2_.is_one_byte_) {
   11178             :           is_equal = Equals<uint16_t, uint8_t>(&state_1_, &state_2_, to_check);
   11179             :         } else {
   11180             :           is_equal = Equals<uint16_t, uint16_t>(&state_1_, &state_2_, to_check);
   11181             :         }
   11182             :       }
   11183             :       // Looping done.
   11184    34398326 :       if (!is_equal) return false;
   11185    34385549 :       length -= to_check;
   11186             :       // Exit condition. Strings are equal.
   11187    34385549 :       if (length == 0) return true;
   11188    28240506 :       state_1_.Advance(to_check);
   11189    28240506 :       state_2_.Advance(to_check);
   11190    28240506 :     }
   11191             :   }
   11192             : 
   11193             :  private:
   11194             :   State state_1_;
   11195             :   State state_2_;
   11196             : 
   11197             :   DISALLOW_COPY_AND_ASSIGN(StringComparator);
   11198             : };
   11199             : 
   11200             : 
   11201    35267732 : bool String::SlowEquals(String* other) {
   11202             :   DisallowHeapAllocation no_gc;
   11203             :   // Fast check: negative check with lengths.
   11204             :   int len = length();
   11205    35267732 :   if (len != other->length()) return false;
   11206    26104648 :   if (len == 0) return true;
   11207             : 
   11208             :   // Fast check: if at least one ThinString is involved, dereference it/them
   11209             :   // and restart.
   11210    52208043 :   if (this->IsThinString() || other->IsThinString()) {
   11211        4960 :     if (other->IsThinString()) other = ThinString::cast(other)->actual();
   11212        4960 :     if (this->IsThinString()) {
   11213        1252 :       return ThinString::cast(this)->actual()->Equals(other);
   11214             :     } else {
   11215        3708 :       return this->Equals(other);
   11216             :     }
   11217             :   }
   11218             : 
   11219             :   // Fast check: if hash code is computed for both strings
   11220             :   // a fast negative check can be performed.
   11221    51851719 :   if (HasHashCode() && other->HasHashCode()) {
   11222             : #ifdef ENABLE_SLOW_DCHECKS
   11223             :     if (FLAG_enable_slow_asserts) {
   11224             :       if (Hash() != other->Hash()) {
   11225             :         bool found_difference = false;
   11226             :         for (int i = 0; i < len; i++) {
   11227             :           if (Get(i) != other->Get(i)) {
   11228             :             found_difference = true;
   11229             :             break;
   11230             :           }
   11231             :         }
   11232             :         DCHECK(found_difference);
   11233             :       }
   11234             :     }
   11235             : #endif
   11236    25750928 :     if (Hash() != other->Hash()) return false;
   11237             :   }
   11238             : 
   11239             :   // We know the strings are both non-empty. Compare the first chars
   11240             :   // before we try to flatten the strings.
   11241    23614123 :   if (this->Get(0) != other->Get(0)) return false;
   11242             : 
   11243    41722343 :   if (IsSeqOneByteString() && other->IsSeqOneByteString()) {
   11244    17454798 :     const uint8_t* str1 = SeqOneByteString::cast(this)->GetChars();
   11245    17454798 :     const uint8_t* str2 = SeqOneByteString::cast(other)->GetChars();
   11246    17454798 :     return CompareRawStringContents(str1, str2, len);
   11247             :   }
   11248             : 
   11249             :   StringComparator comparator;
   11250     6157820 :   return comparator.Equals(this, other);
   11251             : }
   11252             : 
   11253             : 
   11254     6451089 : bool String::SlowEquals(Handle<String> one, Handle<String> two) {
   11255             :   // Fast check: negative check with lengths.
   11256             :   int one_length = one->length();
   11257     6451089 :   if (one_length != two->length()) return false;
   11258     6411202 :   if (one_length == 0) return true;
   11259             : 
   11260             :   // Fast check: if at least one ThinString is involved, dereference it/them
   11261             :   // and restart.
   11262    12822404 :   if (one->IsThinString() || two->IsThinString()) {
   11263          19 :     if (one->IsThinString()) one = handle(ThinString::cast(*one)->actual());
   11264          19 :     if (two->IsThinString()) two = handle(ThinString::cast(*two)->actual());
   11265          19 :     return String::Equals(one, two);
   11266             :   }
   11267             : 
   11268             :   // Fast check: if hash code is computed for both strings
   11269             :   // a fast negative check can be performed.
   11270     6427839 :   if (one->HasHashCode() && two->HasHashCode()) {
   11271             : #ifdef ENABLE_SLOW_DCHECKS
   11272             :     if (FLAG_enable_slow_asserts) {
   11273             :       if (one->Hash() != two->Hash()) {
   11274             :         bool found_difference = false;
   11275             :         for (int i = 0; i < one_length; i++) {
   11276             :           if (one->Get(i) != two->Get(i)) {
   11277             :             found_difference = true;
   11278             :             break;
   11279             :           }
   11280             :         }
   11281             :         DCHECK(found_difference);
   11282             :       }
   11283             :     }
   11284             : #endif
   11285        3656 :     if (one->Hash() != two->Hash()) return false;
   11286             :   }
   11287             : 
   11288             :   // We know the strings are both non-empty. Compare the first chars
   11289             :   // before we try to flatten the strings.
   11290     6411167 :   if (one->Get(0) != two->Get(0)) return false;
   11291             : 
   11292     4391484 :   one = String::Flatten(one);
   11293     4391484 :   two = String::Flatten(two);
   11294             : 
   11295             :   DisallowHeapAllocation no_gc;
   11296     4391484 :   String::FlatContent flat1 = one->GetFlatContent();
   11297     4391484 :   String::FlatContent flat2 = two->GetFlatContent();
   11298             : 
   11299     4391484 :   if (flat1.IsOneByte() && flat2.IsOneByte()) {
   11300             :       return CompareRawStringContents(flat1.ToOneByteVector().start(),
   11301             :                                       flat2.ToOneByteVector().start(),
   11302             :                                       one_length);
   11303             :   } else {
   11304    20597132 :     for (int i = 0; i < one_length; i++) {
   11305    20597132 :       if (flat1.Get(i) != flat2.Get(i)) return false;
   11306             :     }
   11307             :     return true;
   11308             :   }
   11309             : }
   11310             : 
   11311             : 
   11312             : // static
   11313     7363753 : ComparisonResult String::Compare(Handle<String> x, Handle<String> y) {
   11314             :   // A few fast case tests before we flatten.
   11315     7363753 :   if (x.is_identical_to(y)) {
   11316             :     return ComparisonResult::kEqual;
   11317     7363238 :   } else if (y->length() == 0) {
   11318             :     return x->length() == 0 ? ComparisonResult::kEqual
   11319           0 :                             : ComparisonResult::kGreaterThan;
   11320     7363238 :   } else if (x->length() == 0) {
   11321             :     return ComparisonResult::kLessThan;
   11322             :   }
   11323             : 
   11324    14726476 :   int const d = x->Get(0) - y->Get(0);
   11325     7363238 :   if (d < 0) {
   11326             :     return ComparisonResult::kLessThan;
   11327     5847955 :   } else if (d > 0) {
   11328             :     return ComparisonResult::kGreaterThan;
   11329             :   }
   11330             : 
   11331             :   // Slow case.
   11332       30338 :   x = String::Flatten(x);
   11333       30338 :   y = String::Flatten(y);
   11334             : 
   11335             :   DisallowHeapAllocation no_gc;
   11336             :   ComparisonResult result = ComparisonResult::kEqual;
   11337             :   int prefix_length = x->length();
   11338       30338 :   if (y->length() < prefix_length) {
   11339             :     prefix_length = y->length();
   11340             :     result = ComparisonResult::kGreaterThan;
   11341       30338 :   } else if (y->length() > prefix_length) {
   11342             :     result = ComparisonResult::kLessThan;
   11343             :   }
   11344             :   int r;
   11345       30338 :   String::FlatContent x_content = x->GetFlatContent();
   11346       30338 :   String::FlatContent y_content = y->GetFlatContent();
   11347       30338 :   if (x_content.IsOneByte()) {
   11348             :     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
   11349        3303 :     if (y_content.IsOneByte()) {
   11350             :       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   11351          55 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11352             :     } else {
   11353             :       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   11354        3248 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11355             :     }
   11356             :   } else {
   11357             :     Vector<const uc16> x_chars = x_content.ToUC16Vector();
   11358       27035 :     if (y_content.IsOneByte()) {
   11359             :       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   11360        1624 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11361             :     } else {
   11362             :       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   11363       25411 :       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   11364             :     }
   11365             :   }
   11366       30338 :   if (r < 0) {
   11367             :     result = ComparisonResult::kLessThan;
   11368       18299 :   } else if (r > 0) {
   11369             :     result = ComparisonResult::kGreaterThan;
   11370             :   }
   11371       30338 :   return result;
   11372             : }
   11373             : 
   11374        3383 : Object* String::IndexOf(Isolate* isolate, Handle<Object> receiver,
   11375             :                         Handle<Object> search, Handle<Object> position) {
   11376        3383 :   if (receiver->IsNullOrUndefined(isolate)) {
   11377         900 :     THROW_NEW_ERROR_RETURN_FAILURE(
   11378             :         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
   11379             :                               isolate->factory()->NewStringFromAsciiChecked(
   11380             :                                   "String.prototype.indexOf")));
   11381             :   }
   11382             :   Handle<String> receiver_string;
   11383        6166 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_string,
   11384             :                                      Object::ToString(isolate, receiver));
   11385             : 
   11386             :   Handle<String> search_string;
   11387        6166 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, search_string,
   11388             :                                      Object::ToString(isolate, search));
   11389             : 
   11390        3083 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   11391             :                                      Object::ToInteger(isolate, position));
   11392             : 
   11393             :   uint32_t index = receiver_string->ToValidIndex(*position);
   11394             :   return Smi::FromInt(
   11395        6166 :       String::IndexOf(isolate, receiver_string, search_string, index));
   11396             : }
   11397             : 
   11398             : namespace {
   11399             : 
   11400             : template <typename T>
   11401      183143 : int SearchString(Isolate* isolate, String::FlatContent receiver_content,
   11402         240 :                  Vector<T> pat_vector, int start_index) {
   11403      183143 :   if (receiver_content.IsOneByte()) {
   11404             :     return SearchString(isolate, receiver_content.ToOneByteVector(), pat_vector,
   11405      182674 :                         start_index);
   11406             :   }
   11407             :   return SearchString(isolate, receiver_content.ToUC16Vector(), pat_vector,
   11408         469 :                       start_index);
   11409             : }
   11410             : 
   11411             : }  // namespace
   11412             : 
   11413      187332 : int String::IndexOf(Isolate* isolate, Handle<String> receiver,
   11414             :                     Handle<String> search, int start_index) {
   11415             :   DCHECK(0 <= start_index);
   11416             :   DCHECK(start_index <= receiver->length());
   11417             : 
   11418      187332 :   uint32_t search_length = search->length();
   11419      187332 :   if (search_length == 0) return start_index;
   11420             : 
   11421      187218 :   uint32_t receiver_length = receiver->length();
   11422      187218 :   if (start_index + search_length > receiver_length) return -1;
   11423             : 
   11424      183143 :   receiver = String::Flatten(receiver);
   11425      183143 :   search = String::Flatten(search);
   11426             : 
   11427             :   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   11428             :   // Extract flattened substrings of cons strings before getting encoding.
   11429      183143 :   String::FlatContent receiver_content = receiver->GetFlatContent();
   11430      183143 :   String::FlatContent search_content = search->GetFlatContent();
   11431             : 
   11432             :   // dispatch on type of strings
   11433      183143 :   if (search_content.IsOneByte()) {
   11434             :     Vector<const uint8_t> pat_vector = search_content.ToOneByteVector();
   11435             :     return SearchString<const uint8_t>(isolate, receiver_content, pat_vector,
   11436      179993 :                                        start_index);
   11437             :   }
   11438        3150 :   Vector<const uc16> pat_vector = search_content.ToUC16Vector();
   11439             :   return SearchString<const uc16>(isolate, receiver_content, pat_vector,
   11440        3150 :                                   start_index);
   11441             : }
   11442             : 
   11443        5600 : MaybeHandle<String> String::GetSubstitution(Isolate* isolate, Match* match,
   11444             :                                             Handle<String> replacement,
   11445             :                                             int start_index) {
   11446             :   DCHECK_IMPLIES(match->HasNamedCaptures(), FLAG_harmony_regexp_named_captures);
   11447             :   DCHECK_GE(start_index, 0);
   11448             : 
   11449             :   Factory* factory = isolate->factory();
   11450             : 
   11451             :   const int replacement_length = replacement->length();
   11452        5600 :   const int captures_length = match->CaptureCount();
   11453             : 
   11454        5600 :   replacement = String::Flatten(replacement);
   11455             : 
   11456             :   Handle<String> dollar_string =
   11457        5600 :       factory->LookupSingleCharacterStringFromCode('$');
   11458             :   int next_dollar_ix =
   11459        5600 :       String::IndexOf(isolate, replacement, dollar_string, start_index);
   11460        5600 :   if (next_dollar_ix < 0) {
   11461             :     return replacement;
   11462             :   }
   11463             : 
   11464        5525 :   IncrementalStringBuilder builder(isolate);
   11465             : 
   11466        5525 :   if (next_dollar_ix > 0) {
   11467         465 :     builder.AppendString(factory->NewSubString(replacement, 0, next_dollar_ix));
   11468             :   }
   11469             : 
   11470             :   while (true) {
   11471       12473 :     const int peek_ix = next_dollar_ix + 1;
   11472       12473 :     if (peek_ix >= replacement_length) {
   11473             :       builder.AppendCharacter('$');
   11474          30 :       return builder.Finish();
   11475             :     }
   11476             : 
   11477             :     int continue_from_ix = -1;
   11478             :     const uint16_t peek = replacement->Get(peek_ix);
   11479       12443 :     switch (peek) {
   11480             :       case '$':  // $$
   11481             :         builder.AppendCharacter('$');
   11482          90 :         continue_from_ix = peek_ix + 1;
   11483          90 :         break;
   11484             :       case '&':  // $& - match
   11485          90 :         builder.AppendString(match->GetMatch());
   11486          90 :         continue_from_ix = peek_ix + 1;
   11487          90 :         break;
   11488             :       case '`':  // $` - prefix
   11489          60 :         builder.AppendString(match->GetPrefix());
   11490          60 :         continue_from_ix = peek_ix + 1;
   11491          60 :         break;
   11492             :       case '\'':  // $' - suffix
   11493          60 :         builder.AppendString(match->GetSuffix());
   11494          60 :         continue_from_ix = peek_ix + 1;
   11495          60 :         break;
   11496             :       case '0':
   11497             :       case '1':
   11498             :       case '2':
   11499             :       case '3':
   11500             :       case '4':
   11501             :       case '5':
   11502             :       case '6':
   11503             :       case '7':
   11504             :       case '8':
   11505             :       case '9': {
   11506             :         // Valid indices are $1 .. $9, $01 .. $09 and $10 .. $99
   11507       11678 :         int scaled_index = (peek - '0');
   11508             :         int advance = 1;
   11509             : 
   11510       11678 :         if (peek_ix + 1 < replacement_length) {
   11511             :           const uint16_t next_peek = replacement->Get(peek_ix + 1);
   11512        9731 :           if (next_peek >= '0' && next_peek <= '9') {
   11513        2235 :             const int new_scaled_index = scaled_index * 10 + (next_peek - '0');
   11514        2235 :             if (new_scaled_index < captures_length) {
   11515             :               scaled_index = new_scaled_index;
   11516             :               advance = 2;
   11517             :             }
   11518             :           }
   11519             :         }
   11520             : 
   11521       11678 :         if (scaled_index == 0 || scaled_index >= captures_length) {
   11522             :           builder.AppendCharacter('$');
   11523             :           continue_from_ix = peek_ix;
   11524       11828 :           break;
   11525             :         }
   11526             : 
   11527             :         bool capture_exists;
   11528             :         Handle<String> capture;
   11529       23056 :         ASSIGN_RETURN_ON_EXCEPTION(
   11530             :             isolate, capture, match->GetCapture(scaled_index, &capture_exists),
   11531             :             String);
   11532       11528 :         if (capture_exists) builder.AppendString(capture);
   11533       11528 :         continue_from_ix = peek_ix + advance;
   11534       11528 :         break;
   11535             :       }
   11536             :       case '<': {  // $<name> - named capture
   11537             :         typedef String::Match::CaptureState CaptureState;
   11538             : 
   11539         420 :         if (!match->HasNamedCaptures()) {
   11540             :           builder.AppendCharacter('$');
   11541             :           continue_from_ix = peek_ix;
   11542         336 :           break;
   11543             :         }
   11544             : 
   11545             :         Handle<String> bracket_string =
   11546         336 :             factory->LookupSingleCharacterStringFromCode('>');
   11547             :         const int closing_bracket_ix =
   11548         336 :             String::IndexOf(isolate, replacement, bracket_string, peek_ix + 1);
   11549             : 
   11550         336 :         if (closing_bracket_ix == -1) {
   11551          84 :           THROW_NEW_ERROR(
   11552             :               isolate,
   11553             :               NewSyntaxError(MessageTemplate::kRegExpInvalidReplaceString,
   11554             :                              replacement),
   11555             :               String);
   11556             :         }
   11557             : 
   11558             :         Handle<String> capture_name =
   11559         294 :             factory->NewSubString(replacement, peek_ix + 1, closing_bracket_ix);
   11560             :         Handle<String> capture;
   11561             :         CaptureState capture_state;
   11562         588 :         ASSIGN_RETURN_ON_EXCEPTION(
   11563             :             isolate, capture,
   11564             :             match->GetNamedCapture(capture_name, &capture_state), String);
   11565             : 
   11566         294 :         switch (capture_state) {
   11567             :           case CaptureState::INVALID:
   11568         252 :             THROW_NEW_ERROR(
   11569             :                 isolate,
   11570             :                 NewSyntaxError(MessageTemplate::kRegExpInvalidReplaceString,
   11571             :                                replacement),
   11572             :                 String);
   11573             :             break;
   11574             :           case CaptureState::UNMATCHED:
   11575             :             break;
   11576             :           case CaptureState::MATCHED:
   11577         112 :             builder.AppendString(capture);
   11578         112 :             break;
   11579             :         }
   11580             : 
   11581         168 :         continue_from_ix = closing_bracket_ix + 1;
   11582         168 :         break;
   11583             :       }
   11584             :       default:
   11585             :         builder.AppendCharacter('$');
   11586             :         continue_from_ix = peek_ix;
   11587          45 :         break;
   11588             :     }
   11589             : 
   11590             :     // Go the the next $ in the replacement.
   11591             :     // TODO(jgruber): Single-char lookups could be much more efficient.
   11592             :     DCHECK_NE(continue_from_ix, -1);
   11593             :     next_dollar_ix =
   11594       12275 :         String::IndexOf(isolate, replacement, dollar_string, continue_from_ix);
   11595             : 
   11596             :     // Return if there are no more $ characters in the replacement. If we
   11597             :     // haven't reached the end, we need to append the suffix.
   11598       12275 :     if (next_dollar_ix < 0) {
   11599        5327 :       if (continue_from_ix < replacement_length) {
   11600             :         builder.AppendString(factory->NewSubString(
   11601        1738 :             replacement, continue_from_ix, replacement_length));
   11602             :       }
   11603        5327 :       return builder.Finish();
   11604             :     }
   11605             : 
   11606             :     // Append substring between the previous and the next $ character.
   11607        6948 :     if (next_dollar_ix > continue_from_ix) {
   11608             :       builder.AppendString(
   11609          42 :           factory->NewSubString(replacement, continue_from_ix, next_dollar_ix));
   11610             :     }
   11611             :   }
   11612             : 
   11613             :   UNREACHABLE();
   11614             :   return MaybeHandle<String>();
   11615             : }
   11616             : 
   11617             : namespace {  // for String.Prototype.lastIndexOf
   11618             : 
   11619             : template <typename schar, typename pchar>
   11620        2260 : int StringMatchBackwards(Vector<const schar> subject,
   11621             :                          Vector<const pchar> pattern, int idx) {
   11622        2260 :   int pattern_length = pattern.length();
   11623             :   DCHECK(pattern_length >= 1);
   11624             :   DCHECK(idx + pattern_length <= subject.length());
   11625             : 
   11626             :   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
   11627           0 :     for (int i = 0; i < pattern_length; i++) {
   11628           0 :       uc16 c = pattern[i];
   11629           0 :       if (c > String::kMaxOneByteCharCode) {
   11630             :         return -1;
   11631             :       }
   11632             :     }
   11633             :   }
   11634             : 
   11635        2260 :   pchar pattern_first_char = pattern[0];
   11636        8229 :   for (int i = idx; i >= 0; i--) {
   11637       10210 :     if (subject[i] != pattern_first_char) continue;
   11638             :     int j = 1;
   11639        3116 :     while (j < pattern_length) {
   11640        2270 :       if (pattern[j] != subject[i + j]) {
   11641             :         break;
   11642             :       }
   11643        1105 :       j++;
   11644             :     }
   11645        2011 :     if (j == pattern_length) {
   11646             :       return i;
   11647             :     }
   11648             :   }
   11649             :   return -1;
   11650             : }
   11651             : 
   11652             : }  // namespace
   11653             : 
   11654        2905 : Object* String::LastIndexOf(Isolate* isolate, Handle<Object> receiver,
   11655             :                             Handle<Object> search, Handle<Object> position) {
   11656        2905 :   if (receiver->IsNullOrUndefined(isolate)) {
   11657         810 :     THROW_NEW_ERROR_RETURN_FAILURE(
   11658             :         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
   11659             :                               isolate->factory()->NewStringFromAsciiChecked(
   11660             :                                   "String.prototype.lastIndexOf")));
   11661             :   }
   11662             :   Handle<String> receiver_string;
   11663        5270 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_string,
   11664             :                                      Object::ToString(isolate, receiver));
   11665             : 
   11666             :   Handle<String> search_string;
   11667        5270 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, search_string,
   11668             :                                      Object::ToString(isolate, search));
   11669             : 
   11670        5270 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   11671             :                                      Object::ToNumber(position));
   11672             : 
   11673             :   uint32_t start_index;
   11674             : 
   11675        2635 :   if (position->IsNaN()) {
   11676        1885 :     start_index = receiver_string->length();
   11677             :   } else {
   11678         750 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
   11679             :                                        Object::ToInteger(isolate, position));
   11680             :     start_index = receiver_string->ToValidIndex(*position);
   11681             :   }
   11682             : 
   11683        2635 :   uint32_t pattern_length = search_string->length();
   11684        2635 :   uint32_t receiver_length = receiver_string->length();
   11685             : 
   11686        2635 :   if (start_index + pattern_length > receiver_length) {
   11687        2005 :     start_index = receiver_length - pattern_length;
   11688             :   }
   11689             : 
   11690        2635 :   if (pattern_length == 0) {
   11691         750 :     return Smi::FromInt(start_index);
   11692             :   }
   11693             : 
   11694        2260 :   receiver_string = String::Flatten(receiver_string);
   11695        2260 :   search_string = String::Flatten(search_string);
   11696             : 
   11697             :   int last_index = -1;
   11698             :   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   11699             : 
   11700        2260 :   String::FlatContent receiver_content = receiver_string->GetFlatContent();
   11701        2260 :   String::FlatContent search_content = search_string->GetFlatContent();
   11702             : 
   11703        2260 :   if (search_content.IsOneByte()) {
   11704             :     Vector<const uint8_t> pat_vector = search_content.ToOneByteVector();
   11705        2260 :     if (receiver_content.IsOneByte()) {
   11706             :       last_index = StringMatchBackwards(receiver_content.ToOneByteVector(),
   11707        2253 :                                         pat_vector, start_index);
   11708             :     } else {
   11709             :       last_index = StringMatchBackwards(receiver_content.ToUC16Vector(),
   11710           7 :                                         pat_vector, start_index);
   11711             :     }
   11712             :   } else {
   11713             :     Vector<const uc16> pat_vector = search_content.ToUC16Vector();
   11714           0 :     if (receiver_content.IsOneByte()) {
   11715             :       last_index = StringMatchBackwards(receiver_content.ToOneByteVector(),
   11716           0 :                                         pat_vector, start_index);
   11717             :     } else {
   11718             :       last_index = StringMatchBackwards(receiver_content.ToUC16Vector(),
   11719           0 :                                         pat_vector, start_index);
   11720             :     }
   11721             :   }
   11722        2260 :   return Smi::FromInt(last_index);
   11723             : }
   11724             : 
   11725    59350098 : bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) {
   11726             :   int slen = length();
   11727             :   // Can't check exact length equality, but we can check bounds.
   11728    59350098 :   int str_len = str.length();
   11729    59350098 :   if (!allow_prefix_match &&
   11730    58021913 :       (str_len < slen ||
   11731    58021913 :           str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) {
   11732             :     return false;
   11733             :   }
   11734             :   int i;
   11735    56787065 :   size_t remaining_in_str = static_cast<size_t>(str_len);
   11736    56787065 :   const uint8_t* utf8_data = reinterpret_cast<const uint8_t*>(str.start());
   11737  1126077312 :   for (i = 0; i < slen && remaining_in_str > 0; i++) {
   11738   538666039 :     size_t cursor = 0;
   11739   538666039 :     uint32_t r = unibrow::Utf8::ValueOf(utf8_data, remaining_in_str, &cursor);
   11740             :     DCHECK(cursor > 0 && cursor <= remaining_in_str);
   11741   538666046 :     if (r > unibrow::Utf16::kMaxNonSurrogateCharCode) {
   11742    32414463 :       if (i > slen - 1) return false;
   11743          28 :       if (Get(i++) != unibrow::Utf16::LeadSurrogate(r)) return false;
   11744          14 :       if (Get(i) != unibrow::Utf16::TrailSurrogate(r)) return false;
   11745             :     } else {
   11746   538666026 :       if (Get(i) != r) return false;
   11747             :     }
   11748   506251591 :     utf8_data += cursor;
   11749   506251591 :     remaining_in_str -= cursor;
   11750             :   }
   11751    24372617 :   return (allow_prefix_match || i == slen) && remaining_in_str == 0;
   11752             : }
   11753             : 
   11754             : template <>
   11755         210 : bool String::IsEqualTo(Vector<const uint8_t> str) {
   11756         210 :   return IsOneByteEqualTo(str);
   11757             : }
   11758             : 
   11759             : template <>
   11760           0 : bool String::IsEqualTo(Vector<const uc16> str) {
   11761           0 :   return IsTwoByteEqualTo(str);
   11762             : }
   11763             : 
   11764    96500761 : bool String::IsOneByteEqualTo(Vector<const uint8_t> str) {
   11765             :   int slen = length();
   11766    96500761 :   if (str.length() != slen) return false;
   11767             :   DisallowHeapAllocation no_gc;
   11768    69353226 :   FlatContent content = GetFlatContent();
   11769    69353227 :   if (content.IsOneByte()) {
   11770    69353126 :     return CompareChars(content.ToOneByteVector().start(),
   11771   138706252 :                         str.start(), slen) == 0;
   11772             :   }
   11773         170 :   for (int i = 0; i < slen; i++) {
   11774         254 :     if (Get(i) != static_cast<uint16_t>(str[i])) return false;
   11775             :   }
   11776             :   return true;
   11777             : }
   11778             : 
   11779             : 
   11780       40734 : bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
   11781             :   int slen = length();
   11782       40734 :   if (str.length() != slen) return false;
   11783             :   DisallowHeapAllocation no_gc;
   11784       12506 :   FlatContent content = GetFlatContent();
   11785       12506 :   if (content.IsTwoByte()) {
   11786       24162 :     return CompareChars(content.ToUC16Vector().start(), str.start(), slen) == 0;
   11787             :   }
   11788           0 :   for (int i = 0; i < slen; i++) {
   11789         425 :     if (Get(i) != str[i]) return false;
   11790             :   }
   11791             :   return true;
   11792             : }
   11793             : 
   11794             : 
   11795    29106397 : uint32_t String::ComputeAndSetHash() {
   11796             :   // Should only be called if hash code has not yet been computed.
   11797             :   DCHECK(!HasHashCode());
   11798             : 
   11799             :   // Store the hash code in the object.
   11800    29106397 :   uint32_t field = IteratingStringHasher::Hash(this, GetHeap()->HashSeed());
   11801             :   set_hash_field(field);
   11802             : 
   11803             :   // Check the hash code is there.
   11804             :   DCHECK(HasHashCode());
   11805    29106399 :   uint32_t result = field >> kHashShift;
   11806             :   DCHECK(result != 0);  // Ensure that the hash value of 0 is never computed.
   11807    29106399 :   return result;
   11808             : }
   11809             : 
   11810             : 
   11811     4309301 : bool String::ComputeArrayIndex(uint32_t* index) {
   11812             :   int length = this->length();
   11813     4309301 :   if (length == 0 || length > kMaxArrayIndexSize) return false;
   11814             :   StringCharacterStream stream(this);
   11815     1840269 :   return StringToArrayIndex(&stream, index);
   11816             : }
   11817             : 
   11818             : 
   11819    23891694 : bool String::SlowAsArrayIndex(uint32_t* index) {
   11820    23891694 :   if (length() <= kMaxCachedArrayIndexLength) {
   11821    19582393 :     Hash();  // force computation of hash code
   11822             :     uint32_t field = hash_field();
   11823    19582393 :     if ((field & kIsNotArrayIndexMask) != 0) return false;
   11824             :     // Isolate the array index form the full hash field.
   11825     6707712 :     *index = ArrayIndexValueBits::decode(field);
   11826     6707712 :     return true;
   11827             :   } else {
   11828     4309301 :     return ComputeArrayIndex(index);
   11829             :   }
   11830             : }
   11831             : 
   11832             : 
   11833    38297426 : Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) {
   11834             :   Heap* heap = string->GetHeap();
   11835    38297426 :   if (new_length == 0) return heap->isolate()->factory()->empty_string();
   11836             : 
   11837             :   int new_size, old_size;
   11838             :   int old_length = string->length();
   11839    28892863 :   if (old_length <= new_length) return string;
   11840             : 
   11841    27264198 :   if (string->IsSeqOneByteString()) {
   11842             :     old_size = SeqOneByteString::SizeFor(old_length);
   11843             :     new_size = SeqOneByteString::SizeFor(new_length);
   11844             :   } else {
   11845             :     DCHECK(string->IsSeqTwoByteString());
   11846             :     old_size = SeqTwoByteString::SizeFor(old_length);
   11847             :     new_size = SeqTwoByteString::SizeFor(new_length);
   11848             :   }
   11849             : 
   11850    27264198 :   int delta = old_size - new_size;
   11851             : 
   11852    27264198 :   Address start_of_string = string->address();
   11853             :   DCHECK_OBJECT_ALIGNED(start_of_string);
   11854             :   DCHECK_OBJECT_ALIGNED(start_of_string + new_size);
   11855             : 
   11856             :   // Sizes are pointer size aligned, so that we can use filler objects
   11857             :   // that are a multiple of pointer size.
   11858             :   heap->CreateFillerObjectAt(start_of_string + new_size, delta,
   11859    27264198 :                              ClearRecordedSlots::kNo);
   11860    54528396 :   heap->AdjustLiveBytes(*string, -delta);
   11861             : 
   11862             :   // We are storing the new length using release store after creating a filler
   11863             :   // for the left-over space to avoid races with the sweeper thread.
   11864             :   string->synchronized_set_length(new_length);
   11865             : 
   11866    27264198 :   return string;
   11867             : }
   11868             : 
   11869             : 
   11870     2303138 : uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
   11871             :   // For array indexes mix the length into the hash as an array index could
   11872             :   // be zero.
   11873             :   DCHECK(length > 0);
   11874             :   DCHECK(length <= String::kMaxArrayIndexSize);
   11875             :   DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) <
   11876             :          (1 << String::kArrayIndexValueBits));
   11877             : 
   11878    13358700 :   value <<= String::ArrayIndexValueBits::kShift;
   11879    13358700 :   value |= length << String::ArrayIndexLengthBits::kShift;
   11880             : 
   11881             :   DCHECK((value & String::kIsNotArrayIndexMask) == 0);
   11882             :   DCHECK_EQ(length <= String::kMaxCachedArrayIndexLength,
   11883             :             (value & String::kContainsCachedArrayIndexMask) == 0);
   11884     2303138 :   return value;
   11885             : }
   11886             : 
   11887             : 
   11888   212848599 : uint32_t StringHasher::GetHashField() {
   11889   212848599 :   if (length_ <= String::kMaxHashCalcLength) {
   11890   212787594 :     if (is_array_index_) {
   11891    21145784 :       return MakeArrayIndexHash(array_index_, length_);
   11892             :     }
   11893   404429404 :     return (GetHashCore(raw_running_hash_) << String::kHashShift) |
   11894   202214702 :            String::kIsNotArrayIndexMask;
   11895             :   } else {
   11896       61005 :     return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask;
   11897             :   }
   11898             : }
   11899             : 
   11900             : 
   11901    24519251 : uint32_t StringHasher::ComputeUtf8Hash(Vector<const char> chars,
   11902             :                                        uint32_t seed,
   11903             :                                        int* utf16_length_out) {
   11904    24519251 :   int vector_length = chars.length();
   11905             :   // Handle some edge cases
   11906    24519251 :   if (vector_length <= 1) {
   11907             :     DCHECK(vector_length == 0 ||
   11908             :            static_cast<uint8_t>(chars.start()[0]) <=
   11909             :                unibrow::Utf8::kMaxOneByteChar);
   11910       42218 :     *utf16_length_out = vector_length;
   11911       42218 :     return HashSequentialString(chars.start(), vector_length, seed);
   11912             :   }
   11913             :   // Start with a fake length which won't affect computation.
   11914             :   // It will be updated later.
   11915             :   StringHasher hasher(String::kMaxArrayIndexSize, seed);
   11916    24477033 :   size_t remaining = static_cast<size_t>(vector_length);
   11917             :   const uint8_t* stream = reinterpret_cast<const uint8_t*>(chars.start());
   11918             :   int utf16_length = 0;
   11919             :   bool is_index = true;
   11920             :   DCHECK(hasher.is_array_index_);
   11921   576423782 :   while (remaining > 0) {
   11922   527469716 :     size_t consumed = 0;
   11923   527469716 :     uint32_t c = unibrow::Utf8::ValueOf(stream, remaining, &consumed);
   11924             :     DCHECK(consumed > 0 && consumed <= remaining);
   11925   527469716 :     stream += consumed;
   11926   527469716 :     remaining -= consumed;
   11927   527469716 :     bool is_two_characters = c > unibrow::Utf16::kMaxNonSurrogateCharCode;
   11928   527469716 :     utf16_length += is_two_characters ? 2 : 1;
   11929             :     // No need to keep hashing. But we do need to calculate utf16_length.
   11930   527469716 :     if (utf16_length > String::kMaxHashCalcLength) continue;
   11931   527469716 :     if (is_two_characters) {
   11932             :       uint16_t c1 = unibrow::Utf16::LeadSurrogate(c);
   11933             :       uint16_t c2 = unibrow::Utf16::TrailSurrogate(c);
   11934             :       hasher.AddCharacter(c1);
   11935             :       hasher.AddCharacter(c2);
   11936          14 :       if (is_index) is_index = hasher.UpdateIndex(c1);
   11937          14 :       if (is_index) is_index = hasher.UpdateIndex(c2);
   11938             :     } else {
   11939             :       hasher.AddCharacter(c);
   11940   527469702 :       if (is_index) is_index = hasher.UpdateIndex(c);
   11941             :     }
   11942             :   }
   11943    24477033 :   *utf16_length_out = static_cast<int>(utf16_length);
   11944             :   // Must set length here so that hash computation is correct.
   11945    24477033 :   hasher.length_ = utf16_length;
   11946    24477033 :   return hasher.GetHashField();
   11947             : }
   11948             : 
   11949             : 
   11950     2502457 : void IteratingStringHasher::VisitConsString(ConsString* cons_string) {
   11951             :   // Run small ConsStrings through ConsStringIterator.
   11952     2502457 :   if (cons_string->length() < 64) {
   11953             :     ConsStringIterator iter(cons_string);
   11954             :     int offset;
   11955             :     String* string;
   11956    15012985 :     while (nullptr != (string = iter.Next(&offset))) {
   11957             :       DCHECK_EQ(0, offset);
   11958    12825446 :       String::VisitFlat(this, string, 0);
   11959             :     }
   11960     2502457 :     return;
   11961             :   }
   11962             :   // Slow case.
   11963      314918 :   const int max_length = String::kMaxHashCalcLength;
   11964      629836 :   int length = std::min(cons_string->length(), max_length);
   11965      314918 :   if (cons_string->HasOnlyOneByteChars()) {
   11966      279226 :     uint8_t* buffer = new uint8_t[length];
   11967      279226 :     String::WriteToFlat(cons_string, buffer, 0, length);
   11968      279226 :     AddCharacters(buffer, length);
   11969      279226 :     delete[] buffer;
   11970             :   } else {
   11971       35692 :     uint16_t* buffer = new uint16_t[length];
   11972       35692 :     String::WriteToFlat(cons_string, buffer, 0, length);
   11973       35692 :     AddCharacters(buffer, length);
   11974       35692 :     delete[] buffer;
   11975             :   }
   11976             : }
   11977             : 
   11978             : 
   11979       51674 : void String::PrintOn(FILE* file) {
   11980             :   int length = this->length();
   11981     4535154 :   for (int i = 0; i < length; i++) {
   11982     4483480 :     PrintF(file, "%c", Get(i));
   11983             :   }
   11984       51674 : }
   11985             : 
   11986             : 
   11987     1412102 : int Map::Hash() {
   11988             :   // For performance reasons we only hash the 3 most variable fields of a map:
   11989             :   // constructor, prototype and bit_field2. For predictability reasons we
   11990             :   // use objects' offsets in respective pages for hashing instead of raw
   11991             :   // addresses.
   11992             : 
   11993             :   // Shift away the tag.
   11994     2824204 :   int hash = ObjectAddressForHashing(GetConstructor()) >> 2;
   11995             : 
   11996             :   // XOR-ing the prototype and constructor directly yields too many zero bits
   11997             :   // when the two pointers are close (which is fairly common).
   11998             :   // To avoid this we shift the prototype bits relatively to the constructor.
   11999     1412102 :   hash ^= ObjectAddressForHashing(prototype()) << (32 - kPageSizeBits);
   12000             : 
   12001     2824204 :   return hash ^ (hash >> 16) ^ bit_field2();
   12002             : }
   12003             : 
   12004             : 
   12005             : namespace {
   12006             : 
   12007     2461738 : bool CheckEquivalent(Map* first, Map* second) {
   12008     4868035 :   return first->GetConstructor() == second->GetConstructor() &&
   12009     2393126 :          first->prototype() == second->prototype() &&
   12010     2393098 :          first->instance_type() == second->instance_type() &&
   12011     2393098 :          first->bit_field() == second->bit_field() &&
   12012     2392909 :          first->is_extensible() == second->is_extensible() &&
   12013     4854617 :          first->new_target_is_base() == second->new_target_is_base() &&
   12014     2461738 :          first->has_hidden_prototype() == second->has_hidden_prototype();
   12015             : }
   12016             : 
   12017             : }  // namespace
   12018             : 
   12019             : 
   12020     1494603 : bool Map::EquivalentToForTransition(Map* other) {
   12021     1494603 :   if (!CheckEquivalent(this, other)) return false;
   12022     1494399 :   if (instance_type() == JS_FUNCTION_TYPE) {
   12023             :     // JSFunctions require more checks to ensure that sloppy function is
   12024             :     // not equvalent to strict function.
   12025             :     int nof = Min(NumberOfOwnDescriptors(), other->NumberOfOwnDescriptors());
   12026             :     return instance_descriptors()->IsEqualUpTo(other->instance_descriptors(),
   12027        8607 :                                                nof);
   12028             :   }
   12029             :   return true;
   12030             : }
   12031             : 
   12032             : 
   12033      967135 : bool Map::EquivalentToForNormalization(Map* other,
   12034             :                                        PropertyNormalizationMode mode) {
   12035             :   int properties =
   12036      967135 :       mode == CLEAR_INOBJECT_PROPERTIES ? 0 : other->GetInObjectProperties();
   12037     2764095 :   return CheckEquivalent(this, other) && bit_field2() == other->bit_field2() &&
   12038     1720574 :          GetInObjectProperties() == properties &&
   12039      753439 :          JSObject::GetEmbedderFieldCount(this) ==
   12040     1720574 :              JSObject::GetEmbedderFieldCount(other);
   12041             : }
   12042             : 
   12043             : 
   12044    24822240 : bool JSFunction::Inlines(SharedFunctionInfo* candidate) {
   12045             :   DisallowHeapAllocation no_gc;
   12046    24822240 :   if (shared() == candidate) return true;
   12047    24807966 :   if (code()->kind() != Code::OPTIMIZED_FUNCTION) return false;
   12048             :   DeoptimizationInputData* const data =
   12049             :       DeoptimizationInputData::cast(code()->deoptimization_data());
   12050      230857 :   if (data->length() == 0) return false;
   12051             :   FixedArray* const literals = data->LiteralArray();
   12052             :   int const inlined_count = data->InlinedFunctionCount()->value();
   12053      253772 :   for (int i = 0; i < inlined_count; ++i) {
   12054       22973 :     if (SharedFunctionInfo::cast(literals->get(i)) == candidate) {
   12055             :       return true;
   12056             :     }
   12057             :   }
   12058             :   return false;
   12059             : }
   12060             : 
   12061     1216485 : void JSFunction::MarkForOptimization() {
   12062             :   Isolate* isolate = GetIsolate();
   12063             :   DCHECK(!IsOptimized());
   12064             :   DCHECK(shared()->allows_lazy_compilation() ||
   12065             :          !shared()->optimization_disabled());
   12066             :   set_code_no_write_barrier(
   12067             :       isolate->builtins()->builtin(Builtins::kCompileOptimized));
   12068             :   // No write barrier required, since the builtin is part of the root set.
   12069     1217243 :   if (FLAG_mark_shared_functions_for_tier_up) {
   12070             :     shared()->set_marked_for_tier_up(true);
   12071             :   }
   12072     1216485 : }
   12073             : 
   12074             : 
   12075      141101 : void JSFunction::AttemptConcurrentOptimization() {
   12076      281449 :   Isolate* isolate = GetIsolate();
   12077      281449 :   if (!isolate->concurrent_recompilation_enabled() ||
   12078      140348 :       isolate->bootstrapper()->IsActive()) {
   12079             :     MarkForOptimization();
   12080      141101 :     return;
   12081             :   }
   12082             :   DCHECK(!IsInOptimizationQueue());
   12083             :   DCHECK(!IsOptimized());
   12084             :   DCHECK(shared()->allows_lazy_compilation() ||
   12085             :          !shared()->optimization_disabled());
   12086             :   DCHECK(isolate->concurrent_recompilation_enabled());
   12087      140343 :   if (FLAG_trace_concurrent_recompilation) {
   12088           0 :     PrintF("  ** Marking ");
   12089           0 :     ShortPrint();
   12090           0 :     PrintF(" for concurrent recompilation.\n");
   12091             :   }
   12092             : 
   12093             :   set_code_no_write_barrier(
   12094             :       isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
   12095             :   // No write barrier required, since the builtin is part of the root set.
   12096      140343 :   if (FLAG_mark_shared_functions_for_tier_up) {
   12097             :     // TODO(leszeks): The compilation isn't concurrent if we trigger it using
   12098             :     // this bit.
   12099             :     shared()->set_marked_for_tier_up(true);
   12100             :   }
   12101             : }
   12102             : 
   12103             : // static
   12104      277951 : void SharedFunctionInfo::AddToOptimizedCodeMap(
   12105             :     Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
   12106             :     Handle<Code> code, BailoutId osr_ast_id) {
   12107      277951 :   Isolate* isolate = shared->GetIsolate();
   12108      286293 :   if (isolate->serializer_enabled()) return;
   12109             :   DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
   12110             :   DCHECK(native_context->IsNativeContext());
   12111             :   STATIC_ASSERT(kEntryLength == 2);
   12112             :   Handle<FixedArray> new_code_map;
   12113             :   int entry;
   12114             : 
   12115      277951 :   if (!osr_ast_id.IsNone()) {
   12116        2547 :     Context::AddToOptimizedCodeMap(native_context, shared, code, osr_ast_id);
   12117        2547 :     return;
   12118             :   }
   12119             : 
   12120             :   DCHECK(osr_ast_id.IsNone());
   12121      275404 :   if (shared->OptimizedCodeMapIsCleared()) {
   12122      234093 :     new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
   12123             :     entry = kEntriesStart;
   12124             :   } else {
   12125             :     Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
   12126       41311 :     entry = shared->SearchOptimizedCodeMapEntry(*native_context);
   12127       41311 :     if (entry >= kEntriesStart) {
   12128             :       // Just set the code of the entry.
   12129        5795 :       Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code);
   12130       11590 :       old_code_map->set(entry + kCachedCodeOffset, *code_cell);
   12131             :       return;
   12132             :     }
   12133             : 
   12134             :     // Can we reuse an entry?
   12135             :     DCHECK(entry < kEntriesStart);
   12136             :     int length = old_code_map->length();
   12137      121996 :     for (int i = kEntriesStart; i < length; i += kEntryLength) {
   12138       90384 :       if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) {
   12139             :         new_code_map = old_code_map;
   12140             :         entry = i;
   12141             :         break;
   12142             :       }
   12143             :     }
   12144             : 
   12145       35516 :     if (entry < kEntriesStart) {
   12146             :       // Copy old optimized code map and append one new entry.
   12147             :       new_code_map = isolate->factory()->CopyFixedArrayAndGrow(
   12148       31612 :           old_code_map, kEntryLength, TENURED);
   12149             :       // TODO(mstarzinger): Temporary workaround. The allocation above might
   12150             :       // have flushed the optimized code map and the copy we created is full of
   12151             :       // holes. For now we just give up on adding the entry and pretend it got
   12152             :       // flushed.
   12153       31612 :       if (shared->OptimizedCodeMapIsCleared()) return;
   12154             :       entry = old_code_map->length();
   12155             :     }
   12156             :   }
   12157             : 
   12158      269609 :   Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code);
   12159             :   WeakCell* context_cell = native_context->self_weak_cell();
   12160             : 
   12161      269608 :   new_code_map->set(entry + kContextOffset, context_cell);
   12162      539218 :   new_code_map->set(entry + kCachedCodeOffset, *code_cell);
   12163             : 
   12164             : #ifdef DEBUG
   12165             :   for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
   12166             :     WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset));
   12167             :     DCHECK(cell->cleared() || cell->value()->IsNativeContext());
   12168             :     cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset));
   12169             :     DCHECK(cell->cleared() ||
   12170             :            (cell->value()->IsCode() &&
   12171             :             Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION));
   12172             :   }
   12173             : #endif
   12174             : 
   12175             :   FixedArray* old_code_map = shared->optimized_code_map();
   12176      269609 :   if (old_code_map != *new_code_map) {
   12177      265705 :     shared->set_optimized_code_map(*new_code_map);
   12178             :   }
   12179             : }
   12180             : 
   12181             : 
   12182         296 : void SharedFunctionInfo::ClearOptimizedCodeMap() {
   12183         296 :   FixedArray* empty_fixed_array = GetHeap()->empty_fixed_array();
   12184         296 :   set_optimized_code_map(empty_fixed_array, SKIP_WRITE_BARRIER);
   12185         296 : }
   12186             : 
   12187             : 
   12188      438599 : void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
   12189             :                                                    const char* reason) {
   12190             :   DisallowHeapAllocation no_gc;
   12191             :   Isolate* isolate = GetIsolate();
   12192             :   bool found = false;
   12193             : 
   12194      438599 :   if (!OptimizedCodeMapIsCleared()) {
   12195      176696 :     Heap* heap = isolate->heap();
   12196             :     FixedArray* code_map = optimized_code_map();
   12197             :     int length = code_map->length();
   12198      536562 :     for (int src = kEntriesStart; src < length; src += kEntryLength) {
   12199             :       DCHECK(WeakCell::cast(code_map->get(src))->cleared() ||
   12200             :              WeakCell::cast(code_map->get(src))->value()->IsNativeContext());
   12201      325058 :       found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() ==
   12202      325058 :               optimized_code;
   12203      325058 :       if (found) {
   12204      176696 :         if (FLAG_trace_opt) {
   12205           0 :           PrintF("[evicting entry from optimizing code map (%s) for ", reason);
   12206           0 :           ShortPrint();
   12207           0 :           PrintF("]\n");
   12208             :         }
   12209             :         // Just clear the code.
   12210             :         code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(),
   12211      176696 :                       SKIP_WRITE_BARRIER);
   12212             :       }
   12213             :     }
   12214             :   }
   12215             : 
   12216      438599 :   if (!found) {
   12217             :     // We didn't find the code in here. It must be osr'd code.
   12218      280169 :     isolate->EvictOSROptimizedCode(optimized_code, reason);
   12219             :   }
   12220      438599 : }
   12221             : 
   12222             : // static
   12223    18752916 : void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
   12224             :   Handle<SharedFunctionInfo> shared(function->shared());
   12225             :   Isolate* isolate = shared->GetIsolate();
   12226             : 
   12227    18752918 :   FeedbackVectorState state = function->GetFeedbackVectorState(isolate);
   12228    18752916 :   switch (state) {
   12229             :     case TOP_LEVEL_SCRIPT_NEEDS_VECTOR: {
   12230             :       // A top level script didn't get it's literals installed.
   12231             :       Handle<FeedbackVector> feedback_vector =
   12232     6121472 :           FeedbackVector::New(isolate, shared);
   12233             :       Handle<Cell> new_cell =
   12234     6121475 :           isolate->factory()->NewOneClosureCell(feedback_vector);
   12235     6121474 :       function->set_feedback_vector_cell(*new_cell);
   12236             :       break;
   12237             :     }
   12238             :     case NEEDS_VECTOR: {
   12239             :       Handle<FeedbackVector> feedback_vector =
   12240     2398992 :           FeedbackVector::New(isolate, shared);
   12241     2398991 :       function->feedback_vector_cell()->set_value(*feedback_vector);
   12242             :       break;
   12243             :     }
   12244             :     case HAS_VECTOR:
   12245             :       // Nothing to do.
   12246             :       break;
   12247             :   }
   12248    18752918 : }
   12249             : 
   12250      344364 : static void GetMinInobjectSlack(Map* map, void* data) {
   12251             :   int slack = map->unused_property_fields();
   12252      344364 :   if (*reinterpret_cast<int*>(data) > slack) {
   12253       88632 :     *reinterpret_cast<int*>(data) = slack;
   12254             :   }
   12255      344364 : }
   12256             : 
   12257             : 
   12258      337007 : static void ShrinkInstanceSize(Map* map, void* data) {
   12259      337007 :   int slack = *reinterpret_cast<int*>(data);
   12260      337007 :   map->SetInObjectProperties(map->GetInObjectProperties() - slack);
   12261      337007 :   map->set_unused_property_fields(map->unused_property_fields() - slack);
   12262      337007 :   map->set_instance_size(map->instance_size() - slack * kPointerSize);
   12263             :   map->set_construction_counter(Map::kNoSlackTracking);
   12264             : 
   12265             :   // Visitor id might depend on the instance size, recalculate it.
   12266      337007 :   map->set_visitor_id(Heap::GetStaticVisitorIdForMap(map));
   12267      337007 : }
   12268             : 
   12269        7357 : static void StopSlackTracking(Map* map, void* data) {
   12270             :   map->set_construction_counter(Map::kNoSlackTracking);
   12271        7357 : }
   12272             : 
   12273       92937 : void Map::CompleteInobjectSlackTracking() {
   12274             :   // Has to be an initial map.
   12275             :   DCHECK(GetBackPointer()->IsUndefined(GetIsolate()));
   12276             : 
   12277       92937 :   int slack = unused_property_fields();
   12278             :   TransitionArray::TraverseTransitionTree(this, &GetMinInobjectSlack, &slack);
   12279       92937 :   if (slack != 0) {
   12280             :     // Resize the initial map and all maps in its transition tree.
   12281             :     TransitionArray::TraverseTransitionTree(this, &ShrinkInstanceSize, &slack);
   12282             :   } else {
   12283             :     TransitionArray::TraverseTransitionTree(this, &StopSlackTracking, nullptr);
   12284             :   }
   12285       92937 : }
   12286             : 
   12287             : 
   12288    27763918 : static bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) {
   12289             :   DisallowHeapAllocation no_gc;
   12290    27763918 :   if (!object->HasFastProperties()) return false;
   12291    26465674 :   if (object->IsJSGlobalProxy()) return false;
   12292    26433425 :   if (object->GetIsolate()->bootstrapper()->IsActive()) return false;
   12293    11493683 :   return !object->map()->is_prototype_map() ||
   12294    11493683 :          !object->map()->should_be_fast_prototype_map();
   12295             : }
   12296             : 
   12297             : // static
   12298     5943447 : void JSObject::MakePrototypesFast(Handle<Object> receiver,
   12299             :                                   WhereToStart where_to_start,
   12300             :                                   Isolate* isolate) {
   12301     5943447 :   if (!receiver->IsJSReceiver()) return;
   12302    15962145 :   for (PrototypeIterator iter(isolate, Handle<JSReceiver>::cast(receiver),
   12303     5874236 :                               where_to_start);
   12304    14301580 :        !iter.IsAtEnd(); iter.Advance()) {
   12305             :     Handle<Object> current = PrototypeIterator::GetCurrent(iter);
   12306     9609096 :     if (!current->IsJSObject()) return;
   12307             :     Handle<JSObject> current_obj = Handle<JSObject>::cast(current);
   12308             :     Map* current_map = current_obj->map();
   12309     9603622 :     if (current_map->is_prototype_map()) {
   12310             :       // If the map is already marked as should be fast, we're done. Its
   12311             :       // prototypes will have been marked already as well.
   12312    11109670 :       if (current_map->should_be_fast_prototype_map()) return;
   12313             :       Handle<Map> map(current_map);
   12314      329770 :       Map::SetShouldBeFastPrototypeMap(map, true, isolate);
   12315      329770 :       JSObject::OptimizeAsPrototype(current_obj, FAST_PROTOTYPE);
   12316             :     }
   12317             :   }
   12318             : }
   12319             : 
   12320             : // static
   12321    27949692 : void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
   12322             :                                    PrototypeOptimizationMode mode) {
   12323    55899377 :   if (object->IsJSGlobalObject()) return;
   12324    27833451 :   if (mode == FAST_PROTOTYPE && PrototypeBenefitsFromNormalization(object)) {
   12325             :     // First normalize to ensure all JSFunctions are DATA_CONSTANT.
   12326             :     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0,
   12327      594366 :                                   "NormalizeAsPrototype");
   12328             :   }
   12329             :   Handle<Map> previous_map(object->map());
   12330    27833449 :   if (object->map()->is_prototype_map()) {
   12331    39960318 :     if (object->map()->should_be_fast_prototype_map() &&
   12332    17129593 :         !object->HasFastProperties()) {
   12333      293328 :       JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype");
   12334             :     }
   12335             :   } else {
   12336     5002722 :     if (object->map() == *previous_map) {
   12337     5002721 :       Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype");
   12338     5002720 :       JSObject::MigrateToMap(object, new_map);
   12339             :     }
   12340             :     object->map()->set_is_prototype_map(true);
   12341             : 
   12342             :     // Replace the pointer to the exact constructor with the Object function
   12343             :     // from the same context if undetectable from JS. This is to avoid keeping
   12344             :     // memory alive unnecessarily.
   12345     5002721 :     Object* maybe_constructor = object->map()->GetConstructor();
   12346     5002721 :     if (maybe_constructor->IsJSFunction()) {
   12347             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
   12348             :       Isolate* isolate = object->GetIsolate();
   12349     9511091 :       if (!constructor->shared()->IsApiFunction() &&
   12350     4512207 :           object->class_name() == isolate->heap()->Object_string()) {
   12351             :         Context* context = constructor->context()->native_context();
   12352             :         JSFunction* object_function = context->object_function();
   12353             :         object->map()->SetConstructor(object_function);
   12354             :       }
   12355             :     }
   12356             :   }
   12357             : }
   12358             : 
   12359             : 
   12360             : // static
   12361     6583834 : void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) {
   12362     6583834 :   if (!object->map()->is_prototype_map()) return;
   12363       90338 :   if (!object->map()->should_be_fast_prototype_map()) return;
   12364       60333 :   OptimizeAsPrototype(object, FAST_PROTOTYPE);
   12365             : }
   12366             : 
   12367             : 
   12368             : // static
   12369     3008331 : void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
   12370             :   // Contract: In line with InvalidatePrototypeChains()'s requirements,
   12371             :   // leaf maps don't need to register as users, only prototypes do.
   12372             :   DCHECK(user->is_prototype_map());
   12373             : 
   12374     3008331 :   Handle<Map> current_user = user;
   12375             :   Handle<PrototypeInfo> current_user_info =
   12376     3008331 :       Map::GetOrCreatePrototypeInfo(user, isolate);
   12377     7012928 :   for (PrototypeIterator iter(user); !iter.IsAtEnd(); iter.Advance()) {
   12378             :     // Walk up the prototype chain as far as links haven't been registered yet.
   12379     2906167 :     if (current_user_info->registry_slot() != PrototypeInfo::UNREGISTERED) {
   12380             :       break;
   12381             :     }
   12382             :     Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter);
   12383             :     // Proxies on the prototype chain are not supported. They make it
   12384             :     // impossible to make any assumptions about the prototype chain anyway.
   12385     3506548 :     if (maybe_proto->IsJSProxy()) return;
   12386             :     Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto);
   12387             :     Handle<PrototypeInfo> proto_info =
   12388      498133 :         Map::GetOrCreatePrototypeInfo(proto, isolate);
   12389             :     Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
   12390      498133 :     int slot = 0;
   12391             :     Handle<WeakFixedArray> new_array =
   12392      498133 :         WeakFixedArray::Add(maybe_registry, current_user, &slot);
   12393      498133 :     current_user_info->set_registry_slot(slot);
   12394      498133 :     if (!maybe_registry.is_identical_to(new_array)) {
   12395      151031 :       proto_info->set_prototype_users(*new_array);
   12396             :     }
   12397      498133 :     if (FLAG_trace_prototype_users) {
   12398             :       PrintF("Registering %p as a user of prototype %p (map=%p).\n",
   12399             :              reinterpret_cast<void*>(*current_user),
   12400             :              reinterpret_cast<void*>(*proto),
   12401           0 :              reinterpret_cast<void*>(proto->map()));
   12402             :     }
   12403             : 
   12404             :     current_user = handle(proto->map(), isolate);
   12405             :     current_user_info = proto_info;
   12406             :   }
   12407             : }
   12408             : 
   12409             : 
   12410             : // Can be called regardless of whether |user| was actually registered with
   12411             : // |prototype|. Returns true when there was a registration.
   12412             : // static
   12413     5497297 : bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
   12414             :   DCHECK(user->is_prototype_map());
   12415             :   // If it doesn't have a PrototypeInfo, it was never registered.
   12416     5497297 :   if (!user->prototype_info()->IsPrototypeInfo()) return false;
   12417             :   // If it had no prototype before, see if it had users that might expect
   12418             :   // registration.
   12419      540369 :   if (!user->prototype()->IsJSObject()) {
   12420             :     Object* users =
   12421             :         PrototypeInfo::cast(user->prototype_info())->prototype_users();
   12422      112473 :     return users->IsWeakFixedArray();
   12423             :   }
   12424             :   Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate);
   12425             :   Handle<PrototypeInfo> user_info =
   12426      427896 :       Map::GetOrCreatePrototypeInfo(user, isolate);
   12427             :   int slot = user_info->registry_slot();
   12428      427896 :   if (slot == PrototypeInfo::UNREGISTERED) return false;
   12429             :   DCHECK(prototype->map()->is_prototype_map());
   12430             :   Object* maybe_proto_info = prototype->map()->prototype_info();
   12431             :   // User knows its registry slot, prototype info and user registry must exist.
   12432             :   DCHECK(maybe_proto_info->IsPrototypeInfo());
   12433             :   Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info),
   12434             :                                    isolate);
   12435             :   Object* maybe_registry = proto_info->prototype_users();
   12436             :   DCHECK(maybe_registry->IsWeakFixedArray());
   12437             :   DCHECK(WeakFixedArray::cast(maybe_registry)->Get(slot) == *user);
   12438             :   WeakFixedArray::cast(maybe_registry)->Clear(slot);
   12439      176128 :   if (FLAG_trace_prototype_users) {
   12440             :     PrintF("Unregistering %p as a user of prototype %p.\n",
   12441           0 :            reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
   12442             :   }
   12443             :   return true;
   12444             : }
   12445             : 
   12446             : 
   12447     5736684 : static void InvalidatePrototypeChainsInternal(Map* map) {
   12448             :   DCHECK(map->is_prototype_map());
   12449     5736684 :   if (FLAG_trace_prototype_users) {
   12450             :     PrintF("Invalidating prototype map %p 's cell\n",
   12451           0 :            reinterpret_cast<void*>(map));
   12452             :   }
   12453             :   Object* maybe_proto_info = map->prototype_info();
   12454    10694143 :   if (!maybe_proto_info->IsPrototypeInfo()) return;
   12455             :   PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_proto_info);
   12456             :   Object* maybe_cell = proto_info->validity_cell();
   12457      779225 :   if (maybe_cell->IsCell()) {
   12458             :     // Just set the value; the cell will be replaced lazily.
   12459             :     Cell* cell = Cell::cast(maybe_cell);
   12460      503389 :     cell->set_value(Smi::FromInt(Map::kPrototypeChainInvalid));
   12461             :   }
   12462             : 
   12463             :   WeakFixedArray::Iterator iterator(proto_info->prototype_users());
   12464             :   // For now, only maps register themselves as users.
   12465             :   Map* user;
   12466     1017065 :   while ((user = iterator.Next<Map>()) != nullptr) {
   12467             :     // Walk the prototype chain (backwards, towards leaf objects) if necessary.
   12468      237840 :     InvalidatePrototypeChainsInternal(user);
   12469             :   }
   12470             : }
   12471             : 
   12472             : 
   12473             : // static
   12474           0 : void JSObject::InvalidatePrototypeChains(Map* map) {
   12475             :   DisallowHeapAllocation no_gc;
   12476     5498844 :   InvalidatePrototypeChainsInternal(map);
   12477           0 : }
   12478             : 
   12479             : 
   12480             : // static
   12481     4614362 : Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<JSObject> prototype,
   12482             :                                                     Isolate* isolate) {
   12483             :   Object* maybe_proto_info = prototype->map()->prototype_info();
   12484     4614362 :   if (maybe_proto_info->IsPrototypeInfo()) {
   12485             :     return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
   12486             :   }
   12487      196849 :   Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
   12488      196849 :   prototype->map()->set_prototype_info(*proto_info);
   12489      196849 :   return proto_info;
   12490             : }
   12491             : 
   12492             : 
   12493             : // static
   12494     3766693 : Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> prototype_map,
   12495             :                                                     Isolate* isolate) {
   12496             :   Object* maybe_proto_info = prototype_map->prototype_info();
   12497     3766693 :   if (maybe_proto_info->IsPrototypeInfo()) {
   12498             :     return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
   12499             :   }
   12500      302960 :   Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
   12501      302960 :   prototype_map->set_prototype_info(*proto_info);
   12502      302960 :   return proto_info;
   12503             : }
   12504             : 
   12505             : // static
   12506      330466 : void Map::SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
   12507             :                                       Isolate* isolate) {
   12508      330466 :   if (value == false && !map->prototype_info()->IsPrototypeInfo()) {
   12509             :     // "False" is the implicit default value, so there's nothing to do.
   12510      330466 :     return;
   12511             :   }
   12512      660932 :   GetOrCreatePrototypeInfo(map, isolate)->set_should_be_fast_map(value);
   12513             : }
   12514             : 
   12515             : // static
   12516     3061911 : Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
   12517             :                                                         Isolate* isolate) {
   12518             :   Handle<Object> maybe_prototype;
   12519     3061911 :   if (map->IsJSGlobalObjectMap()) {
   12520             :     DCHECK(map->is_prototype_map());
   12521             :     // Global object is prototype of a global proxy and therefore we can
   12522             :     // use its validity cell for guarding global object's prototype change.
   12523        2869 :     maybe_prototype = isolate->global_object();
   12524             :   } else {
   12525             :     maybe_prototype =
   12526     3059042 :         handle(map->GetPrototypeChainRootMap(isolate)->prototype(), isolate);
   12527     3059042 :     if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null();
   12528             :   }
   12529             :   Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
   12530             :   // Ensure the prototype is registered with its own prototypes so its cell
   12531             :   // will be invalidated when necessary.
   12532             :   JSObject::LazyRegisterPrototypeUser(handle(prototype->map(), isolate),
   12533     2723929 :                                       isolate);
   12534             :   Handle<PrototypeInfo> proto_info =
   12535     2723929 :       GetOrCreatePrototypeInfo(prototype, isolate);
   12536             :   Object* maybe_cell = proto_info->validity_cell();
   12537             :   // Return existing cell if it's still valid.
   12538     2723929 :   if (maybe_cell->IsCell()) {
   12539             :     Handle<Cell> cell(Cell::cast(maybe_cell), isolate);
   12540     2451838 :     if (cell->value() == Smi::FromInt(Map::kPrototypeChainValid)) {
   12541     2397911 :       return cell;
   12542             :     }
   12543             :   }
   12544             :   // Otherwise create a new cell.
   12545             :   Handle<Cell> cell = isolate->factory()->NewCell(
   12546      326018 :       handle(Smi::FromInt(Map::kPrototypeChainValid), isolate));
   12547      326018 :   proto_info->set_validity_cell(*cell);
   12548      326018 :   return cell;
   12549             : }
   12550             : 
   12551             : // static
   12552     1204609 : Handle<WeakCell> Map::GetOrCreatePrototypeWeakCell(Handle<JSObject> prototype,
   12553             :                                                    Isolate* isolate) {
   12554             :   DCHECK(!prototype.is_null());
   12555             :   Handle<PrototypeInfo> proto_info =
   12556     1204609 :       GetOrCreatePrototypeInfo(prototype, isolate);
   12557             :   Object* maybe_cell = proto_info->weak_cell();
   12558             :   // Return existing cell if it's already created.
   12559     1204609 :   if (maybe_cell->IsWeakCell()) {
   12560             :     Handle<WeakCell> cell(WeakCell::cast(maybe_cell), isolate);
   12561             :     DCHECK(!cell->cleared());
   12562     1048917 :     return cell;
   12563             :   }
   12564             :   // Otherwise create a new cell.
   12565      155692 :   Handle<WeakCell> cell = isolate->factory()->NewWeakCell(prototype);
   12566      155692 :   proto_info->set_weak_cell(*cell);
   12567      155692 :   return cell;
   12568             : }
   12569             : 
   12570             : // static
   12571    31773330 : void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype,
   12572             :                        PrototypeOptimizationMode proto_mode) {
   12573    31773330 :   RuntimeCallTimerScope stats_scope(*map, &RuntimeCallStats::Map_SetPrototype);
   12574             : 
   12575             :   bool is_hidden = false;
   12576    31773352 :   if (prototype->IsJSObject()) {
   12577             :     Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype);
   12578    26595847 :     JSObject::OptimizeAsPrototype(prototype_jsobj, proto_mode);
   12579             : 
   12580    26595836 :     Object* maybe_constructor = prototype_jsobj->map()->GetConstructor();
   12581    26595833 :     if (maybe_constructor->IsJSFunction()) {
   12582             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
   12583             :       Object* data = constructor->shared()->function_data();
   12584      714747 :       is_hidden = (data->IsFunctionTemplateInfo() &&
   12585    48530003 :                    FunctionTemplateInfo::cast(data)->hidden_prototype()) ||
   12586             :                   prototype->IsJSGlobalObject();
   12587     2330666 :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
   12588             :       is_hidden =
   12589          48 :           FunctionTemplateInfo::cast(maybe_constructor)->hidden_prototype() ||
   12590             :           prototype->IsJSGlobalObject();
   12591             :     }
   12592             :   }
   12593             :   map->set_has_hidden_prototype(is_hidden);
   12594             : 
   12595             :   WriteBarrierMode wb_mode = prototype->IsNull(map->GetIsolate())
   12596             :                                  ? SKIP_WRITE_BARRIER
   12597    31773328 :                                  : UPDATE_WRITE_BARRIER;
   12598    31773328 :   map->set_prototype(*prototype, wb_mode);
   12599    31773333 : }
   12600             : 
   12601             : 
   12602         158 : Handle<Object> CacheInitialJSArrayMaps(
   12603             :     Handle<Context> native_context, Handle<Map> initial_map) {
   12604             :   // Replace all of the cached initial array maps in the native context with
   12605             :   // the appropriate transitioned elements kind maps.
   12606         158 :   Handle<Map> current_map = initial_map;
   12607             :   ElementsKind kind = current_map->elements_kind();
   12608             :   DCHECK_EQ(GetInitialFastElementsKind(), kind);
   12609         158 :   native_context->set(Context::ArrayMapIndex(kind), *current_map);
   12610         948 :   for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
   12611             :        i < kFastElementsKindCount; ++i) {
   12612             :     Handle<Map> new_map;
   12613         790 :     ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
   12614         790 :     if (Map* maybe_elements_transition = current_map->ElementsTransitionMap()) {
   12615             :       new_map = handle(maybe_elements_transition);
   12616             :     } else {
   12617             :       new_map = Map::CopyAsElementsKind(
   12618         790 :           current_map, next_kind, INSERT_TRANSITION);
   12619             :     }
   12620             :     DCHECK_EQ(next_kind, new_map->elements_kind());
   12621         790 :     native_context->set(Context::ArrayMapIndex(next_kind), *new_map);
   12622             :     current_map = new_map;
   12623             :   }
   12624         158 :   return initial_map;
   12625             : }
   12626             : 
   12627             : namespace {
   12628             : 
   12629      695459 : void SetInstancePrototype(Isolate* isolate, Handle<JSFunction> function,
   12630             :                           Handle<JSReceiver> value) {
   12631             :   // Now some logic for the maps of the objects that are created by using this
   12632             :   // function as a constructor.
   12633      695459 :   if (function->has_initial_map()) {
   12634             :     // If the function has allocated the initial map replace it with a
   12635             :     // copy containing the new prototype.  Also complete any in-object
   12636             :     // slack tracking that is in progress at this point because it is
   12637             :     // still tracking the old copy.
   12638       42801 :     function->CompleteInobjectSlackTrackingIfActive();
   12639             : 
   12640             :     Handle<Map> initial_map(function->initial_map(), isolate);
   12641             : 
   12642       83074 :     if (!initial_map->GetIsolate()->bootstrapper()->IsActive() &&
   12643             :         initial_map->instance_type() == JS_OBJECT_TYPE) {
   12644             :       // Put the value in the initial map field until an initial map is needed.
   12645             :       // At that point, a new initial map is created and the prototype is put
   12646             :       // into the initial map where it belongs.
   12647       39909 :       function->set_prototype_or_initial_map(*value);
   12648             :     } else {
   12649        2892 :       Handle<Map> new_map = Map::Copy(initial_map, "SetInstancePrototype");
   12650        2892 :       JSFunction::SetInitialMap(function, new_map, value);
   12651             : 
   12652             :       // If the function is used as the global Array function, cache the
   12653             :       // updated initial maps (and transitioned versions) in the native context.
   12654             :       Handle<Context> native_context(function->context()->native_context(),
   12655             :                                      isolate);
   12656             :       Handle<Object> array_function(
   12657             :           native_context->get(Context::ARRAY_FUNCTION_INDEX), isolate);
   12658        5705 :       if (array_function->IsJSFunction() &&
   12659             :           *function == JSFunction::cast(*array_function)) {
   12660          79 :         CacheInitialJSArrayMaps(native_context, new_map);
   12661             :       }
   12662             :     }
   12663             : 
   12664             :     // Deoptimize all code that embeds the previous initial map.
   12665             :     initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
   12666       42801 :         isolate, DependentCode::kInitialMapChangedGroup);
   12667             :   } else {
   12668             :     // Put the value in the initial map field until an initial map is
   12669             :     // needed.  At that point, a new initial map is created and the
   12670             :     // prototype is put into the initial map where it belongs.
   12671      652658 :     function->set_prototype_or_initial_map(*value);
   12672      652658 :     if (value->IsJSObject()) {
   12673             :       // Optimize as prototype to detach it from its transition tree.
   12674             :       JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value),
   12675      652560 :                                     FAST_PROTOTYPE);
   12676             :     }
   12677             :   }
   12678             :   isolate->heap()->ClearInstanceofCache();
   12679      695459 : }
   12680             : 
   12681             : }  // anonymous namespace
   12682             : 
   12683      695459 : void JSFunction::SetPrototype(Handle<JSFunction> function,
   12684             :                               Handle<Object> value) {
   12685             :   DCHECK(function->IsConstructor() ||
   12686             :          IsGeneratorFunction(function->shared()->kind()));
   12687             :   Isolate* isolate = function->GetIsolate();
   12688             :   Handle<JSReceiver> construct_prototype;
   12689             : 
   12690             :   // If the value is not a JSReceiver, store the value in the map's
   12691             :   // constructor field so it can be accessed.  Also, set the prototype
   12692             :   // used for constructing objects to the original object prototype.
   12693             :   // See ECMA-262 13.2.2.
   12694      695459 :   if (!value->IsJSReceiver()) {
   12695             :     // Copy the map so this does not affect unrelated functions.
   12696             :     // Remove map transitions because they point to maps with a
   12697             :     // different prototype.
   12698        6597 :     Handle<Map> new_map = Map::Copy(handle(function->map()), "SetPrototype");
   12699             : 
   12700        6597 :     JSObject::MigrateToMap(function, new_map);
   12701             :     new_map->SetConstructor(*value);
   12702             :     new_map->set_non_instance_prototype(true);
   12703             : 
   12704             :     FunctionKind kind = function->shared()->kind();
   12705             :     Handle<Context> native_context(function->context()->native_context());
   12706             : 
   12707             :     construct_prototype = Handle<JSReceiver>(
   12708             :         IsGeneratorFunction(kind)
   12709             :             ? IsAsyncFunction(kind)
   12710             :                   ? native_context->initial_async_generator_prototype()
   12711             :                   : native_context->initial_generator_prototype()
   12712             :             : native_context->initial_object_prototype(),
   12713       13208 :         isolate);
   12714             :   } else {
   12715      688862 :     construct_prototype = Handle<JSReceiver>::cast(value);
   12716      688862 :     if (function->map()->has_non_instance_prototype()) {
   12717             :       function->map()->set_non_instance_prototype(false);
   12718          29 :       function->map()->SetConstructor(isolate->heap()->null_value());
   12719             :     }
   12720             :   }
   12721             : 
   12722      695459 :   SetInstancePrototype(isolate, function, construct_prototype);
   12723      695459 : }
   12724             : 
   12725             : 
   12726       46949 : bool JSFunction::RemovePrototype() {
   12727             :   Context* native_context = context()->native_context();
   12728             :   Map* no_prototype_map =
   12729             :       is_strict(shared()->language_mode())
   12730             :           ? native_context->strict_function_without_prototype_map()
   12731       46949 :           : native_context->sloppy_function_without_prototype_map();
   12732             : 
   12733       46949 :   if (map() == no_prototype_map) return true;
   12734             : 
   12735             : #ifdef DEBUG
   12736             :   if (map() != (is_strict(shared()->language_mode())
   12737             :                     ? native_context->strict_function_map()
   12738             :                     : native_context->sloppy_function_map())) {
   12739             :     return false;
   12740             :   }
   12741             : #endif
   12742             : 
   12743       46001 :   set_map(no_prototype_map);
   12744       46001 :   set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
   12745       46001 :   return true;
   12746             : }
   12747             : 
   12748             : 
   12749     4861137 : void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
   12750             :                                Handle<Object> prototype) {
   12751     4861137 :   if (map->prototype() != *prototype) {
   12752     4860495 :     Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
   12753             :   }
   12754     4861138 :   function->set_prototype_or_initial_map(*map);
   12755             :   map->SetConstructor(*function);
   12756             : #if TRACE_MAPS
   12757             :   if (FLAG_trace_maps) {
   12758             :     PrintF("[TraceMaps: InitialMap map= %p SFI= %d_%s ]\n",
   12759             :            reinterpret_cast<void*>(*map), function->shared()->unique_id(),
   12760             :            function->shared()->DebugName()->ToCString().get());
   12761             :   }
   12762             : #endif
   12763     4861138 : }
   12764             : 
   12765             : 
   12766             : #ifdef DEBUG
   12767             : namespace {
   12768             : 
   12769             : bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
   12770             :   switch (instance_type) {
   12771             :     case JS_API_OBJECT_TYPE:
   12772             :     case JS_ARRAY_BUFFER_TYPE:
   12773             :     case JS_ARRAY_TYPE:
   12774             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
   12775             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
   12776             :     case JS_DATA_VIEW_TYPE:
   12777             :     case JS_DATE_TYPE:
   12778             :     case JS_FUNCTION_TYPE:
   12779             :     case JS_GENERATOR_OBJECT_TYPE:
   12780             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
   12781             :     case JS_MAP_ITERATOR_TYPE:
   12782             :     case JS_MAP_TYPE:
   12783             :     case JS_MESSAGE_OBJECT_TYPE:
   12784             :     case JS_OBJECT_TYPE:
   12785             :     case JS_ERROR_TYPE:
   12786             :     case JS_ARGUMENTS_TYPE:
   12787             :     case JS_PROMISE_TYPE:
   12788             :     case JS_REGEXP_TYPE:
   12789             :     case JS_SET_ITERATOR_TYPE:
   12790             :     case JS_SET_TYPE:
   12791             :     case JS_SPECIAL_API_OBJECT_TYPE:
   12792             :     case JS_TYPED_ARRAY_TYPE:
   12793             :     case JS_VALUE_TYPE:
   12794             :     case JS_WEAK_MAP_TYPE:
   12795             :     case JS_WEAK_SET_TYPE:
   12796             :       return true;
   12797             : 
   12798             :     case BYTECODE_ARRAY_TYPE:
   12799             :     case BYTE_ARRAY_TYPE:
   12800             :     case CELL_TYPE:
   12801             :     case CODE_TYPE:
   12802             :     case FILLER_TYPE:
   12803             :     case FIXED_ARRAY_TYPE:
   12804             :     case FIXED_DOUBLE_ARRAY_TYPE:
   12805             :     case FOREIGN_TYPE:
   12806             :     case FREE_SPACE_TYPE:
   12807             :     case HEAP_NUMBER_TYPE:
   12808             :     case JS_BOUND_FUNCTION_TYPE:
   12809             :     case JS_GLOBAL_OBJECT_TYPE:
   12810             :     case JS_GLOBAL_PROXY_TYPE:
   12811             :     case JS_PROXY_TYPE:
   12812             :     case MAP_TYPE:
   12813             :     case MUTABLE_HEAP_NUMBER_TYPE:
   12814             :     case ODDBALL_TYPE:
   12815             :     case PROPERTY_CELL_TYPE:
   12816             :     case SHARED_FUNCTION_INFO_TYPE:
   12817             :     case SYMBOL_TYPE:
   12818             :     case WEAK_CELL_TYPE:
   12819             : 
   12820             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
   12821             :   case FIXED_##TYPE##_ARRAY_TYPE:
   12822             : #undef TYPED_ARRAY_CASE
   12823             : 
   12824             : #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
   12825             :       STRUCT_LIST(MAKE_STRUCT_CASE)
   12826             : #undef MAKE_STRUCT_CASE
   12827             :       // We must not end up here for these instance types at all.
   12828             :       UNREACHABLE();
   12829             :     // Fall through.
   12830             :     default:
   12831             :       return false;
   12832             :   }
   12833             : }
   12834             : 
   12835             : }  // namespace
   12836             : #endif
   12837             : 
   12838             : 
   12839    20797261 : void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
   12840             :   DCHECK(function->IsConstructor() ||
   12841             :          IsResumableFunction(function->shared()->kind()));
   12842    41104724 :   if (function->has_initial_map()) return;
   12843             :   Isolate* isolate = function->GetIsolate();
   12844             : 
   12845             :   // First create a new map with the size and number of in-object properties
   12846             :   // suggested by the function.
   12847             :   InstanceType instance_type;
   12848      489798 :   if (IsResumableFunction(function->shared()->kind())) {
   12849             :     instance_type = IsAsyncGeneratorFunction(function->shared()->kind())
   12850             :                         ? JS_ASYNC_GENERATOR_OBJECT_TYPE
   12851       19742 :                         : JS_GENERATOR_OBJECT_TYPE;
   12852             :   } else {
   12853             :     instance_type = JS_OBJECT_TYPE;
   12854             :   }
   12855             : 
   12856             :   // The constructor should be compiled for the optimization hints to be
   12857             :   // available.
   12858             :   int expected_nof_properties = 0;
   12859      584078 :   if (function->shared()->is_compiled() ||
   12860       94280 :       Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) {
   12861             :     DCHECK(function->shared()->is_compiled());
   12862             :     expected_nof_properties = function->shared()->expected_nof_properties();
   12863             :   }
   12864             : 
   12865             :   int instance_size;
   12866             :   int in_object_properties;
   12867             :   CalculateInstanceSizeHelper(instance_type, 0, expected_nof_properties,
   12868      489798 :                               &instance_size, &in_object_properties);
   12869             : 
   12870      489798 :   Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size);
   12871             : 
   12872             :   // Fetch or allocate prototype.
   12873             :   Handle<Object> prototype;
   12874      489798 :   if (function->has_instance_prototype()) {
   12875      391306 :     prototype = handle(function->instance_prototype(), isolate);
   12876             :   } else {
   12877       98492 :     prototype = isolate->factory()->NewFunctionPrototype(function);
   12878             :   }
   12879      489798 :   map->SetInObjectProperties(in_object_properties);
   12880             :   map->set_unused_property_fields(in_object_properties);
   12881             :   DCHECK(map->has_fast_object_elements());
   12882             : 
   12883             :   // Finally link initial map and constructor function.
   12884             :   DCHECK(prototype->IsJSReceiver());
   12885      489798 :   JSFunction::SetInitialMap(function, map, prototype);
   12886             :   map->StartInobjectSlackTracking();
   12887             : }
   12888             : 
   12889             : 
   12890             : // static
   12891     3960606 : MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
   12892             :                                            Handle<JSFunction> constructor,
   12893             :                                            Handle<JSReceiver> new_target) {
   12894     3960606 :   EnsureHasInitialMap(constructor);
   12895             : 
   12896             :   Handle<Map> constructor_initial_map(constructor->initial_map(), isolate);
   12897     3960606 :   if (*new_target == *constructor) return constructor_initial_map;
   12898             : 
   12899             :   // Fast case, new.target is a subclass of constructor. The map is cacheable
   12900             :   // (and may already have been cached). new.target.prototype is guaranteed to
   12901             :   // be a JSReceiver.
   12902      133401 :   if (new_target->IsJSFunction()) {
   12903             :     Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
   12904             : 
   12905             :     // Check that |function|'s initial map still in sync with the |constructor|,
   12906             :     // otherwise we must create a new initial map for |function|.
   12907      254918 :     if (function->has_initial_map() &&
   12908      121849 :         function->initial_map()->GetConstructor() == *constructor) {
   12909             :       return handle(function->initial_map(), isolate);
   12910             :     }
   12911             : 
   12912             :     // Create a new map with the size and number of in-object properties
   12913             :     // suggested by |function|.
   12914             : 
   12915             :     // Link initial map and constructor function if the new.target is actually a
   12916             :     // subclass constructor.
   12917       11412 :     if (IsDerivedConstructor(function->shared()->kind())) {
   12918             :       Handle<Object> prototype(function->instance_prototype(), isolate);
   12919             :       InstanceType instance_type = constructor_initial_map->instance_type();
   12920             :       DCHECK(CanSubclassHaveInobjectProperties(instance_type));
   12921             :       int embedder_fields =
   12922        9044 :           JSObject::GetEmbedderFieldCount(*constructor_initial_map);
   12923             :       int pre_allocated = constructor_initial_map->GetInObjectProperties() -
   12924        9044 :                           constructor_initial_map->unused_property_fields();
   12925             :       int instance_size;
   12926             :       int in_object_properties;
   12927             :       CalculateInstanceSizeForDerivedClass(function, instance_type,
   12928             :                                            embedder_fields, &instance_size,
   12929        9044 :                                            &in_object_properties);
   12930             : 
   12931        9044 :       int unused_property_fields = in_object_properties - pre_allocated;
   12932             :       Handle<Map> map =
   12933             :           Map::CopyInitialMap(constructor_initial_map, instance_size,
   12934        9044 :                               in_object_properties, unused_property_fields);
   12935             :       map->set_new_target_is_base(false);
   12936             : 
   12937        9044 :       JSFunction::SetInitialMap(function, map, prototype);
   12938             :       map->SetConstructor(*constructor);
   12939             :       map->set_construction_counter(Map::kNoSlackTracking);
   12940             :       map->StartInobjectSlackTracking();
   12941             :       return map;
   12942             :     }
   12943             :   }
   12944             : 
   12945             :   // Slow path, new.target is either a proxy or can't cache the map.
   12946             :   // new.target.prototype is not guaranteed to be a JSReceiver, and may need to
   12947             :   // fall back to the intrinsicDefaultProto.
   12948             :   Handle<Object> prototype;
   12949        2700 :   if (new_target->IsJSFunction()) {
   12950             :     Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
   12951             :     // Make sure the new.target.prototype is cached.
   12952        2368 :     EnsureHasInitialMap(function);
   12953        2368 :     prototype = handle(function->prototype(), isolate);
   12954             :   } else {
   12955             :     Handle<String> prototype_string = isolate->factory()->prototype_string();
   12956         664 :     ASSIGN_RETURN_ON_EXCEPTION(
   12957             :         isolate, prototype,
   12958             :         JSReceiver::GetProperty(new_target, prototype_string), Map);
   12959             :     // The above prototype lookup might change the constructor and its
   12960             :     // prototype, hence we have to reload the initial map.
   12961         287 :     EnsureHasInitialMap(constructor);
   12962             :     constructor_initial_map = handle(constructor->initial_map(), isolate);
   12963             :   }
   12964             : 
   12965             :   // If prototype is not a JSReceiver, fetch the intrinsicDefaultProto from the
   12966             :   // correct realm. Rather than directly fetching the .prototype, we fetch the
   12967             :   // constructor that points to the .prototype. This relies on
   12968             :   // constructor.prototype being FROZEN for those constructors.
   12969        2655 :   if (!prototype->IsJSReceiver()) {
   12970             :     Handle<Context> context;
   12971        4090 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, context,
   12972             :                                JSReceiver::GetFunctionRealm(new_target), Map);
   12973             :     DCHECK(context->IsNativeContext());
   12974             :     Handle<Object> maybe_index = JSReceiver::GetDataProperty(
   12975        2045 :         constructor, isolate->factory()->native_context_index_symbol());
   12976             :     int index = maybe_index->IsSmi() ? Smi::cast(*maybe_index)->value()
   12977        2045 :                                      : Context::OBJECT_FUNCTION_INDEX;
   12978             :     Handle<JSFunction> realm_constructor(JSFunction::cast(context->get(index)));
   12979        2045 :     prototype = handle(realm_constructor->prototype(), isolate);
   12980             :   }
   12981             : 
   12982        2655 :   Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
   12983             :   map->set_new_target_is_base(false);
   12984             :   DCHECK(prototype->IsJSReceiver());
   12985        2655 :   if (map->prototype() != *prototype) {
   12986        1489 :     Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
   12987             :   }
   12988             :   map->SetConstructor(*constructor);
   12989             :   return map;
   12990             : }
   12991             : 
   12992             : 
   12993           0 : void JSFunction::PrintName(FILE* out) {
   12994           0 :   std::unique_ptr<char[]> name = shared()->DebugName()->ToCString();
   12995           0 :   PrintF(out, "%s", name.get());
   12996           0 : }
   12997             : 
   12998             : 
   12999      620671 : Handle<String> JSFunction::GetName(Handle<JSFunction> function) {
   13000             :   Isolate* isolate = function->GetIsolate();
   13001             :   Handle<Object> name =
   13002      620671 :       JSReceiver::GetDataProperty(function, isolate->factory()->name_string());
   13003      620671 :   if (name->IsString()) return Handle<String>::cast(name);
   13004      619668 :   return handle(function->shared()->DebugName(), isolate);
   13005             : }
   13006             : 
   13007             : 
   13008      374858 : Handle<String> JSFunction::GetDebugName(Handle<JSFunction> function) {
   13009             :   Isolate* isolate = function->GetIsolate();
   13010             :   Handle<Object> name = JSReceiver::GetDataProperty(
   13011      374858 :       function, isolate->factory()->display_name_string());
   13012      374858 :   if (name->IsString()) return Handle<String>::cast(name);
   13013      374812 :   return JSFunction::GetName(function);
   13014             : }
   13015             : 
   13016     1487332 : void JSFunction::SetName(Handle<JSFunction> function, Handle<Name> name,
   13017             :                          Handle<String> prefix) {
   13018             :   Isolate* isolate = function->GetIsolate();
   13019     2974665 :   Handle<String> function_name = Name::ToFunctionName(name).ToHandleChecked();
   13020     1487333 :   if (prefix->length() > 0) {
   13021        3480 :     IncrementalStringBuilder builder(isolate);
   13022        3480 :     builder.AppendString(prefix);
   13023             :     builder.AppendCharacter(' ');
   13024        3480 :     builder.AppendString(function_name);
   13025        6960 :     function_name = builder.Finish().ToHandleChecked();
   13026             :   }
   13027             :   JSObject::DefinePropertyOrElementIgnoreAttributes(
   13028             :       function, isolate->factory()->name_string(), function_name,
   13029             :       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY))
   13030     2974665 :       .ToHandleChecked();
   13031     1487332 : }
   13032             : 
   13033             : namespace {
   13034             : 
   13035             : char const kNativeCodeSource[] = "function () { [native code] }";
   13036             : 
   13037             : 
   13038     1552727 : Handle<String> NativeCodeFunctionSourceString(
   13039             :     Handle<SharedFunctionInfo> shared_info) {
   13040             :   Isolate* const isolate = shared_info->GetIsolate();
   13041     1552727 :   if (shared_info->name()->IsString()) {
   13042     1552727 :     IncrementalStringBuilder builder(isolate);
   13043             :     builder.AppendCString("function ");
   13044     1552727 :     builder.AppendString(handle(String::cast(shared_info->name()), isolate));
   13045             :     builder.AppendCString("() { [native code] }");
   13046     3105454 :     return builder.Finish().ToHandleChecked();
   13047             :   }
   13048           0 :   return isolate->factory()->NewStringFromAsciiChecked(kNativeCodeSource);
   13049             : }
   13050             : 
   13051             : }  // namespace
   13052             : 
   13053             : 
   13054             : // static
   13055          81 : Handle<String> JSBoundFunction::ToString(Handle<JSBoundFunction> function) {
   13056             :   Isolate* const isolate = function->GetIsolate();
   13057          81 :   return isolate->factory()->NewStringFromAsciiChecked(kNativeCodeSource);
   13058             : }
   13059             : 
   13060             : 
   13061             : // static
   13062     2636894 : Handle<String> JSFunction::ToString(Handle<JSFunction> function) {
   13063             :   Isolate* const isolate = function->GetIsolate();
   13064             :   Handle<SharedFunctionInfo> shared_info(function->shared(), isolate);
   13065             : 
   13066             :   // Check if {function} should hide its source code.
   13067     2636894 :   if (!shared_info->IsUserJavaScript()) {
   13068     1552727 :     return NativeCodeFunctionSourceString(shared_info);
   13069             :   }
   13070             : 
   13071             :   // Check if we should print {function} as a class.
   13072             :   Handle<Object> class_start_position = JSReceiver::GetDataProperty(
   13073     1084167 :       function, isolate->factory()->class_start_position_symbol());
   13074     1084167 :   if (class_start_position->IsSmi()) {
   13075             :     Handle<Object> class_end_position = JSReceiver::GetDataProperty(
   13076       33811 :         function, isolate->factory()->class_end_position_symbol());
   13077             :     Handle<String> script_source(
   13078             :         String::cast(Script::cast(shared_info->script())->source()), isolate);
   13079             :     return isolate->factory()->NewSubString(
   13080             :         script_source, Handle<Smi>::cast(class_start_position)->value(),
   13081       33811 :         Handle<Smi>::cast(class_end_position)->value());
   13082             :   }
   13083             : 
   13084             :   // Check if we have source code for the {function}.
   13085     1050356 :   if (!shared_info->HasSourceCode()) {
   13086           0 :     return NativeCodeFunctionSourceString(shared_info);
   13087             :   }
   13088             : 
   13089     1050356 :   if (FLAG_harmony_function_tostring) {
   13090        1260 :     return Handle<String>::cast(shared_info->GetSourceCodeHarmony());
   13091             :   }
   13092             : 
   13093     1049096 :   IncrementalStringBuilder builder(isolate);
   13094             :   FunctionKind kind = shared_info->kind();
   13095     1049096 :   if (!IsArrowFunction(kind)) {
   13096     1043685 :     if (IsConciseMethod(kind)) {
   13097          98 :       if (IsAsyncGeneratorFunction(kind)) {
   13098             :         builder.AppendCString("async *");
   13099          56 :       } else if (IsGeneratorFunction(kind)) {
   13100             :         builder.AppendCharacter('*');
   13101          42 :       } else if (IsAsyncFunction(kind)) {
   13102             :         builder.AppendCString("async ");
   13103             :       }
   13104             :     } else {
   13105     1043587 :       if (IsAsyncGeneratorFunction(kind)) {
   13106             :         builder.AppendCString("async function* ");
   13107     1043517 :       } else if (IsGeneratorFunction(kind)) {
   13108             :         builder.AppendCString("function* ");
   13109     1043323 :       } else if (IsAsyncFunction(kind)) {
   13110             :         builder.AppendCString("async function ");
   13111             :       } else {
   13112             :         builder.AppendCString("function ");
   13113             :       }
   13114             :     }
   13115     1043685 :     if (shared_info->name_should_print_as_anonymous()) {
   13116             :       builder.AppendCString("anonymous");
   13117     1043123 :     } else if (!shared_info->is_anonymous_expression()) {
   13118      939165 :       builder.AppendString(handle(String::cast(shared_info->name()), isolate));
   13119             :     }
   13120             :   }
   13121     1049096 :   builder.AppendString(Handle<String>::cast(shared_info->GetSourceCode()));
   13122     2098192 :   return builder.Finish().ToHandleChecked();
   13123             : }
   13124             : 
   13125         473 : void Oddball::Initialize(Isolate* isolate, Handle<Oddball> oddball,
   13126             :                          const char* to_string, Handle<Object> to_number,
   13127             :                          const char* type_of, byte kind) {
   13128             :   Handle<String> internalized_to_string =
   13129         473 :       isolate->factory()->InternalizeUtf8String(to_string);
   13130             :   Handle<String> internalized_type_of =
   13131         473 :       isolate->factory()->InternalizeUtf8String(type_of);
   13132         473 :   if (to_number->IsHeapNumber()) {
   13133             :     oddball->set_to_number_raw_as_bits(
   13134             :         Handle<HeapNumber>::cast(to_number)->value_as_bits());
   13135             :   } else {
   13136             :     oddball->set_to_number_raw(to_number->Number());
   13137             :   }
   13138         473 :   oddball->set_to_number(*to_number);
   13139         473 :   oddball->set_to_string(*internalized_to_string);
   13140         473 :   oddball->set_type_of(*internalized_type_of);
   13141             :   oddball->set_kind(kind);
   13142         473 : }
   13143             : 
   13144     1294349 : void Script::SetEvalOrigin(Handle<Script> script,
   13145             :                            Handle<SharedFunctionInfo> outer_info,
   13146             :                            int eval_position) {
   13147     1294349 :   if (eval_position == kNoSourcePosition) {
   13148             :     // If the position is missing, attempt to get the code offset from the
   13149             :     // current activation.  Do not translate the code offset into source
   13150             :     // position, but store it as negative value for lazy translation.
   13151      477387 :     StackTraceFrameIterator it(script->GetIsolate());
   13152      954697 :     if (!it.done() && it.is_javascript()) {
   13153      477310 :       FrameSummary summary = FrameSummary::GetTop(it.javascript_frame());
   13154      477310 :       script->set_eval_from_shared(summary.AsJavaScript().function()->shared());
   13155      477310 :       script->set_eval_from_position(-summary.code_offset());
   13156     1771659 :       return;
   13157             :     }
   13158             :     eval_position = 0;
   13159             :   }
   13160      817039 :   script->set_eval_from_shared(*outer_info);
   13161             :   script->set_eval_from_position(eval_position);
   13162             : }
   13163             : 
   13164       12476 : int Script::GetEvalPosition() {
   13165             :   DisallowHeapAllocation no_gc;
   13166             :   DCHECK(compilation_type() == Script::COMPILATION_TYPE_EVAL);
   13167             :   int position = eval_from_position();
   13168       12476 :   if (position < 0) {
   13169             :     // Due to laziness, the position may not have been translated from code
   13170             :     // offset yet, which would be encoded as negative integer. In that case,
   13171             :     // translate and set the position.
   13172        1105 :     if (eval_from_shared()->IsUndefined(GetIsolate())) {
   13173             :       position = 0;
   13174             :     } else {
   13175             :       SharedFunctionInfo* shared = SharedFunctionInfo::cast(eval_from_shared());
   13176        2210 :       position = shared->abstract_code()->SourcePosition(-position);
   13177             :     }
   13178             :     DCHECK(position >= 0);
   13179             :     set_eval_from_position(position);
   13180             :   }
   13181       12476 :   return position;
   13182             : }
   13183             : 
   13184     1672105 : void Script::InitLineEnds(Handle<Script> script) {
   13185             :   Isolate* isolate = script->GetIsolate();
   13186     3344210 :   if (!script->line_ends()->IsUndefined(isolate)) return;
   13187             :   DCHECK_NE(Script::TYPE_WASM, script->type());
   13188             : 
   13189             :   Object* src_obj = script->source();
   13190       63131 :   if (!src_obj->IsString()) {
   13191             :     DCHECK(src_obj->IsUndefined(isolate));
   13192          14 :     script->set_line_ends(isolate->heap()->empty_fixed_array());
   13193             :   } else {
   13194             :     DCHECK(src_obj->IsString());
   13195             :     Handle<String> src(String::cast(src_obj), isolate);
   13196       63124 :     Handle<FixedArray> array = String::CalculateLineEnds(src, true);
   13197       63124 :     script->set_line_ends(*array);
   13198             :   }
   13199             : 
   13200             :   DCHECK(script->line_ends()->IsFixedArray());
   13201             : }
   13202             : 
   13203     1385921 : bool Script::GetPositionInfo(Handle<Script> script, int position,
   13204             :                              PositionInfo* info, OffsetFlag offset_flag) {
   13205             :   // For wasm, we do not create an artificial line_ends array, but do the
   13206             :   // translation directly.
   13207     1385921 :   if (script->type() != Script::TYPE_WASM) InitLineEnds(script);
   13208     1385921 :   return script->GetPositionInfo(position, info, offset_flag);
   13209             : }
   13210             : 
   13211    54620317 : bool Script::IsUserJavaScript() { return type() == Script::TYPE_NORMAL; }
   13212             : 
   13213             : namespace {
   13214        1791 : bool GetPositionInfoSlow(const Script* script, int position,
   13215             :                          Script::PositionInfo* info) {
   13216        1791 :   if (!script->source()->IsString()) return false;
   13217        1791 :   if (position < 0) position = 0;
   13218             : 
   13219             :   String* source_string = String::cast(script->source());
   13220             :   int line = 0;
   13221             :   int line_start = 0;
   13222             :   int len = source_string->length();
   13223      539845 :   for (int pos = 0; pos <= len; ++pos) {
   13224     1079590 :     if (pos == len || source_string->Get(pos) == '\n') {
   13225       22152 :       if (position <= pos) {
   13226        1779 :         info->line = line;
   13227        1779 :         info->column = position - line_start;
   13228        1779 :         info->line_start = line_start;
   13229        1779 :         info->line_end = pos;
   13230        1779 :         return true;
   13231             :       }
   13232       20373 :       line++;
   13233       20373 :       line_start = pos + 1;
   13234             :     }
   13235             :   }
   13236             :   return false;
   13237             : }
   13238             : }  // namespace
   13239             : 
   13240             : #define SMI_VALUE(x) (Smi::cast(x)->value())
   13241     1443019 : bool Script::GetPositionInfo(int position, PositionInfo* info,
   13242             :                              OffsetFlag offset_flag) const {
   13243             :   DisallowHeapAllocation no_allocation;
   13244             : 
   13245             :   // For wasm, we do not rely on the line_ends array, but do the translation
   13246             :   // directly.
   13247     1443019 :   if (type() == Script::TYPE_WASM) {
   13248             :     Handle<WasmCompiledModule> compiled_module(
   13249             :         WasmCompiledModule::cast(wasm_compiled_module()));
   13250             :     DCHECK_LE(0, position);
   13251             :     return compiled_module->GetPositionInfo(static_cast<uint32_t>(position),
   13252        1036 :                                             info);
   13253             :   }
   13254             : 
   13255     1442501 :   if (line_ends()->IsUndefined(GetIsolate())) {
   13256             :     // Slow mode: we do not have line_ends. We have to iterate through source.
   13257        1791 :     if (!GetPositionInfoSlow(this, position, info)) return false;
   13258             :   } else {
   13259             :     DCHECK(line_ends()->IsFixedArray());
   13260             :     FixedArray* ends = FixedArray::cast(line_ends());
   13261             : 
   13262             :     const int ends_len = ends->length();
   13263     1440710 :     if (ends_len == 0) return false;
   13264             : 
   13265             :     // Return early on invalid positions. Negative positions behave as if 0 was
   13266             :     // passed, and positions beyond the end of the script return as failure.
   13267     1440689 :     if (position < 0) {
   13268             :       position = 0;
   13269     2880374 :     } else if (position > SMI_VALUE(ends->get(ends_len - 1))) {
   13270             :       return false;
   13271             :     }
   13272             : 
   13273             :     // Determine line number by doing a binary search on the line ends array.
   13274     1440663 :     if (SMI_VALUE(ends->get(0)) >= position) {
   13275      199002 :       info->line = 0;
   13276      199002 :       info->line_start = 0;
   13277      199002 :       info->column = position;
   13278             :     } else {
   13279             :       int left = 0;
   13280     1241661 :       int right = ends_len - 1;
   13281             : 
   13282     8767256 :       while (right > 0) {
   13283             :         DCHECK_LE(left, right);
   13284     7525595 :         const int mid = (left + right) / 2;
   13285     7525595 :         if (position > SMI_VALUE(ends->get(mid))) {
   13286     3844270 :           left = mid + 1;
   13287     7362650 :         } else if (position <= SMI_VALUE(ends->get(mid - 1))) {
   13288             :           right = mid - 1;
   13289             :         } else {
   13290     1241661 :           info->line = mid;
   13291     1241661 :           break;
   13292             :         }
   13293             :       }
   13294             :       DCHECK(SMI_VALUE(ends->get(info->line)) >= position &&
   13295             :              SMI_VALUE(ends->get(info->line - 1)) < position);
   13296     2483322 :       info->line_start = SMI_VALUE(ends->get(info->line - 1)) + 1;
   13297     1241661 :       info->column = position - info->line_start;
   13298             :     }
   13299             : 
   13300             :     // Line end is position of the linebreak character.
   13301     2881326 :     info->line_end = SMI_VALUE(ends->get(info->line));
   13302     1440663 :     if (info->line_end > 0) {
   13303             :       DCHECK(source()->IsString());
   13304             :       String* src = String::cast(source());
   13305     2880850 :       if (src->length() >= info->line_end &&
   13306     1440425 :           src->Get(info->line_end - 1) == '\r') {
   13307           0 :         info->line_end--;
   13308             :       }
   13309             :     }
   13310             :   }
   13311             : 
   13312             :   // Add offsets if requested.
   13313     1442442 :   if (offset_flag == WITH_OFFSET) {
   13314     1218318 :     if (info->line == 0) {
   13315      163662 :       info->column += column_offset();
   13316             :     }
   13317     1218318 :     info->line += line_offset();
   13318             :   }
   13319             : 
   13320             :   return true;
   13321             : }
   13322             : #undef SMI_VALUE
   13323             : 
   13324      203270 : int Script::GetColumnNumber(Handle<Script> script, int code_pos) {
   13325             :   PositionInfo info;
   13326      203270 :   GetPositionInfo(script, code_pos, &info, WITH_OFFSET);
   13327      203270 :   return info.column;
   13328             : }
   13329             : 
   13330           0 : int Script::GetColumnNumber(int code_pos) const {
   13331             :   PositionInfo info;
   13332           0 :   GetPositionInfo(code_pos, &info, WITH_OFFSET);
   13333           0 :   return info.column;
   13334             : }
   13335             : 
   13336      210501 : int Script::GetLineNumber(Handle<Script> script, int code_pos) {
   13337             :   PositionInfo info;
   13338      210501 :   GetPositionInfo(script, code_pos, &info, WITH_OFFSET);
   13339      210501 :   return info.line;
   13340             : }
   13341             : 
   13342       56978 : int Script::GetLineNumber(int code_pos) const {
   13343             :   PositionInfo info;
   13344       56978 :   GetPositionInfo(code_pos, &info, WITH_OFFSET);
   13345       56978 :   return info.line;
   13346             : }
   13347             : 
   13348       49078 : Object* Script::GetNameOrSourceURL() {
   13349             :   Isolate* isolate = GetIsolate();
   13350             :   // Keep in sync with ScriptNameOrSourceURL in messages.js.
   13351       51247 :   if (!source_url()->IsUndefined(isolate)) return source_url();
   13352       46909 :   return name();
   13353             : }
   13354             : 
   13355             : 
   13356     2036127 : Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
   13357      629356 :   Isolate* isolate = script->GetIsolate();
   13358     2036127 :   if (!script->wrapper()->IsUndefined(isolate)) {
   13359             :     DCHECK(script->wrapper()->IsWeakCell());
   13360             :     Handle<WeakCell> cell(WeakCell::cast(script->wrapper()));
   13361     1545187 :     if (!cell->cleared()) {
   13362             :       // Return a handle for the existing script wrapper from the cache.
   13363             :       return handle(JSObject::cast(cell->value()));
   13364             :     }
   13365             :     // If we found an empty WeakCell, that means the script wrapper was
   13366             :     // GCed.  We are not notified directly of that, so we decrement here
   13367             :     // so that we at least don't count double for any given script.
   13368       69208 :     isolate->counters()->script_wrappers()->Decrement();
   13369             :   }
   13370             :   // Construct a new script wrapper.
   13371      560148 :   isolate->counters()->script_wrappers()->Increment();
   13372      560148 :   Handle<JSFunction> constructor = isolate->script_function();
   13373             :   Handle<JSValue> result =
   13374      560148 :       Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
   13375      560148 :   result->set_value(*script);
   13376      560148 :   Handle<WeakCell> cell = isolate->factory()->NewWeakCell(result);
   13377      560148 :   script->set_wrapper(*cell);
   13378      560148 :   return result;
   13379             : }
   13380             : 
   13381     5863424 : MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
   13382     5863424 :     Isolate* isolate, const FunctionLiteral* fun) {
   13383             :   DCHECK_NE(fun->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
   13384             :   DCHECK_LT(fun->function_literal_id(), shared_function_infos()->length());
   13385             :   Object* shared = shared_function_infos()->get(fun->function_literal_id());
   13386     6837322 :   if (shared->IsUndefined(isolate) || WeakCell::cast(shared)->cleared()) {
   13387             :     return MaybeHandle<SharedFunctionInfo>();
   13388             :   }
   13389             :   return handle(SharedFunctionInfo::cast(WeakCell::cast(shared)->value()));
   13390             : }
   13391             : 
   13392      212457 : Script::Iterator::Iterator(Isolate* isolate)
   13393      436611 :     : iterator_(isolate->heap()->script_list()) {}
   13394             : 
   13395             : 
   13396     6114413 : Script* Script::Iterator::Next() { return iterator_.Next<Script>(); }
   13397             : 
   13398          42 : bool Script::HasPreparsedScopeData() const {
   13399          42 :   return preparsed_scope_data()->length() > 0;
   13400             : }
   13401             : 
   13402       90460 : SharedFunctionInfo::ScriptIterator::ScriptIterator(Handle<Script> script)
   13403             :     : ScriptIterator(script->GetIsolate(),
   13404       90460 :                      handle(script->shared_function_infos())) {}
   13405             : 
   13406         642 : SharedFunctionInfo::ScriptIterator::ScriptIterator(
   13407             :     Isolate* isolate, Handle<FixedArray> shared_function_infos)
   13408             :     : isolate_(isolate),
   13409             :       shared_function_infos_(shared_function_infos),
   13410       91102 :       index_(0) {}
   13411             : 
   13412    11827619 : SharedFunctionInfo* SharedFunctionInfo::ScriptIterator::Next() {
   13413    39415009 :   while (index_ < shared_function_infos_->length()) {
   13414    13344251 :     Object* raw = shared_function_infos_->get(index_++);
   13415    38419159 :     if (raw->IsUndefined(isolate_) || WeakCell::cast(raw)->cleared()) continue;
   13416    11378175 :     return SharedFunctionInfo::cast(WeakCell::cast(raw)->value());
   13417             :   }
   13418             :   return nullptr;
   13419             : }
   13420             : 
   13421      358357 : void SharedFunctionInfo::ScriptIterator::Reset(Handle<Script> script) {
   13422      358357 :   shared_function_infos_ = handle(script->shared_function_infos());
   13423      358357 :   index_ = 0;
   13424      358357 : }
   13425             : 
   13426       11697 : SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate)
   13427             :     : script_iterator_(isolate),
   13428             :       noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()),
   13429       23394 :       sfi_iterator_(handle(script_iterator_.Next(), isolate)) {}
   13430             : 
   13431    16574437 : SharedFunctionInfo* SharedFunctionInfo::GlobalIterator::Next() {
   13432    16574437 :   SharedFunctionInfo* next = noscript_sfi_iterator_.Next<SharedFunctionInfo>();
   13433    16574437 :   if (next != nullptr) return next;
   13434             :   for (;;) {
   13435    10658592 :     next = sfi_iterator_.Next();
   13436    10658592 :     if (next != nullptr) return next;
   13437             :     Script* next_script = script_iterator_.Next();
   13438      370054 :     if (next_script == nullptr) return nullptr;
   13439      358357 :     sfi_iterator_.Reset(handle(next_script));
   13440      358357 :   }
   13441             : }
   13442             : 
   13443             : 
   13444     6241439 : void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
   13445             :                                    Handle<Object> script_object) {
   13446             :   DCHECK_NE(shared->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
   13447    12482884 :   if (shared->script() == *script_object) return;
   13448             :   Isolate* isolate = shared->GetIsolate();
   13449             : 
   13450             :   // Add shared function info to new script's list. If a collection occurs,
   13451             :   // the shared function info may be temporarily in two lists.
   13452             :   // This is okay because the gc-time processing of these lists can tolerate
   13453             :   // duplicates.
   13454     6241445 :   if (script_object->IsScript()) {
   13455             :     Handle<Script> script = Handle<Script>::cast(script_object);
   13456             :     Handle<FixedArray> list = handle(script->shared_function_infos(), isolate);
   13457             : #ifdef DEBUG
   13458             :     DCHECK_LT(shared->function_literal_id(), list->length());
   13459             :     if (list->get(shared->function_literal_id())->IsWeakCell() &&
   13460             :         !WeakCell::cast(list->get(shared->function_literal_id()))->cleared()) {
   13461             :       DCHECK(
   13462             :           WeakCell::cast(list->get(shared->function_literal_id()))->value() ==
   13463             :           *shared);
   13464             :     }
   13465             : #endif
   13466     6234904 :     Handle<WeakCell> cell = isolate->factory()->NewWeakCell(shared);
   13467     6234906 :     list->set(shared->function_literal_id(), *cell);
   13468             :   } else {
   13469             :     Handle<Object> list = isolate->factory()->noscript_shared_function_infos();
   13470             : 
   13471             : #ifdef DEBUG
   13472             :     if (FLAG_enable_slow_asserts) {
   13473             :       WeakFixedArray::Iterator iterator(*list);
   13474             :       SharedFunctionInfo* next;
   13475             :       while ((next = iterator.Next<SharedFunctionInfo>()) != nullptr) {
   13476             :         DCHECK_NE(next, *shared);
   13477             :       }
   13478             :     }
   13479             : #endif  // DEBUG
   13480             : 
   13481        6539 :     list = WeakFixedArray::Add(list, shared);
   13482             : 
   13483             :     isolate->heap()->SetRootNoScriptSharedFunctionInfos(*list);
   13484             :   }
   13485             : 
   13486     6241446 :   if (shared->script()->IsScript()) {
   13487             :     // Remove shared function info from old script's list.
   13488             :     Script* old_script = Script::cast(shared->script());
   13489             : 
   13490             :     // Due to liveedit, it might happen that the old_script doesn't know
   13491             :     // about the SharedFunctionInfo, so we have to guard against that.
   13492             :     Handle<FixedArray> infos(old_script->shared_function_infos(), isolate);
   13493        6571 :     if (shared->function_literal_id() < infos->length()) {
   13494             :       Object* raw = old_script->shared_function_infos()->get(
   13495             :           shared->function_literal_id());
   13496       13080 :       if (!raw->IsWeakCell() || WeakCell::cast(raw)->value() == *shared) {
   13497             :         old_script->shared_function_infos()->set(
   13498        3450 :             shared->function_literal_id(), isolate->heap()->undefined_value());
   13499             :       }
   13500             :     }
   13501             :   } else {
   13502             :     // Remove shared function info from root array.
   13503     6234875 :     Object* list = isolate->heap()->noscript_shared_function_infos();
   13504     6234875 :     CHECK(WeakFixedArray::cast(list)->Remove(shared));
   13505             :   }
   13506             : 
   13507             :   // Finally set new script.
   13508     6241445 :   shared->set_script(*script_object);
   13509             : }
   13510             : 
   13511             : 
   13512     3096797 : String* SharedFunctionInfo::DebugName() {
   13513             :   Object* n = name();
   13514     6193593 :   if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name();
   13515             :   return String::cast(n);
   13516             : }
   13517             : 
   13518       14088 : bool SharedFunctionInfo::HasNoSideEffect() {
   13519       14088 :   if (!computed_has_no_side_effect()) {
   13520             :     DisallowHeapAllocation not_handlified;
   13521             :     Handle<SharedFunctionInfo> info(this);
   13522       11074 :     set_has_no_side_effect(DebugEvaluate::FunctionHasNoSideEffect(info));
   13523       11074 :     set_computed_has_no_side_effect(true);
   13524             :   }
   13525       14088 :   return has_no_side_effect();
   13526             : }
   13527             : 
   13528             : // The filter is a pattern that matches function names in this way:
   13529             : //   "*"      all; the default
   13530             : //   "-"      all but the top-level function
   13531             : //   "-name"  all but the function "name"
   13532             : //   ""       only the top-level function
   13533             : //   "name"   only the function "name"
   13534             : //   "name*"  only functions starting with "name"
   13535             : //   "~"      none; the tilde is not an identifier
   13536     4003381 : bool SharedFunctionInfo::PassesFilter(const char* raw_filter) {
   13537     4003381 :   if (*raw_filter == '*') return true;
   13538     1507706 :   String* name = DebugName();
   13539     1507704 :   Vector<const char> filter = CStrVector(raw_filter);
   13540     1507704 :   if (filter.length() == 0) return name->length() == 0;
   13541     1507704 :   if (filter[0] == '-') {
   13542             :     // Negative filter.
   13543           0 :     if (filter.length() == 1) {
   13544           0 :       return (name->length() != 0);
   13545           0 :     } else if (name->IsUtf8EqualTo(filter.SubVector(1, filter.length()))) {
   13546             :       return false;
   13547             :     }
   13548           0 :     if (filter[filter.length() - 1] == '*' &&
   13549           0 :         name->IsUtf8EqualTo(filter.SubVector(1, filter.length() - 1), true)) {
   13550             :       return false;
   13551             :     }
   13552           0 :     return true;
   13553             : 
   13554     1507704 :   } else if (name->IsUtf8EqualTo(filter)) {
   13555             :     return true;
   13556             :   }
   13557     3014835 :   if (filter[filter.length() - 1] == '*' &&
   13558         125 :       name->IsUtf8EqualTo(filter.SubVector(0, filter.length() - 1), true)) {
   13559             :     return true;
   13560             :   }
   13561     1507282 :   return false;
   13562             : }
   13563             : 
   13564    14230898 : bool SharedFunctionInfo::HasSourceCode() const {
   13565             :   Isolate* isolate = GetIsolate();
   13566    28461789 :   return !script()->IsUndefined(isolate) &&
   13567    14230898 :          !reinterpret_cast<Script*>(script())->source()->IsUndefined(isolate);
   13568             : }
   13569             : 
   13570             : 
   13571     1049488 : Handle<Object> SharedFunctionInfo::GetSourceCode() {
   13572     1049488 :   if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value();
   13573             :   Handle<String> source(String::cast(Script::cast(script())->source()));
   13574             :   return GetIsolate()->factory()->NewSubString(
   13575     1049488 :       source, start_position(), end_position());
   13576             : }
   13577             : 
   13578        1260 : Handle<Object> SharedFunctionInfo::GetSourceCodeHarmony() {
   13579             :   Isolate* isolate = GetIsolate();
   13580        1260 :   if (!HasSourceCode()) return isolate->factory()->undefined_value();
   13581             :   Handle<String> script_source(String::cast(Script::cast(script())->source()));
   13582             :   int start_pos = function_token_position();
   13583        1260 :   if (start_pos == kNoSourcePosition) start_pos = start_position();
   13584             :   return isolate->factory()->NewSubString(script_source, start_pos,
   13585        1260 :                                           end_position());
   13586             : }
   13587             : 
   13588      180256 : bool SharedFunctionInfo::IsInlineable() {
   13589             :   // Check that the function has a script associated with it.
   13590      180256 :   if (!script()->IsScript()) return false;
   13591      180268 :   if (GetIsolate()->is_precise_binary_code_coverage() &&
   13592             :       !has_reported_binary_coverage()) {
   13593             :     // We may miss invocations if this function is inlined.
   13594             :     return false;
   13595             :   }
   13596      180256 :   return !optimization_disabled();
   13597             : }
   13598             : 
   13599      151597 : int SharedFunctionInfo::SourceSize() {
   13600      151597 :   return end_position() - start_position();
   13601             : }
   13602             : 
   13603      709484 : void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type,
   13604             :                                              int requested_embedder_fields,
   13605             :                                              int requested_in_object_properties,
   13606             :                                              int* instance_size,
   13607             :                                              int* in_object_properties) {
   13608      709484 :   int header_size = JSObject::GetHeaderSize(instance_type);
   13609             :   DCHECK_LE(requested_embedder_fields,
   13610             :             (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2);
   13611             :   *instance_size =
   13612             :       Min(header_size +
   13613      709484 :               ((requested_embedder_fields + requested_in_object_properties)
   13614      709484 :                << kPointerSizeLog2),
   13615     1418968 :           JSObject::kMaxInstanceSize);
   13616      709484 :   *in_object_properties = ((*instance_size - header_size) >> kPointerSizeLog2) -
   13617      709484 :                           requested_embedder_fields;
   13618      709484 : }
   13619             : 
   13620        9044 : void JSFunction::CalculateInstanceSizeForDerivedClass(
   13621             :     Handle<JSFunction> function, InstanceType instance_type,
   13622             :     int requested_embedder_fields, int* instance_size,
   13623             :     int* in_object_properties) {
   13624             :   Isolate* isolate = function->GetIsolate();
   13625             :   int expected_nof_properties = 0;
   13626       37792 :   for (PrototypeIterator iter(isolate, function, kStartAtReceiver);
   13627       19704 :        !iter.IsAtEnd(); iter.Advance()) {
   13628             :     Handle<JSReceiver> current =
   13629             :         PrototypeIterator::GetCurrent<JSReceiver>(iter);
   13630       28748 :     if (!current->IsJSFunction()) break;
   13631             :     Handle<JSFunction> func(Handle<JSFunction>::cast(current));
   13632             :     // The super constructor should be compiled for the number of expected
   13633             :     // properties to be available.
   13634             :     Handle<SharedFunctionInfo> shared(func->shared());
   13635       29028 :     if (shared->is_compiled() ||
   13636         295 :         Compiler::Compile(func, Compiler::CLEAR_EXCEPTION)) {
   13637             :       DCHECK(shared->is_compiled());
   13638       28733 :       expected_nof_properties += shared->expected_nof_properties();
   13639             :     }
   13640       28733 :     if (!IsDerivedConstructor(shared->kind())) {
   13641             :       break;
   13642             :     }
   13643             :   }
   13644             :   CalculateInstanceSizeHelper(instance_type, requested_embedder_fields,
   13645             :                               expected_nof_properties, instance_size,
   13646        9044 :                               in_object_properties);
   13647        9044 : }
   13648             : 
   13649             : 
   13650             : // Output the source code without any allocation in the heap.
   13651          21 : std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) {
   13652          21 :   const SharedFunctionInfo* s = v.value;
   13653             :   // For some native functions there is no source.
   13654          21 :   if (!s->HasSourceCode()) return os << "<No Source>";
   13655             : 
   13656             :   // Get the source for the script which this function came from.
   13657             :   // Don't use String::cast because we don't want more assertion errors while
   13658             :   // we are already creating a stack dump.
   13659             :   String* script_source =
   13660             :       reinterpret_cast<String*>(Script::cast(s->script())->source());
   13661             : 
   13662          14 :   if (!script_source->LooksValid()) return os << "<Invalid Source>";
   13663             : 
   13664          14 :   if (!s->is_toplevel()) {
   13665          14 :     os << "function ";
   13666             :     Object* name = s->name();
   13667          28 :     if (name->IsString() && String::cast(name)->length() > 0) {
   13668          14 :       String::cast(name)->PrintUC16(os);
   13669             :     }
   13670             :   }
   13671             : 
   13672          14 :   int len = s->end_position() - s->start_position();
   13673          14 :   if (len <= v.max_length || v.max_length < 0) {
   13674          14 :     script_source->PrintUC16(os, s->start_position(), s->end_position());
   13675          14 :     return os;
   13676             :   } else {
   13677             :     script_source->PrintUC16(os, s->start_position(),
   13678           0 :                              s->start_position() + v.max_length);
   13679           0 :     return os << "...\n";
   13680             :   }
   13681             : }
   13682             : 
   13683             : 
   13684      231562 : static bool IsCodeEquivalent(Code* code, Code* recompiled) {
   13685      231562 :   if (code->instruction_size() != recompiled->instruction_size()) return false;
   13686             :   ByteArray* code_relocation = code->relocation_info();
   13687             :   ByteArray* recompiled_relocation = recompiled->relocation_info();
   13688             :   int length = code_relocation->length();
   13689      228494 :   if (length != recompiled_relocation->length()) return false;
   13690      228494 :   int compare = memcmp(code_relocation->GetDataStartAddress(),
   13691      228494 :                        recompiled_relocation->GetDataStartAddress(),
   13692      456988 :                        length);
   13693      228494 :   return compare == 0;
   13694             : }
   13695             : 
   13696             : 
   13697      231562 : void SharedFunctionInfo::EnableDeoptimizationSupport(Code* recompiled) {
   13698             :   DCHECK(!has_deoptimization_support());
   13699             :   DisallowHeapAllocation no_allocation;
   13700             :   Code* code = this->code();
   13701      231562 :   if (IsCodeEquivalent(code, recompiled)) {
   13702             :     // Copy the deoptimization data from the recompiled code.
   13703      228494 :     code->set_deoptimization_data(recompiled->deoptimization_data());
   13704             :     code->set_has_deoptimization_support(true);
   13705             :   } else {
   13706             :     // TODO(3025757): In case the recompiled isn't equivalent to the
   13707             :     // old code, we have to replace it. We should try to avoid this
   13708             :     // altogether because it flushes valuable type feedback by
   13709             :     // effectively resetting all IC state.
   13710        3069 :     ReplaceCode(recompiled);
   13711             :   }
   13712             :   DCHECK(has_deoptimization_support());
   13713      231563 : }
   13714             : 
   13715             : 
   13716       57082 : void SharedFunctionInfo::DisableOptimization(BailoutReason reason) {
   13717             :   // Disable optimization for the shared function info and mark the
   13718             :   // code as non-optimizable. The marker on the shared function info
   13719             :   // is there because we flush non-optimized code thereby loosing the
   13720             :   // non-optimizable information for the code. When the code is
   13721             :   // regenerated and set on the shared function info it is marked as
   13722             :   // non-optimizable if optimization is disabled for the shared
   13723             :   // function info.
   13724             :   DCHECK(reason != kNoReason);
   13725             :   set_optimization_disabled(true);
   13726             :   set_disable_optimization_reason(reason);
   13727             :   // Code should be the lazy compilation stub or else unoptimized.
   13728             :   DCHECK(abstract_code()->kind() == AbstractCode::FUNCTION ||
   13729             :          abstract_code()->kind() == AbstractCode::INTERPRETED_FUNCTION ||
   13730             :          abstract_code()->kind() == AbstractCode::BUILTIN);
   13731       57082 :   PROFILE(GetIsolate(), CodeDisableOptEvent(abstract_code(), this));
   13732       57082 :   if (FLAG_trace_opt) {
   13733           0 :     PrintF("[disabled optimization for ");
   13734           0 :     ShortPrint();
   13735           0 :     PrintF(", reason: %s]\n", GetBailoutReason(reason));
   13736             :   }
   13737       57082 : }
   13738             : 
   13739     6231069 : void SharedFunctionInfo::InitFromFunctionLiteral(
   13740    54574301 :     Handle<SharedFunctionInfo> shared_info, FunctionLiteral* lit) {
   13741             :   // When adding fields here, make sure DeclarationScope::AnalyzePartially is
   13742             :   // updated accordingly.
   13743             :   shared_info->set_internal_formal_parameter_count(lit->parameter_count());
   13744             :   shared_info->set_function_token_position(lit->function_token_position());
   13745     6231069 :   shared_info->set_start_position(lit->start_position());
   13746     6231074 :   shared_info->set_end_position(lit->end_position());
   13747             :   shared_info->set_is_declaration(lit->is_declaration());
   13748             :   shared_info->set_is_named_expression(lit->is_named_expression());
   13749     6231074 :   shared_info->set_is_anonymous_expression(lit->is_anonymous_expression());
   13750    12462146 :   shared_info->set_inferred_name(*lit->inferred_name());
   13751     6231074 :   shared_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
   13752     6231072 :   shared_info->set_language_mode(lit->language_mode());
   13753     6231071 :   shared_info->set_uses_arguments(lit->scope()->arguments() != NULL);
   13754     6231071 :   shared_info->set_kind(lit->kind());
   13755     6231075 :   if (!IsConstructable(lit->kind())) {
   13756             :     shared_info->SetConstructStub(
   13757      934062 :         *shared_info->GetIsolate()->builtins()->ConstructedNonConstructable());
   13758             :   }
   13759     6231072 :   shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject());
   13760             :   shared_info->set_asm_function(lit->scope()->asm_function());
   13761             :   shared_info->set_function_literal_id(lit->function_literal_id());
   13762             : 
   13763             :   // For lazy parsed functions, the following flags will be inaccurate since we
   13764             :   // don't have the information yet. They're set later in
   13765             :   // SetSharedFunctionFlagsFromLiteral (compiler.cc), when the function is
   13766             :   // really parsed and compiled.
   13767     6231074 :   if (lit->body() != nullptr) {
   13768             :     shared_info->set_length(lit->function_length());
   13769             :     shared_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
   13770             :     shared_info->SetExpectedNofPropertiesFromEstimate(lit);
   13771             :   } else {
   13772             :     // Set an invalid length for lazy functions. This way we can set the correct
   13773             :     // value after compiling, but avoid overwriting values set manually by the
   13774             :     // bootstrapper.
   13775             :     shared_info->set_length(SharedFunctionInfo::kInvalidLength);
   13776             :   }
   13777     6231074 : }
   13778             : 
   13779     3339060 : void SharedFunctionInfo::SetExpectedNofPropertiesFromEstimate(
   13780     8817459 :     FunctionLiteral* literal) {
   13781             :   int estimate = literal->expected_property_count();
   13782             : 
   13783             :   // If no properties are added in the constructor, they are more likely
   13784             :   // to be added later.
   13785     8817459 :   if (estimate == 0) estimate = 2;
   13786             : 
   13787             :   // Inobject slack tracking will reclaim redundant inobject space later,
   13788             :   // so we can afford to adjust the estimate generously.
   13789     8817459 :   estimate += 8;
   13790             : 
   13791             :   set_expected_nof_properties(estimate);
   13792     3339060 : }
   13793             : 
   13794           0 : bool SharedFunctionInfo::VerifyBailoutId(BailoutId id) {
   13795             :   DCHECK(!id.IsNone());
   13796             :   Code* unoptimized = code();
   13797             :   DeoptimizationOutputData* data =
   13798             :       DeoptimizationOutputData::cast(unoptimized->deoptimization_data());
   13799           0 :   unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this);
   13800             :   USE(ignore);
   13801           0 :   return true;  // Return true if there was no DCHECK.
   13802             : }
   13803             : 
   13804    14896380 : void SharedFunctionInfo::SetConstructStub(Code* code) {
   13805    14896380 :   if (code->kind() == Code::BUILTIN) code->set_is_construct_stub(true);
   13806    14896380 :   set_construct_stub(code);
   13807    14896385 : }
   13808             : 
   13809           0 : void Map::StartInobjectSlackTracking() {
   13810             :   DCHECK(!IsInobjectSlackTrackingInProgress());
   13811      498842 :   if (unused_property_fields() == 0) return;
   13812             :   set_construction_counter(Map::kSlackTrackingCounterStart);
   13813             : }
   13814             : 
   13815             : 
   13816     4501247 : void SharedFunctionInfo::ResetForNewContext(int new_ic_age) {
   13817     4501247 :   code()->ClearInlineCaches();
   13818             :   set_ic_age(new_ic_age);
   13819     4501251 :   if (code()->kind() == Code::FUNCTION) {
   13820             :     code()->set_profiler_ticks(0);
   13821        9672 :     if (optimization_disabled() && deopt_count() >= FLAG_max_deopt_count) {
   13822             :       // Re-enable optimizations if they were disabled due to deopt_count limit.
   13823             :       set_optimization_disabled(false);
   13824             :     }
   13825             :     set_opt_count(0);
   13826             :     set_deopt_count(0);
   13827     4491675 :   } else if (IsInterpreted()) {
   13828             :     set_profiler_ticks(0);
   13829       28198 :     if (optimization_disabled() && deopt_count() >= FLAG_max_deopt_count) {
   13830             :       // Re-enable optimizations if they were disabled due to deopt_count limit.
   13831             :       set_optimization_disabled(false);
   13832             :     }
   13833             :     set_opt_count(0);
   13834             :     set_deopt_count(0);
   13835             :   }
   13836     4501243 : }
   13837             : 
   13838    27975351 : int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context) {
   13839             :   DisallowHeapAllocation no_gc;
   13840             :   DCHECK(native_context->IsNativeContext());
   13841    27975351 :   if (!OptimizedCodeMapIsCleared()) {
   13842             :     FixedArray* optimized_code_map = this->optimized_code_map();
   13843             :     int length = optimized_code_map->length();
   13844     1913256 :     for (int i = kEntriesStart; i < length; i += kEntryLength) {
   13845     1656207 :       if (WeakCell::cast(optimized_code_map->get(i + kContextOffset))
   13846             :               ->value() == native_context) {
   13847             :         return i;
   13848             :       }
   13849             :     }
   13850             :   }
   13851             :   return -1;
   13852             : }
   13853             : 
   13854    16557760 : void SharedFunctionInfo::ClearCodeFromOptimizedCodeMap() {
   13855    16557760 :   if (!OptimizedCodeMapIsCleared()) {
   13856             :     FixedArray* optimized_code_map = this->optimized_code_map();
   13857             :     int length = optimized_code_map->length();
   13858      126459 :     WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell();
   13859      254079 :     for (int i = kEntriesStart; i < length; i += kEntryLength) {
   13860             :       optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell,
   13861      127620 :                               SKIP_WRITE_BARRIER);
   13862             :     }
   13863             :   }
   13864    16557760 : }
   13865             : 
   13866    27942515 : Code* SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
   13867             :                                                  BailoutId osr_ast_id) {
   13868             :   Code* result = nullptr;
   13869    27942515 :   if (!osr_ast_id.IsNone()) {
   13870        8475 :     return native_context->SearchOptimizedCodeMap(this, osr_ast_id);
   13871             :   }
   13872             : 
   13873             :   DCHECK(osr_ast_id.IsNone());
   13874    27934040 :   int entry = SearchOptimizedCodeMapEntry(native_context);
   13875    27934039 :   if (entry != kNotFound) {
   13876             :     FixedArray* code_map = optimized_code_map();
   13877             :     DCHECK_LE(entry + kEntryLength, code_map->length());
   13878      915837 :     WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset));
   13879      915837 :     result = cell->cleared() ? nullptr : Code::cast(cell->value());
   13880             :   }
   13881    27934039 :   return result;
   13882             : }
   13883             : 
   13884    14306879 : void ObjectVisitor::VisitCodeTarget(Code* host, RelocInfo* rinfo) {
   13885             :   DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
   13886    14306879 :   Object* old_pointer = Code::GetCodeFromTargetAddress(rinfo->target_address());
   13887    14306879 :   Object* new_pointer = old_pointer;
   13888    14306879 :   VisitPointer(host, &new_pointer);
   13889             :   DCHECK_EQ(old_pointer, new_pointer);
   13890    14306879 : }
   13891             : 
   13892           0 : void ObjectVisitor::VisitCodeAgeSequence(Code* host, RelocInfo* rinfo) {
   13893             :   DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
   13894             :   Object* old_pointer = rinfo->code_age_stub();
   13895           0 :   Object* new_pointer = old_pointer;
   13896           0 :   if (old_pointer != nullptr) {
   13897           0 :     VisitPointer(host, &new_pointer);
   13898             :     DCHECK_EQ(old_pointer, new_pointer);
   13899             :   }
   13900           0 : }
   13901             : 
   13902     2925048 : void ObjectVisitor::VisitCodeEntry(JSFunction* host, Address entry_address) {
   13903     2925048 :   Object* old_pointer = Code::GetObjectFromEntryAddress(entry_address);
   13904     2925048 :   Object* new_pointer = old_pointer;
   13905     2925048 :   VisitPointer(host, &new_pointer);
   13906             :   DCHECK_EQ(old_pointer, new_pointer);
   13907     2925048 : }
   13908             : 
   13909        3364 : void ObjectVisitor::VisitCellPointer(Code* host, RelocInfo* rinfo) {
   13910             :   DCHECK(rinfo->rmode() == RelocInfo::CELL);
   13911             :   Object* old_pointer = rinfo->target_cell();
   13912        3364 :   Object* new_pointer = old_pointer;
   13913        3364 :   VisitPointer(host, &new_pointer);
   13914             :   DCHECK_EQ(old_pointer, new_pointer);
   13915        3364 : }
   13916             : 
   13917          12 : void ObjectVisitor::VisitDebugTarget(Code* host, RelocInfo* rinfo) {
   13918             :   DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
   13919             :          rinfo->IsPatchedDebugBreakSlotSequence());
   13920             :   Object* old_pointer =
   13921          12 :       Code::GetCodeFromTargetAddress(rinfo->debug_call_address());
   13922          12 :   Object* new_pointer = old_pointer;
   13923          12 :   VisitPointer(host, &new_pointer);
   13924             :   DCHECK_EQ(old_pointer, new_pointer);
   13925          12 : }
   13926             : 
   13927     2082470 : void ObjectVisitor::VisitEmbeddedPointer(Code* host, RelocInfo* rinfo) {
   13928             :   DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
   13929             :   Object* old_pointer = rinfo->target_object();
   13930     2082470 :   Object* new_pointer = old_pointer;
   13931     2082470 :   VisitPointer(host, &new_pointer);
   13932             :   DCHECK_EQ(old_pointer, new_pointer);
   13933     2082470 : }
   13934             : 
   13935             : 
   13936      413300 : void Code::InvalidateRelocation() {
   13937      413300 :   InvalidateEmbeddedObjects();
   13938      413300 :   set_relocation_info(GetHeap()->empty_byte_array());
   13939      413300 : }
   13940             : 
   13941             : 
   13942      418597 : void Code::InvalidateEmbeddedObjects() {
   13943      418597 :   HeapObject* undefined = GetHeap()->undefined_value();
   13944      418597 :   Cell* undefined_cell = GetHeap()->undefined_cell();
   13945             :   int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
   13946             :                   RelocInfo::ModeMask(RelocInfo::CELL);
   13947     4910502 :   for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
   13948     4491905 :     RelocInfo::Mode mode = it.rinfo()->rmode();
   13949     4491905 :     if (mode == RelocInfo::EMBEDDED_OBJECT) {
   13950             :       it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER);
   13951           0 :     } else if (mode == RelocInfo::CELL) {
   13952             :       it.rinfo()->set_target_cell(undefined_cell, SKIP_WRITE_BARRIER);
   13953             :     }
   13954             :   }
   13955      418597 : }
   13956             : 
   13957             : 
   13958      182981 : void Code::Relocate(intptr_t delta) {
   13959      191358 :   if (trap_handler::UseTrapHandler() && is_wasm_code()) {
   13960             :     const int index = trap_handler_index()->value();
   13961        2299 :     if (index >= 0) {
   13962          42 :       trap_handler::UpdateHandlerDataCodePointer(index, instruction_start());
   13963             :     }
   13964             :   }
   13965      700767 :   for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
   13966             :     it.rinfo()->apply(delta);
   13967             :   }
   13968      365962 :   Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size());
   13969      182981 : }
   13970             : 
   13971             : 
   13972     2554076 : void Code::CopyFrom(const CodeDesc& desc) {
   13973             :   // copy code
   13974             :   CopyBytes(instruction_start(), desc.buffer,
   13975     2554076 :             static_cast<size_t>(desc.instr_size));
   13976             : 
   13977             :   // copy unwinding info, if any
   13978     2554070 :   if (desc.unwinding_info) {
   13979             :     DCHECK_GT(desc.unwinding_info_size, 0);
   13980          25 :     set_unwinding_info_size(desc.unwinding_info_size);
   13981             :     CopyBytes(unwinding_info_start(), desc.unwinding_info,
   13982          25 :               static_cast<size_t>(desc.unwinding_info_size));
   13983             :   }
   13984             : 
   13985             :   // copy reloc info
   13986             :   CopyBytes(relocation_start(),
   13987     2554070 :             desc.buffer + desc.buffer_size - desc.reloc_size,
   13988     7662210 :             static_cast<size_t>(desc.reloc_size));
   13989             : 
   13990             :   // unbox handles and relocate
   13991     2554076 :   intptr_t delta = instruction_start() - desc.buffer;
   13992             :   int mode_mask = RelocInfo::kCodeTargetMask |
   13993             :                   RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
   13994             :                   RelocInfo::ModeMask(RelocInfo::CELL) |
   13995     2554076 :                   RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
   13996     2554076 :                   RelocInfo::kApplyMask;
   13997             :   // Needed to find target_object and runtime_entry on X64
   13998     2554076 :   Assembler* origin = desc.origin;
   13999             :   AllowDeferredHandleDereference embedding_raw_address;
   14000    37638241 :   for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
   14001    35084122 :     RelocInfo::Mode mode = it.rinfo()->rmode();
   14002    35084122 :     if (mode == RelocInfo::EMBEDDED_OBJECT) {
   14003    16181444 :       Handle<HeapObject> p = it.rinfo()->target_object_handle(origin);
   14004             :       it.rinfo()->set_target_object(*p, UPDATE_WRITE_BARRIER,
   14005             :                                     SKIP_ICACHE_FLUSH);
   14006    18902678 :     } else if (mode == RelocInfo::CELL) {
   14007       38640 :       Handle<Cell> cell  = it.rinfo()->target_cell_handle();
   14008             :       it.rinfo()->set_target_cell(*cell, UPDATE_WRITE_BARRIER,
   14009             :                                   SKIP_ICACHE_FLUSH);
   14010    18864038 :     } else if (RelocInfo::IsCodeTarget(mode)) {
   14011             :       // rewrite code handles in inline cache targets to direct
   14012             :       // pointers to the first instruction in the code object
   14013    17863285 :       Handle<Object> p = it.rinfo()->target_object_handle(origin);
   14014             :       Code* code = Code::cast(*p);
   14015             :       it.rinfo()->set_target_address(GetIsolate(), code->instruction_start(),
   14016    35726580 :                                      UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
   14017     1000753 :     } else if (RelocInfo::IsRuntimeEntry(mode)) {
   14018      887221 :       Address p = it.rinfo()->target_runtime_entry(origin);
   14019             :       it.rinfo()->set_target_runtime_entry(
   14020             :           GetIsolate(), p, UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
   14021      113532 :     } else if (mode == RelocInfo::CODE_AGE_SEQUENCE) {
   14022          14 :       Handle<Object> p = it.rinfo()->code_age_stub_handle(origin);
   14023             :       Code* code = Code::cast(*p);
   14024          14 :       it.rinfo()->set_code_age_stub(code, SKIP_ICACHE_FLUSH);
   14025             :     } else {
   14026             :       it.rinfo()->apply(delta);
   14027             :     }
   14028             :   }
   14029     5108172 :   Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size());
   14030     2554085 : }
   14031             : 
   14032             : 
   14033     1736619 : SafepointEntry Code::GetSafepointEntry(Address pc) {
   14034     1736619 :   SafepointTable table(this);
   14035     1736619 :   return table.FindEntry(pc);
   14036             : }
   14037             : 
   14038             : 
   14039      833470 : Object* Code::FindNthObject(int n, Map* match_map) {
   14040             :   DCHECK(is_inline_cache_stub());
   14041             :   DisallowHeapAllocation no_allocation;
   14042             :   int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
   14043     1329965 :   for (RelocIterator it(this, mask); !it.done(); it.next()) {
   14044      572114 :     RelocInfo* info = it.rinfo();
   14045             :     Object* object = info->target_object();
   14046      572114 :     if (object->IsWeakCell()) object = WeakCell::cast(object)->value();
   14047      572114 :     if (object->IsHeapObject()) {
   14048      572114 :       if (HeapObject::cast(object)->map() == match_map) {
   14049       75619 :         if (--n == 0) return object;
   14050             :       }
   14051             :     }
   14052             :   }
   14053      757850 :   return NULL;
   14054             : }
   14055             : 
   14056             : 
   14057      386655 : AllocationSite* Code::FindFirstAllocationSite() {
   14058      386655 :   Object* result = FindNthObject(1, GetHeap()->allocation_site_map());
   14059      386655 :   return (result != NULL) ? AllocationSite::cast(result) : NULL;
   14060             : }
   14061             : 
   14062             : 
   14063      446815 : Map* Code::FindFirstMap() {
   14064      446815 :   Object* result = FindNthObject(1, GetHeap()->meta_map());
   14065      446814 :   return (result != NULL) ? Map::cast(result) : NULL;
   14066             : }
   14067             : 
   14068             : 
   14069       46790 : void Code::FindAndReplace(const FindAndReplacePattern& pattern) {
   14070             :   DCHECK(is_inline_cache_stub() || is_handler());
   14071             :   DisallowHeapAllocation no_allocation;
   14072             :   int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
   14073             :   STATIC_ASSERT(FindAndReplacePattern::kMaxCount < 32);
   14074             :   int current_pattern = 0;
   14075       46790 :   for (RelocIterator it(this, mask); !it.done(); it.next()) {
   14076       46790 :     RelocInfo* info = it.rinfo();
   14077             :     HeapObject* object = info->target_object();
   14078       46790 :     if (object->IsWeakCell()) {
   14079             :       object = HeapObject::cast(WeakCell::cast(object)->value());
   14080             :     }
   14081             :     Map* map = object->map();
   14082       93580 :     if (map == *pattern.find_[current_pattern]) {
   14083       46790 :       info->set_target_object(*pattern.replace_[current_pattern]);
   14084       93580 :       if (++current_pattern == pattern.count_) return;
   14085             :     }
   14086             :   }
   14087           0 :   UNREACHABLE();
   14088             : }
   14089             : 
   14090             : 
   14091     4535327 : void Code::ClearInlineCaches() {
   14092             :   int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
   14093             :              RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
   14094    19728284 :   for (RelocIterator it(this, mask); !it.done(); it.next()) {
   14095    15192936 :     RelocInfo* info = it.rinfo();
   14096             :     Code* target(Code::GetCodeFromTargetAddress(info->target_address()));
   14097    15192957 :     if (target->is_inline_cache_stub()) {
   14098             :       ICUtility::Clear(this->GetIsolate(), info->pc(),
   14099      132284 :                        info->host()->constant_pool());
   14100             :     }
   14101             :   }
   14102     4535332 : }
   14103             : 
   14104             : namespace {
   14105             : template <typename Code>
   14106        9579 : void SetStackFrameCacheCommon(Handle<Code> code,
   14107             :                               Handle<UnseededNumberDictionary> cache) {
   14108             :   Handle<Object> maybe_table(code->source_position_table(), code->GetIsolate());
   14109        9579 :   if (maybe_table->IsSourcePositionTableWithFrameCache()) {
   14110         638 :     Handle<SourcePositionTableWithFrameCache>::cast(maybe_table)
   14111             :         ->set_stack_frame_cache(*cache);
   14112       10217 :     return;
   14113             :   }
   14114             :   DCHECK(maybe_table->IsByteArray());
   14115        8941 :   Handle<ByteArray> table(Handle<ByteArray>::cast(maybe_table));
   14116             :   Handle<SourcePositionTableWithFrameCache> table_with_cache =
   14117             :       code->GetIsolate()->factory()->NewSourcePositionTableWithFrameCache(
   14118        8941 :           table, cache);
   14119        8941 :   code->set_source_position_table(*table_with_cache);
   14120             : }
   14121             : }  // namespace
   14122             : 
   14123             : // static
   14124        9579 : void AbstractCode::SetStackFrameCache(Handle<AbstractCode> abstract_code,
   14125             :                                       Handle<UnseededNumberDictionary> cache) {
   14126        9579 :   if (abstract_code->IsCode()) {
   14127        2902 :     SetStackFrameCacheCommon(handle(abstract_code->GetCode()), cache);
   14128             :   } else {
   14129        6677 :     SetStackFrameCacheCommon(handle(abstract_code->GetBytecodeArray()), cache);
   14130             :   }
   14131        9579 : }
   14132             : 
   14133             : namespace {
   14134             : template <typename Code>
   14135     8945708 : void DropStackFrameCacheCommon(Code* code) {
   14136             :   i::Object* maybe_table = code->source_position_table();
   14137    17891416 :   if (maybe_table->IsByteArray()) return;
   14138             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
   14139           0 :   code->set_source_position_table(
   14140             :       i::SourcePositionTableWithFrameCache::cast(maybe_table)
   14141             :           ->source_position_table());
   14142             : }
   14143             : }  // namespace
   14144             : 
   14145     8945708 : void AbstractCode::DropStackFrameCache() {
   14146     8945708 :   if (IsCode()) {
   14147     8935385 :     DropStackFrameCacheCommon(GetCode());
   14148             :   } else {
   14149       10323 :     DropStackFrameCacheCommon(GetBytecodeArray());
   14150             :   }
   14151     8945708 : }
   14152             : 
   14153     2060741 : int AbstractCode::SourcePosition(int offset) {
   14154             :   int position = 0;
   14155             :   // Subtract one because the current PC is one instruction after the call site.
   14156     2060741 :   if (IsCode()) offset--;
   14157    68749268 :   for (SourcePositionTableIterator iterator(source_position_table());
   14158    66688527 :        !iterator.done() && iterator.code_offset() <= offset;
   14159    64627786 :        iterator.Advance()) {
   14160    64627786 :     position = iterator.source_position().ScriptOffset();
   14161             :   }
   14162     2060741 :   return position;
   14163             : }
   14164             : 
   14165      155350 : int AbstractCode::SourceStatementPosition(int offset) {
   14166             :   // First find the closest position.
   14167      155350 :   int position = SourcePosition(offset);
   14168             :   // Now find the closest statement position before the position.
   14169             :   int statement_position = 0;
   14170    25647559 :   for (SourcePositionTableIterator it(source_position_table()); !it.done();
   14171    25336859 :        it.Advance()) {
   14172    25336859 :     if (it.is_statement()) {
   14173    10861866 :       int p = it.source_position().ScriptOffset();
   14174    10861866 :       if (statement_position < p && p <= position) {
   14175             :         statement_position = p;
   14176             :       }
   14177             :     }
   14178             :   }
   14179      155350 :   return statement_position;
   14180             : }
   14181             : 
   14182      240567 : void JSFunction::ClearTypeFeedbackInfo() {
   14183      240567 :   if (feedback_vector_cell()->value()->IsFeedbackVector()) {
   14184             :     FeedbackVector* vector = feedback_vector();
   14185       91974 :     vector->ClearSlots(this);
   14186             :   }
   14187      240567 : }
   14188             : 
   14189        2639 : BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) {
   14190             :   DisallowHeapAllocation no_gc;
   14191             :   DCHECK(kind() == FUNCTION);
   14192             :   BackEdgeTable back_edges(this, &no_gc);
   14193        3626 :   for (uint32_t i = 0; i < back_edges.length(); i++) {
   14194        3626 :     if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i);
   14195             :   }
   14196             :   return BailoutId::None();
   14197             : }
   14198             : 
   14199             : 
   14200           0 : uint32_t Code::TranslateAstIdToPcOffset(BailoutId ast_id) {
   14201             :   DisallowHeapAllocation no_gc;
   14202             :   DCHECK(kind() == FUNCTION);
   14203             :   BackEdgeTable back_edges(this, &no_gc);
   14204           0 :   for (uint32_t i = 0; i < back_edges.length(); i++) {
   14205           0 :     if (back_edges.ast_id(i) == ast_id) return back_edges.pc_offset(i);
   14206             :   }
   14207           0 :   UNREACHABLE();  // We expect to find the back edge.
   14208             :   return 0;
   14209             : }
   14210             : 
   14211      653325 : void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) {
   14212      653681 :   PatchPlatformCodeAge(isolate, sequence, kNoAgeCodeAge);
   14213      653325 : }
   14214             : 
   14215             : 
   14216          15 : void Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) {
   14217          15 :   PatchPlatformCodeAge(isolate, sequence, kExecutedOnceCodeAge);
   14218          15 : }
   14219             : 
   14220             : 
   14221             : // NextAge defines the Code::Age state transitions during a GC cycle.
   14222             : static Code::Age NextAge(Code::Age age) {
   14223     1181541 :   switch (age) {
   14224             :     case Code::kNotExecutedCodeAge:  // Keep, until we've been executed.
   14225             :     case Code::kToBeExecutedOnceCodeAge:  // Keep, until we've been executed.
   14226             :     case Code::kLastCodeAge:  // Clamp at last Code::Age value.
   14227             :       return age;
   14228             :     case Code::kExecutedOnceCodeAge:
   14229             :       // Pre-age code that has only been executed once.
   14230             :       return static_cast<Code::Age>(Code::kPreAgedCodeAge + 1);
   14231             :     default:
   14232     1012993 :       return static_cast<Code::Age>(age + 1);  // Default case: Increase age.
   14233             :   }
   14234             : }
   14235             : 
   14236             : 
   14237             : // IsOldAge defines the collection criteria for a Code object.
   14238             : static bool IsOldAge(Code::Age age) {
   14239    14057727 :   return age >= Code::kIsOldCodeAge || age == Code::kNotExecutedCodeAge;
   14240             : }
   14241             : 
   14242             : 
   14243      199319 : void Code::MakeYoung(Isolate* isolate) {
   14244      199319 :   byte* sequence = FindCodeAgeSequence();
   14245      199319 :   if (sequence != NULL) MakeCodeAgeSequenceYoung(sequence, isolate);
   14246      199319 : }
   14247             : 
   14248           6 : void Code::PreAge(Isolate* isolate) {
   14249           6 :   byte* sequence = FindCodeAgeSequence();
   14250           6 :   if (sequence != NULL) {
   14251           6 :     PatchPlatformCodeAge(isolate, sequence, kPreAgedCodeAge);
   14252             :   }
   14253           6 : }
   14254             : 
   14255          48 : void Code::MarkToBeExecutedOnce(Isolate* isolate) {
   14256          48 :   byte* sequence = FindCodeAgeSequence();
   14257          48 :   if (sequence != NULL) {
   14258          12 :     PatchPlatformCodeAge(isolate, sequence, kToBeExecutedOnceCodeAge);
   14259             :   }
   14260          48 : }
   14261             : 
   14262    74555257 : void Code::MakeOlder() {
   14263    74555257 :   byte* sequence = FindCodeAgeSequence();
   14264    74555264 :   if (sequence != NULL) {
   14265             :     Isolate* isolate = GetIsolate();
   14266     1181541 :     Age age = GetCodeAge(isolate, sequence);
   14267             :     Age next_age = NextAge(age);
   14268     1181541 :     if (age != next_age) {
   14269     1013001 :       PatchPlatformCodeAge(isolate, sequence, next_age);
   14270             :     }
   14271             :   }
   14272    74555264 : }
   14273             : 
   14274             : 
   14275    13874565 : bool Code::IsOld() {
   14276    27932292 :   return IsOldAge(GetAge());
   14277             : }
   14278             : 
   14279             : 
   14280   177649251 : byte* Code::FindCodeAgeSequence() {
   14281   177649275 :   return FLAG_age_code &&
   14282   112941671 :       prologue_offset() != Code::kPrologueOffsetNotSet &&
   14283   110657856 :       (kind() == OPTIMIZED_FUNCTION ||
   14284     4530313 :        (kind() == FUNCTION && !has_debug_break_slots()))
   14285     6301183 :       ? instruction_start() + prologue_offset()
   14286   183950434 :       : NULL;
   14287             : }
   14288             : 
   14289             : 
   14290    14057733 : Code::Age Code::GetAge() {
   14291    14057733 :   byte* sequence = FindCodeAgeSequence();
   14292    14057733 :   if (sequence == NULL) {
   14293             :     return kNoAgeCodeAge;
   14294             :   }
   14295      640788 :   return GetCodeAge(GetIsolate(), sequence);
   14296             : }
   14297             : 
   14298      625322 : Code::Age Code::GetAgeOfCodeAgeStub(Code* code) {
   14299             :   Isolate* isolate = code->GetIsolate();
   14300      625322 :   Builtins* builtins = isolate->builtins();
   14301             : #define HANDLE_CODE_AGE(AGE)                            \
   14302             :   if (code == *builtins->Make##AGE##CodeYoungAgain()) { \
   14303             :     return k##AGE##CodeAge;                             \
   14304             :   }
   14305     2288301 :   CODE_AGE_LIST(HANDLE_CODE_AGE)
   14306             : #undef HANDLE_CODE_AGE
   14307          98 :   if (code == *builtins->MarkCodeAsExecutedOnce()) {
   14308             :     return kNotExecutedCodeAge;
   14309             :   }
   14310          74 :   if (code == *builtins->MarkCodeAsExecutedTwice()) {
   14311             :     return kExecutedOnceCodeAge;
   14312             :   }
   14313          52 :   if (code == *builtins->MarkCodeAsToBeExecutedOnce()) {
   14314             :     return kToBeExecutedOnceCodeAge;
   14315             :   }
   14316           0 :   UNREACHABLE();
   14317             :   return kNoAgeCodeAge;
   14318             : }
   14319             : 
   14320     1013034 : Code* Code::GetCodeAgeStub(Isolate* isolate, Age age) {
   14321     1013034 :   Builtins* builtins = isolate->builtins();
   14322     1013034 :   switch (age) {
   14323             : #define HANDLE_CODE_AGE(AGE)                       \
   14324             :   case k##AGE##CodeAge: {                          \
   14325             :     return *builtins->Make##AGE##CodeYoungAgain(); \
   14326             :   }
   14327     1797379 :     CODE_AGE_LIST(HANDLE_CODE_AGE)
   14328             : #undef HANDLE_CODE_AGE
   14329             :     case kNotExecutedCodeAge: {
   14330           0 :       return *builtins->MarkCodeAsExecutedOnce();
   14331             :     }
   14332             :     case kExecutedOnceCodeAge: {
   14333          30 :       return *builtins->MarkCodeAsExecutedTwice();
   14334             :     }
   14335             :     case kToBeExecutedOnceCodeAge: {
   14336          24 :       return *builtins->MarkCodeAsToBeExecutedOnce();
   14337             :     }
   14338             :     default:
   14339           0 :       UNREACHABLE();
   14340             :       break;
   14341             :   }
   14342             :   return NULL;
   14343             : }
   14344             : 
   14345             : 
   14346           0 : void Code::PrintDeoptLocation(FILE* out, Address pc) {
   14347           0 :   Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(this, pc);
   14348           0 :   class SourcePosition pos = info.position;
   14349           0 :   if (info.deopt_reason != DeoptimizeReason::kNoReason || pos.IsKnown()) {
   14350           0 :     if (FLAG_hydrogen_track_positions) {
   14351             :       PrintF(out, "            ;;; deoptimize at %d_%d: %s\n", pos.InliningId(),
   14352           0 :              pos.ScriptOffset(), DeoptimizeReasonToString(info.deopt_reason));
   14353             :     } else {
   14354           0 :       PrintF(out, "            ;;; deoptimize at ");
   14355           0 :       OFStream outstr(out);
   14356           0 :       pos.Print(outstr, this);
   14357           0 :       PrintF(out, ", %s\n", DeoptimizeReasonToString(info.deopt_reason));
   14358             :     }
   14359             :   }
   14360           0 : }
   14361             : 
   14362             : 
   14363        5320 : bool Code::CanDeoptAt(Address pc) {
   14364             :   DeoptimizationInputData* deopt_data =
   14365             :       DeoptimizationInputData::cast(deoptimization_data());
   14366        5320 :   Address code_start_address = instruction_start();
   14367      190192 :   for (int i = 0; i < deopt_data->DeoptCount(); i++) {
   14368      188306 :     if (deopt_data->Pc(i)->value() == -1) continue;
   14369      126452 :     Address address = code_start_address + deopt_data->Pc(i)->value();
   14370       67605 :     if (address == pc && deopt_data->AstId(i) != BailoutId::None()) {
   14371             :       return true;
   14372             :     }
   14373             :   }
   14374             :   return false;
   14375             : }
   14376             : 
   14377             : 
   14378             : // Identify kind of code.
   14379       29547 : const char* Code::Kind2String(Kind kind) {
   14380       29547 :   switch (kind) {
   14381             : #define CASE(name) case name: return #name;
   14382           0 :     CODE_KIND_LIST(CASE)
   14383             : #undef CASE
   14384             :     case NUMBER_OF_KINDS: break;
   14385             :   }
   14386           0 :   UNREACHABLE();
   14387             :   return NULL;
   14388             : }
   14389             : 
   14390             : // Identify kind of code.
   14391           0 : const char* AbstractCode::Kind2String(Kind kind) {
   14392           0 :   if (kind < AbstractCode::INTERPRETED_FUNCTION)
   14393           0 :     return Code::Kind2String((Code::Kind)kind);
   14394           0 :   if (kind == AbstractCode::INTERPRETED_FUNCTION) return "INTERPRETED_FUNCTION";
   14395           0 :   UNREACHABLE();
   14396             :   return NULL;
   14397             : }
   14398             : 
   14399     2556480 : Handle<WeakCell> Code::WeakCellFor(Handle<Code> code) {
   14400             :   DCHECK(code->kind() == OPTIMIZED_FUNCTION);
   14401     2556480 :   WeakCell* raw_cell = code->CachedWeakCell();
   14402     4779300 :   if (raw_cell != NULL) return Handle<WeakCell>(raw_cell);
   14403      333667 :   Handle<WeakCell> cell = code->GetIsolate()->factory()->NewWeakCell(code);
   14404             :   DeoptimizationInputData::cast(code->deoptimization_data())
   14405             :       ->SetWeakCellCache(*cell);
   14406      333667 :   return cell;
   14407             : }
   14408             : 
   14409             : 
   14410     2556480 : WeakCell* Code::CachedWeakCell() {
   14411             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
   14412             :   Object* weak_cell_cache =
   14413             :       DeoptimizationInputData::cast(deoptimization_data())->WeakCellCache();
   14414     2556482 :   if (weak_cell_cache->IsWeakCell()) {
   14415             :     DCHECK(this == WeakCell::cast(weak_cell_cache)->value());
   14416     2222816 :     return WeakCell::cast(weak_cell_cache);
   14417             :   }
   14418             :   return NULL;
   14419             : }
   14420             : 
   14421             : #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   14422             : 
   14423             : const char* Code::ICState2String(InlineCacheState state) {
   14424             :   switch (state) {
   14425             :     case UNINITIALIZED:
   14426             :       return "UNINITIALIZED";
   14427             :     case PREMONOMORPHIC:
   14428             :       return "PREMONOMORPHIC";
   14429             :     case MONOMORPHIC:
   14430             :       return "MONOMORPHIC";
   14431             :     case RECOMPUTE_HANDLER:
   14432             :       return "RECOMPUTE_HANDLER";
   14433             :     case POLYMORPHIC:
   14434             :       return "POLYMORPHIC";
   14435             :     case MEGAMORPHIC:
   14436             :       return "MEGAMORPHIC";
   14437             :     case GENERIC:
   14438             :       return "GENERIC";
   14439             :   }
   14440             :   UNREACHABLE();
   14441             :   return NULL;
   14442             : }
   14443             : 
   14444             : void Code::PrintExtraICState(std::ostream& os,  // NOLINT
   14445             :                              Kind kind, ExtraICState extra) {
   14446             :   os << "extra_ic_state = ";
   14447             :   if ((kind == STORE_IC || kind == KEYED_STORE_IC) &&
   14448             :       is_strict(static_cast<LanguageMode>(extra))) {
   14449             :     os << "STRICT\n";
   14450             :   } else {
   14451             :     os << extra << "\n";
   14452             :   }
   14453             : }
   14454             : 
   14455             : #endif  // defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   14456             : 
   14457             : #ifdef ENABLE_DISASSEMBLER
   14458             : 
   14459             : void DeoptimizationInputData::DeoptimizationInputDataPrint(
   14460             :     std::ostream& os) {  // NOLINT
   14461             :   disasm::NameConverter converter;
   14462             :   int const inlined_function_count = InlinedFunctionCount()->value();
   14463             :   os << "Inlined functions (count = " << inlined_function_count << ")\n";
   14464             :   for (int id = 0; id < inlined_function_count; ++id) {
   14465             :     Object* info = LiteralArray()->get(id);
   14466             :     os << " " << Brief(SharedFunctionInfo::cast(info)) << "\n";
   14467             :   }
   14468             :   os << "\n";
   14469             :   int deopt_count = DeoptCount();
   14470             :   os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
   14471             :   if (0 != deopt_count) {
   14472             :     os << " index  ast id    argc     pc";
   14473             :     if (FLAG_print_code_verbose) os << "  commands";
   14474             :     os << "\n";
   14475             :   }
   14476             :   for (int i = 0; i < deopt_count; i++) {
   14477             :     os << std::setw(6) << i << "  " << std::setw(6) << AstId(i).ToInt() << "  "
   14478             :        << std::setw(6) << ArgumentsStackHeight(i)->value() << " "
   14479             :        << std::setw(6) << Pc(i)->value();
   14480             : 
   14481             :     if (!FLAG_print_code_verbose) {
   14482             :       os << "\n";
   14483             :       continue;
   14484             :     }
   14485             :     // Print details of the frame translation.
   14486             :     int translation_index = TranslationIndex(i)->value();
   14487             :     TranslationIterator iterator(TranslationByteArray(), translation_index);
   14488             :     Translation::Opcode opcode =
   14489             :         static_cast<Translation::Opcode>(iterator.Next());
   14490             :     DCHECK(Translation::BEGIN == opcode);
   14491             :     int frame_count = iterator.Next();
   14492             :     int jsframe_count = iterator.Next();
   14493             :     os << "  " << Translation::StringFor(opcode)
   14494             :        << " {frame count=" << frame_count
   14495             :        << ", js frame count=" << jsframe_count << "}\n";
   14496             : 
   14497             :     while (iterator.HasNext() &&
   14498             :            Translation::BEGIN !=
   14499             :            (opcode = static_cast<Translation::Opcode>(iterator.Next()))) {
   14500             :       os << std::setw(31) << "    " << Translation::StringFor(opcode) << " ";
   14501             : 
   14502             :       switch (opcode) {
   14503             :         case Translation::BEGIN:
   14504             :           UNREACHABLE();
   14505             :           break;
   14506             : 
   14507             :         case Translation::JS_FRAME: {
   14508             :           int ast_id = iterator.Next();
   14509             :           int shared_info_id = iterator.Next();
   14510             :           unsigned height = iterator.Next();
   14511             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14512             :           os << "{ast_id=" << ast_id << ", function="
   14513             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14514             :              << ", height=" << height << "}";
   14515             :           break;
   14516             :         }
   14517             : 
   14518             :         case Translation::INTERPRETED_FRAME: {
   14519             :           int bytecode_offset = iterator.Next();
   14520             :           int shared_info_id = iterator.Next();
   14521             :           unsigned height = iterator.Next();
   14522             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14523             :           os << "{bytecode_offset=" << bytecode_offset << ", function="
   14524             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14525             :              << ", height=" << height << "}";
   14526             :           break;
   14527             :         }
   14528             : 
   14529             :         case Translation::CONSTRUCT_STUB_FRAME: {
   14530             :           int bailout_id = iterator.Next();
   14531             :           int shared_info_id = iterator.Next();
   14532             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14533             :           unsigned height = iterator.Next();
   14534             :           os << "{bailout_id=" << bailout_id << ", function="
   14535             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14536             :              << ", height=" << height << "}";
   14537             :           break;
   14538             :         }
   14539             : 
   14540             :         case Translation::COMPILED_STUB_FRAME: {
   14541             :           Code::Kind stub_kind = static_cast<Code::Kind>(iterator.Next());
   14542             :           os << "{kind=" << stub_kind << "}";
   14543             :           break;
   14544             :         }
   14545             : 
   14546             :         case Translation::ARGUMENTS_ADAPTOR_FRAME: {
   14547             :           int shared_info_id = iterator.Next();
   14548             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14549             :           unsigned height = iterator.Next();
   14550             :           os << "{function="
   14551             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14552             :              << ", height=" << height << "}";
   14553             :           break;
   14554             :         }
   14555             : 
   14556             :         case Translation::TAIL_CALLER_FRAME: {
   14557             :           int shared_info_id = iterator.Next();
   14558             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14559             :           os << "{function="
   14560             :              << Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
   14561             :              << "}";
   14562             :           break;
   14563             :         }
   14564             : 
   14565             :         case Translation::GETTER_STUB_FRAME:
   14566             :         case Translation::SETTER_STUB_FRAME: {
   14567             :           int shared_info_id = iterator.Next();
   14568             :           Object* shared_info = LiteralArray()->get(shared_info_id);
   14569             :           os << "{function=" << Brief(SharedFunctionInfo::cast(shared_info)
   14570             :                                           ->DebugName()) << "}";
   14571             :           break;
   14572             :         }
   14573             : 
   14574             :         case Translation::REGISTER: {
   14575             :           int reg_code = iterator.Next();
   14576             :           os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
   14577             :           break;
   14578             :         }
   14579             : 
   14580             :         case Translation::INT32_REGISTER: {
   14581             :           int reg_code = iterator.Next();
   14582             :           os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
   14583             :           break;
   14584             :         }
   14585             : 
   14586             :         case Translation::UINT32_REGISTER: {
   14587             :           int reg_code = iterator.Next();
   14588             :           os << "{input=" << converter.NameOfCPURegister(reg_code)
   14589             :              << " (unsigned)}";
   14590             :           break;
   14591             :         }
   14592             : 
   14593             :         case Translation::BOOL_REGISTER: {
   14594             :           int reg_code = iterator.Next();
   14595             :           os << "{input=" << converter.NameOfCPURegister(reg_code)
   14596             :              << " (bool)}";
   14597             :           break;
   14598             :         }
   14599             : 
   14600             :         case Translation::FLOAT_REGISTER: {
   14601             :           int reg_code = iterator.Next();
   14602             :           os << "{input="
   14603             :              << RegisterConfiguration::Crankshaft()->GetFloatRegisterName(
   14604             :                     reg_code)
   14605             :              << "}";
   14606             :           break;
   14607             :         }
   14608             : 
   14609             :         case Translation::DOUBLE_REGISTER: {
   14610             :           int reg_code = iterator.Next();
   14611             :           os << "{input="
   14612             :              << RegisterConfiguration::Crankshaft()->GetDoubleRegisterName(
   14613             :                     reg_code)
   14614             :              << "}";
   14615             :           break;
   14616             :         }
   14617             : 
   14618             :         case Translation::STACK_SLOT: {
   14619             :           int input_slot_index = iterator.Next();
   14620             :           os << "{input=" << input_slot_index << "}";
   14621             :           break;
   14622             :         }
   14623             : 
   14624             :         case Translation::INT32_STACK_SLOT: {
   14625             :           int input_slot_index = iterator.Next();
   14626             :           os << "{input=" << input_slot_index << "}";
   14627             :           break;
   14628             :         }
   14629             : 
   14630             :         case Translation::UINT32_STACK_SLOT: {
   14631             :           int input_slot_index = iterator.Next();
   14632             :           os << "{input=" << input_slot_index << " (unsigned)}";
   14633             :           break;
   14634             :         }
   14635             : 
   14636             :         case Translation::BOOL_STACK_SLOT: {
   14637             :           int input_slot_index = iterator.Next();
   14638             :           os << "{input=" << input_slot_index << " (bool)}";
   14639             :           break;
   14640             :         }
   14641             : 
   14642             :         case Translation::FLOAT_STACK_SLOT:
   14643             :         case Translation::DOUBLE_STACK_SLOT: {
   14644             :           int input_slot_index = iterator.Next();
   14645             :           os << "{input=" << input_slot_index << "}";
   14646             :           break;
   14647             :         }
   14648             : 
   14649             :         case Translation::LITERAL: {
   14650             :           int literal_index = iterator.Next();
   14651             :           Object* literal_value = LiteralArray()->get(literal_index);
   14652             :           os << "{literal_id=" << literal_index << " (" << Brief(literal_value)
   14653             :              << ")}";
   14654             :           break;
   14655             :         }
   14656             : 
   14657             :         case Translation::DUPLICATED_OBJECT: {
   14658             :           int object_index = iterator.Next();
   14659             :           os << "{object_index=" << object_index << "}";
   14660             :           break;
   14661             :         }
   14662             : 
   14663             :         case Translation::ARGUMENTS_ELEMENTS:
   14664             :         case Translation::ARGUMENTS_LENGTH: {
   14665             :           bool is_rest = iterator.Next();
   14666             :           os << "{is_rest=" << (is_rest ? "true" : "false") << "}";
   14667             :           break;
   14668             :         }
   14669             : 
   14670             :         case Translation::ARGUMENTS_OBJECT:
   14671             :         case Translation::CAPTURED_OBJECT: {
   14672             :           int args_length = iterator.Next();
   14673             :           os << "{length=" << args_length << "}";
   14674             :           break;
   14675             :         }
   14676             :       }
   14677             :       os << "\n";
   14678             :     }
   14679             :   }
   14680             : }
   14681             : 
   14682             : 
   14683             : void DeoptimizationOutputData::DeoptimizationOutputDataPrint(
   14684             :     std::ostream& os) {  // NOLINT
   14685             :   os << "Deoptimization Output Data (deopt points = " << this->DeoptPoints()
   14686             :      << ")\n";
   14687             :   if (this->DeoptPoints() == 0) return;
   14688             : 
   14689             :   os << "ast id        pc  state\n";
   14690             :   for (int i = 0; i < this->DeoptPoints(); i++) {
   14691             :     int pc_and_state = this->PcAndState(i)->value();
   14692             :     os << std::setw(6) << this->AstId(i).ToInt() << "  " << std::setw(8)
   14693             :        << FullCodeGenerator::PcField::decode(pc_and_state) << "  "
   14694             :        << Deoptimizer::BailoutStateToString(
   14695             :               FullCodeGenerator::BailoutStateField::decode(pc_and_state))
   14696             :        << "\n";
   14697             :   }
   14698             : }
   14699             : 
   14700             : 
   14701             : void HandlerTable::HandlerTableRangePrint(std::ostream& os) {
   14702             :   os << "   from   to       hdlr\n";
   14703             :   for (int i = 0; i < length(); i += kRangeEntrySize) {
   14704             :     int pc_start = Smi::cast(get(i + kRangeStartIndex))->value();
   14705             :     int pc_end = Smi::cast(get(i + kRangeEndIndex))->value();
   14706             :     int handler_field = Smi::cast(get(i + kRangeHandlerIndex))->value();
   14707             :     int handler_offset = HandlerOffsetField::decode(handler_field);
   14708             :     CatchPrediction prediction = HandlerPredictionField::decode(handler_field);
   14709             :     int data = Smi::cast(get(i + kRangeDataIndex))->value();
   14710             :     os << "  (" << std::setw(4) << pc_start << "," << std::setw(4) << pc_end
   14711             :        << ")  ->  " << std::setw(4) << handler_offset
   14712             :        << " (prediction=" << prediction << ", data=" << data << ")\n";
   14713             :   }
   14714             : }
   14715             : 
   14716             : 
   14717             : void HandlerTable::HandlerTableReturnPrint(std::ostream& os) {
   14718             :   os << "   off      hdlr (c)\n";
   14719             :   for (int i = 0; i < length(); i += kReturnEntrySize) {
   14720             :     int pc_offset = Smi::cast(get(i + kReturnOffsetIndex))->value();
   14721             :     int handler_field = Smi::cast(get(i + kReturnHandlerIndex))->value();
   14722             :     int handler_offset = HandlerOffsetField::decode(handler_field);
   14723             :     CatchPrediction prediction = HandlerPredictionField::decode(handler_field);
   14724             :     os << "  " << std::setw(4) << pc_offset << "  ->  " << std::setw(4)
   14725             :        << handler_offset << " (prediction=" << prediction << ")\n";
   14726             :   }
   14727             : }
   14728             : 
   14729             : 
   14730             : void Code::Disassemble(const char* name, std::ostream& os) {  // NOLINT
   14731             :   os << "kind = " << Kind2String(kind()) << "\n";
   14732             :   if (IsCodeStubOrIC()) {
   14733             :     const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this));
   14734             :     os << "major_key = " << (n == NULL ? "null" : n) << "\n";
   14735             :   }
   14736             :   if (is_inline_cache_stub()) {
   14737             :     if (is_compare_ic_stub() || is_to_boolean_ic_stub() ||
   14738             :         is_binary_op_stub()) {
   14739             :       InlineCacheState ic_state = IC::StateFromCode(this);
   14740             :       os << "ic_state = " << ICState2String(ic_state) << "\n";
   14741             :       PrintExtraICState(os, kind(), extra_ic_state());
   14742             :     }
   14743             :     if (is_compare_ic_stub()) {
   14744             :       DCHECK(CodeStub::GetMajorKey(this) == CodeStub::CompareIC);
   14745             :       CompareICStub stub(stub_key(), GetIsolate());
   14746             :       os << "compare_state = " << CompareICState::GetStateName(stub.left())
   14747             :          << "*" << CompareICState::GetStateName(stub.right()) << " -> "
   14748             :          << CompareICState::GetStateName(stub.state()) << "\n";
   14749             :       os << "compare_operation = " << Token::Name(stub.op()) << "\n";
   14750             :     }
   14751             :   }
   14752             :   if ((name != nullptr) && (name[0] != '\0')) {
   14753             :     os << "name = " << name << "\n";
   14754             :   } else if (kind() == BUILTIN) {
   14755             :     name = GetIsolate()->builtins()->Lookup(instruction_start());
   14756             :     if (name != nullptr) {
   14757             :       os << "name = " << name << "\n";
   14758             :     }
   14759             :   } else if (kind() == BYTECODE_HANDLER) {
   14760             :     name = GetIsolate()->interpreter()->LookupNameOfBytecodeHandler(this);
   14761             :     if (name != nullptr) {
   14762             :       os << "name = " << name << "\n";
   14763             :     }
   14764             :   }
   14765             :   if (kind() == OPTIMIZED_FUNCTION) {
   14766             :     os << "stack_slots = " << stack_slots() << "\n";
   14767             :   }
   14768             :   os << "compiler = " << (is_turbofanned()
   14769             :                               ? "turbofan"
   14770             :                               : is_crankshafted() ? "crankshaft"
   14771             :                                                   : kind() == Code::FUNCTION
   14772             :                                                         ? "full-codegen"
   14773             :                                                         : "unknown") << "\n";
   14774             : 
   14775             :   os << "Instructions (size = " << instruction_size() << ")\n";
   14776             :   {
   14777             :     Isolate* isolate = GetIsolate();
   14778             :     int size = instruction_size();
   14779             :     int safepoint_offset =
   14780             :         is_crankshafted() ? static_cast<int>(safepoint_table_offset()) : size;
   14781             :     int back_edge_offset = (kind() == Code::FUNCTION)
   14782             :                                ? static_cast<int>(back_edge_table_offset())
   14783             :                                : size;
   14784             :     int constant_pool_offset = FLAG_enable_embedded_constant_pool
   14785             :                                    ? this->constant_pool_offset()
   14786             :                                    : size;
   14787             : 
   14788             :     // Stop before reaching any embedded tables
   14789             :     int code_size = Min(safepoint_offset, back_edge_offset);
   14790             :     code_size = Min(code_size, constant_pool_offset);
   14791             :     byte* begin = instruction_start();
   14792             :     byte* end = begin + code_size;
   14793             :     Disassembler::Decode(isolate, &os, begin, end, this);
   14794             : 
   14795             :     if (constant_pool_offset < size) {
   14796             :       int constant_pool_size = size - constant_pool_offset;
   14797             :       DCHECK((constant_pool_size & kPointerAlignmentMask) == 0);
   14798             :       os << "\nConstant Pool (size = " << constant_pool_size << ")\n";
   14799             :       Vector<char> buf = Vector<char>::New(50);
   14800             :       intptr_t* ptr = reinterpret_cast<intptr_t*>(begin + constant_pool_offset);
   14801             :       for (int i = 0; i < constant_pool_size; i += kPointerSize, ptr++) {
   14802             :         SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr);
   14803             :         os << static_cast<const void*>(ptr) << "  " << buf.start() << "\n";
   14804             :       }
   14805             :     }
   14806             :   }
   14807             :   os << "\n";
   14808             : 
   14809             :   SourcePositionTableIterator it(SourcePositionTable());
   14810             :   if (!it.done()) {
   14811             :     os << "Source positions:\n pc offset  position\n";
   14812             :     for (; !it.done(); it.Advance()) {
   14813             :       os << std::setw(10) << std::hex << it.code_offset() << std::dec
   14814             :          << std::setw(10) << it.source_position().ScriptOffset()
   14815             :          << (it.is_statement() ? "  statement" : "") << "\n";
   14816             :     }
   14817             :     os << "\n";
   14818             :   }
   14819             : 
   14820             :   if (kind() == FUNCTION) {
   14821             :     DeoptimizationOutputData* data =
   14822             :         DeoptimizationOutputData::cast(this->deoptimization_data());
   14823             :     data->DeoptimizationOutputDataPrint(os);
   14824             :   } else if (kind() == OPTIMIZED_FUNCTION) {
   14825             :     DeoptimizationInputData* data =
   14826             :         DeoptimizationInputData::cast(this->deoptimization_data());
   14827             :     data->DeoptimizationInputDataPrint(os);
   14828             :   }
   14829             :   os << "\n";
   14830             : 
   14831             :   if (is_crankshafted()) {
   14832             :     SafepointTable table(this);
   14833             :     os << "Safepoints (size = " << table.size() << ")\n";
   14834             :     for (unsigned i = 0; i < table.length(); i++) {
   14835             :       unsigned pc_offset = table.GetPcOffset(i);
   14836             :       os << static_cast<const void*>(instruction_start() + pc_offset) << "  ";
   14837             :       os << std::setw(4) << std::hex << pc_offset << std::dec << "  ";
   14838             :       table.PrintEntry(i, os);
   14839             :       os << " (sp -> fp)  ";
   14840             :       SafepointEntry entry = table.GetEntry(i);
   14841             :       if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
   14842             :         os << std::setw(6) << entry.deoptimization_index();
   14843             :       } else {
   14844             :         os << "<none>";
   14845             :       }
   14846             :       if (entry.argument_count() > 0) {
   14847             :         os << " argc: " << entry.argument_count();
   14848             :       }
   14849             :       os << "\n";
   14850             :     }
   14851             :     os << "\n";
   14852             :   } else if (kind() == FUNCTION) {
   14853             :     unsigned offset = back_edge_table_offset();
   14854             :     // If there is no back edge table, the "table start" will be at or after
   14855             :     // (due to alignment) the end of the instruction stream.
   14856             :     if (static_cast<int>(offset) < instruction_size()) {
   14857             :       DisallowHeapAllocation no_gc;
   14858             :       BackEdgeTable back_edges(this, &no_gc);
   14859             : 
   14860             :       os << "Back edges (size = " << back_edges.length() << ")\n";
   14861             :       os << "ast_id  pc_offset  loop_depth\n";
   14862             : 
   14863             :       for (uint32_t i = 0; i < back_edges.length(); i++) {
   14864             :         os << std::setw(6) << back_edges.ast_id(i).ToInt() << "  "
   14865             :            << std::setw(9) << std::hex << back_edges.pc_offset(i) << std::dec
   14866             :            << "  " << std::setw(10) << back_edges.loop_depth(i) << "\n";
   14867             :       }
   14868             : 
   14869             :       os << "\n";
   14870             :     }
   14871             : #ifdef OBJECT_PRINT
   14872             :     if (!type_feedback_info()->IsUndefined(GetIsolate())) {
   14873             :       TypeFeedbackInfo* info = TypeFeedbackInfo::cast(type_feedback_info());
   14874             :       HeapObject::PrintHeader(os, "TypeFeedbackInfo");
   14875             :       os << "\n - ic_total_count: " << info->ic_total_count()
   14876             :          << ", ic_with_type_info_count: " << info->ic_with_type_info_count()
   14877             :          << ", ic_generic_count: " << info->ic_generic_count() << "\n";
   14878             :       os << "\n";
   14879             :     }
   14880             : #endif
   14881             :   }
   14882             : 
   14883             :   if (handler_table()->length() > 0) {
   14884             :     os << "Handler Table (size = " << handler_table()->Size() << ")\n";
   14885             :     if (kind() == FUNCTION) {
   14886             :       HandlerTable::cast(handler_table())->HandlerTableRangePrint(os);
   14887             :     } else if (kind() == OPTIMIZED_FUNCTION) {
   14888             :       HandlerTable::cast(handler_table())->HandlerTableReturnPrint(os);
   14889             :     }
   14890             :     os << "\n";
   14891             :   }
   14892             : 
   14893             :   os << "RelocInfo (size = " << relocation_size() << ")\n";
   14894             :   for (RelocIterator it(this); !it.done(); it.next()) {
   14895             :     it.rinfo()->Print(GetIsolate(), os);
   14896             :   }
   14897             :   os << "\n";
   14898             : 
   14899             :   if (has_unwinding_info()) {
   14900             :     os << "UnwindingInfo (size = " << unwinding_info_size() << ")\n";
   14901             :     EhFrameDisassembler eh_frame_disassembler(unwinding_info_start(),
   14902             :                                               unwinding_info_end());
   14903             :     eh_frame_disassembler.DisassembleToStream(os);
   14904             :     os << "\n";
   14905             :   }
   14906             : }
   14907             : #endif  // ENABLE_DISASSEMBLER
   14908             : 
   14909             : 
   14910           0 : void BytecodeArray::Disassemble(std::ostream& os) {
   14911           0 :   os << "Parameter count " << parameter_count() << "\n";
   14912           0 :   os << "Frame size " << frame_size() << "\n";
   14913             : 
   14914           0 :   const uint8_t* base_address = GetFirstBytecodeAddress();
   14915           0 :   SourcePositionTableIterator source_positions(SourcePositionTable());
   14916             : 
   14917           0 :   interpreter::BytecodeArrayIterator iterator(handle(this));
   14918           0 :   while (!iterator.done()) {
   14919           0 :     if (!source_positions.done() &&
   14920           0 :         iterator.current_offset() == source_positions.code_offset()) {
   14921           0 :       os << std::setw(5) << source_positions.source_position().ScriptOffset();
   14922           0 :       os << (source_positions.is_statement() ? " S> " : " E> ");
   14923           0 :       source_positions.Advance();
   14924             :     } else {
   14925           0 :       os << "         ";
   14926             :     }
   14927           0 :     const uint8_t* current_address = base_address + iterator.current_offset();
   14928           0 :     os << reinterpret_cast<const void*>(current_address) << " @ "
   14929           0 :        << std::setw(4) << iterator.current_offset() << " : ";
   14930             :     interpreter::BytecodeDecoder::Decode(os, current_address,
   14931           0 :                                          parameter_count());
   14932           0 :     if (interpreter::Bytecodes::IsJump(iterator.current_bytecode())) {
   14933           0 :       const void* jump_target = base_address + iterator.GetJumpTargetOffset();
   14934           0 :       os << " (" << jump_target << " @ " << iterator.GetJumpTargetOffset()
   14935           0 :          << ")";
   14936             :     }
   14937             :     os << std::endl;
   14938           0 :     iterator.Advance();
   14939             :   }
   14940             : 
   14941           0 :   if (constant_pool()->length() > 0) {
   14942           0 :     os << "Constant pool (size = " << constant_pool()->length() << ")\n";
   14943             :     constant_pool()->Print();
   14944             :   }
   14945             : 
   14946             : #ifdef ENABLE_DISASSEMBLER
   14947             :   if (handler_table()->length() > 0) {
   14948             :     os << "Handler Table (size = " << handler_table()->Size() << ")\n";
   14949             :     HandlerTable::cast(handler_table())->HandlerTableRangePrint(os);
   14950             :   }
   14951             : #endif
   14952           0 : }
   14953             : 
   14954        9470 : void BytecodeArray::CopyBytecodesTo(BytecodeArray* to) {
   14955             :   BytecodeArray* from = this;
   14956             :   DCHECK_EQ(from->length(), to->length());
   14957        9470 :   CopyBytes(to->GetFirstBytecodeAddress(), from->GetFirstBytecodeAddress(),
   14958       18940 :             from->length());
   14959        9470 : }
   14960             : 
   14961     1946409 : void BytecodeArray::MakeOlder() {
   14962             :   Age age = bytecode_age();
   14963     1946409 :   if (age < kLastBytecodeAge) {
   14964     1407165 :     set_bytecode_age(static_cast<Age>(age + 1));
   14965             :   }
   14966             :   DCHECK_GE(bytecode_age(), kFirstBytecodeAge);
   14967             :   DCHECK_LE(bytecode_age(), kLastBytecodeAge);
   14968     1946409 : }
   14969             : 
   14970           0 : bool BytecodeArray::IsOld() const {
   14971      249638 :   return bytecode_age() >= kIsOldBytecodeAge;
   14972             : }
   14973             : 
   14974             : // static
   14975      352164 : void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) {
   14976             :   DCHECK(capacity >= 0);
   14977             :   array->GetIsolate()->factory()->NewJSArrayStorage(
   14978      352164 :       array, length, capacity, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
   14979      352164 : }
   14980             : 
   14981     1562026 : void JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) {
   14982             :   // We should never end in here with a pixel or external array.
   14983             :   DCHECK(array->AllowsSetLength());
   14984     1562026 :   if (array->SetLengthWouldNormalize(new_length)) {
   14985        1515 :     JSObject::NormalizeElements(array);
   14986             :   }
   14987     1562026 :   array->GetElementsAccessor()->SetLength(array, new_length);
   14988     1562026 : }
   14989             : 
   14990             : 
   14991             : // static
   14992      321357 : void Map::AddDependentCode(Handle<Map> map,
   14993             :                            DependentCode::DependencyGroup group,
   14994             :                            Handle<Code> code) {
   14995      321357 :   Handle<WeakCell> cell = Code::WeakCellFor(code);
   14996             :   Handle<DependentCode> codes = DependentCode::InsertWeakCode(
   14997             :       Handle<DependentCode>(map->dependent_code()), group, cell);
   14998      321357 :   if (*codes != map->dependent_code()) map->set_dependent_code(*codes);
   14999      321357 : }
   15000             : 
   15001             : 
   15002      904414 : Handle<DependentCode> DependentCode::InsertCompilationDependencies(
   15003             :     Handle<DependentCode> entries, DependencyGroup group,
   15004             :     Handle<Foreign> info) {
   15005      904414 :   return Insert(entries, group, info);
   15006             : }
   15007             : 
   15008             : 
   15009     1051520 : Handle<DependentCode> DependentCode::InsertWeakCode(
   15010             :     Handle<DependentCode> entries, DependencyGroup group,
   15011             :     Handle<WeakCell> code_cell) {
   15012     1372877 :   return Insert(entries, group, code_cell);
   15013             : }
   15014             : 
   15015             : 
   15016     2297332 : Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
   15017             :                                             DependencyGroup group,
   15018             :                                             Handle<Object> object) {
   15019     4218794 :   if (entries->length() == 0 || entries->group() > group) {
   15020             :     // There is no such group.
   15021      391164 :     return DependentCode::New(group, object, entries);
   15022             :   }
   15023     1906168 :   if (entries->group() < group) {
   15024             :     // The group comes later in the list.
   15025             :     Handle<DependentCode> old_next(entries->next_link());
   15026       20042 :     Handle<DependentCode> new_next = Insert(old_next, group, object);
   15027       20042 :     if (!old_next.is_identical_to(new_next)) {
   15028             :       entries->set_next_link(*new_next);
   15029             :     }
   15030       20042 :     return entries;
   15031             :   }
   15032             :   DCHECK_EQ(group, entries->group());
   15033             :   int count = entries->count();
   15034             :   // Check for existing entry to avoid duplicates.
   15035   168608393 :   for (int i = 0; i < count; i++) {
   15036   167911126 :     if (entries->object_at(i) == *object) return entries;
   15037             :   }
   15038     1394534 :   if (entries->length() < kCodesStartIndex + count + 1) {
   15039      269799 :     entries = EnsureSpace(entries);
   15040             :     // Count could have changed, reload it.
   15041             :     count = entries->count();
   15042             :   }
   15043             :   entries->set_object_at(count, *object);
   15044     1394534 :   entries->set_count(count + 1);
   15045      697267 :   return entries;
   15046             : }
   15047             : 
   15048             : 
   15049      391164 : Handle<DependentCode> DependentCode::New(DependencyGroup group,
   15050             :                                          Handle<Object> object,
   15051             :                                          Handle<DependentCode> next) {
   15052             :   Isolate* isolate = next->GetIsolate();
   15053             :   Handle<DependentCode> result = Handle<DependentCode>::cast(
   15054      391164 :       isolate->factory()->NewFixedArray(kCodesStartIndex + 1, TENURED));
   15055             :   result->set_next_link(*next);
   15056      391164 :   result->set_flags(GroupField::encode(group) | CountField::encode(1));
   15057             :   result->set_object_at(0, *object);
   15058      391164 :   return result;
   15059             : }
   15060             : 
   15061             : 
   15062      269799 : Handle<DependentCode> DependentCode::EnsureSpace(
   15063             :     Handle<DependentCode> entries) {
   15064      269799 :   if (entries->Compact()) return entries;
   15065             :   Isolate* isolate = entries->GetIsolate();
   15066      259735 :   int capacity = kCodesStartIndex + DependentCode::Grow(entries->count());
   15067      259735 :   int grow_by = capacity - entries->length();
   15068             :   return Handle<DependentCode>::cast(
   15069      259735 :       isolate->factory()->CopyFixedArrayAndGrow(entries, grow_by, TENURED));
   15070             : }
   15071             : 
   15072             : 
   15073      269799 : bool DependentCode::Compact() {
   15074             :   int old_count = count();
   15075             :   int new_count = 0;
   15076     2904687 :   for (int i = 0; i < old_count; i++) {
   15077             :     Object* obj = object_at(i);
   15078     5257521 :     if (!obj->IsWeakCell() || !WeakCell::cast(obj)->cleared()) {
   15079     2599659 :       if (i != new_count) {
   15080        9040 :         copy(i, new_count);
   15081             :       }
   15082     2599659 :       new_count++;
   15083             :     }
   15084             :   }
   15085      269799 :   set_count(new_count);
   15086      305028 :   for (int i = new_count; i < old_count; i++) {
   15087             :     clear_at(i);
   15088             :   }
   15089      269799 :   return new_count < old_count;
   15090             : }
   15091             : 
   15092             : 
   15093      869947 : void DependentCode::UpdateToFinishedCode(DependencyGroup group, Foreign* info,
   15094             :                                          WeakCell* code_cell) {
   15095     1768502 :   if (this->length() == 0 || this->group() > group) {
   15096             :     // There is no such group.
   15097             :     return;
   15098             :   }
   15099      884251 :   if (this->group() < group) {
   15100             :     // The group comes later in the list.
   15101             :     next_link()->UpdateToFinishedCode(group, info, code_cell);
   15102       14304 :     return;
   15103             :   }
   15104             :   DCHECK_EQ(group, this->group());
   15105             :   DisallowHeapAllocation no_gc;
   15106             :   int count = this->count();
   15107    87162232 :   for (int i = 0; i < count; i++) {
   15108    86781905 :     if (object_at(i) == info) {
   15109             :       set_object_at(i, code_cell);
   15110             :       break;
   15111             :     }
   15112             :   }
   15113             : #ifdef DEBUG
   15114             :   for (int i = 0; i < count; i++) {
   15115             :     DCHECK(object_at(i) != info);
   15116             :   }
   15117             : #endif
   15118             : }
   15119             : 
   15120             : 
   15121       34453 : void DependentCode::RemoveCompilationDependencies(
   15122             :     DependentCode::DependencyGroup group, Foreign* info) {
   15123       70100 :   if (this->length() == 0 || this->group() > group) {
   15124             :     // There is no such group.
   15125             :     return;
   15126             :   }
   15127       35050 :   if (this->group() < group) {
   15128             :     // The group comes later in the list.
   15129             :     next_link()->RemoveCompilationDependencies(group, info);
   15130         597 :     return;
   15131             :   }
   15132             :   DCHECK_EQ(group, this->group());
   15133             :   DisallowHeapAllocation no_allocation;
   15134             :   int old_count = count();
   15135             :   // Find compilation info wrapper.
   15136             :   int info_pos = -1;
   15137     1140147 :   for (int i = 0; i < old_count; i++) {
   15138     1126166 :     if (object_at(i) == info) {
   15139             :       info_pos = i;
   15140             :       break;
   15141             :     }
   15142             :   }
   15143       34453 :   if (info_pos == -1) return;  // Not found.
   15144             :   // Use the last code to fill the gap.
   15145       20472 :   if (info_pos < old_count - 1) {
   15146        4603 :     copy(old_count - 1, info_pos);
   15147             :   }
   15148             :   clear_at(old_count - 1);
   15149       20472 :   set_count(old_count - 1);
   15150             : 
   15151             : #ifdef DEBUG
   15152             :   for (int i = 0; i < old_count - 1; i++) {
   15153             :     DCHECK(object_at(i) != info);
   15154             :   }
   15155             : #endif
   15156             : }
   15157             : 
   15158             : 
   15159           0 : bool DependentCode::Contains(DependencyGroup group, WeakCell* code_cell) {
   15160           0 :   if (this->length() == 0 || this->group() > group) {
   15161             :     // There is no such group.
   15162             :     return false;
   15163             :   }
   15164           0 :   if (this->group() < group) {
   15165             :     // The group comes later in the list.
   15166           0 :     return next_link()->Contains(group, code_cell);
   15167             :   }
   15168             :   DCHECK_EQ(group, this->group());
   15169             :   int count = this->count();
   15170           0 :   for (int i = 0; i < count; i++) {
   15171           0 :     if (object_at(i) == code_cell) return true;
   15172             :   }
   15173             :   return false;
   15174             : }
   15175             : 
   15176             : 
   15177      202133 : bool DependentCode::IsEmpty(DependencyGroup group) {
   15178      376973 :   if (this->length() == 0 || this->group() > group) {
   15179             :     // There is no such group.
   15180             :     return true;
   15181             :   }
   15182      164098 :   if (this->group() < group) {
   15183             :     // The group comes later in the list.
   15184           0 :     return next_link()->IsEmpty(group);
   15185             :   }
   15186             :   DCHECK_EQ(group, this->group());
   15187      164098 :   return count() == 0;
   15188             : }
   15189             : 
   15190             : 
   15191    20072595 : bool DependentCode::MarkCodeForDeoptimization(
   15192             :     Isolate* isolate,
   15193             :     DependentCode::DependencyGroup group) {
   15194    20116163 :   if (this->length() == 0 || this->group() > group) {
   15195             :     // There is no such group.
   15196             :     return false;
   15197             :   }
   15198       41008 :   if (this->group() < group) {
   15199             :     // The group comes later in the list.
   15200        1949 :     return next_link()->MarkCodeForDeoptimization(isolate, group);
   15201             :   }
   15202             :   DCHECK_EQ(group, this->group());
   15203             :   DisallowHeapAllocation no_allocation_scope;
   15204             :   // Mark all the code that needs to be deoptimized.
   15205             :   bool marked = false;
   15206             :   bool invalidate_embedded_objects = group == kWeakCodeGroup;
   15207             :   int count = this->count();
   15208      124319 :   for (int i = 0; i < count; i++) {
   15209             :     Object* obj = object_at(i);
   15210       85260 :     if (obj->IsWeakCell()) {
   15211             :       WeakCell* cell = WeakCell::cast(obj);
   15212       85055 :       if (cell->cleared()) continue;
   15213             :       Code* code = Code::cast(cell->value());
   15214       23273 :       if (!code->marked_for_deoptimization()) {
   15215       14390 :         SetMarkedForDeoptimization(code, group);
   15216       14390 :         if (invalidate_embedded_objects) {
   15217        5283 :           code->InvalidateEmbeddedObjects();
   15218             :         }
   15219             :         marked = true;
   15220             :       }
   15221             :     } else {
   15222             :       DCHECK(obj->IsForeign());
   15223             :       CompilationDependencies* info =
   15224             :           reinterpret_cast<CompilationDependencies*>(
   15225             :               Foreign::cast(obj)->foreign_address());
   15226             :       info->Abort();
   15227             :     }
   15228             :   }
   15229       85260 :   for (int i = 0; i < count; i++) {
   15230             :     clear_at(i);
   15231             :   }
   15232       39059 :   set_count(0);
   15233       39059 :   return marked;
   15234             : }
   15235             : 
   15236             : 
   15237    20040468 : void DependentCode::DeoptimizeDependentCodeGroup(
   15238             :     Isolate* isolate,
   15239             :     DependentCode::DependencyGroup group) {
   15240             :   DisallowHeapAllocation no_allocation_scope;
   15241    20040468 :   bool marked = MarkCodeForDeoptimization(isolate, group);
   15242    20040470 :   if (marked) {
   15243             :     DCHECK(AllowCodeDependencyChange::IsAllowed());
   15244        5935 :     Deoptimizer::DeoptimizeMarkedCode(isolate);
   15245             :   }
   15246    20040470 : }
   15247             : 
   15248             : 
   15249       14404 : void DependentCode::SetMarkedForDeoptimization(Code* code,
   15250             :                                                DependencyGroup group) {
   15251             :   code->set_marked_for_deoptimization(true);
   15252       14404 :   if (FLAG_trace_deopt &&
   15253           0 :       (code->deoptimization_data() != code->GetHeap()->empty_fixed_array())) {
   15254             :     DeoptimizationInputData* deopt_data =
   15255             :         DeoptimizationInputData::cast(code->deoptimization_data());
   15256           0 :     CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer());
   15257             :     PrintF(scope.file(), "[marking dependent code 0x%08" V8PRIxPTR
   15258             :                          " (opt #%d) for deoptimization, reason: %s]\n",
   15259             :            reinterpret_cast<intptr_t>(code),
   15260           0 :            deopt_data->OptimizationId()->value(), DependencyGroupName(group));
   15261             :   }
   15262       14404 : }
   15263             : 
   15264             : 
   15265           0 : const char* DependentCode::DependencyGroupName(DependencyGroup group) {
   15266           0 :   switch (group) {
   15267             :     case kWeakCodeGroup:
   15268             :       return "weak-code";
   15269             :     case kTransitionGroup:
   15270           0 :       return "transition";
   15271             :     case kPrototypeCheckGroup:
   15272           0 :       return "prototype-check";
   15273             :     case kPropertyCellChangedGroup:
   15274           0 :       return "property-cell-changed";
   15275             :     case kFieldOwnerGroup:
   15276           0 :       return "field-owner";
   15277             :     case kInitialMapChangedGroup:
   15278           0 :       return "initial-map-changed";
   15279             :     case kAllocationSiteTenuringChangedGroup:
   15280           0 :       return "allocation-site-tenuring-changed";
   15281             :     case kAllocationSiteTransitionChangedGroup:
   15282           0 :       return "allocation-site-transition-changed";
   15283             :   }
   15284           0 :   UNREACHABLE();
   15285             :   return "?";
   15286             : }
   15287             : 
   15288             : 
   15289     4154295 : Handle<Map> Map::TransitionToPrototype(Handle<Map> map,
   15290             :                                        Handle<Object> prototype,
   15291             :                                        PrototypeOptimizationMode mode) {
   15292     4154295 :   Handle<Map> new_map = TransitionArray::GetPrototypeTransition(map, prototype);
   15293     4154295 :   if (new_map.is_null()) {
   15294      138924 :     new_map = Copy(map, "TransitionToPrototype");
   15295      138924 :     TransitionArray::PutPrototypeTransition(map, prototype, new_map);
   15296      138924 :     Map::SetPrototype(new_map, prototype, mode);
   15297             :   }
   15298     4154295 :   return new_map;
   15299             : }
   15300             : 
   15301             : 
   15302     4182272 : Maybe<bool> JSReceiver::SetPrototype(Handle<JSReceiver> object,
   15303             :                                      Handle<Object> value, bool from_javascript,
   15304             :                                      ShouldThrow should_throw) {
   15305     4182272 :   if (object->IsJSProxy()) {
   15306             :     return JSProxy::SetPrototype(Handle<JSProxy>::cast(object), value,
   15307         532 :                                  from_javascript, should_throw);
   15308             :   }
   15309             :   return JSObject::SetPrototype(Handle<JSObject>::cast(object), value,
   15310     4181740 :                                 from_javascript, should_throw);
   15311             : }
   15312             : 
   15313             : 
   15314             : // ES6: 9.5.2 [[SetPrototypeOf]] (V)
   15315             : // static
   15316         532 : Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value,
   15317             :                                   bool from_javascript,
   15318             :                                   ShouldThrow should_throw) {
   15319             :   Isolate* isolate = proxy->GetIsolate();
   15320         532 :   STACK_CHECK(isolate, Nothing<bool>());
   15321             :   Handle<Name> trap_name = isolate->factory()->setPrototypeOf_string();
   15322             :   // 1. Assert: Either Type(V) is Object or Type(V) is Null.
   15323             :   DCHECK(value->IsJSReceiver() || value->IsNull(isolate));
   15324             :   // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
   15325             :   Handle<Object> handler(proxy->handler(), isolate);
   15326             :   // 3. If handler is null, throw a TypeError exception.
   15327             :   // 4. Assert: Type(handler) is Object.
   15328         532 :   if (proxy->IsRevoked()) {
   15329             :     isolate->Throw(*isolate->factory()->NewTypeError(
   15330          28 :         MessageTemplate::kProxyRevoked, trap_name));
   15331             :     return Nothing<bool>();
   15332             :   }
   15333             :   // 5. Let target be the value of the [[ProxyTarget]] internal slot.
   15334             :   Handle<JSReceiver> target(proxy->target(), isolate);
   15335             :   // 6. Let trap be ? GetMethod(handler, "getPrototypeOf").
   15336             :   Handle<Object> trap;
   15337        1036 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   15338             :       isolate, trap,
   15339             :       Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name),
   15340             :       Nothing<bool>());
   15341             :   // 7. If trap is undefined, then return target.[[SetPrototypeOf]]().
   15342         518 :   if (trap->IsUndefined(isolate)) {
   15343             :     return JSReceiver::SetPrototype(target, value, from_javascript,
   15344         364 :                                     should_throw);
   15345             :   }
   15346             :   // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, V»)).
   15347         154 :   Handle<Object> argv[] = {target, value};
   15348             :   Handle<Object> trap_result;
   15349         308 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   15350             :       isolate, trap_result,
   15351             :       Execution::Call(isolate, trap, handler, arraysize(argv), argv),
   15352             :       Nothing<bool>());
   15353         140 :   bool bool_trap_result = trap_result->BooleanValue();
   15354             :   // 9. If booleanTrapResult is false, return false.
   15355         140 :   if (!bool_trap_result) {
   15356         140 :     RETURN_FAILURE(
   15357             :         isolate, should_throw,
   15358             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
   15359             :   }
   15360             :   // 10. Let extensibleTarget be ? IsExtensible(target).
   15361          84 :   Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
   15362          84 :   if (is_extensible.IsNothing()) return Nothing<bool>();
   15363             :   // 11. If extensibleTarget is true, return true.
   15364          84 :   if (is_extensible.FromJust()) {
   15365          42 :     if (bool_trap_result) return Just(true);
   15366           0 :     RETURN_FAILURE(
   15367             :         isolate, should_throw,
   15368             :         NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
   15369             :   }
   15370             :   // 12. Let targetProto be ? target.[[GetPrototypeOf]]().
   15371             :   Handle<Object> target_proto;
   15372          84 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_proto,
   15373             :                                    JSReceiver::GetPrototype(isolate, target),
   15374             :                                    Nothing<bool>());
   15375             :   // 13. If SameValue(V, targetProto) is false, throw a TypeError exception.
   15376          56 :   if (bool_trap_result && !value->SameValue(*target_proto)) {
   15377             :     isolate->Throw(*isolate->factory()->NewTypeError(
   15378          28 :         MessageTemplate::kProxySetPrototypeOfNonExtensible));
   15379             :     return Nothing<bool>();
   15380             :   }
   15381             :   // 14. Return true.
   15382             :   return Just(true);
   15383             : }
   15384             : 
   15385             : 
   15386     4194431 : Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
   15387             :                                    Handle<Object> value, bool from_javascript,
   15388             :                                    ShouldThrow should_throw) {
   15389          42 :   Isolate* isolate = object->GetIsolate();
   15390             : 
   15391             : #ifdef DEBUG
   15392             :   int size = object->Size();
   15393             : #endif
   15394             : 
   15395     4194431 :   if (from_javascript) {
   15396      115644 :     if (object->IsAccessCheckNeeded() &&
   15397          42 :         !isolate->MayAccess(handle(isolate->context()), object)) {
   15398           0 :       isolate->ReportFailedAccessCheck(object);
   15399           0 :       RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
   15400           0 :       RETURN_FAILURE(isolate, should_throw,
   15401             :                      NewTypeError(MessageTemplate::kNoAccess));
   15402             :     }
   15403             :   } else {
   15404             :     DCHECK(!object->IsAccessCheckNeeded());
   15405             :   }
   15406             : 
   15407             :   Heap* heap = isolate->heap();
   15408             :   // Silently ignore the change if value is not a JSObject or null.
   15409             :   // SpiderMonkey behaves this way.
   15410     8252454 :   if (!value->IsJSReceiver() && !value->IsNull(isolate)) return Just(true);
   15411             : 
   15412             :   bool all_extensible = object->map()->is_extensible();
   15413             :   Handle<JSObject> real_receiver = object;
   15414     4194413 :   if (from_javascript) {
   15415             :     // Find the first object in the chain whose prototype object is not
   15416             :     // hidden.
   15417             :     PrototypeIterator iter(isolate, real_receiver, kStartAtPrototype,
   15418      115602 :                            PrototypeIterator::END_AT_NON_HIDDEN);
   15419      235849 :     while (!iter.IsAtEnd()) {
   15420             :       // Casting to JSObject is fine because hidden prototypes are never
   15421             :       // JSProxies.
   15422             :       real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
   15423        4645 :       iter.Advance();
   15424        9290 :       all_extensible = all_extensible && real_receiver->map()->is_extensible();
   15425             :     }
   15426             :   }
   15427             :   Handle<Map> map(real_receiver->map());
   15428             : 
   15429             :   // Nothing to do if prototype is already set.
   15430     4194413 :   if (map->prototype() == *value) return Just(true);
   15431             : 
   15432             :   bool immutable_proto = map->is_immutable_proto();
   15433     4153594 :   if (immutable_proto) {
   15434         251 :     RETURN_FAILURE(
   15435             :         isolate, should_throw,
   15436             :         NewTypeError(MessageTemplate::kImmutablePrototypeSet, object));
   15437             :   }
   15438             : 
   15439             :   // From 8.6.2 Object Internal Methods
   15440             :   // ...
   15441             :   // In addition, if [[Extensible]] is false the value of the [[Class]] and
   15442             :   // [[Prototype]] internal properties of the object may not be modified.
   15443             :   // ...
   15444             :   // Implementation specific extensions that modify [[Class]], [[Prototype]]
   15445             :   // or [[Extensible]] must not violate the invariants defined in the preceding
   15446             :   // paragraph.
   15447     4153501 :   if (!all_extensible) {
   15448         822 :     RETURN_FAILURE(isolate, should_throw,
   15449             :                    NewTypeError(MessageTemplate::kNonExtensibleProto, object));
   15450             :   }
   15451             : 
   15452             :   // Before we can set the prototype we need to be sure prototype cycles are
   15453             :   // prevented.  It is sufficient to validate that the receiver is not in the
   15454             :   // new prototype chain.
   15455     4153105 :   if (value->IsJSReceiver()) {
   15456      357631 :     for (PrototypeIterator iter(isolate, JSReceiver::cast(*value),
   15457             :                                 kStartAtReceiver);
   15458      262388 :          !iter.IsAtEnd(); iter.Advance()) {
   15459      525020 :       if (iter.GetCurrent<JSReceiver>() == *object) {
   15460             :         // Cycle detected.
   15461         310 :         RETURN_FAILURE(isolate, should_throw,
   15462             :                        NewTypeError(MessageTemplate::kCyclicProto));
   15463             :       }
   15464             :     }
   15465             :   }
   15466             : 
   15467             :   // Set the new prototype of the object.
   15468             : 
   15469             :   isolate->UpdateArrayProtectorOnSetPrototype(real_receiver);
   15470             : 
   15471             :   PrototypeOptimizationMode mode =
   15472     4152983 :       from_javascript ? REGULAR_PROTOTYPE : FAST_PROTOTYPE;
   15473     4152983 :   Handle<Map> new_map = Map::TransitionToPrototype(map, value, mode);
   15474             :   DCHECK(new_map->prototype() == *value);
   15475     4152983 :   JSObject::MigrateToMap(real_receiver, new_map);
   15476             : 
   15477             :   heap->ClearInstanceofCache();
   15478             :   DCHECK(size == object->Size());
   15479             :   return Just(true);
   15480             : }
   15481             : 
   15482             : // static
   15483          28 : void JSObject::SetImmutableProto(Handle<JSObject> object) {
   15484             :   DCHECK(!object->IsAccessCheckNeeded());  // Never called from JS
   15485             :   Handle<Map> map(object->map());
   15486             : 
   15487             :   // Nothing to do if prototype is already set.
   15488          49 :   if (map->is_immutable_proto()) return;
   15489             : 
   15490           7 :   Handle<Map> new_map = Map::TransitionToImmutableProto(map);
   15491           7 :   object->set_map(*new_map);
   15492             : }
   15493             : 
   15494     1144031 : void JSObject::EnsureCanContainElements(Handle<JSObject> object,
   15495     1144031 :                                         Arguments* args,
   15496             :                                         uint32_t first_arg,
   15497             :                                         uint32_t arg_count,
   15498             :                                         EnsureElementsMode mode) {
   15499             :   // Elements in |Arguments| are ordered backwards (because they're on the
   15500             :   // stack), but the method that's called here iterates over them in forward
   15501             :   // direction.
   15502             :   return EnsureCanContainElements(
   15503     1144031 :       object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode);
   15504             : }
   15505             : 
   15506             : 
   15507   512760675 : ElementsAccessor* JSObject::GetElementsAccessor() {
   15508   512760675 :   return ElementsAccessor::ForKind(GetElementsKind());
   15509             : }
   15510             : 
   15511             : 
   15512    21511152 : void JSObject::ValidateElements(Handle<JSObject> object) {
   15513             : #ifdef ENABLE_SLOW_DCHECKS
   15514             :   if (FLAG_enable_slow_asserts) {
   15515             :     ElementsAccessor* accessor = object->GetElementsAccessor();
   15516             :     accessor->Validate(object);
   15517             :   }
   15518             : #endif
   15519    21511152 : }
   15520             : 
   15521             : 
   15522     1963873 : static bool ShouldConvertToSlowElements(JSObject* object, uint32_t capacity,
   15523             :                                         uint32_t index,
   15524             :                                         uint32_t* new_capacity) {
   15525             :   STATIC_ASSERT(JSObject::kMaxUncheckedOldFastElementsLength <=
   15526             :                 JSObject::kMaxUncheckedFastElementsLength);
   15527     1963873 :   if (index < capacity) {
   15528      963081 :     *new_capacity = capacity;
   15529      963081 :     return false;
   15530             :   }
   15531     1000792 :   if (index - capacity >= JSObject::kMaxGap) return true;
   15532     1223844 :   *new_capacity = JSObject::NewElementsCapacity(index + 1);
   15533             :   DCHECK_LT(index, *new_capacity);
   15534     1223844 :   if (*new_capacity <= JSObject::kMaxUncheckedOldFastElementsLength ||
   15535       69292 :       (*new_capacity <= JSObject::kMaxUncheckedFastElementsLength &&
   15536             :        object->GetHeap()->InNewSpace(object))) {
   15537             :     return false;
   15538             :   }
   15539             :   // If the fast-case backing storage takes up roughly three times as
   15540             :   // much space (in machine words) as a dictionary backing storage
   15541             :   // would, the object should have slow elements.
   15542        1776 :   int used_elements = object->GetFastElementsUsage();
   15543             :   int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) *
   15544        1776 :                         SeededNumberDictionary::kEntrySize;
   15545        1776 :   return 3 * static_cast<uint32_t>(dictionary_size) <= *new_capacity;
   15546             : }
   15547             : 
   15548             : 
   15549      186759 : bool JSObject::WouldConvertToSlowElements(uint32_t index) {
   15550      186759 :   if (HasFastElements()) {
   15551             :     Handle<FixedArrayBase> backing_store(FixedArrayBase::cast(elements()));
   15552       36043 :     uint32_t capacity = static_cast<uint32_t>(backing_store->length());
   15553             :     uint32_t new_capacity;
   15554       36043 :     return ShouldConvertToSlowElements(this, capacity, index, &new_capacity);
   15555             :   }
   15556             :   return false;
   15557             : }
   15558             : 
   15559             : 
   15560        2961 : static ElementsKind BestFittingFastElementsKind(JSObject* object) {
   15561        2961 :   if (object->HasSloppyArgumentsElements()) {
   15562             :     return FAST_SLOPPY_ARGUMENTS_ELEMENTS;
   15563             :   }
   15564        2931 :   if (object->HasStringWrapperElements()) {
   15565             :     return FAST_STRING_WRAPPER_ELEMENTS;
   15566             :   }
   15567             :   DCHECK(object->HasDictionaryElements());
   15568             :   SeededNumberDictionary* dictionary = object->element_dictionary();
   15569             :   ElementsKind kind = FAST_HOLEY_SMI_ELEMENTS;
   15570     3957332 :   for (int i = 0; i < dictionary->Capacity(); i++) {
   15571             :     Object* key = dictionary->KeyAt(i);
   15572     1975837 :     if (key->IsNumber()) {
   15573      655163 :       Object* value = dictionary->ValueAt(i);
   15574      655163 :       if (!value->IsNumber()) return FAST_HOLEY_ELEMENTS;
   15575      655076 :       if (!value->IsSmi()) {
   15576       73635 :         if (!FLAG_unbox_double_arrays) return FAST_HOLEY_ELEMENTS;
   15577             :         kind = FAST_HOLEY_DOUBLE_ELEMENTS;
   15578             :       }
   15579             :     }
   15580             :   }
   15581             :   return kind;
   15582             : }
   15583             : 
   15584             : 
   15585     1736825 : static bool ShouldConvertToFastElements(JSObject* object,
   15586             :                                         SeededNumberDictionary* dictionary,
   15587             :                                         uint32_t index,
   15588             :                                         uint32_t* new_capacity) {
   15589             :   // If properties with non-standard attributes or accessors were added, we
   15590             :   // cannot go back to fast elements.
   15591     1736825 :   if (dictionary->requires_slow_elements()) return false;
   15592             : 
   15593             :   // Adding a property with this index will require slow elements.
   15594     1697738 :   if (index >= static_cast<uint32_t>(Smi::kMaxValue)) return false;
   15595             : 
   15596     1697224 :   if (object->IsJSArray()) {
   15597             :     Object* length = JSArray::cast(object)->length();
   15598      903797 :     if (!length->IsSmi()) return false;
   15599      902537 :     *new_capacity = static_cast<uint32_t>(Smi::cast(length)->value());
   15600             :   } else {
   15601      793427 :     *new_capacity = dictionary->max_number_key() + 1;
   15602             :   }
   15603     3391928 :   *new_capacity = Max(index + 1, *new_capacity);
   15604             : 
   15605     1695964 :   uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
   15606     1695964 :                              SeededNumberDictionary::kEntrySize;
   15607             : 
   15608             :   // Turn fast if the dictionary only saves 50% space.
   15609     1695964 :   return 2 * dictionary_size >= *new_capacity;
   15610             : }
   15611             : 
   15612             : 
   15613             : // static
   15614       32929 : MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object,
   15615             :                                              uint32_t index,
   15616             :                                              Handle<Object> value,
   15617             :                                              PropertyAttributes attributes) {
   15618       32929 :   MAYBE_RETURN_NULL(
   15619             :       AddDataElement(object, index, value, attributes, THROW_ON_ERROR));
   15620             :   return value;
   15621             : }
   15622             : 
   15623             : 
   15624             : // static
   15625     3710517 : Maybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
   15626             :                                      Handle<Object> value,
   15627             :                                      PropertyAttributes attributes,
   15628             :                                      ShouldThrow should_throw) {
   15629             :   DCHECK(object->map()->is_extensible());
   15630             : 
   15631             :   Isolate* isolate = object->GetIsolate();
   15632             : 
   15633     3710517 :   uint32_t old_length = 0;
   15634     3710517 :   uint32_t new_capacity = 0;
   15635             : 
   15636     3710517 :   if (object->IsJSArray()) {
   15637     1550916 :     CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length));
   15638             :   }
   15639             : 
   15640             :   ElementsKind kind = object->GetElementsKind();
   15641             :   FixedArrayBase* elements = object->elements();
   15642             :   ElementsKind dictionary_kind = DICTIONARY_ELEMENTS;
   15643     3710517 :   if (IsSloppyArgumentsElementsKind(kind)) {
   15644             :     elements = FixedArrayBase::cast(FixedArray::cast(elements)->get(1));
   15645             :     dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
   15646     3511441 :   } else if (IsStringWrapperElementsKind(kind)) {
   15647             :     dictionary_kind = SLOW_STRING_WRAPPER_ELEMENTS;
   15648             :   }
   15649             : 
   15650     3710517 :   if (attributes != NONE) {
   15651             :     kind = dictionary_kind;
   15652     3663140 :   } else if (elements->IsSeededNumberDictionary()) {
   15653             :     kind = ShouldConvertToFastElements(*object,
   15654             :                                        SeededNumberDictionary::cast(elements),
   15655     1736825 :                                        index, &new_capacity)
   15656             :                ? BestFittingFastElementsKind(*object)
   15657     1739786 :                : dictionary_kind;  // Overwrite in case of arguments.
   15658     1926315 :   } else if (ShouldConvertToSlowElements(
   15659             :                  *object, static_cast<uint32_t>(elements->length()), index,
   15660     1926315 :                  &new_capacity)) {
   15661             :     kind = dictionary_kind;
   15662             :   }
   15663             : 
   15664     3710517 :   ElementsKind to = value->OptimalElementsKind();
   15665     4270869 :   if (IsHoleyElementsKind(kind) || !object->IsJSArray() || index > old_length) {
   15666             :     to = GetHoleyElementsKind(to);
   15667             :     kind = GetHoleyElementsKind(kind);
   15668             :   }
   15669             :   to = GetMoreGeneralElementsKind(kind, to);
   15670             :   ElementsAccessor* accessor = ElementsAccessor::ForKind(to);
   15671     3710517 :   accessor->Add(object, index, value, attributes, new_capacity);
   15672             : 
   15673     3710517 :   if (object->IsJSArray() && index >= old_length) {
   15674             :     Handle<Object> new_length =
   15675     1322180 :         isolate->factory()->NewNumberFromUint(index + 1);
   15676     1322180 :     JSArray::cast(*object)->set_length(*new_length);
   15677             :   }
   15678             : 
   15679     3710517 :   return Just(true);
   15680             : }
   15681             : 
   15682             : 
   15683     1562026 : bool JSArray::SetLengthWouldNormalize(uint32_t new_length) {
   15684     1562026 :   if (!HasFastElements()) return false;
   15685     1537137 :   uint32_t capacity = static_cast<uint32_t>(elements()->length());
   15686             :   uint32_t new_capacity;
   15687     1538652 :   return JSArray::SetLengthWouldNormalize(GetHeap(), new_length) &&
   15688             :          ShouldConvertToSlowElements(this, capacity, new_length - 1,
   15689     1538652 :                                      &new_capacity);
   15690             : }
   15691             : 
   15692             : 
   15693             : const double AllocationSite::kPretenureRatio = 0.85;
   15694             : 
   15695             : 
   15696           0 : void AllocationSite::ResetPretenureDecision() {
   15697             :   set_pretenure_decision(kUndecided);
   15698             :   set_memento_found_count(0);
   15699             :   set_memento_create_count(0);
   15700           0 : }
   15701             : 
   15702             : 
   15703       45053 : PretenureFlag AllocationSite::GetPretenureMode() {
   15704             :   PretenureDecision mode = pretenure_decision();
   15705             :   // Zombie objects "decide" to be untenured.
   15706       45053 :   return mode == kTenure ? TENURED : NOT_TENURED;
   15707             : }
   15708             : 
   15709             : 
   15710           0 : bool AllocationSite::IsNestedSite() {
   15711             :   DCHECK(FLAG_trace_track_allocation_sites);
   15712           0 :   Object* current = GetHeap()->allocation_sites_list();
   15713           0 :   while (current->IsAllocationSite()) {
   15714             :     AllocationSite* current_site = AllocationSite::cast(current);
   15715           0 :     if (current_site->nested_site() == this) {
   15716             :       return true;
   15717             :     }
   15718             :     current = current_site->weak_next();
   15719             :   }
   15720             :   return false;
   15721             : }
   15722             : 
   15723             : template <AllocationSiteUpdateMode update_or_check>
   15724      634931 : bool AllocationSite::DigestTransitionFeedback(Handle<AllocationSite> site,
   15725             :                                               ElementsKind to_kind) {
   15726             :   Isolate* isolate = site->GetIsolate();
   15727             :   bool result = false;
   15728             : 
   15729     1242724 :   if (site->SitePointsToLiteral() && site->transition_info()->IsJSArray()) {
   15730             :     Handle<JSArray> transition_info =
   15731             :         handle(JSArray::cast(site->transition_info()));
   15732             :     ElementsKind kind = transition_info->GetElementsKind();
   15733             :     // if kind is holey ensure that to_kind is as well.
   15734      607793 :     if (IsHoleyElementsKind(kind)) {
   15735             :       to_kind = GetHoleyElementsKind(to_kind);
   15736             :     }
   15737      607793 :     if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
   15738             :       // If the array is huge, it's not likely to be defined in a local
   15739             :       // function, so we shouldn't make new instances of it very often.
   15740       61454 :       uint32_t length = 0;
   15741       61454 :       CHECK(transition_info->length()->ToArrayLength(&length));
   15742       61454 :       if (length <= kMaximumArrayBytesToPretransition) {
   15743             :         if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) {
   15744           0 :           return true;
   15745             :         }
   15746       61454 :         if (FLAG_trace_track_allocation_sites) {
   15747           0 :           bool is_nested = site->IsNestedSite();
   15748           0 :           PrintF(
   15749             :               "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
   15750             :               reinterpret_cast<void*>(*site),
   15751             :               is_nested ? "(nested)" : "",
   15752             :               ElementsKindToString(kind),
   15753           0 :               ElementsKindToString(to_kind));
   15754             :         }
   15755       61454 :         JSObject::TransitionElementsKind(transition_info, to_kind);
   15756       61454 :         site->dependent_code()->DeoptimizeDependentCodeGroup(
   15757             :             isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
   15758             :         result = true;
   15759             :       }
   15760             :     }
   15761             :   } else {
   15762             :     ElementsKind kind = site->GetElementsKind();
   15763             :     // if kind is holey ensure that to_kind is as well.
   15764       27138 :     if (IsHoleyElementsKind(kind)) {
   15765             :       to_kind = GetHoleyElementsKind(to_kind);
   15766             :     }
   15767       27138 :     if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
   15768             :       if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) return true;
   15769       23552 :       if (FLAG_trace_track_allocation_sites) {
   15770           0 :         PrintF("AllocationSite: JSArray %p site updated %s->%s\n",
   15771             :                reinterpret_cast<void*>(*site),
   15772             :                ElementsKindToString(kind),
   15773           0 :                ElementsKindToString(to_kind));
   15774             :       }
   15775       23552 :       site->SetElementsKind(to_kind);
   15776       23552 :       site->dependent_code()->DeoptimizeDependentCodeGroup(
   15777             :           isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
   15778             :       result = true;
   15779             :     }
   15780             :   }
   15781             :   return result;
   15782             : }
   15783             : 
   15784        3312 : AllocationSiteMode AllocationSite::GetMode(ElementsKind from, ElementsKind to) {
   15785        5930 :   if (IsFastSmiElementsKind(from) &&
   15786        2618 :       IsMoreGeneralElementsKindTransition(from, to)) {
   15787             :     return TRACK_ALLOCATION_SITE;
   15788             :   }
   15789             : 
   15790         694 :   return DONT_TRACK_ALLOCATION_SITE;
   15791             : }
   15792             : 
   15793           0 : const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) {
   15794           0 :   switch (decision) {
   15795             :     case kUndecided: return "undecided";
   15796           0 :     case kDontTenure: return "don't tenure";
   15797           0 :     case kMaybeTenure: return "maybe tenure";
   15798           0 :     case kTenure: return "tenure";
   15799           0 :     case kZombie: return "zombie";
   15800           0 :     default: UNREACHABLE();
   15801             :   }
   15802             :   return NULL;
   15803             : }
   15804             : 
   15805             : template <AllocationSiteUpdateMode update_or_check>
   15806     1725146 : bool JSObject::UpdateAllocationSite(Handle<JSObject> object,
   15807             :                                     ElementsKind to_kind) {
   15808     1725146 :   if (!object->IsJSArray()) return false;
   15809             : 
   15810             :   Heap* heap = object->GetHeap();
   15811     1307902 :   if (!heap->InNewSpace(*object)) return false;
   15812             : 
   15813             :   Handle<AllocationSite> site;
   15814             :   {
   15815             :     DisallowHeapAllocation no_allocation;
   15816             : 
   15817             :     AllocationMemento* memento =
   15818     1238942 :         heap->FindAllocationMemento<Heap::kForRuntime>(*object);
   15819     1238942 :     if (memento == NULL) return false;
   15820             : 
   15821             :     // Walk through to the Allocation Site
   15822      634931 :     site = handle(memento->GetAllocationSite());
   15823             :   }
   15824             :   return AllocationSite::DigestTransitionFeedback<update_or_check>(site,
   15825      634931 :                                                                    to_kind);
   15826             : }
   15827             : 
   15828             : template bool
   15829             : JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kCheckOnly>(
   15830             :     Handle<JSObject> object, ElementsKind to_kind);
   15831             : 
   15832             : template bool JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kUpdate>(
   15833             :     Handle<JSObject> object, ElementsKind to_kind);
   15834             : 
   15835      444557 : void JSObject::TransitionElementsKind(Handle<JSObject> object,
   15836             :                                       ElementsKind to_kind) {
   15837             :   ElementsKind from_kind = object->GetElementsKind();
   15838             : 
   15839      444557 :   if (IsFastHoleyElementsKind(from_kind)) {
   15840             :     to_kind = GetHoleyElementsKind(to_kind);
   15841             :   }
   15842             : 
   15843      889114 :   if (from_kind == to_kind) return;
   15844             : 
   15845             :   // This method should never be called for any other case.
   15846             :   DCHECK(IsFastElementsKind(from_kind));
   15847             :   DCHECK(IsFastElementsKind(to_kind));
   15848             :   DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
   15849             : 
   15850      444468 :   UpdateAllocationSite(object, to_kind);
   15851      813503 :   if (object->elements() == object->GetHeap()->empty_fixed_array() ||
   15852             :       IsFastDoubleElementsKind(from_kind) ==
   15853             :           IsFastDoubleElementsKind(to_kind)) {
   15854             :     // No change is needed to the elements() buffer, the transition
   15855             :     // only requires a map change.
   15856      436765 :     Handle<Map> new_map = GetElementsTransitionMap(object, to_kind);
   15857      436765 :     MigrateToMap(object, new_map);
   15858             :     if (FLAG_trace_elements_transitions) {
   15859             :       Handle<FixedArrayBase> elms(object->elements());
   15860             :       PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms);
   15861             :     }
   15862             :   } else {
   15863             :     DCHECK((IsFastSmiElementsKind(from_kind) &&
   15864             :             IsFastDoubleElementsKind(to_kind)) ||
   15865             :            (IsFastDoubleElementsKind(from_kind) &&
   15866             :             IsFastObjectElementsKind(to_kind)));
   15867        7703 :     uint32_t c = static_cast<uint32_t>(object->elements()->length());
   15868        7703 :     ElementsAccessor::ForKind(to_kind)->GrowCapacityAndConvert(object, c);
   15869             :   }
   15870             : }
   15871             : 
   15872             : 
   15873             : // static
   15874           0 : bool Map::IsValidElementsTransition(ElementsKind from_kind,
   15875             :                                     ElementsKind to_kind) {
   15876             :   // Transitions can't go backwards.
   15877           0 :   if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
   15878             :     return false;
   15879             :   }
   15880             : 
   15881             :   // Transitions from HOLEY -> PACKED are not allowed.
   15882           0 :   return !IsFastHoleyElementsKind(from_kind) ||
   15883           0 :       IsFastHoleyElementsKind(to_kind);
   15884             : }
   15885             : 
   15886             : 
   15887     4364472 : bool JSArray::HasReadOnlyLength(Handle<JSArray> array) {
   15888             :   Map* map = array->map();
   15889             :   // Fast path: "length" is the first fast property of arrays. Since it's not
   15890             :   // configurable, it's guaranteed to be the first in the descriptor array.
   15891     4364472 :   if (!map->is_dictionary_map()) {
   15892             :     DCHECK(map->instance_descriptors()->GetKey(0) ==
   15893             :            array->GetHeap()->length_string());
   15894     8691714 :     return map->instance_descriptors()->GetDetails(0).IsReadOnly();
   15895             :   }
   15896             : 
   15897             :   Isolate* isolate = array->GetIsolate();
   15898             :   LookupIterator it(array, isolate->factory()->length_string(), array,
   15899       18615 :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
   15900       18615 :   CHECK_EQ(LookupIterator::ACCESSOR, it.state());
   15901       18615 :   return it.IsReadOnly();
   15902             : }
   15903             : 
   15904             : 
   15905     1518673 : bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
   15906             :                                         uint32_t index) {
   15907     1518673 :   uint32_t length = 0;
   15908     1518673 :   CHECK(array->length()->ToArrayLength(&length));
   15909     1518673 :   if (length <= index) return HasReadOnlyLength(array);
   15910             :   return false;
   15911             : }
   15912             : 
   15913             : 
   15914             : template <typename BackingStore>
   15915      439690 : static int FastHoleyElementsUsage(JSObject* object, BackingStore* store) {
   15916             :   Isolate* isolate = store->GetIsolate();
   15917             :   int limit = object->IsJSArray()
   15918             :                   ? Smi::cast(JSArray::cast(object)->length())->value()
   15919      439690 :                   : store->length();
   15920             :   int used = 0;
   15921   523603629 :   for (int i = 0; i < limit; ++i) {
   15922   523163939 :     if (!store->is_the_hole(isolate, i)) ++used;
   15923             :   }
   15924      439690 :   return used;
   15925             : }
   15926             : 
   15927             : 
   15928      466612 : int JSObject::GetFastElementsUsage() {
   15929             :   FixedArrayBase* store = elements();
   15930      466612 :   switch (GetElementsKind()) {
   15931             :     case FAST_SMI_ELEMENTS:
   15932             :     case FAST_DOUBLE_ELEMENTS:
   15933             :     case FAST_ELEMENTS:
   15934             :       return IsJSArray() ? Smi::cast(JSArray::cast(this)->length())->value()
   15935       53754 :                          : store->length();
   15936             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
   15937             :       store = SloppyArgumentsElements::cast(store)->arguments();
   15938             :     // Fall through.
   15939             :     case FAST_HOLEY_SMI_ELEMENTS:
   15940             :     case FAST_HOLEY_ELEMENTS:
   15941             :     case FAST_STRING_WRAPPER_ELEMENTS:
   15942      439542 :       return FastHoleyElementsUsage(this, FixedArray::cast(store));
   15943             :     case FAST_HOLEY_DOUBLE_ELEMENTS:
   15944         193 :       if (elements()->length() == 0) return 0;
   15945         148 :       return FastHoleyElementsUsage(this, FixedDoubleArray::cast(store));
   15946             : 
   15947             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
   15948             :     case SLOW_STRING_WRAPPER_ELEMENTS:
   15949             :     case DICTIONARY_ELEMENTS:
   15950             :     case NO_ELEMENTS:
   15951             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
   15952             :     case TYPE##_ELEMENTS:                                                    \
   15953             : 
   15954             :     TYPED_ARRAYS(TYPED_ARRAY_CASE)
   15955             : #undef TYPED_ARRAY_CASE
   15956           0 :     UNREACHABLE();
   15957             :   }
   15958             :   return 0;
   15959             : }
   15960             : 
   15961             : 
   15962             : // Certain compilers request function template instantiation when they
   15963             : // see the definition of the other template functions in the
   15964             : // class. This requires us to have the template functions put
   15965             : // together, so even though this function belongs in objects-debug.cc,
   15966             : // we keep it here instead to satisfy certain compilers.
   15967             : #ifdef OBJECT_PRINT
   15968             : template <typename Derived, typename Shape, typename Key>
   15969             : void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) {  // NOLINT
   15970             :   Isolate* isolate = this->GetIsolate();
   15971             :   int capacity = this->Capacity();
   15972             :   for (int i = 0; i < capacity; i++) {
   15973             :     Object* k = this->KeyAt(i);
   15974             :     if (this->IsKey(isolate, k)) {
   15975             :       os << "\n   ";
   15976             :       if (k->IsString()) {
   15977             :         String::cast(k)->StringPrint(os);
   15978             :       } else {
   15979             :         os << Brief(k);
   15980             :       }
   15981             :       os << ": " << Brief(this->ValueAt(i)) << " ";
   15982             :       this->DetailsAt(i).PrintAsSlowTo(os);
   15983             :     }
   15984             :   }
   15985             : }
   15986             : template <typename Derived, typename Shape, typename Key>
   15987             : void Dictionary<Derived, Shape, Key>::Print() {
   15988             :   OFStream os(stdout);
   15989             :   Print(os);
   15990             : }
   15991             : #endif
   15992             : 
   15993             : 
   15994        5152 : MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
   15995             :                                                          bool* done) {
   15996             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
   15997        5152 :   return GetPropertyWithInterceptorInternal(it, it->GetInterceptor(), done);
   15998             : }
   15999             : 
   16000    66895821 : Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object,
   16001             :                                            Handle<Name> name) {
   16002             :   LookupIterator it = LookupIterator::PropertyOrElement(
   16003    66895821 :       name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   16004    66895821 :   return HasProperty(&it);
   16005             : }
   16006             : 
   16007             : 
   16008          20 : Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object,
   16009             :                                              uint32_t index) {
   16010             :   Isolate* isolate = object->GetIsolate();
   16011             :   LookupIterator it(isolate, object, index, object,
   16012             :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
   16013          20 :   return HasProperty(&it);
   16014             : }
   16015             : 
   16016             : 
   16017           6 : Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
   16018             :                                                    Handle<Name> name) {
   16019             :   LookupIterator it = LookupIterator::PropertyOrElement(
   16020           6 :       name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   16021           6 :   Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
   16022           6 :   return maybe_result.IsJust() ? Just(it.state() == LookupIterator::ACCESSOR)
   16023          12 :                                : Nothing<bool>();
   16024             : }
   16025             : 
   16026        3449 : int FixedArrayBase::GetMaxLengthForNewSpaceAllocation(ElementsKind kind) {
   16027             :   return ((kMaxRegularHeapObjectSize - FixedArrayBase::kHeaderSize) >>
   16028        3449 :           ElementsKindToShiftSize(kind));
   16029             : }
   16030             : 
   16031       49010 : bool JSObject::WasConstructedFromApiFunction() {
   16032             :   auto instance_type = map()->instance_type();
   16033       49010 :   bool is_api_object = instance_type == JS_API_OBJECT_TYPE ||
   16034       49010 :                        instance_type == JS_SPECIAL_API_OBJECT_TYPE;
   16035             : #ifdef ENABLE_SLOW_DCHECKS
   16036             :   if (FLAG_enable_slow_asserts) {
   16037             :     Object* maybe_constructor = map()->GetConstructor();
   16038             :     if (maybe_constructor->IsJSFunction()) {
   16039             :       JSFunction* constructor = JSFunction::cast(maybe_constructor);
   16040             :       if (constructor->shared()->IsApiFunction()) {
   16041             :         DCHECK(is_api_object);
   16042             :       } else {
   16043             :         DCHECK(!is_api_object);
   16044             :       }
   16045             :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
   16046             :       DCHECK(is_api_object);
   16047             :     } else {
   16048             :       return false;
   16049             :     }
   16050             :   }
   16051             : #endif
   16052       49010 :   return is_api_object;
   16053             : }
   16054             : 
   16055         210 : const char* Symbol::PrivateSymbolToName() const {
   16056        7140 :   Heap* heap = GetIsolate()->heap();
   16057             : #define SYMBOL_CHECK_AND_PRINT(name) \
   16058             :   if (this == heap->name()) return #name;
   16059        7140 :   PRIVATE_SYMBOL_LIST(SYMBOL_CHECK_AND_PRINT)
   16060             : #undef SYMBOL_CHECK_AND_PRINT
   16061         210 :   return "UNKNOWN";
   16062             : }
   16063             : 
   16064             : 
   16065         227 : void Symbol::SymbolShortPrint(std::ostream& os) {
   16066         227 :   os << "<Symbol:";
   16067         227 :   if (!name()->IsUndefined(GetIsolate())) {
   16068          17 :     os << " ";
   16069             :     HeapStringAllocator allocator;
   16070             :     StringStream accumulator(&allocator);
   16071          17 :     String::cast(name())->StringShortPrint(&accumulator, false);
   16072          51 :     os << accumulator.ToCString().get();
   16073             :   } else {
   16074         210 :     os << " (" << PrivateSymbolToName() << ")";
   16075             :   }
   16076         227 :   os << ">";
   16077         227 : }
   16078             : 
   16079             : 
   16080             : // StringSharedKeys are used as keys in the eval cache.
   16081           0 : class StringSharedKey : public HashTableKey {
   16082             :  public:
   16083             :   // This tuple unambiguously identifies calls to eval() or
   16084             :   // CreateDynamicFunction() (such as through the Function() constructor).
   16085             :   // * source is the string passed into eval(). For dynamic functions, this is
   16086             :   //   the effective source for the function, some of which is implicitly
   16087             :   //   generated.
   16088             :   // * shared is the shared function info for the function containing the call
   16089             :   //   to eval(). for dynamic functions, shared is the native context closure.
   16090             :   // * When positive, position is the position in the source where eval is
   16091             :   //   called. When negative, position is the negation of the position in the
   16092             :   //   dynamic function's effective source where the ')' ends the parameters.
   16093             :   StringSharedKey(Handle<String> source, Handle<SharedFunctionInfo> shared,
   16094             :                   LanguageMode language_mode, int position)
   16095             :       : source_(source),
   16096             :         shared_(shared),
   16097             :         language_mode_(language_mode),
   16098     7850993 :         position_(position) {}
   16099             : 
   16100     9649113 :   bool IsMatch(Object* other) override {
   16101             :     DisallowHeapAllocation no_allocation;
   16102     9649113 :     if (!other->IsFixedArray()) {
   16103     2549780 :       if (!other->IsNumber()) return false;
   16104     2549780 :       uint32_t other_hash = static_cast<uint32_t>(other->Number());
   16105     2549780 :       return Hash() == other_hash;
   16106             :     }
   16107             :     FixedArray* other_array = FixedArray::cast(other);
   16108             :     SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
   16109     7099333 :     if (shared != *shared_) return false;
   16110             :     int language_unchecked = Smi::cast(other_array->get(2))->value();
   16111             :     DCHECK(is_valid_language_mode(language_unchecked));
   16112     6776483 :     LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
   16113     6776483 :     if (language_mode != language_mode_) return false;
   16114             :     int position = Smi::cast(other_array->get(3))->value();
   16115     6750051 :     if (position != position_) return false;
   16116             :     String* source = String::cast(other_array->get(1));
   16117     6750021 :     return source->Equals(*source_);
   16118             :   }
   16119             : 
   16120    12129773 :   static uint32_t StringSharedHashHelper(String* source,
   16121             :                                          SharedFunctionInfo* shared,
   16122             :                                          LanguageMode language_mode,
   16123             :                                          int position) {
   16124             :     uint32_t hash = source->Hash();
   16125    12129773 :     if (shared->HasSourceCode()) {
   16126             :       // Instead of using the SharedFunctionInfo pointer in the hash
   16127             :       // code computation, we use a combination of the hash of the
   16128             :       // script source code and the start position of the calling scope.
   16129             :       // We do this to ensure that the cache entries can survive garbage
   16130             :       // collection.
   16131             :       Script* script(Script::cast(shared->script()));
   16132    12129773 :       hash ^= String::cast(script->source())->Hash();
   16133             :       STATIC_ASSERT(LANGUAGE_END == 2);
   16134    12129773 :       if (is_strict(language_mode)) hash ^= 0x8000;
   16135    12129773 :       hash += position;
   16136             :     }
   16137    12129773 :     return hash;
   16138             :   }
   16139             : 
   16140    11954739 :   uint32_t Hash() override {
   16141             :     return StringSharedHashHelper(*source_, *shared_, language_mode_,
   16142    23909478 :                                   position_);
   16143             :   }
   16144             : 
   16145     1019703 :   uint32_t HashForObject(Object* obj) override {
   16146             :     DisallowHeapAllocation no_allocation;
   16147     1019703 :     if (obj->IsNumber()) {
   16148      844669 :       return static_cast<uint32_t>(obj->Number());
   16149             :     }
   16150             :     FixedArray* other_array = FixedArray::cast(obj);
   16151             :     SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
   16152             :     String* source = String::cast(other_array->get(1));
   16153             :     int language_unchecked = Smi::cast(other_array->get(2))->value();
   16154             :     DCHECK(is_valid_language_mode(language_unchecked));
   16155      175034 :     LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
   16156             :     int position = Smi::cast(other_array->get(3))->value();
   16157      175034 :     return StringSharedHashHelper(source, shared, language_mode, position);
   16158             :   }
   16159             : 
   16160             : 
   16161     1985791 :   Handle<Object> AsHandle(Isolate* isolate) override {
   16162     1985791 :     Handle<FixedArray> array = isolate->factory()->NewFixedArray(4);
   16163     1985791 :     array->set(0, *shared_);
   16164     1985791 :     array->set(1, *source_);
   16165     1985791 :     array->set(2, Smi::FromInt(language_mode_));
   16166     1985791 :     array->set(3, Smi::FromInt(position_));
   16167     1985791 :     return array;
   16168             :   }
   16169             : 
   16170             :  private:
   16171             :   Handle<String> source_;
   16172             :   Handle<SharedFunctionInfo> shared_;
   16173             :   LanguageMode language_mode_;
   16174             :   int position_;
   16175             : };
   16176             : 
   16177             : // static
   16178          30 : const char* JSPromise::Status(int status) {
   16179          30 :   switch (status) {
   16180             :     case v8::Promise::kFulfilled:
   16181             :       return "resolved";
   16182             :     case v8::Promise::kPending:
   16183          12 :       return "pending";
   16184             :     case v8::Promise::kRejected:
   16185           0 :       return "rejected";
   16186             :   }
   16187           0 :   UNREACHABLE();
   16188             :   return NULL;
   16189             : }
   16190             : 
   16191             : namespace {
   16192             : 
   16193      593209 : JSRegExp::Flags RegExpFlagsFromString(Handle<String> flags, bool* success) {
   16194             :   JSRegExp::Flags value = JSRegExp::kNone;
   16195             :   int length = flags->length();
   16196             :   // A longer flags string cannot be valid.
   16197      593209 :   if (length > JSRegExp::FlagCount()) return JSRegExp::Flags(0);
   16198       97165 :   for (int i = 0; i < length; i++) {
   16199             :     JSRegExp::Flag flag = JSRegExp::kNone;
   16200       97445 :     switch (flags->Get(i)) {
   16201             :       case 'g':
   16202             :         flag = JSRegExp::kGlobal;
   16203             :         break;
   16204             :       case 'i':
   16205             :         flag = JSRegExp::kIgnoreCase;
   16206       76841 :         break;
   16207             :       case 'm':
   16208             :         flag = JSRegExp::kMultiline;
   16209         719 :         break;
   16210             :       case 's':
   16211          84 :         if (FLAG_harmony_regexp_dotall) {
   16212             :           flag = JSRegExp::kDotAll;
   16213             :         } else {
   16214          28 :           return JSRegExp::Flags(0);
   16215             :         }
   16216             :         break;
   16217             :       case 'u':
   16218             :         flag = JSRegExp::kUnicode;
   16219        1835 :         break;
   16220             :       case 'y':
   16221             :         flag = JSRegExp::kSticky;
   16222         130 :         break;
   16223             :       default:
   16224          43 :         return JSRegExp::Flags(0);
   16225             :     }
   16226             :     // Duplicate flag.
   16227       97374 :     if (value & flag) return JSRegExp::Flags(0);
   16228             :     value |= flag;
   16229             :   }
   16230      592929 :   *success = true;
   16231      592929 :   return value;
   16232             : }
   16233             : 
   16234             : }  // namespace
   16235             : 
   16236             : 
   16237             : // static
   16238      125419 : MaybeHandle<JSRegExp> JSRegExp::New(Handle<String> pattern, Flags flags) {
   16239             :   Isolate* isolate = pattern->GetIsolate();
   16240      125419 :   Handle<JSFunction> constructor = isolate->regexp_function();
   16241             :   Handle<JSRegExp> regexp =
   16242      125419 :       Handle<JSRegExp>::cast(isolate->factory()->NewJSObject(constructor));
   16243             : 
   16244      125419 :   return JSRegExp::Initialize(regexp, pattern, flags);
   16245             : }
   16246             : 
   16247             : 
   16248             : // static
   16249      122005 : Handle<JSRegExp> JSRegExp::Copy(Handle<JSRegExp> regexp) {
   16250             :   Isolate* const isolate = regexp->GetIsolate();
   16251      122005 :   return Handle<JSRegExp>::cast(isolate->factory()->CopyJSObject(regexp));
   16252             : }
   16253             : 
   16254             : 
   16255             : template <typename Char>
   16256      719976 : inline int CountRequiredEscapes(Handle<String> source) {
   16257             :   DisallowHeapAllocation no_gc;
   16258             :   int escapes = 0;
   16259             :   Vector<const Char> src = source->GetCharVector<Char>();
   16260    16857041 :   for (int i = 0; i < src.length(); i++) {
   16261    16137065 :     if (src[i] == '\\') {
   16262             :       // Escape. Skip next character;
   16263      152785 :       i++;
   16264    15984280 :     } else if (src[i] == '/') {
   16265             :       // Not escaped forward-slash needs escape.
   16266        2627 :       escapes++;
   16267             :     }
   16268             :   }
   16269      719976 :   return escapes;
   16270             : }
   16271             : 
   16272             : 
   16273             : template <typename Char, typename StringType>
   16274         958 : inline Handle<StringType> WriteEscapedRegExpSource(Handle<String> source,
   16275             :                                                    Handle<StringType> result) {
   16276             :   DisallowHeapAllocation no_gc;
   16277             :   Vector<const Char> src = source->GetCharVector<Char>();
   16278         958 :   Vector<Char> dst(result->GetChars(), result->length());
   16279             :   int s = 0;
   16280             :   int d = 0;
   16281       52745 :   while (s < src.length()) {
   16282       50829 :     if (src[s] == '\\') {
   16283             :       // Escape. Copy this and next character.
   16284        6196 :       dst[d++] = src[s++];
   16285        3098 :       if (s == src.length()) break;
   16286       47731 :     } else if (src[s] == '/') {
   16287             :       // Not escaped forward-slash needs escape.
   16288        5254 :       dst[d++] = '\\';
   16289             :     }
   16290      152487 :     dst[d++] = src[s++];
   16291             :   }
   16292             :   DCHECK_EQ(result->length(), d);
   16293         958 :   return result;
   16294             : }
   16295             : 
   16296             : 
   16297      719976 : MaybeHandle<String> EscapeRegExpSource(Isolate* isolate,
   16298             :                                        Handle<String> source) {
   16299             :   DCHECK(source->IsFlat());
   16300      719976 :   if (source->length() == 0) return isolate->factory()->query_colon_string();
   16301      719976 :   bool one_byte = source->IsOneByteRepresentationUnderneath();
   16302             :   int escapes = one_byte ? CountRequiredEscapes<uint8_t>(source)
   16303      719976 :                          : CountRequiredEscapes<uc16>(source);
   16304      719976 :   if (escapes == 0) return source;
   16305         958 :   int length = source->length() + escapes;
   16306         958 :   if (one_byte) {
   16307             :     Handle<SeqOneByteString> result;
   16308        1916 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   16309             :                                isolate->factory()->NewRawOneByteString(length),
   16310             :                                String);
   16311         958 :     return WriteEscapedRegExpSource<uint8_t>(source, result);
   16312             :   } else {
   16313             :     Handle<SeqTwoByteString> result;
   16314           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   16315             :                                isolate->factory()->NewRawTwoByteString(length),
   16316             :                                String);
   16317           0 :     return WriteEscapedRegExpSource<uc16>(source, result);
   16318             :   }
   16319             : }
   16320             : 
   16321             : 
   16322             : // static
   16323      593209 : MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
   16324             :                                            Handle<String> source,
   16325             :                                            Handle<String> flags_string) {
   16326             :   Isolate* isolate = source->GetIsolate();
   16327      593209 :   bool success = false;
   16328      593209 :   Flags flags = RegExpFlagsFromString(flags_string, &success);
   16329      593209 :   if (!success) {
   16330         560 :     THROW_NEW_ERROR(
   16331             :         isolate,
   16332             :         NewSyntaxError(MessageTemplate::kInvalidRegExpFlags, flags_string),
   16333             :         JSRegExp);
   16334             :   }
   16335      592929 :   return Initialize(regexp, source, flags);
   16336             : }
   16337             : 
   16338             : 
   16339             : // static
   16340      719976 : MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
   16341             :                                            Handle<String> source, Flags flags) {
   16342             :   Isolate* isolate = regexp->GetIsolate();
   16343             :   Factory* factory = isolate->factory();
   16344             :   // If source is the empty string we set it to "(?:)" instead as
   16345             :   // suggested by ECMA-262, 5th, section 15.10.4.1.
   16346      719976 :   if (source->length() == 0) source = factory->query_colon_string();
   16347             : 
   16348      719976 :   source = String::Flatten(source);
   16349             : 
   16350             :   Handle<String> escaped_source;
   16351     1439952 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, escaped_source,
   16352             :                              EscapeRegExpSource(isolate, source), JSRegExp);
   16353             : 
   16354     1439952 :   RETURN_ON_EXCEPTION(isolate, RegExpImpl::Compile(regexp, source, flags),
   16355             :                       JSRegExp);
   16356             : 
   16357      716414 :   regexp->set_source(*escaped_source);
   16358      716414 :   regexp->set_flags(Smi::FromInt(flags));
   16359             : 
   16360             :   Map* map = regexp->map();
   16361      716414 :   Object* constructor = map->GetConstructor();
   16362     1432828 :   if (constructor->IsJSFunction() &&
   16363             :       JSFunction::cast(constructor)->initial_map() == map) {
   16364             :     // If we still have the original map, set in-object properties directly.
   16365             :     regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, Smi::kZero,
   16366      716116 :                                   SKIP_WRITE_BARRIER);
   16367             :   } else {
   16368             :     // Map has changed, so use generic, but slower, method.
   16369         596 :     RETURN_ON_EXCEPTION(isolate, JSReceiver::SetProperty(
   16370             :                                      regexp, factory->lastIndex_string(),
   16371             :                                      Handle<Smi>(Smi::kZero, isolate), STRICT),
   16372             :                         JSRegExp);
   16373             :   }
   16374             : 
   16375             :   return regexp;
   16376             : }
   16377             : 
   16378             : 
   16379             : // RegExpKey carries the source and flags of a regular expression as key.
   16380           0 : class RegExpKey : public HashTableKey {
   16381             :  public:
   16382             :   RegExpKey(Handle<String> string, JSRegExp::Flags flags)
   16383     2845342 :       : string_(string), flags_(Smi::FromInt(flags)) {}
   16384             : 
   16385             :   // Rather than storing the key in the hash table, a pointer to the
   16386             :   // stored value is stored where the key should be.  IsMatch then
   16387             :   // compares the search key to the found object, rather than comparing
   16388             :   // a key to a key.
   16389      845391 :   bool IsMatch(Object* obj) override {
   16390             :     FixedArray* val = FixedArray::cast(obj);
   16391      845391 :     return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex)))
   16392     1201848 :         && (flags_ == val->get(JSRegExp::kFlagsIndex));
   16393             :   }
   16394             : 
   16395     2845342 :   uint32_t Hash() override { return RegExpHash(*string_, flags_); }
   16396             : 
   16397           0 :   Handle<Object> AsHandle(Isolate* isolate) override {
   16398             :     // Plain hash maps, which is where regexp keys are used, don't
   16399             :     // use this function.
   16400           0 :     UNREACHABLE();
   16401             :     return MaybeHandle<Object>().ToHandleChecked();
   16402             :   }
   16403             : 
   16404      511813 :   uint32_t HashForObject(Object* obj) override {
   16405             :     FixedArray* val = FixedArray::cast(obj);
   16406             :     return RegExpHash(String::cast(val->get(JSRegExp::kSourceIndex)),
   16407      511813 :                       Smi::cast(val->get(JSRegExp::kFlagsIndex)));
   16408             :   }
   16409             : 
   16410     1934484 :   static uint32_t RegExpHash(String* string, Smi* flags) {
   16411     1934484 :     return string->Hash() + flags->value();
   16412             :   }
   16413             : 
   16414             :   Handle<String> string_;
   16415             :   Smi* flags_;
   16416             : };
   16417             : 
   16418             : 
   16419       55683 : Handle<Object> OneByteStringKey::AsHandle(Isolate* isolate) {
   16420       55683 :   if (hash_field_ == 0) Hash();
   16421       55683 :   return isolate->factory()->NewOneByteInternalizedString(string_, hash_field_);
   16422             : }
   16423             : 
   16424             : 
   16425           0 : Handle<Object> TwoByteStringKey::AsHandle(Isolate* isolate) {
   16426           0 :   if (hash_field_ == 0) Hash();
   16427           0 :   return isolate->factory()->NewTwoByteInternalizedString(string_, hash_field_);
   16428             : }
   16429             : 
   16430             : 
   16431      115049 : Handle<Object> SeqOneByteSubStringKey::AsHandle(Isolate* isolate) {
   16432      115049 :   if (hash_field_ == 0) Hash();
   16433             :   return isolate->factory()->NewOneByteInternalizedSubString(
   16434      115049 :       string_, from_, length_, hash_field_);
   16435             : }
   16436             : 
   16437             : 
   16438      163661 : bool SeqOneByteSubStringKey::IsMatch(Object* string) {
   16439      327322 :   Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
   16440      163661 :   return String::cast(string)->IsOneByteEqualTo(chars);
   16441             : }
   16442             : 
   16443             : 
   16444             : // InternalizedStringKey carries a string/internalized-string object as key.
   16445           0 : class InternalizedStringKey : public HashTableKey {
   16446             :  public:
   16447             :   explicit InternalizedStringKey(Handle<String> string)
   16448    22837777 :       : string_(String::Flatten(string)) {}
   16449             : 
   16450    30602494 :   bool IsMatch(Object* string) override {
   16451    30602494 :     return String::cast(string)->Equals(*string_);
   16452             :   }
   16453             : 
   16454    49481464 :   uint32_t Hash() override { return string_->Hash(); }
   16455             : 
   16456      549938 :   uint32_t HashForObject(Object* other) override {
   16457      549938 :     return String::cast(other)->Hash();
   16458             :   }
   16459             : 
   16460     1903339 :   Handle<Object> AsHandle(Isolate* isolate) override {
   16461             :     // Internalize the string if possible.
   16462             :     MaybeHandle<Map> maybe_map =
   16463     1903339 :         isolate->factory()->InternalizedStringMapForString(string_);
   16464             :     Handle<Map> map;
   16465     1903339 :     if (maybe_map.ToHandle(&map)) {
   16466             :       string_->set_map_no_write_barrier(*map);
   16467             :       DCHECK(string_->IsInternalizedString());
   16468       10899 :       return string_;
   16469             :     }
   16470     1892440 :     if (FLAG_thin_strings) {
   16471             :       // External strings get special treatment, to avoid copying their
   16472             :       // contents.
   16473     1330761 :       if (string_->IsExternalOneByteString()) {
   16474             :         return isolate->factory()
   16475           6 :             ->InternalizeExternalString<ExternalOneByteString>(string_);
   16476     1330755 :       } else if (string_->IsExternalTwoByteString()) {
   16477             :         return isolate->factory()
   16478           0 :             ->InternalizeExternalString<ExternalTwoByteString>(string_);
   16479             :       }
   16480             :     }
   16481             :     // Otherwise allocate a new internalized string.
   16482             :     return isolate->factory()->NewInternalizedStringImpl(
   16483     1892434 :         string_, string_->length(), string_->hash_field());
   16484             :   }
   16485             : 
   16486             :   static uint32_t StringHash(Object* obj) {
   16487             :     return String::cast(obj)->Hash();
   16488             :   }
   16489             : 
   16490             :  private:
   16491             :   Handle<String> string_;
   16492             : };
   16493             : 
   16494             : 
   16495             : template<typename Derived, typename Shape, typename Key>
   16496       53294 : void HashTable<Derived, Shape, Key>::IteratePrefix(ObjectVisitor* v) {
   16497             :   BodyDescriptorBase::IteratePointers(this, 0, kElementsStartOffset, v);
   16498       53294 : }
   16499             : 
   16500             : 
   16501             : template<typename Derived, typename Shape, typename Key>
   16502       71384 : void HashTable<Derived, Shape, Key>::IterateElements(ObjectVisitor* v) {
   16503             :   BodyDescriptorBase::IteratePointers(this, kElementsStartOffset,
   16504       71384 :                                       kHeaderSize + length() * kPointerSize, v);
   16505       71384 : }
   16506             : 
   16507             : 
   16508             : template<typename Derived, typename Shape, typename Key>
   16509     7430455 : Handle<Derived> HashTable<Derived, Shape, Key>::New(
   16510             :     Isolate* isolate,
   16511             :     int at_least_space_for,
   16512             :     MinimumCapacity capacity_option,
   16513             :     PretenureFlag pretenure) {
   16514             :   DCHECK(0 <= at_least_space_for);
   16515             :   DCHECK_IMPLIES(capacity_option == USE_CUSTOM_MINIMUM_CAPACITY,
   16516             :                  base::bits::IsPowerOfTwo32(at_least_space_for));
   16517             : 
   16518             :   int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
   16519             :                      ? at_least_space_for
   16520     7430455 :                      : ComputeCapacity(at_least_space_for);
   16521     7430455 :   if (capacity > HashTable::kMaxCapacity) {
   16522           0 :     v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
   16523             :   }
   16524     7430455 :   return New(isolate, capacity, pretenure);
   16525             : }
   16526             : 
   16527             : template <typename Derived, typename Shape, typename Key>
   16528     7430739 : Handle<Derived> HashTable<Derived, Shape, Key>::New(Isolate* isolate,
   16529             :                                                     int capacity,
   16530             :                                                     PretenureFlag pretenure) {
   16531             :   Factory* factory = isolate->factory();
   16532             :   int length = EntryToIndex(capacity);
   16533     7430739 :   Handle<FixedArray> array = factory->NewFixedArray(length, pretenure);
   16534             :   array->set_map_no_write_barrier(Shape::GetMap(isolate));
   16535             :   Handle<Derived> table = Handle<Derived>::cast(array);
   16536             : 
   16537             :   table->SetNumberOfElements(0);
   16538             :   table->SetNumberOfDeletedElements(0);
   16539             :   table->SetCapacity(capacity);
   16540     7430737 :   return table;
   16541             : }
   16542             : 
   16543             : // Find entry for key otherwise return kNotFound.
   16544             : template <typename Derived, typename Shape>
   16545    94076451 : int NameDictionaryBase<Derived, Shape>::FindEntry(Handle<Name> key) {
   16546    94076451 :   if (!key->IsUniqueName()) {
   16547           0 :     return DerivedDictionary::FindEntry(key);
   16548             :   }
   16549             : 
   16550             :   // Optimized for unique names. Knowledge of the key type allows:
   16551             :   // 1. Move the check if the key is unique out of the loop.
   16552             :   // 2. Avoid comparing hash codes in unique-to-unique comparison.
   16553             :   // 3. Detect a case when a dictionary key is not unique but the key is.
   16554             :   //    In case of positive result the dictionary key may be replaced by the
   16555             :   //    internalized string with minimal performance penalty. It gives a chance
   16556             :   //    to perform further lookups in code stubs (and significant performance
   16557             :   //    boost a certain style of code).
   16558             : 
   16559             :   // EnsureCapacity will guarantee the hash table is never full.
   16560    94076451 :   uint32_t capacity = this->Capacity();
   16561             :   uint32_t entry = Derived::FirstProbe(key->Hash(), capacity);
   16562             :   uint32_t count = 1;
   16563             :   Isolate* isolate = this->GetIsolate();
   16564             :   while (true) {
   16565   151673521 :     Object* element = this->KeyAt(entry);
   16566   151673511 :     if (element->IsUndefined(isolate)) break;  // Empty entry.
   16567   107072172 :     if (*key == element) return entry;
   16568             :     DCHECK(element->IsTheHole(isolate) || element->IsUniqueName());
   16569    57597070 :     entry = Derived::NextProbe(entry, count++, capacity);
   16570             :   }
   16571    57597070 :   return Derived::kNotFound;
   16572             : }
   16573             : 
   16574             : 
   16575             : template<typename Derived, typename Shape, typename Key>
   16576     3427166 : void HashTable<Derived, Shape, Key>::Rehash(
   16577             :     Handle<Derived> new_table,
   16578             :     Key key) {
   16579             :   DCHECK(NumberOfElements() < new_table->Capacity());
   16580             : 
   16581             :   DisallowHeapAllocation no_gc;
   16582     3427166 :   WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc);
   16583             : 
   16584             :   // Copy prefix to new array.
   16585    10226247 :   for (int i = kPrefixStartIndex;
   16586             :        i < kPrefixStartIndex + Shape::kPrefixSize;
   16587             :        i++) {
   16588     6817498 :     new_table->set(i, get(i), mode);
   16589             :   }
   16590             : 
   16591             :   // Rehash the elements.
   16592             :   int capacity = this->Capacity();
   16593     3427166 :   Heap* heap = new_table->GetHeap();
   16594             :   Object* the_hole = heap->the_hole_value();
   16595             :   Object* undefined = heap->undefined_value();
   16596    73589081 :   for (int i = 0; i < capacity; i++) {
   16597    70159402 :     uint32_t from_index = EntryToIndex(i);
   16598             :     Object* k = this->get(from_index);
   16599    70159402 :     if (k != the_hole && k != undefined) {
   16600             :       uint32_t hash = this->HashForObject(key, k);
   16601             :       uint32_t insertion_index =
   16602    78329098 :           EntryToIndex(new_table->FindInsertionEntry(hash));
   16603   135876972 :       for (int j = 0; j < Shape::kEntrySize; j++) {
   16604   290137269 :         new_table->set(insertion_index + j, get(from_index + j), mode);
   16605             :       }
   16606             :     }
   16607             :   }
   16608             :   new_table->SetNumberOfElements(NumberOfElements());
   16609             :   new_table->SetNumberOfDeletedElements(0);
   16610     3427166 : }
   16611             : 
   16612             : 
   16613             : template<typename Derived, typename Shape, typename Key>
   16614     1428621 : uint32_t HashTable<Derived, Shape, Key>::EntryForProbe(
   16615             :     Key key,
   16616             :     Object* k,
   16617             :     int probe,
   16618             :     uint32_t expected) {
   16619             :   uint32_t hash = this->HashForObject(key, k);
   16620     1428621 :   uint32_t capacity = this->Capacity();
   16621             :   uint32_t entry = FirstProbe(hash, capacity);
   16622     3498116 :   for (int i = 1; i < probe; i++) {
   16623     2838300 :     if (entry == expected) return expected;
   16624     2069495 :     entry = NextProbe(entry, i, capacity);
   16625             :   }
   16626             :   return entry;
   16627             : }
   16628             : 
   16629             : 
   16630             : template<typename Derived, typename Shape, typename Key>
   16631        9497 : void HashTable<Derived, Shape, Key>::Swap(uint32_t entry1,
   16632             :                                           uint32_t entry2,
   16633             :                                           WriteBarrierMode mode) {
   16634        9497 :   int index1 = EntryToIndex(entry1);
   16635        9497 :   int index2 = EntryToIndex(entry2);
   16636             :   Object* temp[Shape::kEntrySize];
   16637       28491 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   16638       37988 :     temp[j] = get(index1 + j);
   16639             :   }
   16640       18994 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   16641       37988 :     set(index1 + j, get(index2 + j), mode);
   16642             :   }
   16643       18994 :   for (int j = 0; j < Shape::kEntrySize; j++) {
   16644       18994 :     set(index2 + j, temp[j], mode);
   16645             :   }
   16646        9497 : }
   16647             : 
   16648             : 
   16649             : template<typename Derived, typename Shape, typename Key>
   16650       53315 : void HashTable<Derived, Shape, Key>::Rehash(Key key) {
   16651             :   DisallowHeapAllocation no_gc;
   16652       53315 :   WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
   16653             :   Isolate* isolate = GetIsolate();
   16654       53315 :   uint32_t capacity = Capacity();
   16655             :   bool done = false;
   16656      141562 :   for (int probe = 1; !done; probe++) {
   16657             :     // All elements at entries given by one of the first _probe_ probes
   16658             :     // are placed correctly. Other elements might need to be moved.
   16659             :     done = true;
   16660     4180121 :     for (uint32_t current = 0; current < capacity; current++) {
   16661     4180121 :       Object* current_key = KeyAt(current);
   16662     4180121 :       if (IsKey(isolate, current_key)) {
   16663     1177775 :         uint32_t target = EntryForProbe(key, current_key, probe, current);
   16664     1177775 :         if (current == target) continue;
   16665      257264 :         Object* target_key = KeyAt(target);
   16666      508110 :         if (!IsKey(isolate, target_key) ||
   16667      250846 :             EntryForProbe(key, target_key, probe, target) != target) {
   16668             :           // Put the current element into the correct position.
   16669        9497 :           Swap(current, target, mode);
   16670             :           // The other element will be processed on the next iteration.
   16671        9497 :           current--;
   16672             :         } else {
   16673             :           // The place for the current element is occupied. Leave the element
   16674             :           // for the next probe.
   16675             :           done = false;
   16676             :         }
   16677             :       }
   16678             :     }
   16679             :   }
   16680             :   // Wipe deleted entries.
   16681       53315 :   Object* the_hole = isolate->heap()->the_hole_value();
   16682       53315 :   Object* undefined = isolate->heap()->undefined_value();
   16683     1977507 :   for (uint32_t current = 0; current < capacity; current++) {
   16684     3848384 :     if (KeyAt(current) == the_hole) {
   16685       15731 :       set(EntryToIndex(current) + Derived::kEntryKeyIndex, undefined);
   16686             :     }
   16687             :   }
   16688             :   SetNumberOfDeletedElements(0);
   16689       53315 : }
   16690             : 
   16691             : 
   16692             : template<typename Derived, typename Shape, typename Key>
   16693    69331169 : Handle<Derived> HashTable<Derived, Shape, Key>::EnsureCapacity(
   16694             :     Handle<Derived> table,
   16695             :     int n,
   16696             :     Key key,
   16697             :     PretenureFlag pretenure) {
   16698    69331169 :   if (table->HasSufficientCapacityToAdd(n)) return table;
   16699             : 
   16700             :   Isolate* isolate = table->GetIsolate();
   16701             :   int capacity = table->Capacity();
   16702     3426737 :   int new_nof = table->NumberOfElements() + n;
   16703             : 
   16704             :   const int kMinCapacityForPretenure = 256;
   16705             :   bool should_pretenure = pretenure == TENURED ||
   16706             :       ((capacity > kMinCapacityForPretenure) &&
   16707     3433762 :           !isolate->heap()->InNewSpace(*table));
   16708             :   Handle<Derived> new_table =
   16709             :       HashTable::New(isolate, new_nof, USE_DEFAULT_MINIMUM_CAPACITY,
   16710     3426737 :                      should_pretenure ? TENURED : NOT_TENURED);
   16711             : 
   16712     3426737 :   table->Rehash(new_table, key);
   16713     3426737 :   return new_table;
   16714             : }
   16715             : 
   16716             : template <typename Derived, typename Shape, typename Key>
   16717    69336984 : bool HashTable<Derived, Shape, Key>::HasSufficientCapacityToAdd(
   16718             :     int number_of_additional_elements) {
   16719             :   int capacity = Capacity();
   16720    69336984 :   int nof = NumberOfElements() + number_of_additional_elements;
   16721             :   int nod = NumberOfDeletedElements();
   16722             :   // Return true if:
   16723             :   //   50% is still free after adding number_of_additional_elements elements and
   16724             :   //   at most 50% of the free elements are deleted elements.
   16725    69336984 :   if ((nof < capacity) && ((nod <= (capacity - nof) >> 1))) {
   16726    66366858 :     int needed_free = nof >> 1;
   16727    66366858 :     if (nof + needed_free <= capacity) return true;
   16728             :   }
   16729     3427139 :   return false;
   16730             : }
   16731             : 
   16732             : 
   16733             : template<typename Derived, typename Shape, typename Key>
   16734     6170046 : Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table,
   16735             :                                                        Key key) {
   16736             :   int capacity = table->Capacity();
   16737             :   int nof = table->NumberOfElements();
   16738             : 
   16739             :   // Shrink to fit the number of elements if only a quarter of the
   16740             :   // capacity is filled with elements.
   16741     6170046 :   if (nof > (capacity >> 2)) return table;
   16742             :   // Allocate a new dictionary with room for at least the current
   16743             :   // number of elements. The allocation method will make sure that
   16744             :   // there is extra room in the dictionary for additions. Don't go
   16745             :   // lower than room for 16 elements.
   16746             :   int at_least_room_for = nof;
   16747     6119485 :   if (at_least_room_for < 16) return table;
   16748             : 
   16749             :   Isolate* isolate = table->GetIsolate();
   16750             :   const int kMinCapacityForPretenure = 256;
   16751             :   bool pretenure =
   16752             :       (at_least_room_for > kMinCapacityForPretenure) &&
   16753         458 :       !isolate->heap()->InNewSpace(*table);
   16754             :   Handle<Derived> new_table = HashTable::New(
   16755             :       isolate,
   16756             :       at_least_room_for,
   16757             :       USE_DEFAULT_MINIMUM_CAPACITY,
   16758         429 :       pretenure ? TENURED : NOT_TENURED);
   16759             : 
   16760         429 :   table->Rehash(new_table, key);
   16761         429 :   return new_table;
   16762             : }
   16763             : 
   16764             : 
   16765             : template<typename Derived, typename Shape, typename Key>
   16766   108495329 : uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) {
   16767   108495329 :   uint32_t capacity = Capacity();
   16768             :   uint32_t entry = FirstProbe(hash, capacity);
   16769             :   uint32_t count = 1;
   16770             :   // EnsureCapacity will guarantee the hash table is never full.
   16771             :   Isolate* isolate = GetIsolate();
   16772             :   while (true) {
   16773   180994568 :     Object* element = KeyAt(entry);
   16774   180994568 :     if (!IsKey(isolate, element)) break;
   16775    72499239 :     entry = NextProbe(entry, count++, capacity);
   16776             :   }
   16777    72499239 :   return entry;
   16778             : }
   16779             : 
   16780             : 
   16781             : // Force instantiation of template instances class.
   16782             : // Please note this list is compiler dependent.
   16783             : 
   16784             : template class HashTable<StringTable, StringTableShape, HashTableKey*>;
   16785             : 
   16786             : template class HashTable<CompilationCacheTable,
   16787             :                          CompilationCacheShape,
   16788             :                          HashTableKey*>;
   16789             : 
   16790             : template class HashTable<ObjectHashTable,
   16791             :                          ObjectHashTableShape,
   16792             :                          Handle<Object> >;
   16793             : 
   16794             : template class HashTable<WeakHashTable, WeakHashTableShape<2>, Handle<Object> >;
   16795             : 
   16796             : template class Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >;
   16797             : 
   16798             : template class Dictionary<GlobalDictionary, GlobalDictionaryShape,
   16799             :                           Handle<Name> >;
   16800             : 
   16801             : template class Dictionary<SeededNumberDictionary,
   16802             :                           SeededNumberDictionaryShape,
   16803             :                           uint32_t>;
   16804             : 
   16805             : template class Dictionary<UnseededNumberDictionary,
   16806             :                           UnseededNumberDictionaryShape,
   16807             :                           uint32_t>;
   16808             : 
   16809             : template Handle<SeededNumberDictionary>
   16810             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::New(
   16811             :     Isolate*, int at_least_space_for, PretenureFlag pretenure,
   16812             :     MinimumCapacity capacity_option);
   16813             : 
   16814             : template Handle<SeededNumberDictionary>
   16815             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape,
   16816             :            uint32_t>::NewEmpty(Isolate*, PretenureFlag pretenure);
   16817             : 
   16818             : template Handle<UnseededNumberDictionary>
   16819             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape,
   16820             :            uint32_t>::NewEmpty(Isolate*, PretenureFlag pretenure);
   16821             : 
   16822             : template Handle<UnseededNumberDictionary>
   16823             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape,
   16824             :            uint32_t>::New(Isolate*, int at_least_space_for,
   16825             :                           PretenureFlag pretenure,
   16826             :                           MinimumCapacity capacity_option);
   16827             : 
   16828             : template Handle<NameDictionary>
   16829             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::New(
   16830             :     Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
   16831             : 
   16832             : template Handle<NameDictionary>
   16833             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::NewEmpty(
   16834             :     Isolate*, PretenureFlag pretenure);
   16835             : 
   16836             : template Handle<GlobalDictionary>
   16837             : Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::New(
   16838             :     Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
   16839             : 
   16840             : template Handle<SeededNumberDictionary>
   16841             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
   16842             :     AtPut(Handle<SeededNumberDictionary>, uint32_t, Handle<Object>);
   16843             : 
   16844             : template Handle<UnseededNumberDictionary>
   16845             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
   16846             :     AtPut(Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>);
   16847             : 
   16848             : template Object*
   16849             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
   16850             :     SlowReverseLookup(Object* value);
   16851             : 
   16852             : template Object*
   16853             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
   16854             :     SlowReverseLookup(Object* value);
   16855             : 
   16856             : template Handle<Object>
   16857             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::DeleteProperty(
   16858             :     Handle<NameDictionary>, int);
   16859             : 
   16860             : template Handle<Object>
   16861             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape,
   16862             :            uint32_t>::DeleteProperty(Handle<SeededNumberDictionary>, int);
   16863             : 
   16864             : template Handle<Object>
   16865             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape,
   16866             :            uint32_t>::DeleteProperty(Handle<UnseededNumberDictionary>, int);
   16867             : 
   16868             : template Handle<NameDictionary>
   16869             : HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >::
   16870             :     New(Isolate*, int, MinimumCapacity, PretenureFlag);
   16871             : 
   16872             : template Handle<ObjectHashSet> HashTable<ObjectHashSet, ObjectHashSetShape,
   16873             :                                          Handle<Object>>::New(Isolate*, int n,
   16874             :                                                               MinimumCapacity,
   16875             :                                                               PretenureFlag);
   16876             : 
   16877             : template Handle<NameDictionary>
   16878             : HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >::
   16879             :     Shrink(Handle<NameDictionary>, Handle<Name>);
   16880             : 
   16881             : template Handle<SeededNumberDictionary>
   16882             : HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
   16883             :     Shrink(Handle<SeededNumberDictionary>, uint32_t);
   16884             : 
   16885             : template Handle<UnseededNumberDictionary>
   16886             :     HashTable<UnseededNumberDictionary, UnseededNumberDictionaryShape,
   16887             :               uint32_t>::Shrink(Handle<UnseededNumberDictionary>, uint32_t);
   16888             : 
   16889             : template Handle<NameDictionary>
   16890             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::Add(
   16891             :     Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
   16892             :     int*);
   16893             : 
   16894             : template Handle<GlobalDictionary>
   16895             : Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::Add(
   16896             :     Handle<GlobalDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
   16897             :     int*);
   16898             : 
   16899             : template Handle<SeededNumberDictionary>
   16900             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::Add(
   16901             :     Handle<SeededNumberDictionary>, uint32_t, Handle<Object>, PropertyDetails,
   16902             :     int*);
   16903             : 
   16904             : template Handle<UnseededNumberDictionary>
   16905             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape,
   16906             :            uint32_t>::Add(Handle<UnseededNumberDictionary>, uint32_t,
   16907             :                           Handle<Object>, PropertyDetails, int*);
   16908             : 
   16909             : template Handle<SeededNumberDictionary>
   16910             : Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
   16911             :     EnsureCapacity(Handle<SeededNumberDictionary>, int, uint32_t);
   16912             : 
   16913             : template Handle<UnseededNumberDictionary>
   16914             : Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
   16915             :     EnsureCapacity(Handle<UnseededNumberDictionary>, int, uint32_t);
   16916             : 
   16917             : template void Dictionary<NameDictionary, NameDictionaryShape,
   16918             :                          Handle<Name> >::SetRequiresCopyOnCapacityChange();
   16919             : 
   16920             : template Handle<NameDictionary>
   16921             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
   16922             :     EnsureCapacity(Handle<NameDictionary>, int, Handle<Name>);
   16923             : 
   16924             : template int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape,
   16925             :                        uint32_t>::FindEntry(uint32_t);
   16926             : 
   16927             : template int NameDictionaryBase<NameDictionary, NameDictionaryShape>::FindEntry(
   16928             :     Handle<Name>);
   16929             : 
   16930             : template int Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::
   16931             :     NumberOfElementsFilterAttributes(PropertyFilter filter);
   16932             : 
   16933             : template int Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::
   16934             :     NumberOfElementsFilterAttributes(PropertyFilter filter);
   16935             : 
   16936             : template void
   16937             : Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::
   16938             :     CopyEnumKeysTo(Handle<Dictionary<GlobalDictionary, GlobalDictionaryShape,
   16939             :                                      Handle<Name>>>
   16940             :                        dictionary,
   16941             :                    Handle<FixedArray> storage, KeyCollectionMode mode,
   16942             :                    KeyAccumulator* accumulator);
   16943             : 
   16944             : template void
   16945             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::CopyEnumKeysTo(
   16946             :     Handle<Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>>
   16947             :         dictionary,
   16948             :     Handle<FixedArray> storage, KeyCollectionMode mode,
   16949             :     KeyAccumulator* accumulator);
   16950             : 
   16951             : template Handle<FixedArray>
   16952             : Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::
   16953             :     IterationIndices(
   16954             :         Handle<
   16955             :             Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>>
   16956             :             dictionary);
   16957             : template void
   16958             : Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::
   16959             :     CollectKeysTo(Handle<Dictionary<GlobalDictionary, GlobalDictionaryShape,
   16960             :                                     Handle<Name>>>
   16961             :                       dictionary,
   16962             :                   KeyAccumulator* keys);
   16963             : 
   16964             : template Handle<FixedArray>
   16965             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::IterationIndices(
   16966             :     Handle<Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>>
   16967             :         dictionary);
   16968             : template void
   16969             : Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::CollectKeysTo(
   16970             :     Handle<Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>>
   16971             :         dictionary,
   16972             :     KeyAccumulator* keys);
   16973             : 
   16974         103 : Handle<Object> JSObject::PrepareSlowElementsForSort(
   16975             :     Handle<JSObject> object, uint32_t limit) {
   16976             :   DCHECK(object->HasDictionaryElements());
   16977             :   Isolate* isolate = object->GetIsolate();
   16978             :   // Must stay in dictionary mode, either because of requires_slow_elements,
   16979             :   // or because we are not going to sort (and therefore compact) all of the
   16980             :   // elements.
   16981             :   Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate);
   16982             :   Handle<SeededNumberDictionary> new_dict =
   16983         103 :       SeededNumberDictionary::New(isolate, dict->NumberOfElements());
   16984             : 
   16985             :   uint32_t pos = 0;
   16986             :   uint32_t undefs = 0;
   16987             :   int capacity = dict->Capacity();
   16988             :   Handle<Smi> bailout(Smi::FromInt(-1), isolate);
   16989             :   // Entry to the new dictionary does not cause it to grow, as we have
   16990             :   // allocated one that is large enough for all entries.
   16991             :   DisallowHeapAllocation no_gc;
   16992         429 :   for (int i = 0; i < capacity; i++) {
   16993             :     Object* k = dict->KeyAt(i);
   16994         385 :     if (!dict->IsKey(isolate, k)) continue;
   16995             : 
   16996             :     DCHECK(k->IsNumber());
   16997             :     DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0);
   16998             :     DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0);
   16999             :     DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32);
   17000             : 
   17001             :     HandleScope scope(isolate);
   17002         238 :     Handle<Object> value(dict->ValueAt(i), isolate);
   17003             :     PropertyDetails details = dict->DetailsAt(i);
   17004         432 :     if (details.kind() == kAccessor || details.IsReadOnly()) {
   17005             :       // Bail out and do the sorting of undefineds and array holes in JS.
   17006             :       // Also bail out if the element is not supposed to be moved.
   17007          44 :       return bailout;
   17008             :     }
   17009             : 
   17010         194 :     uint32_t key = NumberToUint32(k);
   17011         194 :     if (key < limit) {
   17012         164 :       if (value->IsUndefined(isolate)) {
   17013          15 :         undefs++;
   17014         149 :       } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
   17015             :         // Adding an entry with the key beyond smi-range requires
   17016             :         // allocation. Bailout.
   17017           0 :         return bailout;
   17018             :       } else {
   17019             :         Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
   17020         149 :             new_dict, pos, value, details, object);
   17021             :         DCHECK(result.is_identical_to(new_dict));
   17022             :         USE(result);
   17023         149 :         pos++;
   17024             :       }
   17025          30 :     } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) {
   17026             :       // Adding an entry with the key beyond smi-range requires
   17027             :       // allocation. Bailout.
   17028          15 :       return bailout;
   17029             :     } else {
   17030             :       Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
   17031          15 :           new_dict, key, value, details, object);
   17032             :       DCHECK(result.is_identical_to(new_dict));
   17033             :       USE(result);
   17034             :     }
   17035             :   }
   17036             : 
   17037             :   uint32_t result = pos;
   17038          44 :   PropertyDetails no_details = PropertyDetails::Empty();
   17039         103 :   while (undefs > 0) {
   17040          15 :     if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
   17041             :       // Adding an entry with the key beyond smi-range requires
   17042             :       // allocation. Bailout.
   17043           0 :       return bailout;
   17044             :     }
   17045             :     HandleScope scope(isolate);
   17046             :     Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
   17047             :         new_dict, pos, isolate->factory()->undefined_value(), no_details,
   17048          15 :         object);
   17049             :     DCHECK(result.is_identical_to(new_dict));
   17050             :     USE(result);
   17051          15 :     pos++;
   17052          15 :     undefs--;
   17053             :   }
   17054             : 
   17055          44 :   object->set_elements(*new_dict);
   17056             : 
   17057             :   AllowHeapAllocation allocate_return_value;
   17058          44 :   return isolate->factory()->NewNumberFromUint(result);
   17059             : }
   17060             : 
   17061             : 
   17062             : // Collects all defined (non-hole) and non-undefined (array) elements at
   17063             : // the start of the elements array.
   17064             : // If the object is in dictionary mode, it is converted to fast elements
   17065             : // mode.
   17066      126632 : Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
   17067             :                                                 uint32_t limit) {
   17068             :   Isolate* isolate = object->GetIsolate();
   17069      253234 :   if (object->HasSloppyArgumentsElements() || !object->map()->is_extensible()) {
   17070         105 :     return handle(Smi::FromInt(-1), isolate);
   17071             :   }
   17072             : 
   17073      126527 :   if (object->HasStringWrapperElements()) {
   17074             :     int len = String::cast(Handle<JSValue>::cast(object)->value())->length();
   17075          15 :     return handle(Smi::FromInt(len), isolate);
   17076             :   }
   17077             : 
   17078      126512 :   if (object->HasDictionaryElements()) {
   17079             :     // Convert to fast elements containing only the existing properties.
   17080             :     // Ordering is irrelevant, since we are going to sort anyway.
   17081             :     Handle<SeededNumberDictionary> dict(object->element_dictionary());
   17082         342 :     if (object->IsJSArray() || dict->requires_slow_elements() ||
   17083          60 :         dict->max_number_key() >= limit) {
   17084         103 :       return JSObject::PrepareSlowElementsForSort(object, limit);
   17085             :     }
   17086             :     // Convert to fast elements.
   17087             : 
   17088             :     Handle<Map> new_map =
   17089          60 :         JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS);
   17090             : 
   17091             :     PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ?
   17092          60 :         NOT_TENURED: TENURED;
   17093             :     Handle<FixedArray> fast_elements =
   17094          60 :         isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure);
   17095          60 :     dict->CopyValuesTo(*fast_elements);
   17096             :     JSObject::ValidateElements(object);
   17097             : 
   17098          60 :     JSObject::SetMapAndElements(object, new_map, fast_elements);
   17099      126349 :   } else if (object->HasFixedTypedArrayElements()) {
   17100             :     // Typed arrays cannot have holes or undefined elements.
   17101             :     return handle(Smi::FromInt(
   17102         141 :         FixedArrayBase::cast(object->elements())->length()), isolate);
   17103      126208 :   } else if (!object->HasFastDoubleElements()) {
   17104      126151 :     EnsureWritableFastElements(object);
   17105             :   }
   17106             :   DCHECK(object->HasFastSmiOrObjectElements() ||
   17107             :          object->HasFastDoubleElements());
   17108             : 
   17109             :   // Collect holes at the end, undefined before that and the rest at the
   17110             :   // start, and return the number of non-hole, non-undefined values.
   17111             : 
   17112             :   Handle<FixedArrayBase> elements_base(object->elements());
   17113      126268 :   uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
   17114      126268 :   if (limit > elements_length) {
   17115             :     limit = elements_length;
   17116             :   }
   17117      126268 :   if (limit == 0) {
   17118          15 :     return handle(Smi::kZero, isolate);
   17119             :   }
   17120             : 
   17121             :   uint32_t result = 0;
   17122      126253 :   if (elements_base->map() == isolate->heap()->fixed_double_array_map()) {
   17123             :     FixedDoubleArray* elements = FixedDoubleArray::cast(*elements_base);
   17124             :     // Split elements into defined and the_hole, in that order.
   17125             :     unsigned int holes = limit;
   17126             :     // Assume most arrays contain no holes and undefined values, so minimize the
   17127             :     // number of stores of non-undefined, non-the-hole values.
   17128        5915 :     for (unsigned int i = 0; i < holes; i++) {
   17129       11716 :       if (elements->is_the_hole(i)) {
   17130           0 :         holes--;
   17131             :       } else {
   17132             :         continue;
   17133             :       }
   17134             :       // Position i needs to be filled.
   17135           0 :       while (holes > i) {
   17136           0 :         if (elements->is_the_hole(holes)) {
   17137           0 :           holes--;
   17138             :         } else {
   17139             :           elements->set(i, elements->get_scalar(holes));
   17140             :           break;
   17141             :         }
   17142             :       }
   17143             :     }
   17144             :     result = holes;
   17145          57 :     while (holes < limit) {
   17146           0 :       elements->set_the_hole(holes);
   17147           0 :       holes++;
   17148             :     }
   17149             :   } else {
   17150             :     FixedArray* elements = FixedArray::cast(*elements_base);
   17151             :     DisallowHeapAllocation no_gc;
   17152             : 
   17153             :     // Split elements into defined, undefined and the_hole, in that order.  Only
   17154             :     // count locations for undefined and the hole, and fill them afterwards.
   17155      126196 :     WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_gc);
   17156             :     unsigned int undefs = limit;
   17157             :     unsigned int holes = limit;
   17158             :     // Assume most arrays contain no holes and undefined values, so minimize the
   17159             :     // number of stores of non-undefined, non-the-hole values.
   17160     5889831 :     for (unsigned int i = 0; i < undefs; i++) {
   17161     5763635 :       Object* current = elements->get(i);
   17162     5763635 :       if (current->IsTheHole(isolate)) {
   17163       31206 :         holes--;
   17164       31206 :         undefs--;
   17165     5732429 :       } else if (current->IsUndefined(isolate)) {
   17166        1136 :         undefs--;
   17167             :       } else {
   17168             :         continue;
   17169             :       }
   17170             :       // Position i needs to be filled.
   17171     7706829 :       while (undefs > i) {
   17172     7706137 :         current = elements->get(undefs);
   17173     7706137 :         if (current->IsTheHole(isolate)) {
   17174     7673296 :           holes--;
   17175     7673296 :           undefs--;
   17176       32841 :         } else if (current->IsUndefined(isolate)) {
   17177        1191 :           undefs--;
   17178             :         } else {
   17179       31650 :           elements->set(i, current, write_barrier);
   17180       31650 :           break;
   17181             :         }
   17182             :       }
   17183             :     }
   17184             :     result = undefs;
   17185      128523 :     while (undefs < holes) {
   17186        2327 :       elements->set_undefined(isolate, undefs);
   17187        2327 :       undefs++;
   17188             :     }
   17189     7830698 :     while (holes < limit) {
   17190     7704502 :       elements->set_the_hole(isolate, holes);
   17191     7704502 :       holes++;
   17192             :     }
   17193             :   }
   17194             : 
   17195      126253 :   return isolate->factory()->NewNumberFromUint(result);
   17196             : }
   17197             : 
   17198             : namespace {
   17199             : 
   17200        4492 : bool CanonicalNumericIndexString(Isolate* isolate, Handle<Object> s,
   17201             :                                  Handle<Object>* index) {
   17202             :   DCHECK(s->IsString() || s->IsSmi());
   17203             : 
   17204             :   Handle<Object> result;
   17205        4492 :   if (s->IsSmi()) {
   17206             :     result = s;
   17207             :   } else {
   17208        4464 :     result = String::ToNumber(Handle<String>::cast(s));
   17209        4464 :     if (!result->IsMinusZero()) {
   17210        8900 :       Handle<String> str = Object::ToString(isolate, result).ToHandleChecked();
   17211             :       // Avoid treating strings like "2E1" and "20" as the same key.
   17212        4450 :       if (!str->SameValue(*s)) return false;
   17213             :     }
   17214             :   }
   17215         275 :   *index = result;
   17216         275 :   return true;
   17217             : }
   17218             : 
   17219             : }  // anonymous namespace
   17220             : 
   17221             : // ES#sec-integer-indexed-exotic-objects-defineownproperty-p-desc
   17222             : // static
   17223        4786 : Maybe<bool> JSTypedArray::DefineOwnProperty(Isolate* isolate,
   17224             :                                             Handle<JSTypedArray> o,
   17225             :                                             Handle<Object> key,
   17226             :                                             PropertyDescriptor* desc,
   17227             :                                             ShouldThrow should_throw) {
   17228             :   // 1. Assert: IsPropertyKey(P) is true.
   17229             :   DCHECK(key->IsName() || key->IsNumber());
   17230             :   // 2. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot.
   17231             :   // 3. If Type(P) is String, then
   17232        5108 :   if (key->IsString() || key->IsSmi()) {
   17233             :     // 3a. Let numericIndex be ! CanonicalNumericIndexString(P)
   17234             :     // 3b. If numericIndex is not undefined, then
   17235             :     Handle<Object> numeric_index;
   17236        4492 :     if (CanonicalNumericIndexString(isolate, key, &numeric_index)) {
   17237             :       // 3b i. If IsInteger(numericIndex) is false, return false.
   17238             :       // 3b ii. If numericIndex = -0, return false.
   17239             :       // 3b iii. If numericIndex < 0, return false.
   17240             :       // FIXME: the standard allows up to 2^53 elements.
   17241             :       uint32_t index;
   17242         536 :       if (numeric_index->IsMinusZero() || !numeric_index->ToUint32(&index)) {
   17243         126 :         RETURN_FAILURE(isolate, should_throw,
   17244             :                        NewTypeError(MessageTemplate::kInvalidTypedArrayIndex));
   17245             :       }
   17246             :       // 3b iv. Let length be O.[[ArrayLength]].
   17247         233 :       uint32_t length = o->length()->Number();
   17248             :       // 3b v. If numericIndex ≥ length, return false.
   17249         233 :       if (index >= length) {
   17250          42 :         RETURN_FAILURE(isolate, should_throw,
   17251             :                        NewTypeError(MessageTemplate::kInvalidTypedArrayIndex));
   17252             :       }
   17253             :       // 3b vi. If IsAccessorDescriptor(Desc) is true, return false.
   17254         219 :       if (PropertyDescriptor::IsAccessorDescriptor(desc)) {
   17255         234 :         RETURN_FAILURE(isolate, should_throw,
   17256             :                        NewTypeError(MessageTemplate::kRedefineDisallowed, key));
   17257             :       }
   17258             :       // 3b vii. If Desc has a [[Configurable]] field and if
   17259             :       //         Desc.[[Configurable]] is true, return false.
   17260             :       // 3b viii. If Desc has an [[Enumerable]] field and if Desc.[[Enumerable]]
   17261             :       //          is false, return false.
   17262             :       // 3b ix. If Desc has a [[Writable]] field and if Desc.[[Writable]] is
   17263             :       //        false, return false.
   17264          30 :       if ((desc->has_configurable() && desc->configurable()) ||
   17265          30 :           (desc->has_enumerable() && !desc->enumerable()) ||
   17266          15 :           (desc->has_writable() && !desc->writable())) {
   17267          45 :         RETURN_FAILURE(isolate, should_throw,
   17268             :                        NewTypeError(MessageTemplate::kRedefineDisallowed, key));
   17269             :       }
   17270             :       // 3b x. If Desc has a [[Value]] field, then
   17271             :       //   3b x 1. Let value be Desc.[[Value]].
   17272             :       //   3b x 2. Return ? IntegerIndexedElementSet(O, numericIndex, value).
   17273           0 :       if (desc->has_value()) {
   17274           0 :         if (!desc->has_configurable()) desc->set_configurable(false);
   17275           0 :         if (!desc->has_enumerable()) desc->set_enumerable(true);
   17276           0 :         if (!desc->has_writable()) desc->set_writable(true);
   17277           0 :         Handle<Object> value = desc->value();
   17278           0 :         RETURN_ON_EXCEPTION_VALUE(isolate,
   17279             :                                   SetOwnElementIgnoreAttributes(
   17280             :                                       o, index, value, desc->ToAttributes()),
   17281             :                                   Nothing<bool>());
   17282             :       }
   17283             :       // 3b xi. Return true.
   17284             :       return Just(true);
   17285             :     }
   17286             :   }
   17287             :   // 4. Return ! OrdinaryDefineOwnProperty(O, P, Desc).
   17288        4511 :   return OrdinaryDefineOwnProperty(isolate, o, key, desc, should_throw);
   17289             : }
   17290             : 
   17291    18988096 : ExternalArrayType JSTypedArray::type() {
   17292    18988096 :   switch (elements()->map()->instance_type()) {
   17293             : #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size)            \
   17294             :     case FIXED_##TYPE##_ARRAY_TYPE:                                           \
   17295             :       return kExternal##Type##Array;
   17296             : 
   17297        5939 :     TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE)
   17298             : #undef INSTANCE_TYPE_TO_ARRAY_TYPE
   17299             : 
   17300             :     default:
   17301           0 :       UNREACHABLE();
   17302             :       return static_cast<ExternalArrayType>(-1);
   17303             :   }
   17304             : }
   17305             : 
   17306             : 
   17307       15924 : size_t JSTypedArray::element_size() {
   17308       15924 :   switch (elements()->map()->instance_type()) {
   17309             : #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \
   17310             :   case FIXED_##TYPE##_ARRAY_TYPE:                                    \
   17311             :     return size;
   17312             : 
   17313        1013 :     TYPED_ARRAYS(INSTANCE_TYPE_TO_ELEMENT_SIZE)
   17314             : #undef INSTANCE_TYPE_TO_ELEMENT_SIZE
   17315             : 
   17316             :     default:
   17317           0 :       UNREACHABLE();
   17318             :       return 0;
   17319             :   }
   17320             : }
   17321             : 
   17322             : 
   17323      326473 : void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
   17324             :                                             Handle<Name> name) {
   17325             :   DCHECK(!global->HasFastProperties());
   17326             :   auto dictionary = handle(global->global_dictionary());
   17327      326473 :   int entry = dictionary->FindEntry(name);
   17328      652946 :   if (entry == GlobalDictionary::kNotFound) return;
   17329          90 :   PropertyCell::InvalidateEntry(dictionary, entry);
   17330             : }
   17331             : 
   17332     8831220 : Handle<PropertyCell> JSGlobalObject::EnsureEmptyPropertyCell(
   17333             :     Handle<JSGlobalObject> global, Handle<Name> name,
   17334             :     PropertyCellType cell_type, int* entry_out) {
   17335             :   Isolate* isolate = global->GetIsolate();
   17336             :   DCHECK(!global->HasFastProperties());
   17337             :   Handle<GlobalDictionary> dictionary(global->global_dictionary(), isolate);
   17338     8831220 :   int entry = dictionary->FindEntry(name);
   17339             :   Handle<PropertyCell> cell;
   17340     8831222 :   if (entry != GlobalDictionary::kNotFound) {
   17341        6491 :     if (entry_out) *entry_out = entry;
   17342             :     // This call should be idempotent.
   17343             :     DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
   17344        6491 :     cell = handle(PropertyCell::cast(dictionary->ValueAt(entry)));
   17345             :     PropertyCellType original_cell_type = cell->property_details().cell_type();
   17346             :     DCHECK(original_cell_type == PropertyCellType::kInvalidated ||
   17347             :            original_cell_type == PropertyCellType::kUninitialized);
   17348             :     DCHECK(cell->value()->IsTheHole(isolate));
   17349        6491 :     if (original_cell_type == PropertyCellType::kInvalidated) {
   17350        2427 :       cell = PropertyCell::InvalidateEntry(dictionary, entry);
   17351             :     }
   17352             :     PropertyDetails details(kData, NONE, 0, cell_type);
   17353             :     cell->set_property_details(details);
   17354        6491 :     return cell;
   17355             :   }
   17356     8824731 :   cell = isolate->factory()->NewPropertyCell();
   17357             :   PropertyDetails details(kData, NONE, 0, cell_type);
   17358             :   dictionary =
   17359     8824730 :       GlobalDictionary::Add(dictionary, name, cell, details, entry_out);
   17360             :   // {*entry_out} is initialized inside GlobalDictionary::Add().
   17361     8824729 :   global->set_properties(*dictionary);
   17362     8824731 :   return cell;
   17363             : }
   17364             : 
   17365             : 
   17366             : // This class is used for looking up two character strings in the string table.
   17367             : // If we don't have a hit we don't want to waste much time so we unroll the
   17368             : // string hash calculation loop here for speed.  Doesn't work if the two
   17369             : // characters form a decimal integer, since such strings have a different hash
   17370             : // algorithm.
   17371           0 : class TwoCharHashTableKey : public HashTableKey {
   17372             :  public:
   17373     7323327 :   TwoCharHashTableKey(uint16_t c1, uint16_t c2, uint32_t seed)
   17374     7323327 :     : c1_(c1), c2_(c2) {
   17375             :     // Char 1.
   17376             :     uint32_t hash = seed;
   17377     7323327 :     hash += c1;
   17378     7323327 :     hash += hash << 10;
   17379     7323327 :     hash ^= hash >> 6;
   17380             :     // Char 2.
   17381     7323327 :     hash += c2;
   17382     7323327 :     hash += hash << 10;
   17383     7323327 :     hash ^= hash >> 6;
   17384             :     // GetHash.
   17385     7323327 :     hash += hash << 3;
   17386     7323327 :     hash ^= hash >> 11;
   17387     7323327 :     hash += hash << 15;
   17388     7323327 :     if ((hash & String::kHashBitMask) == 0) hash = StringHasher::kZeroHash;
   17389     7323327 :     hash_ = hash;
   17390             : #ifdef DEBUG
   17391             :     // If this assert fails then we failed to reproduce the two-character
   17392             :     // version of the string hashing algorithm above.  One reason could be
   17393             :     // that we were passed two digits as characters, since the hash
   17394             :     // algorithm is different in that case.
   17395             :     uint16_t chars[2] = {c1, c2};
   17396             :     uint32_t check_hash = StringHasher::HashSequentialString(chars, 2, seed);
   17397             :     hash = (hash << String::kHashShift) | String::kIsNotArrayIndexMask;
   17398             :     DCHECK_EQ(static_cast<int32_t>(hash), static_cast<int32_t>(check_hash));
   17399             : #endif
   17400     7323327 :   }
   17401             : 
   17402     2099647 :   bool IsMatch(Object* o) override {
   17403     2099647 :     if (!o->IsString()) return false;
   17404             :     String* other = String::cast(o);
   17405     2099647 :     if (other->length() != 2) return false;
   17406      472959 :     if (other->Get(0) != c1_) return false;
   17407       22121 :     return other->Get(1) == c2_;
   17408             :   }
   17409             : 
   17410     7323327 :   uint32_t Hash() override { return hash_; }
   17411           0 :   uint32_t HashForObject(Object* key) override {
   17412           0 :     if (!key->IsString()) return 0;
   17413           0 :     return String::cast(key)->Hash();
   17414             :   }
   17415             : 
   17416           0 :   Handle<Object> AsHandle(Isolate* isolate) override {
   17417             :     // The TwoCharHashTableKey is only used for looking in the string
   17418             :     // table, not for adding to it.
   17419           0 :     UNREACHABLE();
   17420             :     return MaybeHandle<Object>().ToHandleChecked();
   17421             :   }
   17422             : 
   17423             :  private:
   17424             :   uint16_t c1_;
   17425             :   uint16_t c2_;
   17426             :   uint32_t hash_;
   17427             : };
   17428             : 
   17429             : 
   17430     4258708 : MaybeHandle<String> StringTable::InternalizeStringIfExists(
   17431             :     Isolate* isolate,
   17432             :     Handle<String> string) {
   17433     4258709 :   if (string->IsInternalizedString()) {
   17434             :     return string;
   17435             :   }
   17436           0 :   if (string->IsThinString()) {
   17437             :     return handle(Handle<ThinString>::cast(string)->actual(), isolate);
   17438             :   }
   17439           0 :   return LookupStringIfExists(isolate, string);
   17440             : }
   17441             : 
   17442             : 
   17443           0 : MaybeHandle<String> StringTable::LookupStringIfExists(
   17444             :     Isolate* isolate,
   17445             :     Handle<String> string) {
   17446             :   Handle<StringTable> string_table = isolate->factory()->string_table();
   17447             :   InternalizedStringKey key(string);
   17448             :   int entry = string_table->FindEntry(&key);
   17449           0 :   if (entry == kNotFound) {
   17450             :     return MaybeHandle<String>();
   17451             :   } else {
   17452             :     Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
   17453             :     DCHECK(StringShape(*result).IsInternalized());
   17454             :     return result;
   17455             :   }
   17456             : }
   17457             : 
   17458             : 
   17459     7323327 : MaybeHandle<String> StringTable::LookupTwoCharsStringIfExists(
   17460             :     Isolate* isolate,
   17461             :     uint16_t c1,
   17462             :     uint16_t c2) {
   17463             :   Handle<StringTable> string_table = isolate->factory()->string_table();
   17464     7323327 :   TwoCharHashTableKey key(c1, c2, isolate->heap()->HashSeed());
   17465             :   int entry = string_table->FindEntry(&key);
   17466     7323327 :   if (entry == kNotFound) {
   17467             :     return MaybeHandle<String>();
   17468             :   } else {
   17469             :     Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
   17470             :     DCHECK(StringShape(*result).IsInternalized());
   17471             :     return result;
   17472             :   }
   17473             : }
   17474             : 
   17475             : 
   17476         385 : void StringTable::EnsureCapacityForDeserialization(Isolate* isolate,
   17477             :                                                    int expected) {
   17478             :   Handle<StringTable> table = isolate->factory()->string_table();
   17479             :   // We need a key instance for the virtual hash function.
   17480             :   InternalizedStringKey dummy_key(isolate->factory()->empty_string());
   17481         385 :   table = StringTable::EnsureCapacity(table, expected, &dummy_key);
   17482             :   isolate->heap()->SetRootStringTable(*table);
   17483         385 : }
   17484             : 
   17485             : namespace {
   17486             : 
   17487             : template <class StringClass>
   17488          20 : void MigrateExternalStringResource(Isolate* isolate, String* from, String* to) {
   17489             :   StringClass* cast_from = StringClass::cast(from);
   17490             :   StringClass* cast_to = StringClass::cast(to);
   17491             :   const typename StringClass::Resource* to_resource = cast_to->resource();
   17492          20 :   if (to_resource == nullptr) {
   17493             :     // |to| is a just-created internalized copy of |from|. Migrate the resource.
   17494             :     cast_to->set_resource(cast_from->resource());
   17495             :     // Zap |from|'s resource pointer to reflect the fact that |from| has
   17496             :     // relinquished ownership of its resource.
   17497             :     cast_from->set_resource(nullptr);
   17498          14 :   } else if (to_resource != cast_from->resource()) {
   17499             :     // |to| already existed and has its own resource. Finalize |from|.
   17500             :     isolate->heap()->FinalizeExternalString(from);
   17501             :   }
   17502          20 : }
   17503             : 
   17504     9701951 : void MakeStringThin(String* string, String* internalized, Isolate* isolate) {
   17505     9701951 :   if (string->IsExternalString()) {
   17506          20 :     if (internalized->IsExternalOneByteString()) {
   17507             :       MigrateExternalStringResource<ExternalOneByteString>(isolate, string,
   17508          11 :                                                            internalized);
   17509           9 :     } else if (internalized->IsExternalTwoByteString()) {
   17510             :       MigrateExternalStringResource<ExternalTwoByteString>(isolate, string,
   17511           9 :                                                            internalized);
   17512             :     } else {
   17513             :       // If the external string is duped into an existing non-external
   17514             :       // internalized string, free its resource (it's about to be rewritten
   17515             :       // into a ThinString below).
   17516             :       isolate->heap()->FinalizeExternalString(string);
   17517             :     }
   17518             :   }
   17519             : 
   17520     9701951 :   if (!string->IsInternalizedString()) {
   17521             :     DisallowHeapAllocation no_gc;
   17522             :     bool one_byte = internalized->IsOneByteRepresentation();
   17523             :     Handle<Map> map = one_byte ? isolate->factory()->thin_one_byte_string_map()
   17524     9694333 :                                : isolate->factory()->thin_string_map();
   17525     9694333 :     int old_size = string->Size();
   17526             :     DCHECK(old_size >= ThinString::kSize);
   17527     9694333 :     string->synchronized_set_map(*map);
   17528             :     ThinString* thin = ThinString::cast(string);
   17529     9694333 :     thin->set_actual(internalized);
   17530     9694333 :     Address thin_end = thin->address() + ThinString::kSize;
   17531     9694333 :     int size_delta = old_size - ThinString::kSize;
   17532     9694333 :     if (size_delta != 0) {
   17533     2394967 :       Heap* heap = isolate->heap();
   17534     2394967 :       heap->CreateFillerObjectAt(thin_end, size_delta, ClearRecordedSlots::kNo);
   17535     2394967 :       heap->AdjustLiveBytes(thin, -size_delta);
   17536             :     }
   17537             :   }
   17538     9701951 : }
   17539             : 
   17540             : }  // namespace
   17541             : 
   17542    23395027 : Handle<String> StringTable::LookupString(Isolate* isolate,
   17543             :                                          Handle<String> string) {
   17544    23395028 :   if (string->IsThinString()) {
   17545             :     DCHECK(Handle<ThinString>::cast(string)->actual()->IsInternalizedString());
   17546             :     return handle(Handle<ThinString>::cast(string)->actual(), isolate);
   17547             :   }
   17548    23339000 :   if (string->IsConsString() && string->IsFlat()) {
   17549             :     string = handle(Handle<ConsString>::cast(string)->first(), isolate);
   17550       24882 :     if (string->IsInternalizedString()) return string;
   17551             :   }
   17552             : 
   17553             :   InternalizedStringKey key(string);
   17554    22837392 :   Handle<String> result = LookupKey(isolate, &key);
   17555             : 
   17556    22837394 :   if (FLAG_thin_strings) {
   17557     9676445 :     MakeStringThin(*string, *result, isolate);
   17558             :   } else {  // !FLAG_thin_strings
   17559    13160949 :     if (string->IsConsString()) {
   17560             :       Handle<ConsString> cons = Handle<ConsString>::cast(string);
   17561      193003 :       cons->set_first(*result);
   17562      386006 :       cons->set_second(isolate->heap()->empty_string());
   17563    12967946 :     } else if (string->IsSlicedString()) {
   17564             :       STATIC_ASSERT(ConsString::kSize == SlicedString::kSize);
   17565             :       DisallowHeapAllocation no_gc;
   17566             :       bool one_byte = result->IsOneByteRepresentation();
   17567             :       Handle<Map> map = one_byte
   17568             :                             ? isolate->factory()->cons_one_byte_string_map()
   17569       24790 :                             : isolate->factory()->cons_string_map();
   17570       24790 :       string->set_map(*map);
   17571             :       Handle<ConsString> cons = Handle<ConsString>::cast(string);
   17572       24790 :       cons->set_first(*result);
   17573       49580 :       cons->set_second(isolate->heap()->empty_string());
   17574             :     }
   17575             :   }
   17576    22837394 :   return result;
   17577             : }
   17578             : 
   17579             : 
   17580    89018469 : Handle<String> StringTable::LookupKey(Isolate* isolate, HashTableKey* key) {
   17581             :   Handle<StringTable> table = isolate->factory()->string_table();
   17582             :   int entry = table->FindEntry(key);
   17583             : 
   17584             :   // String already in table.
   17585    89018534 :   if (entry != kNotFound) {
   17586             :     return handle(String::cast(table->KeyAt(entry)), isolate);
   17587             :   }
   17588             : 
   17589             :   // Adding new string. Grow table if needed.
   17590    13100099 :   table = StringTable::EnsureCapacity(table, 1, key);
   17591             : 
   17592             :   // Create string object.
   17593    13100099 :   Handle<Object> string = key->AsHandle(isolate);
   17594             :   // There must be no attempts to internalize strings that could throw
   17595             :   // InvalidStringLength error.
   17596    13100095 :   CHECK(!string.is_null());
   17597             : 
   17598             :   // Add the new string and return it along with the string table.
   17599    26200192 :   entry = table->FindInsertionEntry(key->Hash());
   17600    13100096 :   table->set(EntryToIndex(entry), *string);
   17601    13100097 :   table->ElementAdded();
   17602             : 
   17603             :   isolate->heap()->SetRootStringTable(*table);
   17604             :   return Handle<String>::cast(string);
   17605             : }
   17606             : 
   17607             : namespace {
   17608             : 
   17609             : class StringTableNoAllocateKey : public HashTableKey {
   17610             :  public:
   17611       25653 :   StringTableNoAllocateKey(String* string, uint32_t seed)
   17612       51306 :       : string_(string), length_(string->length()) {
   17613             :     StringShape shape(string);
   17614       25653 :     one_byte_ = shape.HasOnlyOneByteChars();
   17615             :     DCHECK(!shape.IsInternalized());
   17616             :     DCHECK(!shape.IsThin());
   17617       25653 :     if (shape.IsCons() && length_ <= String::kMaxHashCalcLength) {
   17618           0 :       special_flattening_ = true;
   17619             :       uint32_t hash_field = 0;
   17620           0 :       if (one_byte_) {
   17621           0 :         one_byte_content_ = new uint8_t[length_];
   17622           0 :         String::WriteToFlat(string, one_byte_content_, 0, length_);
   17623             :         hash_field = StringHasher::HashSequentialString(one_byte_content_,
   17624           0 :                                                         length_, seed);
   17625             :       } else {
   17626           0 :         two_byte_content_ = new uint16_t[length_];
   17627           0 :         String::WriteToFlat(string, two_byte_content_, 0, length_);
   17628             :         hash_field = StringHasher::HashSequentialString(two_byte_content_,
   17629           0 :                                                         length_, seed);
   17630             :       }
   17631             :       string->set_hash_field(hash_field);
   17632             :     } else {
   17633       25653 :       special_flattening_ = false;
   17634       25653 :       one_byte_content_ = nullptr;
   17635             :     }
   17636       25653 :     hash_ = string->Hash();
   17637       25653 :   }
   17638             : 
   17639       25653 :   ~StringTableNoAllocateKey() {
   17640       25653 :     if (one_byte_) {
   17641       23349 :       delete[] one_byte_content_;
   17642             :     } else {
   17643        2304 :       delete[] two_byte_content_;
   17644             :     }
   17645       25653 :   }
   17646             : 
   17647       45282 :   bool IsMatch(Object* otherstring) override {
   17648             :     String* other = String::cast(otherstring);
   17649             :     DCHECK(other->IsInternalizedString());
   17650             :     DCHECK(other->IsFlat());
   17651       90564 :     if (hash_ != other->Hash()) return false;
   17652       25542 :     int len = length_;
   17653       25542 :     if (len != other->length()) return false;
   17654             : 
   17655       25542 :     if (!special_flattening_) {
   17656       51084 :       if (string_->Get(0) != other->Get(0)) return false;
   17657       25542 :       if (string_->IsFlat()) {
   17658       25542 :         StringShape shape1(string_);
   17659             :         StringShape shape2(other);
   17660       48780 :         if (shape1.encoding_tag() == kOneByteStringTag &&
   17661             :             shape2.encoding_tag() == kOneByteStringTag) {
   17662       23238 :           String::FlatContent flat1 = string_->GetFlatContent();
   17663       23238 :           String::FlatContent flat2 = other->GetFlatContent();
   17664       23238 :           return CompareRawStringContents(flat1.ToOneByteVector().start(),
   17665       23238 :                                           flat2.ToOneByteVector().start(), len);
   17666             :         }
   17667        4608 :         if (shape1.encoding_tag() == kTwoByteStringTag &&
   17668             :             shape2.encoding_tag() == kTwoByteStringTag) {
   17669        2304 :           String::FlatContent flat1 = string_->GetFlatContent();
   17670        2304 :           String::FlatContent flat2 = other->GetFlatContent();
   17671        2304 :           return CompareRawStringContents(flat1.ToUC16Vector().start(),
   17672        2304 :                                           flat2.ToUC16Vector().start(), len);
   17673             :         }
   17674             :       }
   17675             :       StringComparator comparator;
   17676           0 :       return comparator.Equals(string_, other);
   17677             :     }
   17678             : 
   17679           0 :     String::FlatContent flat_content = other->GetFlatContent();
   17680           0 :     if (one_byte_) {
   17681           0 :       if (flat_content.IsOneByte()) {
   17682             :         return CompareRawStringContents(
   17683           0 :             one_byte_content_, flat_content.ToOneByteVector().start(), len);
   17684             :       } else {
   17685             :         DCHECK(flat_content.IsTwoByte());
   17686           0 :         for (int i = 0; i < len; i++) {
   17687           0 :           if (flat_content.Get(i) != one_byte_content_[i]) return false;
   17688             :         }
   17689             :         return true;
   17690             :       }
   17691             :     } else {
   17692           0 :       if (flat_content.IsTwoByte()) {
   17693             :         return CompareRawStringContents(
   17694           0 :             two_byte_content_, flat_content.ToUC16Vector().start(), len);
   17695             :       } else {
   17696             :         DCHECK(flat_content.IsOneByte());
   17697           0 :         for (int i = 0; i < len; i++) {
   17698           0 :           if (flat_content.Get(i) != two_byte_content_[i]) return false;
   17699             :         }
   17700             :         return true;
   17701             :       }
   17702             :     }
   17703             :   }
   17704             : 
   17705       25653 :   uint32_t Hash() override { return hash_; }
   17706             : 
   17707           0 :   uint32_t HashForObject(Object* key) override {
   17708           0 :     return String::cast(key)->Hash();
   17709             :   }
   17710             : 
   17711           0 :   MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) override {
   17712           0 :     UNREACHABLE();
   17713             :     return Handle<String>();
   17714             :   }
   17715             : 
   17716             :  private:
   17717             :   String* string_;
   17718             :   int length_;
   17719             :   bool one_byte_;
   17720             :   bool special_flattening_;
   17721             :   uint32_t hash_ = 0;
   17722             :   union {
   17723             :     uint8_t* one_byte_content_;
   17724             :     uint16_t* two_byte_content_;
   17725             :   };
   17726             : };
   17727             : 
   17728             : }  // namespace
   17729             : 
   17730             : // static
   17731       25653 : Object* StringTable::LookupStringIfExists_NoAllocate(String* string) {
   17732             :   DisallowHeapAllocation no_gc;
   17733       25653 :   Heap* heap = string->GetHeap();
   17734             :   Isolate* isolate = heap->isolate();
   17735             :   StringTable* table = heap->string_table();
   17736             : 
   17737       25653 :   StringTableNoAllocateKey key(string, heap->HashSeed());
   17738             : 
   17739             :   // String could be an array index.
   17740             :   DCHECK(string->HasHashCode());
   17741             :   uint32_t hash = string->hash_field();
   17742             : 
   17743             :   // Valid array indices are >= 0, so they cannot be mixed up with any of
   17744             :   // the result sentinels, which are negative.
   17745             :   STATIC_ASSERT(
   17746             :       !String::ArrayIndexValueBits::is_valid(ResultSentinel::kUnsupported));
   17747             :   STATIC_ASSERT(
   17748             :       !String::ArrayIndexValueBits::is_valid(ResultSentinel::kNotFound));
   17749             : 
   17750       25653 :   if ((hash & Name::kContainsCachedArrayIndexMask) == 0) {
   17751           0 :     return Smi::FromInt(String::ArrayIndexValueBits::decode(hash));
   17752             :   }
   17753       25653 :   if ((hash & Name::kIsNotArrayIndexMask) == 0) {
   17754             :     // It is an indexed, but it's not cached.
   17755             :     return Smi::FromInt(ResultSentinel::kUnsupported);
   17756             :   }
   17757             : 
   17758       25653 :   int entry = table->FindEntry(isolate, &key, key.Hash());
   17759       25653 :   if (entry != kNotFound) {
   17760             :     String* internalized = String::cast(table->KeyAt(entry));
   17761       25542 :     if (FLAG_thin_strings) {
   17762       25506 :       MakeStringThin(string, internalized, isolate);
   17763             :     }
   17764       25542 :     return internalized;
   17765             :   }
   17766             :   // A string that's not an array index, and not in the string table,
   17767             :   // cannot have been used as a property name before.
   17768       25653 :   return Smi::FromInt(ResultSentinel::kNotFound);
   17769             : }
   17770             : 
   17771        7460 : String* StringTable::LookupKeyIfExists(Isolate* isolate, HashTableKey* key) {
   17772             :   Handle<StringTable> table = isolate->factory()->string_table();
   17773        7460 :   int entry = table->FindEntry(isolate, key);
   17774       10216 :   if (entry != kNotFound) return String::cast(table->KeyAt(entry));
   17775             :   return NULL;
   17776             : }
   17777             : 
   17778      195518 : Handle<StringSet> StringSet::New(Isolate* isolate) {
   17779      195518 :   return HashTable::New(isolate, 0);
   17780             : }
   17781             : 
   17782     2616926 : Handle<StringSet> StringSet::Add(Handle<StringSet> stringset,
   17783             :                                  Handle<String> name) {
   17784     2616926 :   if (!stringset->Has(name)) {
   17785      172174 :     stringset = EnsureCapacity(stringset, 1, *name);
   17786             :     uint32_t hash = StringSetShape::Hash(*name);
   17787      172174 :     int entry = stringset->FindInsertionEntry(hash);
   17788      172174 :     stringset->set(EntryToIndex(entry), *name);
   17789      172174 :     stringset->ElementAdded();
   17790             :   }
   17791     2616926 :   return stringset;
   17792             : }
   17793             : 
   17794     2636824 : bool StringSet::Has(Handle<String> name) {
   17795     2636824 :   return FindEntry(*name) != kNotFound;
   17796             : }
   17797             : 
   17798    16025435 : Handle<ObjectHashSet> ObjectHashSet::Add(Handle<ObjectHashSet> set,
   17799             :                                          Handle<Object> key) {
   17800             :   Isolate* isolate = set->GetIsolate();
   17801    16025435 :   int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
   17802             : 
   17803    16025435 :   if (!set->Has(isolate, key, hash)) {
   17804    16023124 :     set = EnsureCapacity(set, 1, key);
   17805    32046248 :     int entry = set->FindInsertionEntry(hash);
   17806    16023124 :     set->set(EntryToIndex(entry), *key);
   17807    16023124 :     set->ElementAdded();
   17808             :   }
   17809    16025435 :   return set;
   17810             : }
   17811             : 
   17812           0 : Handle<Object> CompilationCacheTable::Lookup(Handle<String> src,
   17813             :                                              Handle<Context> context,
   17814             :                                              LanguageMode language_mode) {
   17815             :   Isolate* isolate = GetIsolate();
   17816             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   17817             :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17818             :   int entry = FindEntry(&key);
   17819           0 :   if (entry == kNotFound) return isolate->factory()->undefined_value();
   17820             :   int index = EntryToIndex(entry);
   17821           0 :   if (!get(index)->IsFixedArray()) return isolate->factory()->undefined_value();
   17822           0 :   return Handle<Object>(get(index + 1), isolate);
   17823             : }
   17824             : 
   17825             : namespace {
   17826             : 
   17827             : const int kLiteralEntryLength = 2;
   17828             : const int kLiteralInitialLength = 2;
   17829             : const int kLiteralContextOffset = 0;
   17830             : const int kLiteralLiteralsOffset = 1;
   17831             : 
   17832     5184432 : int SearchLiteralsMapEntry(CompilationCacheTable* cache, int cache_entry,
   17833             :                            Context* native_context) {
   17834             :   DisallowHeapAllocation no_gc;
   17835             :   DCHECK(native_context->IsNativeContext());
   17836             :   Object* obj = cache->get(cache_entry);
   17837             : 
   17838     5184432 :   if (obj->IsFixedArray()) {
   17839             :     FixedArray* literals_map = FixedArray::cast(obj);
   17840             :     int length = literals_map->length();
   17841    12446612 :     for (int i = 0; i < length; i += kLiteralEntryLength) {
   17842    10895568 :       if (WeakCell::cast(literals_map->get(i + kLiteralContextOffset))
   17843             :               ->value() == native_context) {
   17844             :         return i;
   17845             :       }
   17846             :     }
   17847             :   }
   17848             :   return -1;
   17849             : }
   17850             : 
   17851     1208808 : void AddToLiteralsMap(Handle<CompilationCacheTable> cache, int cache_entry,
   17852             :                       Handle<Context> native_context, Handle<Cell> literals) {
   17853             :   Isolate* isolate = native_context->GetIsolate();
   17854             :   DCHECK(native_context->IsNativeContext());
   17855             :   STATIC_ASSERT(kLiteralEntryLength == 2);
   17856             :   Handle<FixedArray> new_literals_map;
   17857             :   int entry;
   17858             : 
   17859             :   Object* obj = cache->get(cache_entry);
   17860             : 
   17861     1949315 :   if (!obj->IsFixedArray() || FixedArray::cast(obj)->length() == 0) {
   17862             :     new_literals_map =
   17863      468301 :         isolate->factory()->NewFixedArray(kLiteralInitialLength, TENURED);
   17864             :     entry = 0;
   17865             :   } else {
   17866             :     Handle<FixedArray> old_literals_map(FixedArray::cast(obj), isolate);
   17867      740507 :     entry = SearchLiteralsMapEntry(*cache, cache_entry, *native_context);
   17868      740507 :     if (entry >= 0) {
   17869             :       // Just set the code of the entry.
   17870             :       Handle<WeakCell> literals_cell =
   17871        2109 :           isolate->factory()->NewWeakCell(literals);
   17872        4218 :       old_literals_map->set(entry + kLiteralLiteralsOffset, *literals_cell);
   17873     1208808 :       return;
   17874             :     }
   17875             : 
   17876             :     // Can we reuse an entry?
   17877             :     DCHECK(entry < 0);
   17878             :     int length = old_literals_map->length();
   17879     2012295 :     for (int i = 0; i < length; i += kLiteralEntryLength) {
   17880     1358622 :       if (WeakCell::cast(old_literals_map->get(i + kLiteralContextOffset))
   17881             :               ->cleared()) {
   17882             :         new_literals_map = old_literals_map;
   17883             :         entry = i;
   17884             :         break;
   17885             :       }
   17886             :     }
   17887             : 
   17888      738398 :     if (entry < 0) {
   17889             :       // Copy old optimized code map and append one new entry.
   17890             :       new_literals_map = isolate->factory()->CopyFixedArrayAndGrow(
   17891      653673 :           old_literals_map, kLiteralEntryLength, TENURED);
   17892             :       entry = old_literals_map->length();
   17893             :     }
   17894             :   }
   17895             : 
   17896     1206699 :   Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals);
   17897             :   WeakCell* context_cell = native_context->self_weak_cell();
   17898             : 
   17899     1206699 :   new_literals_map->set(entry + kLiteralContextOffset, context_cell);
   17900     2413398 :   new_literals_map->set(entry + kLiteralLiteralsOffset, *literals_cell);
   17901             : 
   17902             : #ifdef DEBUG
   17903             :   for (int i = 0; i < new_literals_map->length(); i += kLiteralEntryLength) {
   17904             :     WeakCell* cell =
   17905             :         WeakCell::cast(new_literals_map->get(i + kLiteralContextOffset));
   17906             :     DCHECK(cell->cleared() || cell->value()->IsNativeContext());
   17907             :     cell = WeakCell::cast(new_literals_map->get(i + kLiteralLiteralsOffset));
   17908             :     DCHECK(cell->cleared() || (cell->value()->IsCell()));
   17909             :   }
   17910             : #endif
   17911             : 
   17912             :   Object* old_literals_map = cache->get(cache_entry);
   17913     1206699 :   if (old_literals_map != *new_literals_map) {
   17914     1121974 :     cache->set(cache_entry, *new_literals_map);
   17915             :   }
   17916             : }
   17917             : 
   17918     4443925 : Cell* SearchLiteralsMap(CompilationCacheTable* cache, int cache_entry,
   17919             :                         Context* native_context) {
   17920             :   Cell* result = nullptr;
   17921     4443925 :   int entry = SearchLiteralsMapEntry(cache, cache_entry, native_context);
   17922     4443925 :   if (entry >= 0) {
   17923             :     FixedArray* literals_map = FixedArray::cast(cache->get(cache_entry));
   17924             :     DCHECK_LE(entry + kLiteralEntryLength, literals_map->length());
   17925             :     WeakCell* cell =
   17926     3631279 :         WeakCell::cast(literals_map->get(entry + kLiteralLiteralsOffset));
   17927             : 
   17928     3631279 :     result = cell->cleared() ? nullptr : Cell::cast(cell->value());
   17929             :   }
   17930             :   DCHECK(result == nullptr || result->IsCell());
   17931     4443925 :   return result;
   17932             : }
   17933             : 
   17934             : }  // namespace
   17935             : 
   17936      310823 : InfoVectorPair CompilationCacheTable::LookupScript(Handle<String> src,
   17937             :                                                    Handle<Context> context,
   17938             :                                                    LanguageMode language_mode) {
   17939             :   InfoVectorPair empty_result;
   17940             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   17941             :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17942             :   int entry = FindEntry(&key);
   17943      310823 :   if (entry == kNotFound) return empty_result;
   17944             :   int index = EntryToIndex(entry);
   17945      141713 :   if (!get(index)->IsFixedArray()) return empty_result;
   17946      141713 :   Object* obj = get(index + 1);
   17947      141713 :   if (obj->IsSharedFunctionInfo()) {
   17948             :     Cell* literals =
   17949      141713 :         SearchLiteralsMap(this, index + 2, context->native_context());
   17950      141713 :     return InfoVectorPair(SharedFunctionInfo::cast(obj), literals);
   17951             :   }
   17952           0 :   return empty_result;
   17953             : }
   17954             : 
   17955     5554379 : InfoVectorPair CompilationCacheTable::LookupEval(
   17956             :     Handle<String> src, Handle<SharedFunctionInfo> outer_info,
   17957             :     Handle<Context> native_context, LanguageMode language_mode, int position) {
   17958             :   InfoVectorPair empty_result;
   17959             :   StringSharedKey key(src, outer_info, language_mode, position);
   17960             :   int entry = FindEntry(&key);
   17961     5554379 :   if (entry == kNotFound) return empty_result;
   17962             :   int index = EntryToIndex(entry);
   17963     4597179 :   if (!get(index)->IsFixedArray()) return empty_result;
   17964     4302212 :   Object* obj = get(EntryToIndex(entry) + 1);
   17965     4302212 :   if (obj->IsSharedFunctionInfo()) {
   17966             :     Cell* literals =
   17967     4302212 :         SearchLiteralsMap(this, EntryToIndex(entry) + 2, *native_context);
   17968     4302212 :     return InfoVectorPair(SharedFunctionInfo::cast(obj), literals);
   17969             :   }
   17970           0 :   return empty_result;
   17971             : }
   17972             : 
   17973     1069562 : Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src,
   17974             :                                                    JSRegExp::Flags flags) {
   17975             :   Isolate* isolate = GetIsolate();
   17976             :   DisallowHeapAllocation no_allocation;
   17977             :   RegExpKey key(src, flags);
   17978             :   int entry = FindEntry(&key);
   17979     1782712 :   if (entry == kNotFound) return isolate->factory()->undefined_value();
   17980      712824 :   return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
   17981             : }
   17982             : 
   17983             : 
   17984           0 : Handle<CompilationCacheTable> CompilationCacheTable::Put(
   17985             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   17986             :     Handle<Context> context, LanguageMode language_mode, Handle<Object> value) {
   17987             :   Isolate* isolate = cache->GetIsolate();
   17988             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   17989             :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   17990           0 :   Handle<Object> k = key.AsHandle(isolate);
   17991           0 :   cache = EnsureCapacity(cache, 1, &key);
   17992           0 :   int entry = cache->FindInsertionEntry(key.Hash());
   17993           0 :   cache->set(EntryToIndex(entry), *k);
   17994           0 :   cache->set(EntryToIndex(entry) + 1, *value);
   17995           0 :   cache->ElementAdded();
   17996           0 :   return cache;
   17997             : }
   17998             : 
   17999      168303 : Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
   18000             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   18001             :     Handle<Context> context, LanguageMode language_mode,
   18002             :     Handle<SharedFunctionInfo> value, Handle<Cell> literals) {
   18003             :   Isolate* isolate = cache->GetIsolate();
   18004             :   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   18005             :   Handle<Context> native_context(context->native_context());
   18006             :   StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
   18007      168303 :   Handle<Object> k = key.AsHandle(isolate);
   18008      168303 :   cache = EnsureCapacity(cache, 1, &key);
   18009      336606 :   int entry = cache->FindInsertionEntry(key.Hash());
   18010      168303 :   cache->set(EntryToIndex(entry), *k);
   18011      336606 :   cache->set(EntryToIndex(entry) + 1, *value);
   18012      168303 :   AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, literals);
   18013      168303 :   cache->ElementAdded();
   18014      168303 :   return cache;
   18015             : }
   18016             : 
   18017     1817488 : Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
   18018             :     Handle<CompilationCacheTable> cache, Handle<String> src,
   18019             :     Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
   18020             :     Handle<Context> native_context, Handle<Cell> literals, int position) {
   18021             :   Isolate* isolate = cache->GetIsolate();
   18022             :   StringSharedKey key(src, outer_info, value->language_mode(), position);
   18023             :   {
   18024     1817488 :     Handle<Object> k = key.AsHandle(isolate);
   18025             :     int entry = cache->FindEntry(&key);
   18026     1817488 :     if (entry != kNotFound) {
   18027     1040505 :       cache->set(EntryToIndex(entry), *k);
   18028     2081010 :       cache->set(EntryToIndex(entry) + 1, *value);
   18029             :       // AddToLiteralsMap may allocate a new sub-array to live in the entry,
   18030             :       // but it won't change the cache array. Therefore EntryToIndex and
   18031             :       // entry remains correct.
   18032             :       AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context,
   18033     1040505 :                        literals);
   18034     1040505 :       return cache;
   18035             :     }
   18036             :   }
   18037             : 
   18038      776983 :   cache = EnsureCapacity(cache, 1, &key);
   18039     1553966 :   int entry = cache->FindInsertionEntry(key.Hash());
   18040             :   Handle<Object> k =
   18041      776983 :       isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
   18042      776983 :   cache->set(EntryToIndex(entry), *k);
   18043             :   cache->set(EntryToIndex(entry) + 1, Smi::FromInt(kHashGenerations));
   18044      776983 :   cache->ElementAdded();
   18045      776983 :   return cache;
   18046             : }
   18047             : 
   18048             : 
   18049      353109 : Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
   18050             :       Handle<CompilationCacheTable> cache, Handle<String> src,
   18051             :       JSRegExp::Flags flags, Handle<FixedArray> value) {
   18052             :   RegExpKey key(src, flags);
   18053      353109 :   cache = EnsureCapacity(cache, 1, &key);
   18054      353109 :   int entry = cache->FindInsertionEntry(key.Hash());
   18055             :   // We store the value in the key slot, and compare the search key
   18056             :   // to the stored value with a custon IsMatch function during lookups.
   18057      353109 :   cache->set(EntryToIndex(entry), *value);
   18058      706218 :   cache->set(EntryToIndex(entry) + 1, *value);
   18059      353109 :   cache->ElementAdded();
   18060      353109 :   return cache;
   18061             : }
   18062             : 
   18063             : 
   18064       19083 : void CompilationCacheTable::Age() {
   18065             :   DisallowHeapAllocation no_allocation;
   18066       19083 :   Object* the_hole_value = GetHeap()->the_hole_value();
   18067     3931014 :   for (int entry = 0, size = Capacity(); entry < size; entry++) {
   18068             :     int entry_index = EntryToIndex(entry);
   18069     3892848 :     int value_index = entry_index + 1;
   18070             : 
   18071     3892848 :     if (get(entry_index)->IsNumber()) {
   18072             :       Smi* count = Smi::cast(get(value_index));
   18073      298543 :       count = Smi::FromInt(count->value() - 1);
   18074      298543 :       if (count->value() == 0) {
   18075             :         NoWriteBarrierSet(this, entry_index, the_hole_value);
   18076             :         NoWriteBarrierSet(this, value_index, the_hole_value);
   18077         264 :         ElementRemoved();
   18078             :       } else {
   18079             :         NoWriteBarrierSet(this, value_index, count);
   18080             :       }
   18081     3594305 :     } else if (get(entry_index)->IsFixedArray()) {
   18082             :       SharedFunctionInfo* info = SharedFunctionInfo::cast(get(value_index));
   18083             :       bool is_old =
   18084             :           info->IsInterpreted()
   18085             :               ? info->bytecode_array()->IsOld()
   18086      799124 :               : info->code()->kind() != Code::FUNCTION || info->code()->IsOld();
   18087      432800 :       if (is_old) {
   18088       14022 :         for (int i = 0; i < kEntrySize; i++) {
   18089       14022 :           NoWriteBarrierSet(this, entry_index + i, the_hole_value);
   18090             :         }
   18091        4674 :         ElementRemoved();
   18092             :       }
   18093             :     }
   18094             :   }
   18095       19083 : }
   18096             : 
   18097             : 
   18098           0 : void CompilationCacheTable::Remove(Object* value) {
   18099             :   DisallowHeapAllocation no_allocation;
   18100           0 :   Object* the_hole_value = GetHeap()->the_hole_value();
   18101           0 :   for (int entry = 0, size = Capacity(); entry < size; entry++) {
   18102             :     int entry_index = EntryToIndex(entry);
   18103           0 :     int value_index = entry_index + 1;
   18104           0 :     if (get(value_index) == value) {
   18105           0 :       for (int i = 0; i < kEntrySize; i++) {
   18106           0 :         NoWriteBarrierSet(this, entry_index + i, the_hole_value);
   18107             :       }
   18108           0 :       ElementRemoved();
   18109             :     }
   18110             :   }
   18111           0 :   return;
   18112             : }
   18113             : 
   18114             : template <typename Derived, typename Shape, typename Key>
   18115     2279460 : Handle<Derived> Dictionary<Derived, Shape, Key>::New(
   18116             :     Isolate* isolate, int at_least_space_for, PretenureFlag pretenure,
   18117             :     MinimumCapacity capacity_option) {
   18118             :   DCHECK(0 <= at_least_space_for);
   18119             :   Handle<Derived> dict = DerivedHashTable::New(isolate, at_least_space_for,
   18120     2279460 :                                                capacity_option, pretenure);
   18121             : 
   18122             :   // Initialize the next enumeration index.
   18123             :   dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
   18124     2279458 :   return dict;
   18125             : }
   18126             : 
   18127             : template <typename Derived, typename Shape, typename Key>
   18128         284 : Handle<Derived> Dictionary<Derived, Shape, Key>::NewEmpty(
   18129             :     Isolate* isolate, PretenureFlag pretenure) {
   18130         284 :   Handle<Derived> dict = DerivedHashTable::New(isolate, 1, pretenure);
   18131             :   // Attempt to add one element to the empty dictionary must cause reallocation.
   18132             :   DCHECK(!dict->HasSufficientCapacityToAdd(1));
   18133             :   // Initialize the next enumeration index.
   18134             :   dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
   18135         284 :   return dict;
   18136             : }
   18137             : 
   18138             : template <typename Derived, typename Shape, typename Key>
   18139          50 : void Dictionary<Derived, Shape, Key>::SetRequiresCopyOnCapacityChange() {
   18140             :   DCHECK_EQ(0, DerivedHashTable::NumberOfElements());
   18141             :   DCHECK_EQ(0, DerivedHashTable::NumberOfDeletedElements());
   18142             :   // Make sure that HashTable::EnsureCapacity will create a copy.
   18143             :   DerivedHashTable::SetNumberOfDeletedElements(DerivedHashTable::Capacity());
   18144             :   DCHECK(!DerivedHashTable::HasSufficientCapacityToAdd(1));
   18145          50 : }
   18146             : 
   18147             : 
   18148             : template <typename Derived, typename Shape, typename Key>
   18149    38582974 : Handle<Derived> Dictionary<Derived, Shape, Key>::EnsureCapacity(
   18150             :     Handle<Derived> dictionary, int n, Key key) {
   18151             :   // Check whether there are enough enumeration indices to add n elements.
   18152    30893400 :   if (Shape::kIsEnumerable &&
   18153    30893400 :       !PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) {
   18154             :     // If not, we generate new indices for the properties.
   18155             :     int length = dictionary->NumberOfElements();
   18156             : 
   18157           0 :     Handle<FixedArray> iteration_order = IterationIndices(dictionary);
   18158             :     DCHECK_EQ(length, iteration_order->length());
   18159             : 
   18160             :     // Iterate over the dictionary using the enumeration order and update
   18161             :     // the dictionary with new enumeration indices.
   18162           0 :     for (int i = 0; i < length; i++) {
   18163             :       int index = Smi::cast(iteration_order->get(i))->value();
   18164             :       DCHECK(dictionary->IsKey(dictionary->GetIsolate(),
   18165             :                                dictionary->KeyAt(index)));
   18166             : 
   18167           0 :       int enum_index = PropertyDetails::kInitialIndex + i;
   18168             : 
   18169             :       PropertyDetails details = dictionary->DetailsAt(index);
   18170             :       PropertyDetails new_details = details.set_index(enum_index);
   18171             :       dictionary->DetailsAtPut(index, new_details);
   18172             :     }
   18173             : 
   18174             :     // Set the next enumeration index.
   18175           0 :     dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex +
   18176             :                                         length);
   18177             :   }
   18178    38582974 :   return DerivedHashTable::EnsureCapacity(dictionary, n, key);
   18179             : }
   18180             : 
   18181             : 
   18182             : template <typename Derived, typename Shape, typename Key>
   18183     6169666 : Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty(
   18184             :     Handle<Derived> dictionary, int entry) {
   18185             :   Factory* factory = dictionary->GetIsolate()->factory();
   18186             :   PropertyDetails details = dictionary->DetailsAt(entry);
   18187     6169666 :   if (!details.IsConfigurable()) return factory->false_value();
   18188             : 
   18189     6169666 :   dictionary->SetEntry(
   18190             :       entry, factory->the_hole_value(), factory->the_hole_value());
   18191     6169666 :   dictionary->ElementRemoved();
   18192     6169666 :   return factory->true_value();
   18193             : }
   18194             : 
   18195             : 
   18196             : template<typename Derived, typename Shape, typename Key>
   18197     1899407 : Handle<Derived> Dictionary<Derived, Shape, Key>::AtPut(
   18198             :     Handle<Derived> dictionary, Key key, Handle<Object> value) {
   18199             :   int entry = dictionary->FindEntry(key);
   18200             : 
   18201             :   // If the entry is present set the value;
   18202     1899407 :   if (entry != Dictionary::kNotFound) {
   18203             :     dictionary->ValueAtPut(entry, *value);
   18204          24 :     return dictionary;
   18205             :   }
   18206             : 
   18207             :   // Check whether the dictionary should be extended.
   18208     1899383 :   dictionary = EnsureCapacity(dictionary, 1, key);
   18209             : #ifdef DEBUG
   18210             :   USE(Shape::AsHandle(dictionary->GetIsolate(), key));
   18211             : #endif
   18212     1899383 :   PropertyDetails details = PropertyDetails::Empty();
   18213             : 
   18214     1899383 :   AddEntry(dictionary, key, value, details, dictionary->Hash(key));
   18215     1899383 :   return dictionary;
   18216             : }
   18217             : 
   18218             : template <typename Derived, typename Shape, typename Key>
   18219    36683589 : Handle<Derived> Dictionary<Derived, Shape, Key>::Add(Handle<Derived> dictionary,
   18220             :                                                      Key key,
   18221             :                                                      Handle<Object> value,
   18222             :                                                      PropertyDetails details,
   18223             :                                                      int* entry_out) {
   18224             :   // Valdate key is absent.
   18225             :   SLOW_DCHECK((dictionary->FindEntry(key) == Dictionary::kNotFound));
   18226             :   // Check whether the dictionary should be extended.
   18227    36683589 :   dictionary = EnsureCapacity(dictionary, 1, key);
   18228             : 
   18229    36683590 :   int entry = AddEntry(dictionary, key, value, details, dictionary->Hash(key));
   18230    36683588 :   if (entry_out) *entry_out = entry;
   18231    36683588 :   return dictionary;
   18232             : }
   18233             : 
   18234             : // Add a key, value pair to the dictionary. Returns entry value.
   18235             : template <typename Derived, typename Shape, typename Key>
   18236    38582973 : int Dictionary<Derived, Shape, Key>::AddEntry(Handle<Derived> dictionary,
   18237             :                                               Key key, Handle<Object> value,
   18238             :                                               PropertyDetails details,
   18239             :                                               uint32_t hash) {
   18240             :   // Compute the key object.
   18241             :   Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key);
   18242             : 
   18243    38582973 :   uint32_t entry = dictionary->FindInsertionEntry(hash);
   18244             :   // Insert element at empty or deleted entry
   18245    30893401 :   if (details.dictionary_index() == 0 && Shape::kIsEnumerable) {
   18246             :     // Assign an enumeration index to the property and update
   18247             :     // SetNextEnumerationIndex.
   18248             :     int index = dictionary->NextEnumerationIndex();
   18249             :     details = details.set_index(index);
   18250    25094311 :     dictionary->SetNextEnumerationIndex(index + 1);
   18251             :   }
   18252    38582973 :   dictionary->SetEntry(entry, k, value, details);
   18253             :   DCHECK((dictionary->KeyAt(entry)->IsNumber() ||
   18254             :           dictionary->KeyAt(entry)->IsName()));
   18255    38582971 :   dictionary->ElementAdded();
   18256    38582971 :   return entry;
   18257             : }
   18258             : 
   18259        4562 : bool SeededNumberDictionary::HasComplexElements() {
   18260        4562 :   if (!requires_slow_elements()) return false;
   18261             :   Isolate* isolate = this->GetIsolate();
   18262             :   int capacity = this->Capacity();
   18263       20595 :   for (int i = 0; i < capacity; i++) {
   18264             :     Object* k = this->KeyAt(i);
   18265       17970 :     if (!this->IsKey(isolate, k)) continue;
   18266             :     DCHECK(!IsDeleted(i));
   18267             :     PropertyDetails details = this->DetailsAt(i);
   18268        7290 :     if (details.kind() == kAccessor) return true;
   18269             :     PropertyAttributes attr = details.attributes();
   18270        7230 :     if (attr & ALL_ATTRIBUTES_MASK) return true;
   18271             :   }
   18272             :   return false;
   18273             : }
   18274             : 
   18275     6362220 : void SeededNumberDictionary::UpdateMaxNumberKey(
   18276             :     uint32_t key, Handle<JSObject> dictionary_holder) {
   18277             :   DisallowHeapAllocation no_allocation;
   18278             :   // If the dictionary requires slow elements an element has already
   18279             :   // been added at a high index.
   18280     6362220 :   if (requires_slow_elements()) return;
   18281             :   // Check if this index is high enough that we should require slow
   18282             :   // elements.
   18283     6288637 :   if (key > kRequiresSlowElementsLimit) {
   18284        1586 :     if (!dictionary_holder.is_null()) {
   18285        1178 :       dictionary_holder->RequireSlowElements(this);
   18286             :     }
   18287             :     set_requires_slow_elements();
   18288             :     return;
   18289             :   }
   18290             :   // Update max key value.
   18291             :   Object* max_index_object = get(kMaxNumberKeyIndex);
   18292     6287051 :   if (!max_index_object->IsSmi() || max_number_key() < key) {
   18293             :     FixedArray::set(kMaxNumberKeyIndex,
   18294     5378441 :                     Smi::FromInt(key << kRequiresSlowElementsTagSize));
   18295             :   }
   18296             : }
   18297             : 
   18298     5775746 : Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry(
   18299             :     Handle<SeededNumberDictionary> dictionary, uint32_t key,
   18300             :     Handle<Object> value, PropertyDetails details,
   18301             :     Handle<JSObject> dictionary_holder) {
   18302     5775746 :   dictionary->UpdateMaxNumberKey(key, dictionary_holder);
   18303             :   SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
   18304     5775746 :   return Add(dictionary, key, value, details);
   18305             : }
   18306             : 
   18307             : 
   18308           0 : Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry(
   18309             :     Handle<UnseededNumberDictionary> dictionary,
   18310             :     uint32_t key,
   18311             :     Handle<Object> value) {
   18312             :   SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
   18313         393 :   return Add(dictionary, key, value, PropertyDetails::Empty());
   18314             : }
   18315             : 
   18316           0 : Handle<UnseededNumberDictionary> UnseededNumberDictionary::DeleteKey(
   18317             :     Handle<UnseededNumberDictionary> dictionary, uint32_t key) {
   18318             :   int entry = dictionary->FindEntry(key);
   18319           0 :   if (entry == kNotFound) return dictionary;
   18320             : 
   18321             :   Factory* factory = dictionary->GetIsolate()->factory();
   18322             :   dictionary->SetEntry(entry, factory->the_hole_value(),
   18323             :                        factory->the_hole_value());
   18324           0 :   dictionary->ElementRemoved();
   18325           0 :   return dictionary->Shrink(dictionary, key);
   18326             : }
   18327             : 
   18328      586474 : Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut(
   18329             :     Handle<SeededNumberDictionary> dictionary, uint32_t key,
   18330             :     Handle<Object> value, Handle<JSObject> dictionary_holder) {
   18331      586474 :   dictionary->UpdateMaxNumberKey(key, dictionary_holder);
   18332      586474 :   return AtPut(dictionary, key, value);
   18333             : }
   18334             : 
   18335          60 : void SeededNumberDictionary::CopyValuesTo(FixedArray* elements) {
   18336             :   Isolate* isolate = this->GetIsolate();
   18337             :   int pos = 0;
   18338             :   int capacity = this->Capacity();
   18339             :   DisallowHeapAllocation no_gc;
   18340          60 :   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
   18341        1020 :   for (int i = 0; i < capacity; i++) {
   18342             :     Object* k = this->KeyAt(i);
   18343         960 :     if (this->IsKey(isolate, k)) {
   18344         450 :       elements->set(pos++, this->ValueAt(i), mode);
   18345             :     }
   18346             :   }
   18347             :   DCHECK(pos == elements->length());
   18348          60 : }
   18349             : 
   18350     1312933 : Handle<UnseededNumberDictionary> UnseededNumberDictionary::AtNumberPut(
   18351             :     Handle<UnseededNumberDictionary> dictionary,
   18352             :     uint32_t key,
   18353             :     Handle<Object> value) {
   18354     1312933 :   return AtPut(dictionary, key, value);
   18355             : }
   18356             : 
   18357       39202 : Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
   18358             :     Handle<SeededNumberDictionary> dictionary, uint32_t key,
   18359             :     Handle<Object> value, PropertyDetails details,
   18360             :     Handle<JSObject> dictionary_holder) {
   18361             :   int entry = dictionary->FindEntry(key);
   18362       39202 :   if (entry == kNotFound) {
   18363       37558 :     return AddNumberEntry(dictionary, key, value, details, dictionary_holder);
   18364             :   }
   18365             :   // Preserve enumeration index.
   18366             :   details = details.set_index(dictionary->DetailsAt(entry).dictionary_index());
   18367             :   Handle<Object> object_key =
   18368             :       SeededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
   18369             :   dictionary->SetEntry(entry, object_key, value, details);
   18370        1644 :   return dictionary;
   18371             : }
   18372             : 
   18373             : 
   18374        1818 : Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
   18375             :     Handle<UnseededNumberDictionary> dictionary,
   18376             :     uint32_t key,
   18377             :     Handle<Object> value) {
   18378             :   int entry = dictionary->FindEntry(key);
   18379        1818 :   if (entry == kNotFound) return AddNumberEntry(dictionary, key, value);
   18380             :   Handle<Object> object_key =
   18381             :       UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
   18382             :   dictionary->SetEntry(entry, object_key, value);
   18383        1425 :   return dictionary;
   18384             : }
   18385             : 
   18386             : 
   18387             : template <typename Derived, typename Shape, typename Key>
   18388       98702 : int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
   18389             :     PropertyFilter filter) {
   18390             :   Isolate* isolate = this->GetIsolate();
   18391             :   int capacity = this->Capacity();
   18392             :   int result = 0;
   18393    10286962 :   for (int i = 0; i < capacity; i++) {
   18394             :     Object* k = this->KeyAt(i);
   18395    10188260 :     if (this->IsKey(isolate, k) && !k->FilterKey(filter)) {
   18396     3211028 :       if (this->IsDeleted(i)) continue;
   18397             :       PropertyDetails details = this->DetailsAt(i);
   18398             :       PropertyAttributes attr = details.attributes();
   18399     4505899 :       if ((attr & filter) == 0) result++;
   18400             :     }
   18401             :   }
   18402       98702 :   return result;
   18403             : }
   18404             : 
   18405             : 
   18406             : template <typename Dictionary>
   18407             : struct EnumIndexComparator {
   18408      792771 :   explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {}
   18409   130709123 :   bool operator() (Smi* a, Smi* b) {
   18410   130709123 :     PropertyDetails da(dict->DetailsAt(a->value()));
   18411   130709123 :     PropertyDetails db(dict->DetailsAt(b->value()));
   18412   130709123 :     return da.dictionary_index() < db.dictionary_index();
   18413             :   }
   18414             :   Dictionary* dict;
   18415             : };
   18416             : 
   18417             : template <typename Derived, typename Shape, typename Key>
   18418       97481 : void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(
   18419             :     Handle<Dictionary<Derived, Shape, Key>> dictionary,
   18420             :     Handle<FixedArray> storage, KeyCollectionMode mode,
   18421             :     KeyAccumulator* accumulator) {
   18422             :   DCHECK_IMPLIES(mode != KeyCollectionMode::kOwnOnly, accumulator != nullptr);
   18423             :   Isolate* isolate = dictionary->GetIsolate();
   18424             :   int length = storage->length();
   18425             :   int capacity = dictionary->Capacity();
   18426             :   int properties = 0;
   18427    10089303 :   for (int i = 0; i < capacity; i++) {
   18428             :     Object* key = dictionary->KeyAt(i);
   18429             :     bool is_shadowing_key = false;
   18430    10031781 :     if (!dictionary->IsKey(isolate, key)) continue;
   18431     4475088 :     if (key->IsSymbol()) continue;
   18432             :     PropertyDetails details = dictionary->DetailsAt(i);
   18433     4446080 :     if (details.IsDontEnum()) {
   18434     1490117 :       if (mode == KeyCollectionMode::kIncludePrototypes) {
   18435             :         is_shadowing_key = true;
   18436             :       } else {
   18437             :         continue;
   18438             :       }
   18439             :     }
   18440     1682708 :     if (dictionary->IsDeleted(i)) continue;
   18441     2975492 :     if (is_shadowing_key) {
   18442       19664 :       accumulator->AddShadowingKey(key);
   18443       19664 :       continue;
   18444             :     } else {
   18445             :       storage->set(properties, Smi::FromInt(i));
   18446             :     }
   18447     2955828 :     properties++;
   18448     2955828 :     if (mode == KeyCollectionMode::kOwnOnly && properties == length) break;
   18449             :   }
   18450             : 
   18451       97481 :   CHECK_EQ(length, properties);
   18452             :   DisallowHeapAllocation no_gc;
   18453             :   Dictionary<Derived, Shape, Key>* raw_dictionary = *dictionary;
   18454             :   FixedArray* raw_storage = *storage;
   18455             :   EnumIndexComparator<Derived> cmp(static_cast<Derived*>(*dictionary));
   18456       97481 :   Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress());
   18457       97481 :   std::sort(start, start + length, cmp);
   18458     3053309 :   for (int i = 0; i < length; i++) {
   18459             :     int index = Smi::cast(raw_storage->get(i))->value();
   18460     2955828 :     raw_storage->set(i, raw_dictionary->KeyAt(index));
   18461             :   }
   18462       97481 : }
   18463             : 
   18464             : template <typename Derived, typename Shape, typename Key>
   18465      629013 : Handle<FixedArray> Dictionary<Derived, Shape, Key>::IterationIndices(
   18466             :     Handle<Dictionary<Derived, Shape, Key>> dictionary) {
   18467             :   Isolate* isolate = dictionary->GetIsolate();
   18468             :   int capacity = dictionary->Capacity();
   18469             :   int length = dictionary->NumberOfElements();
   18470      629013 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
   18471             :   int array_size = 0;
   18472             :   {
   18473             :     DisallowHeapAllocation no_gc;
   18474             :     Dictionary<Derived, Shape, Key>* raw_dict = *dictionary;
   18475    21453645 :     for (int i = 0; i < capacity; i++) {
   18476             :       Object* k = raw_dict->KeyAt(i);
   18477    20824632 :       if (!raw_dict->IsKey(isolate, k)) continue;
   18478     5551162 :       if (raw_dict->IsDeleted(i)) continue;
   18479     8747994 :       array->set(array_size++, Smi::FromInt(i));
   18480             :     }
   18481             : 
   18482             :     DCHECK_EQ(array_size, length);
   18483             : 
   18484             :     EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict));
   18485      629013 :     Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress());
   18486      629013 :     std::sort(start, start + array_size, cmp);
   18487             :   }
   18488      629013 :   array->Shrink(array_size);
   18489      629013 :   return array;
   18490             : }
   18491             : 
   18492             : template <typename Derived, typename Shape, typename Key>
   18493       66277 : void Dictionary<Derived, Shape, Key>::CollectKeysTo(
   18494             :     Handle<Dictionary<Derived, Shape, Key>> dictionary, KeyAccumulator* keys) {
   18495             :   Isolate* isolate = keys->isolate();
   18496             :   int capacity = dictionary->Capacity();
   18497             :   Handle<FixedArray> array =
   18498       66277 :       isolate->factory()->NewFixedArray(dictionary->NumberOfElements());
   18499             :   int array_size = 0;
   18500             :   PropertyFilter filter = keys->filter();
   18501             :   {
   18502             :     DisallowHeapAllocation no_gc;
   18503             :     Dictionary<Derived, Shape, Key>* raw_dict = *dictionary;
   18504    19381873 :     for (int i = 0; i < capacity; i++) {
   18505             :       Object* k = raw_dict->KeyAt(i);
   18506    19315596 :       if (!raw_dict->IsKey(isolate, k) || k->FilterKey(filter)) continue;
   18507     3174296 :       if (raw_dict->IsDeleted(i)) continue;
   18508             :       PropertyDetails details = raw_dict->DetailsAt(i);
   18509     5856902 :       if ((details.attributes() & filter) != 0) {
   18510         636 :         keys->AddShadowingKey(k);
   18511         636 :         continue;
   18512             :       }
   18513     5856266 :       if (filter & ONLY_ALL_CAN_READ) {
   18514         409 :         if (details.kind() != kAccessor) continue;
   18515          31 :         Object* accessors = raw_dict->ValueAt(i);
   18516          31 :         if (accessors->IsPropertyCell()) {
   18517             :           accessors = PropertyCell::cast(accessors)->value();
   18518             :         }
   18519          31 :         if (!accessors->IsAccessorInfo()) continue;
   18520          31 :         if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
   18521             :       }
   18522     5855876 :       array->set(array_size++, Smi::FromInt(i));
   18523             :     }
   18524             : 
   18525             :     EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict));
   18526       66277 :     Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress());
   18527       66277 :     std::sort(start, start + array_size, cmp);
   18528             :   }
   18529             : 
   18530             :   bool has_seen_symbol = false;
   18531     5922153 :   for (int i = 0; i < array_size; i++) {
   18532             :     int index = Smi::cast(array->get(i))->value();
   18533             :     Object* key = dictionary->KeyAt(index);
   18534     5855876 :     if (key->IsSymbol()) {
   18535             :       has_seen_symbol = true;
   18536             :       continue;
   18537             :     }
   18538     5827222 :     keys->AddKey(key, DO_NOT_CONVERT);
   18539             :   }
   18540       66277 :   if (has_seen_symbol) {
   18541       35075 :     for (int i = 0; i < array_size; i++) {
   18542             :       int index = Smi::cast(array->get(i))->value();
   18543             :       Object* key = dictionary->KeyAt(index);
   18544       35075 :       if (!key->IsSymbol()) continue;
   18545       28654 :       keys->AddKey(key, DO_NOT_CONVERT);
   18546             :     }
   18547             :   }
   18548       66277 : }
   18549             : 
   18550             : 
   18551             : // Backwards lookup (slow).
   18552             : template<typename Derived, typename Shape, typename Key>
   18553          14 : Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
   18554             :   Isolate* isolate = this->GetIsolate();
   18555             :   int capacity = this->Capacity();
   18556        1806 :   for (int i = 0; i < capacity; i++) {
   18557             :     Object* k = this->KeyAt(i);
   18558        1792 :     if (!this->IsKey(isolate, k)) continue;
   18559         756 :     Object* e = this->ValueAt(i);
   18560             :     // TODO(dcarney): this should be templatized.
   18561         756 :     if (e->IsPropertyCell()) {
   18562             :       e = PropertyCell::cast(e)->value();
   18563             :     }
   18564         756 :     if (e == value) return k;
   18565             :   }
   18566          14 :   return isolate->heap()->undefined_value();
   18567             : }
   18568             : 
   18569             : 
   18570        9158 : Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key,
   18571             :                                 int32_t hash) {
   18572             :   DisallowHeapAllocation no_gc;
   18573             :   DCHECK(IsKey(isolate, *key));
   18574             : 
   18575        9158 :   int entry = FindEntry(isolate, key, hash);
   18576        9158 :   if (entry == kNotFound) return isolate->heap()->the_hole_value();
   18577       15462 :   return get(EntryToIndex(entry) + 1);
   18578             : }
   18579             : 
   18580             : 
   18581        7462 : Object* ObjectHashTable::Lookup(Handle<Object> key) {
   18582             :   DisallowHeapAllocation no_gc;
   18583             : 
   18584             :   Isolate* isolate = GetIsolate();
   18585             :   DCHECK(IsKey(isolate, *key));
   18586             : 
   18587             :   // If the object does not have an identity hash, it was never used as a key.
   18588        7462 :   Object* hash = key->GetHash();
   18589        7462 :   if (hash->IsUndefined(isolate)) {
   18590         726 :     return isolate->heap()->the_hole_value();
   18591             :   }
   18592        6736 :   return Lookup(isolate, key, Smi::cast(hash)->value());
   18593             : }
   18594             : 
   18595           0 : Object* ObjectHashTable::ValueAt(int entry) {
   18596           0 :   return get(EntryToValueIndex(entry));
   18597             : }
   18598             : 
   18599        2422 : Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) {
   18600        2422 :   return Lookup(GetIsolate(), key, hash);
   18601             : }
   18602             : 
   18603             : 
   18604        3498 : Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
   18605             :                                              Handle<Object> key,
   18606             :                                              Handle<Object> value) {
   18607             :   Isolate* isolate = table->GetIsolate();
   18608             :   DCHECK(table->IsKey(isolate, *key));
   18609             :   DCHECK(!value->IsTheHole(isolate));
   18610             : 
   18611             :   // Make sure the key object has an identity hash code.
   18612        3498 :   int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
   18613             : 
   18614        3498 :   return Put(table, key, value, hash);
   18615             : }
   18616             : 
   18617             : 
   18618        6436 : Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
   18619             :                                              Handle<Object> key,
   18620             :                                              Handle<Object> value,
   18621             :                                              int32_t hash) {
   18622             :   Isolate* isolate = table->GetIsolate();
   18623             :   DCHECK(table->IsKey(isolate, *key));
   18624             :   DCHECK(!value->IsTheHole(isolate));
   18625             : 
   18626        6436 :   int entry = table->FindEntry(isolate, key, hash);
   18627             : 
   18628             :   // Key is already in table, just overwrite value.
   18629        6436 :   if (entry != kNotFound) {
   18630        1242 :     table->set(EntryToIndex(entry) + 1, *value);
   18631         621 :     return table;
   18632             :   }
   18633             : 
   18634             :   // Rehash if more than 33% of the entries are deleted entries.
   18635             :   // TODO(jochen): Consider to shrink the fixed array in place.
   18636       11630 :   if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) {
   18637           7 :     table->Rehash(isolate->factory()->undefined_value());
   18638             :   }
   18639             :   // If we're out of luck, we didn't get a GC recently, and so rehashing
   18640             :   // isn't enough to avoid a crash.
   18641        5815 :   if (!table->HasSufficientCapacityToAdd(1)) {
   18642         402 :     int nof = table->NumberOfElements() + 1;
   18643         402 :     int capacity = ObjectHashTable::ComputeCapacity(nof * 2);
   18644         402 :     if (capacity > ObjectHashTable::kMaxCapacity) {
   18645           0 :       for (size_t i = 0; i < 2; ++i) {
   18646             :         isolate->heap()->CollectAllGarbage(
   18647             :             Heap::kFinalizeIncrementalMarkingMask,
   18648           0 :             GarbageCollectionReason::kFullHashtable);
   18649             :       }
   18650           0 :       table->Rehash(isolate->factory()->undefined_value());
   18651             :     }
   18652             :   }
   18653             : 
   18654             :   // Check whether the hash table should be extended.
   18655        5815 :   table = EnsureCapacity(table, 1, key);
   18656       17445 :   table->AddEntry(table->FindInsertionEntry(hash), *key, *value);
   18657        5815 :   return table;
   18658             : }
   18659             : 
   18660             : 
   18661           7 : Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
   18662             :                                                 Handle<Object> key,
   18663             :                                                 bool* was_present) {
   18664             :   DCHECK(table->IsKey(table->GetIsolate(), *key));
   18665             : 
   18666           7 :   Object* hash = key->GetHash();
   18667           7 :   if (hash->IsUndefined(table->GetIsolate())) {
   18668           0 :     *was_present = false;
   18669           0 :     return table;
   18670             :   }
   18671             : 
   18672           7 :   return Remove(table, key, was_present, Smi::cast(hash)->value());
   18673             : }
   18674             : 
   18675             : 
   18676         125 : Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
   18677             :                                                 Handle<Object> key,
   18678             :                                                 bool* was_present,
   18679             :                                                 int32_t hash) {
   18680             :   Isolate* isolate = table->GetIsolate();
   18681             :   DCHECK(table->IsKey(isolate, *key));
   18682             : 
   18683         125 :   int entry = table->FindEntry(isolate, key, hash);
   18684         125 :   if (entry == kNotFound) {
   18685           0 :     *was_present = false;
   18686           0 :     return table;
   18687             :   }
   18688             : 
   18689         125 :   *was_present = true;
   18690         125 :   table->RemoveEntry(entry);
   18691             :   return Shrink(table, key);
   18692             : }
   18693             : 
   18694             : 
   18695        5815 : void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
   18696        5815 :   set(EntryToIndex(entry), key);
   18697        5815 :   set(EntryToIndex(entry) + 1, value);
   18698        5815 :   ElementAdded();
   18699        5815 : }
   18700             : 
   18701             : 
   18702         164 : void ObjectHashTable::RemoveEntry(int entry) {
   18703         164 :   set_the_hole(EntryToIndex(entry));
   18704         164 :   set_the_hole(EntryToIndex(entry) + 1);
   18705         164 :   ElementRemoved();
   18706         164 : }
   18707             : 
   18708             : 
   18709     1051520 : Object* WeakHashTable::Lookup(Handle<HeapObject> key) {
   18710             :   DisallowHeapAllocation no_gc;
   18711             :   Isolate* isolate = GetIsolate();
   18712             :   DCHECK(IsKey(isolate, *key));
   18713             :   int entry = FindEntry(key);
   18714     1051520 :   if (entry == kNotFound) return isolate->heap()->the_hole_value();
   18715      904367 :   return get(EntryToValueIndex(entry));
   18716             : }
   18717             : 
   18718             : 
   18719     1051520 : Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table,
   18720             :                                          Handle<HeapObject> key,
   18721             :                                          Handle<HeapObject> value) {
   18722             :   Isolate* isolate = key->GetIsolate();
   18723             :   DCHECK(table->IsKey(isolate, *key));
   18724             :   int entry = table->FindEntry(key);
   18725             :   // Key is already in table, just overwrite value.
   18726     1051519 :   if (entry != kNotFound) {
   18727      904366 :     table->set(EntryToValueIndex(entry), *value);
   18728      904366 :     return table;
   18729             :   }
   18730             : 
   18731      147153 :   Handle<WeakCell> key_cell = isolate->factory()->NewWeakCell(key);
   18732             : 
   18733             :   // Check whether the hash table should be extended.
   18734      147153 :   table = EnsureCapacity(table, 1, key, TENURED);
   18735             : 
   18736      294306 :   table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key_cell, value);
   18737      147153 :   return table;
   18738             : }
   18739             : 
   18740             : 
   18741      147153 : void WeakHashTable::AddEntry(int entry, Handle<WeakCell> key_cell,
   18742             :                              Handle<HeapObject> value) {
   18743             :   DisallowHeapAllocation no_allocation;
   18744      147153 :   set(EntryToIndex(entry), *key_cell);
   18745      147153 :   set(EntryToValueIndex(entry), *value);
   18746      147153 :   ElementAdded();
   18747      147153 : }
   18748             : 
   18749             : template <class Derived, int entrysize>
   18750    10161487 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate(
   18751             :     Isolate* isolate, int capacity, PretenureFlag pretenure) {
   18752             :   // Capacity must be a power of two, since we depend on being able
   18753             :   // to divide and multiple by 2 (kLoadFactor) to derive capacity
   18754             :   // from number of buckets. If we decide to change kLoadFactor
   18755             :   // to something other than 2, capacity should be stored as another
   18756             :   // field of this object.
   18757    10161487 :   capacity = base::bits::RoundUpToPowerOfTwo32(Max(kMinCapacity, capacity));
   18758    10161487 :   if (capacity > kMaxCapacity) {
   18759           0 :     v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
   18760             :   }
   18761    10161487 :   int num_buckets = capacity / kLoadFactor;
   18762             :   Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray(
   18763    10161487 :       kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure);
   18764             :   backing_store->set_map_no_write_barrier(
   18765    10161488 :       isolate->heap()->ordered_hash_table_map());
   18766             :   Handle<Derived> table = Handle<Derived>::cast(backing_store);
   18767    99705260 :   for (int i = 0; i < num_buckets; ++i) {
   18768             :     table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound));
   18769             :   }
   18770             :   table->SetNumberOfBuckets(num_buckets);
   18771             :   table->SetNumberOfElements(0);
   18772             :   table->SetNumberOfDeletedElements(0);
   18773    10161488 :   return table;
   18774             : }
   18775             : 
   18776             : template <class Derived, int entrysize>
   18777    78472341 : Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable(
   18778             :     Handle<Derived> table) {
   18779             :   DCHECK(!table->IsObsolete());
   18780             : 
   18781             :   int nof = table->NumberOfElements();
   18782             :   int nod = table->NumberOfDeletedElements();
   18783             :   int capacity = table->Capacity();
   18784    78472341 :   if ((nof + nod) < capacity) return table;
   18785             :   // Don't need to grow if we can simply clear out deleted entries instead.
   18786             :   // Note that we can't compact in place, though, so we always allocate
   18787             :   // a new table.
   18788      279137 :   return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity);
   18789             : }
   18790             : 
   18791             : template <class Derived, int entrysize>
   18792      202070 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink(
   18793             :     Handle<Derived> table) {
   18794             :   DCHECK(!table->IsObsolete());
   18795             : 
   18796             :   int nof = table->NumberOfElements();
   18797             :   int capacity = table->Capacity();
   18798      202070 :   if (nof >= (capacity >> 2)) return table;
   18799      202070 :   return Rehash(table, capacity / 2);
   18800             : }
   18801             : 
   18802             : template <class Derived, int entrysize>
   18803         359 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Clear(
   18804             :     Handle<Derived> table) {
   18805             :   DCHECK(!table->IsObsolete());
   18806             : 
   18807             :   Handle<Derived> new_table =
   18808             :       Allocate(table->GetIsolate(),
   18809             :                kMinCapacity,
   18810         718 :                table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
   18811             : 
   18812             :   table->SetNextTable(*new_table);
   18813             :   table->SetNumberOfDeletedElements(kClearedTableSentinel);
   18814             : 
   18815         359 :   return new_table;
   18816             : }
   18817             : 
   18818             : template <class Derived, int entrysize>
   18819           0 : bool OrderedHashTable<Derived, entrysize>::HasKey(Handle<Derived> table,
   18820             :                                                   Handle<Object> key) {
   18821             :   DisallowHeapAllocation no_gc;
   18822             :   Isolate* isolate = table->GetIsolate();
   18823             :   Object* raw_key = *key;
   18824           0 :   int entry = table->KeyToFirstEntry(isolate, raw_key);
   18825             :   // Walk the chain in the bucket to find the key.
   18826           0 :   while (entry != kNotFound) {
   18827           0 :     Object* candidate_key = table->KeyAt(entry);
   18828           0 :     if (candidate_key->SameValueZero(raw_key)) return true;
   18829           0 :     entry = table->NextChainEntry(entry);
   18830             :   }
   18831             :   return false;
   18832             : }
   18833             : 
   18834             : 
   18835    78454862 : Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
   18836             :                                            Handle<Object> key) {
   18837    78454862 :   int hash = Object::GetOrCreateHash(table->GetIsolate(), key)->value();
   18838    78454860 :   int entry = table->HashToEntry(hash);
   18839             :   // Walk the chain of the bucket and try finding the key.
   18840   207423050 :   while (entry != kNotFound) {
   18841    50514161 :     Object* candidate_key = table->KeyAt(entry);
   18842             :     // Do not add if we have the key already
   18843    50514161 :     if (candidate_key->SameValueZero(*key)) return table;
   18844    50513329 :     entry = table->NextChainEntry(entry);
   18845             :   }
   18846             : 
   18847    78454029 :   table = OrderedHashSet::EnsureGrowable(table);
   18848             :   // Read the existing bucket values.
   18849             :   int bucket = table->HashToBucket(hash);
   18850    78454028 :   int previous_entry = table->HashToEntry(hash);
   18851             :   int nof = table->NumberOfElements();
   18852             :   // Insert a new entry at the end,
   18853    78454028 :   int new_entry = nof + table->NumberOfDeletedElements();
   18854             :   int new_index = table->EntryToIndex(new_entry);
   18855    78454028 :   table->set(new_index, *key);
   18856             :   table->set(new_index + kChainOffset, Smi::FromInt(previous_entry));
   18857             :   // and point the bucket to the new entry.
   18858             :   table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
   18859    78454028 :   table->SetNumberOfElements(nof + 1);
   18860    78454028 :   return table;
   18861             : }
   18862             : 
   18863     9520923 : Handle<FixedArray> OrderedHashSet::ConvertToKeysArray(
   18864             :     Handle<OrderedHashSet> table, GetKeysConversion convert) {
   18865             :   Isolate* isolate = table->GetIsolate();
   18866             :   int length = table->NumberOfElements();
   18867             :   int nof_buckets = table->NumberOfBuckets();
   18868             :   // Convert the dictionary to a linear list.
   18869             :   Handle<FixedArray> result = Handle<FixedArray>::cast(table);
   18870             :   // From this point on table is no longer a valid OrderedHashSet.
   18871    19041846 :   result->set_map(isolate->heap()->fixed_array_map());
   18872    87974884 :   for (int i = 0; i < length; i++) {
   18873    78453961 :     int index = kHashTableStartIndex + nof_buckets + (i * kEntrySize);
   18874             :     Object* key = table->get(index);
   18875    78453961 :     if (convert == GetKeysConversion::kConvertToString) {
   18876             :       uint32_t index_value;
   18877    11071734 :       if (key->ToArrayIndex(&index_value)) {
   18878      603298 :         key = *isolate->factory()->Uint32ToString(index_value);
   18879             :       } else {
   18880    10770085 :         CHECK(key->IsName());
   18881             :       }
   18882             :     }
   18883    78453961 :     result->set(i, key);
   18884             :   }
   18885     9520923 :   result->Shrink(length);
   18886     9520923 :   return result;
   18887             : }
   18888             : 
   18889             : template <class Derived, int entrysize>
   18890      481207 : Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
   18891             :     Handle<Derived> table, int new_capacity) {
   18892             :   Isolate* isolate = table->GetIsolate();
   18893             :   DCHECK(!table->IsObsolete());
   18894             : 
   18895             :   Handle<Derived> new_table =
   18896             :       Allocate(isolate, new_capacity,
   18897      481207 :                isolate->heap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
   18898             :   int nof = table->NumberOfElements();
   18899             :   int nod = table->NumberOfDeletedElements();
   18900             :   int new_buckets = new_table->NumberOfBuckets();
   18901             :   int new_entry = 0;
   18902             :   int removed_holes_index = 0;
   18903             : 
   18904             :   DisallowHeapAllocation no_gc;
   18905    13348710 :   for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
   18906    12867503 :     Object* key = table->KeyAt(old_entry);
   18907    12867503 :     if (key->IsTheHole(isolate)) {
   18908      212755 :       table->SetRemovedIndexAt(removed_holes_index++, old_entry);
   18909             :       continue;
   18910             :     }
   18911             : 
   18912    12654748 :     Object* hash = key->GetHash();
   18913    12654748 :     int bucket = Smi::cast(hash)->value() & (new_buckets - 1);
   18914    12654748 :     Object* chain_entry = new_table->get(kHashTableStartIndex + bucket);
   18915             :     new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
   18916             :     int new_index = new_table->EntryToIndex(new_entry);
   18917             :     int old_index = table->EntryToIndex(old_entry);
   18918    25378848 :     for (int i = 0; i < entrysize; ++i) {
   18919    12724100 :       Object* value = table->get(old_index + i);
   18920    25448200 :       new_table->set(new_index + i, value);
   18921             :     }
   18922    25309496 :     new_table->set(new_index + kChainOffset, chain_entry);
   18923    12654748 :     ++new_entry;
   18924             :   }
   18925             : 
   18926             :   DCHECK_EQ(nod, removed_holes_index);
   18927             : 
   18928             :   new_table->SetNumberOfElements(nof);
   18929             :   table->SetNextTable(*new_table);
   18930             : 
   18931      481207 :   return new_table;
   18932             : }
   18933             : 
   18934             : template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Allocate(
   18935             :     Isolate* isolate, int capacity, PretenureFlag pretenure);
   18936             : 
   18937             : template Handle<OrderedHashSet> OrderedHashTable<
   18938             :     OrderedHashSet, 1>::EnsureGrowable(Handle<OrderedHashSet> table);
   18939             : 
   18940             : template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Shrink(
   18941             :     Handle<OrderedHashSet> table);
   18942             : 
   18943             : template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Clear(
   18944             :     Handle<OrderedHashSet> table);
   18945             : 
   18946             : template bool OrderedHashTable<OrderedHashSet, 1>::HasKey(
   18947             :     Handle<OrderedHashSet> table, Handle<Object> key);
   18948             : 
   18949             : template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Allocate(
   18950             :     Isolate* isolate, int capacity, PretenureFlag pretenure);
   18951             : 
   18952             : template Handle<OrderedHashMap> OrderedHashTable<
   18953             :     OrderedHashMap, 2>::EnsureGrowable(Handle<OrderedHashMap> table);
   18954             : 
   18955             : template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Shrink(
   18956             :     Handle<OrderedHashMap> table);
   18957             : 
   18958             : template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Clear(
   18959             :     Handle<OrderedHashMap> table);
   18960             : 
   18961             : template bool OrderedHashTable<OrderedHashMap, 2>::HasKey(
   18962             :     Handle<OrderedHashMap> table, Handle<Object> key);
   18963             : 
   18964             : template<class Derived, class TableType>
   18965       12187 : void OrderedHashTableIterator<Derived, TableType>::Transition() {
   18966             :   DisallowHeapAllocation no_allocation;
   18967             :   TableType* table = TableType::cast(this->table());
   18968       24374 :   if (!table->IsObsolete()) return;
   18969             : 
   18970             :   int index = Smi::cast(this->index())->value();
   18971         882 :   while (table->IsObsolete()) {
   18972             :     TableType* next_table = table->NextTable();
   18973             : 
   18974         490 :     if (index > 0) {
   18975             :       int nod = table->NumberOfDeletedElements();
   18976             : 
   18977         252 :       if (nod == TableType::kClearedTableSentinel) {
   18978             :         index = 0;
   18979             :       } else {
   18980             :         int old_index = index;
   18981         168 :         for (int i = 0; i < nod; ++i) {
   18982             :           int removed_index = table->RemovedIndexAt(i);
   18983         224 :           if (removed_index >= old_index) break;
   18984         168 :           --index;
   18985             :         }
   18986             :       }
   18987             :     }
   18988             : 
   18989             :     table = next_table;
   18990             :   }
   18991             : 
   18992         196 :   set_table(table);
   18993         196 :   set_index(Smi::FromInt(index));
   18994             : }
   18995             : 
   18996             : 
   18997             : template<class Derived, class TableType>
   18998       12283 : bool OrderedHashTableIterator<Derived, TableType>::HasMore() {
   18999             :   DisallowHeapAllocation no_allocation;
   19000             :   Isolate* isolate = this->GetIsolate();
   19001       12283 :   if (this->table()->IsUndefined(isolate)) return false;
   19002             : 
   19003       12187 :   Transition();
   19004             : 
   19005             :   TableType* table = TableType::cast(this->table());
   19006             :   int index = Smi::cast(this->index())->value();
   19007       12187 :   int used_capacity = table->UsedCapacity();
   19008             : 
   19009       35607 :   while (index < used_capacity && table->KeyAt(index)->IsTheHole(isolate)) {
   19010         406 :     index++;
   19011             :   }
   19012             : 
   19013       12187 :   set_index(Smi::FromInt(index));
   19014             : 
   19015       12187 :   if (index < used_capacity) return true;
   19016             : 
   19017        1766 :   set_table(isolate->heap()->undefined_value());
   19018        1766 :   return false;
   19019             : }
   19020             : 
   19021             : 
   19022             : template<class Derived, class TableType>
   19023       12031 : Smi* OrderedHashTableIterator<Derived, TableType>::Next(JSArray* value_array) {
   19024             :   DisallowHeapAllocation no_allocation;
   19025       12031 :   if (HasMore()) {
   19026             :     FixedArray* array = FixedArray::cast(value_array->elements());
   19027       10193 :     static_cast<Derived*>(this)->PopulateValueArray(array);
   19028       10193 :     MoveNext();
   19029       10193 :     return Smi::cast(kind());
   19030             :   }
   19031             :   return Smi::kZero;
   19032             : }
   19033             : 
   19034             : 
   19035             : template Smi*
   19036             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Next(
   19037             :     JSArray* value_array);
   19038             : 
   19039             : template bool
   19040             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::HasMore();
   19041             : 
   19042             : template void
   19043             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::MoveNext();
   19044             : 
   19045             : template Object*
   19046             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::CurrentKey();
   19047             : 
   19048             : template void
   19049             : OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Transition();
   19050             : 
   19051             : 
   19052             : template Smi*
   19053             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Next(
   19054             :     JSArray* value_array);
   19055             : 
   19056             : template bool
   19057             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::HasMore();
   19058             : 
   19059             : template void
   19060             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::MoveNext();
   19061             : 
   19062             : template Object*
   19063             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::CurrentKey();
   19064             : 
   19065             : template void
   19066             : OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Transition();
   19067             : 
   19068             : 
   19069       78935 : void JSSet::Initialize(Handle<JSSet> set, Isolate* isolate) {
   19070       78935 :   Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
   19071       78935 :   set->set_table(*table);
   19072       78935 : }
   19073             : 
   19074             : 
   19075          45 : void JSSet::Clear(Handle<JSSet> set) {
   19076             :   Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
   19077          45 :   table = OrderedHashSet::Clear(table);
   19078          45 :   set->set_table(*table);
   19079          45 : }
   19080             : 
   19081             : 
   19082       80008 : void JSMap::Initialize(Handle<JSMap> map, Isolate* isolate) {
   19083       80008 :   Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
   19084       80008 :   map->set_table(*table);
   19085       80008 : }
   19086             : 
   19087             : 
   19088         314 : void JSMap::Clear(Handle<JSMap> map) {
   19089             :   Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
   19090         314 :   table = OrderedHashMap::Clear(table);
   19091         314 :   map->set_table(*table);
   19092         314 : }
   19093             : 
   19094             : 
   19095      129288 : void JSWeakCollection::Initialize(Handle<JSWeakCollection> weak_collection,
   19096             :                                   Isolate* isolate) {
   19097      129288 :   Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
   19098      129288 :   weak_collection->set_table(*table);
   19099      129288 : }
   19100             : 
   19101             : 
   19102        2938 : void JSWeakCollection::Set(Handle<JSWeakCollection> weak_collection,
   19103             :                            Handle<Object> key, Handle<Object> value,
   19104             :                            int32_t hash) {
   19105             :   DCHECK(key->IsJSReceiver() || key->IsSymbol());
   19106             :   Handle<ObjectHashTable> table(
   19107             :       ObjectHashTable::cast(weak_collection->table()));
   19108             :   DCHECK(table->IsKey(table->GetIsolate(), *key));
   19109             :   Handle<ObjectHashTable> new_table =
   19110        2938 :       ObjectHashTable::Put(table, key, value, hash);
   19111        2938 :   weak_collection->set_table(*new_table);
   19112        2938 :   if (*table != *new_table) {
   19113             :     // Zap the old table since we didn't record slots for its elements.
   19114         238 :     table->FillWithHoles(0, table->length());
   19115             :   }
   19116        2938 : }
   19117             : 
   19118             : 
   19119         118 : bool JSWeakCollection::Delete(Handle<JSWeakCollection> weak_collection,
   19120             :                               Handle<Object> key, int32_t hash) {
   19121             :   DCHECK(key->IsJSReceiver() || key->IsSymbol());
   19122             :   Handle<ObjectHashTable> table(
   19123             :       ObjectHashTable::cast(weak_collection->table()));
   19124             :   DCHECK(table->IsKey(table->GetIsolate(), *key));
   19125         118 :   bool was_present = false;
   19126             :   Handle<ObjectHashTable> new_table =
   19127         118 :       ObjectHashTable::Remove(table, key, &was_present, hash);
   19128         118 :   weak_collection->set_table(*new_table);
   19129         118 :   if (*table != *new_table) {
   19130             :     // Zap the old table since we didn't record slots for its elements.
   19131           0 :     table->FillWithHoles(0, table->length());
   19132             :   }
   19133         118 :   return was_present;
   19134             : }
   19135             : 
   19136          36 : Handle<JSArray> JSWeakCollection::GetEntries(Handle<JSWeakCollection> holder,
   19137             :                                              int max_entries) {
   19138             :   Isolate* isolate = holder->GetIsolate();
   19139             :   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   19140          36 :   if (max_entries == 0 || max_entries > table->NumberOfElements()) {
   19141             :     max_entries = table->NumberOfElements();
   19142             :   }
   19143          36 :   int values_per_entry = holder->IsJSWeakMap() ? 2 : 1;
   19144             :   Handle<FixedArray> entries =
   19145          36 :       isolate->factory()->NewFixedArray(max_entries * values_per_entry);
   19146             :   // Recompute max_values because GC could have removed elements from the table.
   19147          36 :   if (max_entries > table->NumberOfElements()) {
   19148             :     max_entries = table->NumberOfElements();
   19149             :   }
   19150             : 
   19151             :   {
   19152             :     DisallowHeapAllocation no_gc;
   19153             :     int count = 0;
   19154         192 :     for (int i = 0;
   19155         156 :          count / values_per_entry < max_entries && i < table->Capacity(); i++) {
   19156             :       Handle<Object> key(table->KeyAt(i), isolate);
   19157          60 :       if (table->IsKey(isolate, *key)) {
   19158          48 :         entries->set(count++, *key);
   19159          24 :         if (values_per_entry > 1) {
   19160          12 :           Object* value = table->Lookup(key);
   19161          24 :           entries->set(count++, value);
   19162             :         }
   19163             :       }
   19164             :     }
   19165             :     DCHECK_EQ(max_entries * values_per_entry, count);
   19166             :   }
   19167          36 :   return isolate->factory()->NewJSArrayWithElements(entries);
   19168             : }
   19169             : 
   19170             : // Check if there is a break point at this source position.
   19171       94182 : bool DebugInfo::HasBreakPoint(int source_position) {
   19172             :   // Get the break point info object for this code offset.
   19173       94182 :   Object* break_point_info = GetBreakPointInfo(source_position);
   19174             : 
   19175             :   // If there is no break point info object or no break points in the break
   19176             :   // point info object there is no break point at this code offset.
   19177       94182 :   if (break_point_info->IsUndefined(GetIsolate())) return false;
   19178        5201 :   return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0;
   19179             : }
   19180             : 
   19181             : // Get the break point info object for this source position.
   19182      102192 : Object* DebugInfo::GetBreakPointInfo(int source_position) {
   19183             :   Isolate* isolate = GetIsolate();
   19184      102192 :   if (!break_points()->IsUndefined(isolate)) {
   19185      839660 :     for (int i = 0; i < break_points()->length(); i++) {
   19186      379117 :       if (!break_points()->get(i)->IsUndefined(isolate)) {
   19187             :         BreakPointInfo* break_point_info =
   19188             :             BreakPointInfo::cast(break_points()->get(i));
   19189       52425 :         if (break_point_info->source_position() == source_position) {
   19190             :           return break_point_info;
   19191             :         }
   19192             :       }
   19193             :     }
   19194             :   }
   19195       91809 :   return isolate->heap()->undefined_value();
   19196             : }
   19197             : 
   19198        2600 : bool DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info,
   19199             :                                 Handle<Object> break_point_object) {
   19200             :   Isolate* isolate = debug_info->GetIsolate();
   19201        2600 :   if (debug_info->break_points()->IsUndefined(isolate)) return false;
   19202             : 
   19203        4292 :   for (int i = 0; i < debug_info->break_points()->length(); i++) {
   19204        3446 :     if (debug_info->break_points()->get(i)->IsUndefined(isolate)) continue;
   19205             :     Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
   19206             :         BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate);
   19207        3446 :     if (BreakPointInfo::HasBreakPointObject(break_point_info,
   19208             :                                             break_point_object)) {
   19209        2600 :       BreakPointInfo::ClearBreakPoint(break_point_info, break_point_object);
   19210        2600 :       return true;
   19211             :     }
   19212             :   }
   19213             :   return false;
   19214             : }
   19215             : 
   19216        2977 : void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
   19217             :                               Handle<Object> break_point_object) {
   19218             :   Isolate* isolate = debug_info->GetIsolate();
   19219             :   Handle<Object> break_point_info(
   19220        2977 :       debug_info->GetBreakPointInfo(source_position), isolate);
   19221        2977 :   if (!break_point_info->IsUndefined(isolate)) {
   19222             :     BreakPointInfo::SetBreakPoint(
   19223             :         Handle<BreakPointInfo>::cast(break_point_info),
   19224         149 :         break_point_object);
   19225        3126 :     return;
   19226             :   }
   19227             : 
   19228             :   // Adding a new break point for a code offset which did not have any
   19229             :   // break points before. Try to find a free slot.
   19230             :   static const int kNoBreakPointInfo = -1;
   19231             :   int index = kNoBreakPointInfo;
   19232        4484 :   for (int i = 0; i < debug_info->break_points()->length(); i++) {
   19233        3638 :     if (debug_info->break_points()->get(i)->IsUndefined(isolate)) {
   19234             :       index = i;
   19235             :       break;
   19236             :     }
   19237             :   }
   19238        2828 :   if (index == kNoBreakPointInfo) {
   19239             :     // No free slot - extend break point info array.
   19240             :     Handle<FixedArray> old_break_points = Handle<FixedArray>(
   19241             :         FixedArray::cast(debug_info->break_points()), isolate);
   19242             :     Handle<FixedArray> new_break_points =
   19243             :         isolate->factory()->NewFixedArray(
   19244             :             old_break_points->length() +
   19245          18 :             DebugInfo::kEstimatedNofBreakPointsInFunction);
   19246             : 
   19247          18 :     debug_info->set_break_points(*new_break_points);
   19248         180 :     for (int i = 0; i < old_break_points->length(); i++) {
   19249          72 :       new_break_points->set(i, old_break_points->get(i));
   19250             :     }
   19251             :     index = old_break_points->length();
   19252             :   }
   19253             :   DCHECK(index != kNoBreakPointInfo);
   19254             : 
   19255             :   // Allocate new BreakPointInfo object and set the break point.
   19256             :   Handle<BreakPointInfo> new_break_point_info =
   19257        2828 :       isolate->factory()->NewBreakPointInfo(source_position);
   19258        2828 :   BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object);
   19259        2828 :   debug_info->break_points()->set(index, *new_break_point_info);
   19260             : }
   19261             : 
   19262             : // Get the break point objects for a source position.
   19263        5033 : Handle<Object> DebugInfo::GetBreakPointObjects(int source_position) {
   19264        5033 :   Object* break_point_info = GetBreakPointInfo(source_position);
   19265             :   Isolate* isolate = GetIsolate();
   19266        5033 :   if (break_point_info->IsUndefined(isolate)) {
   19267           0 :     return isolate->factory()->undefined_value();
   19268             :   }
   19269             :   return Handle<Object>(
   19270        5033 :       BreakPointInfo::cast(break_point_info)->break_point_objects(), isolate);
   19271             : }
   19272             : 
   19273             : 
   19274             : // Get the total number of break points.
   19275        3272 : int DebugInfo::GetBreakPointCount() {
   19276             :   Isolate* isolate = GetIsolate();
   19277        3272 :   if (break_points()->IsUndefined(isolate)) return 0;
   19278             :   int count = 0;
   19279       30744 :   for (int i = 0; i < break_points()->length(); i++) {
   19280       13736 :     if (!break_points()->get(i)->IsUndefined(isolate)) {
   19281             :       BreakPointInfo* break_point_info =
   19282             :           BreakPointInfo::cast(break_points()->get(i));
   19283        5952 :       count += break_point_info->GetBreakPointCount();
   19284             :     }
   19285             :   }
   19286             :   return count;
   19287             : }
   19288             : 
   19289             : 
   19290        9614 : Handle<Object> DebugInfo::FindBreakPointInfo(
   19291             :     Handle<DebugInfo> debug_info, Handle<Object> break_point_object) {
   19292             :   Isolate* isolate = debug_info->GetIsolate();
   19293        9614 :   if (!debug_info->break_points()->IsUndefined(isolate)) {
   19294       67850 :     for (int i = 0; i < debug_info->break_points()->length(); i++) {
   19295       31718 :       if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) {
   19296             :         Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
   19297             :             BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate);
   19298        8716 :         if (BreakPointInfo::HasBreakPointObject(break_point_info,
   19299             :                                                 break_point_object)) {
   19300        2600 :           return break_point_info;
   19301             :         }
   19302             :       }
   19303             :     }
   19304             :   }
   19305        7014 :   return isolate->factory()->undefined_value();
   19306             : }
   19307             : 
   19308             : // Remove the specified break point object.
   19309        2600 : void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info,
   19310             :                                      Handle<Object> break_point_object) {
   19311             :   Isolate* isolate = break_point_info->GetIsolate();
   19312             :   // If there are no break points just ignore.
   19313        2600 :   if (break_point_info->break_point_objects()->IsUndefined(isolate)) return;
   19314             :   // If there is a single break point clear it if it is the same.
   19315        2600 :   if (!break_point_info->break_point_objects()->IsFixedArray()) {
   19316        2428 :     if (break_point_info->break_point_objects() == *break_point_object) {
   19317             :       break_point_info->set_break_point_objects(
   19318        2428 :           isolate->heap()->undefined_value());
   19319             :     }
   19320             :     return;
   19321             :   }
   19322             :   // If there are multiple break points shrink the array
   19323             :   DCHECK(break_point_info->break_point_objects()->IsFixedArray());
   19324             :   Handle<FixedArray> old_array =
   19325             :       Handle<FixedArray>(
   19326             :           FixedArray::cast(break_point_info->break_point_objects()));
   19327             :   Handle<FixedArray> new_array =
   19328         172 :       isolate->factory()->NewFixedArray(old_array->length() - 1);
   19329             :   int found_count = 0;
   19330        1652 :   for (int i = 0; i < old_array->length(); i++) {
   19331         654 :     if (old_array->get(i) == *break_point_object) {
   19332             :       DCHECK(found_count == 0);
   19333         172 :       found_count++;
   19334             :     } else {
   19335         964 :       new_array->set(i - found_count, old_array->get(i));
   19336             :     }
   19337             :   }
   19338             :   // If the break point was found in the list change it.
   19339         344 :   if (found_count > 0) break_point_info->set_break_point_objects(*new_array);
   19340             : }
   19341             : 
   19342             : 
   19343             : // Add the specified break point object.
   19344        3083 : void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info,
   19345             :                                    Handle<Object> break_point_object) {
   19346             :   Isolate* isolate = break_point_info->GetIsolate();
   19347             : 
   19348             :   // If there was no break point objects before just set it.
   19349        3083 :   if (break_point_info->break_point_objects()->IsUndefined(isolate)) {
   19350        2934 :     break_point_info->set_break_point_objects(*break_point_object);
   19351        2934 :     return;
   19352             :   }
   19353             :   // If the break point object is the same as before just ignore.
   19354         149 :   if (break_point_info->break_point_objects() == *break_point_object) return;
   19355             :   // If there was one break point object before replace with array.
   19356         149 :   if (!break_point_info->break_point_objects()->IsFixedArray()) {
   19357          65 :     Handle<FixedArray> array = isolate->factory()->NewFixedArray(2);
   19358          65 :     array->set(0, break_point_info->break_point_objects());
   19359          65 :     array->set(1, *break_point_object);
   19360          65 :     break_point_info->set_break_point_objects(*array);
   19361             :     return;
   19362             :   }
   19363             :   // If there was more than one break point before extend array.
   19364             :   Handle<FixedArray> old_array =
   19365             :       Handle<FixedArray>(
   19366             :           FixedArray::cast(break_point_info->break_point_objects()));
   19367             :   Handle<FixedArray> new_array =
   19368          84 :       isolate->factory()->NewFixedArray(old_array->length() + 1);
   19369        1044 :   for (int i = 0; i < old_array->length(); i++) {
   19370             :     // If the break point was there before just ignore.
   19371         438 :     if (old_array->get(i) == *break_point_object) return;
   19372         438 :     new_array->set(i, old_array->get(i));
   19373             :   }
   19374             :   // Add the new break point.
   19375          84 :   new_array->set(old_array->length(), *break_point_object);
   19376          84 :   break_point_info->set_break_point_objects(*new_array);
   19377             : }
   19378             : 
   19379             : 
   19380       12162 : bool BreakPointInfo::HasBreakPointObject(
   19381             :     Handle<BreakPointInfo> break_point_info,
   19382             :     Handle<Object> break_point_object) {
   19383             :   // No break point.
   19384             :   Isolate* isolate = break_point_info->GetIsolate();
   19385       12162 :   if (break_point_info->break_point_objects()->IsUndefined(isolate)) {
   19386             :     return false;
   19387             :   }
   19388             :   // Single break point.
   19389       10524 :   if (!break_point_info->break_point_objects()->IsFixedArray()) {
   19390       10018 :     return break_point_info->break_point_objects() == *break_point_object;
   19391             :   }
   19392             :   // Multiple break points.
   19393             :   FixedArray* array = FixedArray::cast(break_point_info->break_point_objects());
   19394        1468 :   for (int i = 0; i < array->length(); i++) {
   19395         572 :     if (array->get(i) == *break_point_object) {
   19396             :       return true;
   19397             :     }
   19398             :   }
   19399             :   return false;
   19400             : }
   19401             : 
   19402             : 
   19403             : // Get the number of break points.
   19404       99917 : int BreakPointInfo::GetBreakPointCount() {
   19405             :   // No break point.
   19406       99917 :   if (break_point_objects()->IsUndefined(GetIsolate())) return 0;
   19407             :   // Single break point.
   19408       95473 :   if (!break_point_objects()->IsFixedArray()) return 1;
   19409             :   // Multiple break points.
   19410        1217 :   return FixedArray::cast(break_point_objects())->length();
   19411             : }
   19412             : 
   19413             : 
   19414             : // static
   19415      229130 : MaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor,
   19416             :                                 Handle<JSReceiver> new_target, double tv) {
   19417             :   Isolate* const isolate = constructor->GetIsolate();
   19418             :   Handle<JSObject> result;
   19419      458260 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
   19420             :                              JSObject::New(constructor, new_target), JSDate);
   19421      229130 :   if (-DateCache::kMaxTimeInMs <= tv && tv <= DateCache::kMaxTimeInMs) {
   19422      228372 :     tv = DoubleToInteger(tv) + 0.0;
   19423             :   } else {
   19424             :     tv = std::numeric_limits<double>::quiet_NaN();
   19425             :   }
   19426      229130 :   Handle<Object> value = isolate->factory()->NewNumber(tv);
   19427      458260 :   Handle<JSDate>::cast(result)->SetValue(*value, std::isnan(tv));
   19428             :   return Handle<JSDate>::cast(result);
   19429             : }
   19430             : 
   19431             : 
   19432             : // static
   19433    21999634 : double JSDate::CurrentTimeValue(Isolate* isolate) {
   19434    21999634 :   if (FLAG_log_timer_events || FLAG_prof_cpp) LOG(isolate, CurrentTimeEvent());
   19435             : 
   19436             :   // According to ECMA-262, section 15.9.1, page 117, the precision of
   19437             :   // the number in a Date object representing a particular instant in
   19438             :   // time is milliseconds. Therefore, we floor the result of getting
   19439             :   // the OS time.
   19440             :   return Floor(FLAG_verify_predictable
   19441             :                    ? isolate->heap()->MonotonicallyIncreasingTimeInMs()
   19442    43999268 :                    : base::OS::TimeCurrentMillis());
   19443             : }
   19444             : 
   19445             : 
   19446             : // static
   19447       17182 : Object* JSDate::GetField(Object* object, Smi* index) {
   19448             :   return JSDate::cast(object)->DoGetField(
   19449       17182 :       static_cast<FieldIndex>(index->value()));
   19450             : }
   19451             : 
   19452             : 
   19453       17182 : Object* JSDate::DoGetField(FieldIndex index) {
   19454             :   DCHECK(index != kDateValue);
   19455             : 
   19456       25625 :   DateCache* date_cache = GetIsolate()->date_cache();
   19457             : 
   19458       17182 :   if (index < kFirstUncachedField) {
   19459             :     Object* stamp = cache_stamp();
   19460       16886 :     if (stamp != date_cache->stamp() && stamp->IsSmi()) {
   19461             :       // Since the stamp is not NaN, the value is also not NaN.
   19462             :       int64_t local_time_ms =
   19463         583 :           date_cache->ToLocal(static_cast<int64_t>(value()->Number()));
   19464         583 :       SetCachedFields(local_time_ms, date_cache);
   19465             :     }
   19466        8443 :     switch (index) {
   19467        1390 :       case kYear: return year();
   19468         380 :       case kMonth: return month();
   19469         113 :       case kDay: return day();
   19470           0 :       case kWeekday: return weekday();
   19471        4887 :       case kHour: return hour();
   19472        1322 :       case kMinute: return min();
   19473         351 :       case kSecond: return sec();
   19474           0 :       default: UNREACHABLE();
   19475             :     }
   19476             :   }
   19477             : 
   19478        8739 :   if (index >= kFirstUTCField) {
   19479        8485 :     return GetUTCField(index, value()->Number(), date_cache);
   19480             :   }
   19481             : 
   19482             :   double time = value()->Number();
   19483         254 :   if (std::isnan(time)) return GetIsolate()->heap()->nan_value();
   19484             : 
   19485         169 :   int64_t local_time_ms = date_cache->ToLocal(static_cast<int64_t>(time));
   19486             :   int days = DateCache::DaysFromTime(local_time_ms);
   19487             : 
   19488         169 :   if (index == kDays) return Smi::FromInt(days);
   19489             : 
   19490             :   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
   19491         338 :   if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000);
   19492             :   DCHECK(index == kTimeInDay);
   19493           0 :   return Smi::FromInt(time_in_day_ms);
   19494             : }
   19495             : 
   19496             : 
   19497        8485 : Object* JSDate::GetUTCField(FieldIndex index,
   19498             :                             double value,
   19499             :                             DateCache* date_cache) {
   19500             :   DCHECK(index >= kFirstUTCField);
   19501             : 
   19502       16430 :   if (std::isnan(value)) return GetIsolate()->heap()->nan_value();
   19503             : 
   19504         540 :   int64_t time_ms = static_cast<int64_t>(value);
   19505             : 
   19506         540 :   if (index == kTimezoneOffset) {
   19507          29 :     return Smi::FromInt(date_cache->TimezoneOffset(time_ms));
   19508             :   }
   19509             : 
   19510             :   int days = DateCache::DaysFromTime(time_ms);
   19511             : 
   19512         525 :   if (index == kWeekdayUTC) return Smi::FromInt(date_cache->Weekday(days));
   19513             : 
   19514         497 :   if (index <= kDayUTC) {
   19515             :     int year, month, day;
   19516         185 :     date_cache->YearMonthDayFromDays(days, &year, &month, &day);
   19517         242 :     if (index == kYearUTC) return Smi::FromInt(year);
   19518         184 :     if (index == kMonthUTC) return Smi::FromInt(month);
   19519             :     DCHECK(index == kDayUTC);
   19520         144 :     return Smi::FromInt(day);
   19521             :   }
   19522             : 
   19523             :   int time_in_day_ms = DateCache::TimeInDay(time_ms, days);
   19524         312 :   switch (index) {
   19525         288 :     case kHourUTC: return Smi::FromInt(time_in_day_ms / (60 * 60 * 1000));
   19526         140 :     case kMinuteUTC: return Smi::FromInt((time_in_day_ms / (60 * 1000)) % 60);
   19527         112 :     case kSecondUTC: return Smi::FromInt((time_in_day_ms / 1000) % 60);
   19528          84 :     case kMillisecondUTC: return Smi::FromInt(time_in_day_ms % 1000);
   19529           0 :     case kDaysUTC: return Smi::FromInt(days);
   19530           0 :     case kTimeInDayUTC: return Smi::FromInt(time_in_day_ms);
   19531           0 :     default: UNREACHABLE();
   19532             :   }
   19533             : 
   19534             :   UNREACHABLE();
   19535             :   return NULL;
   19536             : }
   19537             : 
   19538             : 
   19539             : // static
   19540       17391 : Handle<Object> JSDate::SetValue(Handle<JSDate> date, double v) {
   19541             :   Isolate* const isolate = date->GetIsolate();
   19542       17391 :   Handle<Object> value = isolate->factory()->NewNumber(v);
   19543             :   bool value_is_nan = std::isnan(v);
   19544       34782 :   date->SetValue(*value, value_is_nan);
   19545       17391 :   return value;
   19546             : }
   19547             : 
   19548             : 
   19549      246521 : void JSDate::SetValue(Object* value, bool is_value_nan) {
   19550      246521 :   set_value(value);
   19551      246521 :   if (is_value_nan) {
   19552       17376 :     HeapNumber* nan = GetIsolate()->heap()->nan_value();
   19553       17376 :     set_cache_stamp(nan, SKIP_WRITE_BARRIER);
   19554       17376 :     set_year(nan, SKIP_WRITE_BARRIER);
   19555       17376 :     set_month(nan, SKIP_WRITE_BARRIER);
   19556       17376 :     set_day(nan, SKIP_WRITE_BARRIER);
   19557       17376 :     set_hour(nan, SKIP_WRITE_BARRIER);
   19558       17376 :     set_min(nan, SKIP_WRITE_BARRIER);
   19559       17376 :     set_sec(nan, SKIP_WRITE_BARRIER);
   19560       17376 :     set_weekday(nan, SKIP_WRITE_BARRIER);
   19561             :   } else {
   19562      229145 :     set_cache_stamp(Smi::FromInt(DateCache::kInvalidStamp), SKIP_WRITE_BARRIER);
   19563             :   }
   19564      246521 : }
   19565             : 
   19566             : 
   19567        1166 : void JSDate::SetCachedFields(int64_t local_time_ms, DateCache* date_cache) {
   19568             :   int days = DateCache::DaysFromTime(local_time_ms);
   19569             :   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
   19570             :   int year, month, day;
   19571         583 :   date_cache->YearMonthDayFromDays(days, &year, &month, &day);
   19572             :   int weekday = date_cache->Weekday(days);
   19573         583 :   int hour = time_in_day_ms / (60 * 60 * 1000);
   19574         583 :   int min = (time_in_day_ms / (60 * 1000)) % 60;
   19575         583 :   int sec = (time_in_day_ms / 1000) % 60;
   19576         583 :   set_cache_stamp(date_cache->stamp());
   19577        1166 :   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
   19578        1166 :   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
   19579        1166 :   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
   19580         583 :   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
   19581         583 :   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
   19582         583 :   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
   19583         583 :   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
   19584         583 : }
   19585             : 
   19586             : namespace {
   19587             : 
   19588             : Script* ScriptFromJSValue(Object* in) {
   19589             :   DCHECK(in->IsJSValue());
   19590             :   JSValue* jsvalue = JSValue::cast(in);
   19591             :   DCHECK(jsvalue->value()->IsScript());
   19592             :   return Script::cast(jsvalue->value());
   19593             : }
   19594             : 
   19595             : }  // namespace
   19596             : 
   19597       13971 : int JSMessageObject::GetLineNumber() const {
   19598       13971 :   if (start_position() == -1) return Message::kNoLineNumberInfo;
   19599             : 
   19600       13917 :   Handle<Script> the_script = handle(ScriptFromJSValue(script()));
   19601             : 
   19602             :   Script::PositionInfo info;
   19603             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   19604       13917 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   19605       13917 :                                offset_flag)) {
   19606             :     return Message::kNoLineNumberInfo;
   19607             :   }
   19608             : 
   19609       13917 :   return info.line + 1;
   19610             : }
   19611             : 
   19612       24943 : int JSMessageObject::GetColumnNumber() const {
   19613       24943 :   if (start_position() == -1) return -1;
   19614             : 
   19615       24889 :   Handle<Script> the_script = handle(ScriptFromJSValue(script()));
   19616             : 
   19617             :   Script::PositionInfo info;
   19618             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   19619       24889 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   19620       24889 :                                offset_flag)) {
   19621             :     return -1;
   19622             :   }
   19623             : 
   19624       24889 :   return info.column;  // Note: No '+1' in contrast to GetLineNumber.
   19625             : }
   19626             : 
   19627       11538 : Handle<String> JSMessageObject::GetSourceLine() const {
   19628             :   Handle<Script> the_script = handle(ScriptFromJSValue(script()));
   19629             : 
   19630             :   Isolate* isolate = the_script->GetIsolate();
   19631       11538 :   if (the_script->type() == Script::TYPE_WASM) {
   19632             :     return isolate->factory()->empty_string();
   19633             :   }
   19634             : 
   19635             :   Script::PositionInfo info;
   19636             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
   19637       11538 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
   19638       11538 :                                offset_flag)) {
   19639             :     return isolate->factory()->empty_string();
   19640             :   }
   19641             : 
   19642       11538 :   Handle<String> src = handle(String::cast(the_script->source()), isolate);
   19643       11538 :   return isolate->factory()->NewSubString(src, info.line_start, info.line_end);
   19644             : }
   19645             : 
   19646        3268 : void JSArrayBuffer::Neuter() {
   19647        3268 :   CHECK(is_neuterable());
   19648        3268 :   CHECK(is_external());
   19649             :   set_backing_store(NULL);
   19650        3268 :   set_byte_length(Smi::kZero);
   19651             :   set_was_neutered(true);
   19652             :   // Invalidate the neutering protector.
   19653             :   Isolate* const isolate = GetIsolate();
   19654        3268 :   if (isolate->IsArrayBufferNeuteringIntact()) {
   19655         228 :     isolate->InvalidateArrayBufferNeuteringProtector();
   19656             :   }
   19657        3268 : }
   19658             : 
   19659             : 
   19660      132532 : void JSArrayBuffer::Setup(Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
   19661             :                           bool is_external, void* data, size_t allocated_length,
   19662             :                           SharedFlag shared) {
   19663             :   DCHECK(array_buffer->GetEmbedderFieldCount() ==
   19664             :          v8::ArrayBuffer::kEmbedderFieldCount);
   19665      397596 :   for (int i = 0; i < v8::ArrayBuffer::kEmbedderFieldCount; i++) {
   19666             :     array_buffer->SetEmbedderField(i, Smi::kZero);
   19667             :   }
   19668             :   array_buffer->set_bit_field(0);
   19669             :   array_buffer->set_is_external(is_external);
   19670      132532 :   array_buffer->set_is_neuterable(shared == SharedFlag::kNotShared);
   19671      132532 :   array_buffer->set_is_shared(shared == SharedFlag::kShared);
   19672             : 
   19673             :   Handle<Object> byte_length =
   19674      132532 :       isolate->factory()->NewNumberFromSize(allocated_length);
   19675      132626 :   CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
   19676      132532 :   array_buffer->set_byte_length(*byte_length);
   19677             :   // Initialize backing store at last to avoid handling of |JSArrayBuffers| that
   19678             :   // are currently being constructed in the |ArrayBufferTracker|. The
   19679             :   // registration method below handles the case of registering a buffer that has
   19680             :   // already been promoted.
   19681             :   array_buffer->set_backing_store(data);
   19682             : 
   19683      132532 :   if (data && !is_external) {
   19684      114744 :     isolate->heap()->RegisterNewArrayBuffer(*array_buffer);
   19685             :   }
   19686      132532 : }
   19687             : 
   19688             : namespace {
   19689             : 
   19690             : inline int ConvertToMb(size_t size) {
   19691      103542 :   return static_cast<int>(size / static_cast<size_t>(MB));
   19692             : }
   19693             : 
   19694             : }  // namespace
   19695             : 
   19696      120119 : bool JSArrayBuffer::SetupAllocatingData(Handle<JSArrayBuffer> array_buffer,
   19697      327204 :                                         Isolate* isolate,
   19698             :                                         size_t allocated_length,
   19699             :                                         bool initialize, SharedFlag shared) {
   19700             :   void* data;
   19701      120119 :   CHECK(isolate->array_buffer_allocator() != NULL);
   19702             :   // Prevent creating array buffers when serializing.
   19703             :   DCHECK(!isolate->serializer_enabled());
   19704      120119 :   if (allocated_length != 0) {
   19705             :     isolate->counters()->array_buffer_big_allocations()->AddSample(
   19706      103542 :         ConvertToMb(allocated_length));
   19707      103542 :     if (initialize) {
   19708      102408 :       data = isolate->array_buffer_allocator()->Allocate(allocated_length);
   19709             :     } else {
   19710             :       data = isolate->array_buffer_allocator()->AllocateUninitialized(
   19711        1134 :           allocated_length);
   19712             :     }
   19713      103542 :     if (data == NULL) {
   19714             :       isolate->counters()->array_buffer_new_size_failures()->AddSample(
   19715           1 :           ConvertToMb(allocated_length));
   19716           1 :       return false;
   19717             :     }
   19718             :   } else {
   19719             :     data = NULL;
   19720             :   }
   19721             : 
   19722             :   JSArrayBuffer::Setup(array_buffer, isolate, false, data, allocated_length,
   19723      120118 :                        shared);
   19724      120118 :   return true;
   19725             : }
   19726             : 
   19727             : 
   19728       15430 : Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer(
   19729             :     Handle<JSTypedArray> typed_array) {
   19730             : 
   19731             :   Handle<Map> map(typed_array->map());
   19732       15430 :   Isolate* isolate = typed_array->GetIsolate();
   19733             : 
   19734             :   DCHECK(IsFixedTypedArrayElementsKind(map->elements_kind()));
   19735             : 
   19736             :   Handle<FixedTypedArrayBase> fixed_typed_array(
   19737             :       FixedTypedArrayBase::cast(typed_array->elements()));
   19738             : 
   19739             :   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(typed_array->buffer()),
   19740             :                                isolate);
   19741             :   void* backing_store =
   19742             :       isolate->array_buffer_allocator()->AllocateUninitialized(
   19743       30860 :           fixed_typed_array->DataSize());
   19744             :   buffer->set_is_external(false);
   19745             :   DCHECK(buffer->byte_length()->IsSmi() ||
   19746             :          buffer->byte_length()->IsHeapNumber());
   19747             :   DCHECK(NumberToInt32(buffer->byte_length()) == fixed_typed_array->DataSize());
   19748             :   // Initialize backing store at last to avoid handling of |JSArrayBuffers| that
   19749             :   // are currently being constructed in the |ArrayBufferTracker|. The
   19750             :   // registration method below handles the case of registering a buffer that has
   19751             :   // already been promoted.
   19752             :   buffer->set_backing_store(backing_store);
   19753       15430 :   isolate->heap()->RegisterNewArrayBuffer(*buffer);
   19754             :   memcpy(buffer->backing_store(),
   19755             :          fixed_typed_array->DataPtr(),
   19756       15430 :          fixed_typed_array->DataSize());
   19757             :   Handle<FixedTypedArrayBase> new_elements =
   19758             :       isolate->factory()->NewFixedTypedArrayWithExternalPointer(
   19759             :           fixed_typed_array->length(), typed_array->type(),
   19760       30860 :           static_cast<uint8_t*>(buffer->backing_store()));
   19761             : 
   19762       15430 :   typed_array->set_elements(*new_elements);
   19763             : 
   19764       15430 :   return buffer;
   19765             : }
   19766             : 
   19767             : 
   19768    37902625 : Handle<JSArrayBuffer> JSTypedArray::GetBuffer() {
   19769             :   Handle<JSArrayBuffer> array_buffer(JSArrayBuffer::cast(buffer()),
   19770             :                                      GetIsolate());
   19771    75805228 :   if (array_buffer->was_neutered() ||
   19772             :       array_buffer->backing_store() != nullptr) {
   19773    37887204 :     return array_buffer;
   19774             :   }
   19775             :   Handle<JSTypedArray> self(this);
   19776       15430 :   return MaterializeArrayBuffer(self);
   19777             : }
   19778             : 
   19779       22497 : Handle<PropertyCell> PropertyCell::InvalidateEntry(
   19780             :     Handle<GlobalDictionary> dictionary, int entry) {
   19781             :   Isolate* isolate = dictionary->GetIsolate();
   19782             :   // Swap with a copy.
   19783             :   DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
   19784       22497 :   Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
   19785       22497 :   Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell();
   19786       22497 :   new_cell->set_value(cell->value());
   19787             :   dictionary->ValueAtPut(entry, *new_cell);
   19788             :   bool is_the_hole = cell->value()->IsTheHole(isolate);
   19789             :   // Cell is officially mutable henceforth.
   19790             :   PropertyDetails details = cell->property_details();
   19791             :   details = details.set_cell_type(is_the_hole ? PropertyCellType::kUninitialized
   19792       22497 :                                               : PropertyCellType::kMutable);
   19793             :   new_cell->set_property_details(details);
   19794             :   // Old cell is ready for invalidation.
   19795       22497 :   if (is_the_hole) {
   19796       19590 :     cell->set_value(isolate->heap()->undefined_value());
   19797             :   } else {
   19798       25404 :     cell->set_value(isolate->heap()->the_hole_value());
   19799             :   }
   19800             :   details = details.set_cell_type(PropertyCellType::kInvalidated);
   19801             :   cell->set_property_details(details);
   19802             :   cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19803       22497 :       isolate, DependentCode::kPropertyCellChangedGroup);
   19804       22497 :   return new_cell;
   19805             : }
   19806             : 
   19807             : 
   19808       13011 : PropertyCellConstantType PropertyCell::GetConstantType() {
   19809       13011 :   if (value()->IsSmi()) return PropertyCellConstantType::kSmi;
   19810        2763 :   return PropertyCellConstantType::kStableMap;
   19811             : }
   19812             : 
   19813             : 
   19814     1272659 : static bool RemainsConstantType(Handle<PropertyCell> cell,
   19815             :                                 Handle<Object> value) {
   19816             :   // TODO(dcarney): double->smi and smi->double transition from kConstant
   19817     2451524 :   if (cell->value()->IsSmi() && value->IsSmi()) {
   19818             :     return true;
   19819      190038 :   } else if (cell->value()->IsHeapObject() && value->IsHeapObject()) {
   19820             :     return HeapObject::cast(cell->value())->map() ==
   19821      172254 :                HeapObject::cast(*value)->map() &&
   19822       92754 :            HeapObject::cast(*value)->map()->is_stable();
   19823             :   }
   19824             :   return false;
   19825             : }
   19826             : 
   19827             : 
   19828    11911784 : PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell,
   19829             :                                            Handle<Object> value,
   19830             :                                            PropertyDetails details) {
   19831             :   PropertyCellType type = details.cell_type();
   19832             :   Isolate* isolate = cell->GetIsolate();
   19833             :   DCHECK(!value->IsTheHole(isolate));
   19834    11911784 :   if (cell->value()->IsTheHole(isolate)) {
   19835     8835027 :     switch (type) {
   19836             :       // Only allow a cell to transition once into constant state.
   19837             :       case PropertyCellType::kUninitialized:
   19838     8835029 :         if (value->IsUndefined(isolate)) return PropertyCellType::kUndefined;
   19839     7133039 :         return PropertyCellType::kConstant;
   19840             :       case PropertyCellType::kInvalidated:
   19841             :         return PropertyCellType::kMutable;
   19842             :       default:
   19843           0 :         UNREACHABLE();
   19844             :         return PropertyCellType::kMutable;
   19845             :     }
   19846             :   }
   19847     3076757 :   switch (type) {
   19848             :     case PropertyCellType::kUndefined:
   19849             :       return PropertyCellType::kConstant;
   19850             :     case PropertyCellType::kConstant:
   19851      102558 :       if (*value == cell->value()) return PropertyCellType::kConstant;
   19852             :     // Fall through.
   19853             :     case PropertyCellType::kConstantType:
   19854     1272659 :       if (RemainsConstantType(cell, value)) {
   19855             :         return PropertyCellType::kConstantType;
   19856             :       }
   19857             :     // Fall through.
   19858             :     case PropertyCellType::kMutable:
   19859             :       return PropertyCellType::kMutable;
   19860             :   }
   19861           0 :   UNREACHABLE();
   19862             :   return PropertyCellType::kMutable;
   19863             : }
   19864             : 
   19865     3084107 : Handle<PropertyCell> PropertyCell::PrepareForValue(
   19866             :     Handle<GlobalDictionary> dictionary, int entry, Handle<Object> value,
   19867             :     PropertyDetails details) {
   19868             :   Isolate* isolate = dictionary->GetIsolate();
   19869             :   DCHECK(!value->IsTheHole(isolate));
   19870             :   DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
   19871     3084107 :   Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
   19872             :   const PropertyDetails original_details = cell->property_details();
   19873             :   // Data accesses could be cached in ics or optimized code.
   19874             :   bool invalidate =
   19875     6167237 :       original_details.kind() == kData && details.kind() == kAccessor;
   19876             :   int index = original_details.dictionary_index();
   19877             :   PropertyCellType old_type = original_details.cell_type();
   19878             :   // Preserve the enumeration index unless the property was deleted or never
   19879             :   // initialized.
   19880     3084107 :   if (cell->value()->IsTheHole(isolate)) {
   19881             :     index = dictionary->NextEnumerationIndex();
   19882        7350 :     dictionary->SetNextEnumerationIndex(index + 1);
   19883             :   }
   19884             :   DCHECK(index > 0);
   19885             :   details = details.set_index(index);
   19886             : 
   19887     3084107 :   PropertyCellType new_type = UpdatedType(cell, value, original_details);
   19888     3084107 :   if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry);
   19889             : 
   19890             :   // Install new property details.
   19891             :   details = details.set_cell_type(new_type);
   19892             :   cell->set_property_details(details);
   19893             : 
   19894             :   // Deopt when transitioning from a constant type.
   19895     4503113 :   if (!invalidate && (old_type != new_type ||
   19896             :                       original_details.IsReadOnly() != details.IsReadOnly())) {
   19897             :     cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19898     1668804 :         isolate, DependentCode::kPropertyCellChangedGroup);
   19899             :   }
   19900     3084107 :   return cell;
   19901             : }
   19902             : 
   19903             : 
   19904             : // static
   19905        1007 : void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell,
   19906             :                                             Handle<Object> new_value) {
   19907        1007 :   if (cell->value() != *new_value) {
   19908        1007 :     cell->set_value(*new_value);
   19909             :     Isolate* isolate = cell->GetIsolate();
   19910             :     cell->dependent_code()->DeoptimizeDependentCodeGroup(
   19911        1007 :         isolate, DependentCode::kPropertyCellChangedGroup);
   19912             :   }
   19913        1007 : }
   19914             : 
   19915          42 : int JSGeneratorObject::source_position() const {
   19916          42 :   CHECK(is_suspended());
   19917             :   DCHECK(function()->shared()->HasBytecodeArray());
   19918             :   DCHECK(!function()->shared()->HasBaselineCode());
   19919             : 
   19920             :   int code_offset;
   19921             :   const JSAsyncGeneratorObject* async =
   19922          42 :       IsJSAsyncGeneratorObject() ? JSAsyncGeneratorObject::cast(this) : nullptr;
   19923          42 :   if (async != nullptr && async->awaited_promise()->IsJSPromise()) {
   19924             :     code_offset = Smi::cast(async->await_input_or_debug_pos())->value();
   19925             :   } else {
   19926             :     code_offset = Smi::cast(input_or_debug_pos())->value();
   19927             :   }
   19928             : 
   19929             :   // The stored bytecode offset is relative to a different base than what
   19930             :   // is used in the source position table, hence the subtraction.
   19931          42 :   code_offset -= BytecodeArray::kHeaderSize - kHeapObjectTag;
   19932             :   AbstractCode* code =
   19933             :       AbstractCode::cast(function()->shared()->bytecode_array());
   19934          42 :   return code->SourcePosition(code_offset);
   19935             : }
   19936             : 
   19937             : // static
   19938        5978 : AccessCheckInfo* AccessCheckInfo::Get(Isolate* isolate,
   19939             :                                       Handle<JSObject> receiver) {
   19940             :   DisallowHeapAllocation no_gc;
   19941             :   DCHECK(receiver->map()->is_access_check_needed());
   19942        5978 :   Object* maybe_constructor = receiver->map()->GetConstructor();
   19943        5978 :   if (maybe_constructor->IsFunctionTemplateInfo()) {
   19944             :     Object* data_obj =
   19945             :         FunctionTemplateInfo::cast(maybe_constructor)->access_check_info();
   19946         203 :     if (data_obj->IsUndefined(isolate)) return nullptr;
   19947         203 :     return AccessCheckInfo::cast(data_obj);
   19948             :   }
   19949             :   // Might happen for a detached context.
   19950        5775 :   if (!maybe_constructor->IsJSFunction()) return nullptr;
   19951             :   JSFunction* constructor = JSFunction::cast(maybe_constructor);
   19952             :   // Might happen for the debug context.
   19953        5743 :   if (!constructor->shared()->IsApiFunction()) return nullptr;
   19954             : 
   19955             :   Object* data_obj =
   19956             :       constructor->shared()->get_api_func_data()->access_check_info();
   19957        5206 :   if (data_obj->IsUndefined(isolate)) return nullptr;
   19958             : 
   19959        4373 :   return AccessCheckInfo::cast(data_obj);
   19960             : }
   19961             : 
   19962        6145 : bool JSReceiver::HasProxyInPrototype(Isolate* isolate) {
   19963       25300 :   for (PrototypeIterator iter(isolate, this, kStartAtReceiver,
   19964             :                               PrototypeIterator::END_AT_NULL);
   19965       19155 :        !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) {
   19966       38396 :     if (iter.GetCurrent<Object>()->IsJSProxy()) return true;
   19967             :   }
   19968        6102 :   return false;
   19969             : }
   19970             : 
   19971         853 : MaybeHandle<Object> JSModuleNamespace::GetExport(Handle<String> name) {
   19972             :   Isolate* isolate = name->GetIsolate();
   19973             : 
   19974        1706 :   Handle<Object> object(module()->exports()->Lookup(name), isolate);
   19975         853 :   if (object->IsTheHole(isolate)) {
   19976             :     return isolate->factory()->undefined_value();
   19977             :   }
   19978             : 
   19979             :   Handle<Object> value(Handle<Cell>::cast(object)->value(), isolate);
   19980         853 :   if (value->IsTheHole(isolate)) {
   19981         210 :     THROW_NEW_ERROR(
   19982             :         isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object);
   19983             :   }
   19984             : 
   19985             :   return value;
   19986             : }
   19987             : 
   19988             : namespace {
   19989             : 
   19990             : struct ModuleHandleHash {
   19991             :   V8_INLINE size_t operator()(Handle<Module> module) const {
   19992         732 :     return module->hash();
   19993             :   }
   19994             : };
   19995             : 
   19996             : struct ModuleHandleEqual {
   19997             :   V8_INLINE bool operator()(Handle<Module> lhs, Handle<Module> rhs) const {
   19998             :     return *lhs == *rhs;
   19999             :   }
   20000             : };
   20001             : 
   20002             : struct StringHandleHash {
   20003             :   V8_INLINE size_t operator()(Handle<String> string) const {
   20004         552 :     return string->Hash();
   20005             :   }
   20006             : };
   20007             : 
   20008             : struct StringHandleEqual {
   20009             :   V8_INLINE bool operator()(Handle<String> lhs, Handle<String> rhs) const {
   20010          45 :     return lhs->Equals(*rhs);
   20011             :   }
   20012             : };
   20013             : 
   20014             : class UnorderedStringSet
   20015             :     : public std::unordered_set<Handle<String>, StringHandleHash,
   20016             :                                 StringHandleEqual,
   20017             :                                 ZoneAllocator<Handle<String>>> {
   20018             :  public:
   20019         314 :   explicit UnorderedStringSet(Zone* zone)
   20020             :       : std::unordered_set<Handle<String>, StringHandleHash, StringHandleEqual,
   20021             :                            ZoneAllocator<Handle<String>>>(
   20022             :             2 /* bucket count */, StringHandleHash(), StringHandleEqual(),
   20023         314 :             ZoneAllocator<Handle<String>>(zone)) {}
   20024             : };
   20025             : 
   20026             : class UnorderedModuleSet
   20027             :     : public std::unordered_set<Handle<Module>, ModuleHandleHash,
   20028             :                                 ModuleHandleEqual,
   20029             :                                 ZoneAllocator<Handle<Module>>> {
   20030             :  public:
   20031         300 :   explicit UnorderedModuleSet(Zone* zone)
   20032             :       : std::unordered_set<Handle<Module>, ModuleHandleHash, ModuleHandleEqual,
   20033             :                            ZoneAllocator<Handle<Module>>>(
   20034             :             2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(),
   20035         300 :             ZoneAllocator<Handle<Module>>(zone)) {}
   20036             : };
   20037             : 
   20038             : class UnorderedStringMap
   20039             :     : public std::unordered_map<
   20040             :           Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual,
   20041             :           ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>> {
   20042             :  public:
   20043         388 :   explicit UnorderedStringMap(Zone* zone)
   20044             :       : std::unordered_map<
   20045             :             Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual,
   20046             :             ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>>(
   20047             :             2 /* bucket count */, StringHandleHash(), StringHandleEqual(),
   20048             :             ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>(
   20049         388 :                 zone)) {}
   20050             : };
   20051             : 
   20052             : }  // anonymous namespace
   20053             : 
   20054             : class Module::ResolveSet
   20055             :     : public std::unordered_map<
   20056             :           Handle<Module>, UnorderedStringSet*, ModuleHandleHash,
   20057             :           ModuleHandleEqual,
   20058             :           ZoneAllocator<std::pair<const Handle<Module>, UnorderedStringSet*>>> {
   20059             :  public:
   20060        1077 :   explicit ResolveSet(Zone* zone)
   20061             :       : std::unordered_map<Handle<Module>, UnorderedStringSet*,
   20062             :                            ModuleHandleHash, ModuleHandleEqual,
   20063             :                            ZoneAllocator<std::pair<const Handle<Module>,
   20064             :                                                    UnorderedStringSet*>>>(
   20065             :             2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(),
   20066             :             ZoneAllocator<std::pair<const Handle<Module>, UnorderedStringSet*>>(
   20067             :                 zone)),
   20068        1077 :         zone_(zone) {}
   20069             : 
   20070             :   Zone* zone() const { return zone_; }
   20071             : 
   20072             :  private:
   20073             :   Zone* zone_;
   20074             : };
   20075             : 
   20076             : namespace {
   20077             : 
   20078             : int ExportIndex(int cell_index) {
   20079             :   DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
   20080             :             ModuleDescriptor::kExport);
   20081        2060 :   return cell_index - 1;
   20082             : }
   20083             : 
   20084             : int ImportIndex(int cell_index) {
   20085             :   DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
   20086             :             ModuleDescriptor::kImport);
   20087         991 :   return -cell_index - 1;
   20088             : }
   20089             : 
   20090             : }  // anonymous namespace
   20091             : 
   20092         180 : void Module::CreateIndirectExport(Handle<Module> module, Handle<String> name,
   20093             :                                   Handle<ModuleInfoEntry> entry) {
   20094             :   Isolate* isolate = module->GetIsolate();
   20095             :   Handle<ObjectHashTable> exports(module->exports(), isolate);
   20096             :   DCHECK(exports->Lookup(name)->IsTheHole(isolate));
   20097         180 :   exports = ObjectHashTable::Put(exports, name, entry);
   20098         180 :   module->set_exports(*exports);
   20099         180 : }
   20100             : 
   20101        1976 : void Module::CreateExport(Handle<Module> module, int cell_index,
   20102             :                           Handle<FixedArray> names) {
   20103             :   DCHECK_LT(0, names->length());
   20104             :   Isolate* isolate = module->GetIsolate();
   20105             : 
   20106             :   Handle<Cell> cell =
   20107        1976 :       isolate->factory()->NewCell(isolate->factory()->undefined_value());
   20108        1976 :   module->regular_exports()->set(ExportIndex(cell_index), *cell);
   20109             : 
   20110             :   Handle<ObjectHashTable> exports(module->exports(), isolate);
   20111        4147 :   for (int i = 0, n = names->length(); i < n; ++i) {
   20112             :     Handle<String> name(String::cast(names->get(i)), isolate);
   20113             :     DCHECK(exports->Lookup(name)->IsTheHole(isolate));
   20114        2171 :     exports = ObjectHashTable::Put(exports, name, cell);
   20115             :   }
   20116        1976 :   module->set_exports(*exports);
   20117        1976 : }
   20118             : 
   20119         192 : Handle<Object> Module::LoadVariable(Handle<Module> module, int cell_index) {
   20120             :   Isolate* isolate = module->GetIsolate();
   20121             :   Handle<Object> object;
   20122         192 :   switch (ModuleDescriptor::GetCellIndexKind(cell_index)) {
   20123             :     case ModuleDescriptor::kImport:
   20124             :       object = handle(module->regular_imports()->get(ImportIndex(cell_index)),
   20125             :                       isolate);
   20126         108 :       break;
   20127             :     case ModuleDescriptor::kExport:
   20128             :       object = handle(module->regular_exports()->get(ExportIndex(cell_index)),
   20129             :                       isolate);
   20130          84 :       break;
   20131             :     case ModuleDescriptor::kInvalid:
   20132           0 :       UNREACHABLE();
   20133             :       break;
   20134             :   }
   20135         192 :   return handle(Handle<Cell>::cast(object)->value(), isolate);
   20136             : }
   20137             : 
   20138           0 : void Module::StoreVariable(Handle<Module> module, int cell_index,
   20139             :                            Handle<Object> value) {
   20140             :   Isolate* isolate = module->GetIsolate();
   20141             :   DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
   20142             :             ModuleDescriptor::kExport);
   20143             :   Handle<Object> object(module->regular_exports()->get(ExportIndex(cell_index)),
   20144             :                         isolate);
   20145           0 :   Handle<Cell>::cast(object)->set_value(*value);
   20146           0 : }
   20147             : 
   20148        1227 : MaybeHandle<Cell> Module::ResolveImport(Handle<Module> module,
   20149             :                                         Handle<String> name, int module_request,
   20150             :                                         MessageLocation loc, bool must_resolve,
   20151             :                                         Module::ResolveSet* resolve_set) {
   20152             :   Isolate* isolate = module->GetIsolate();
   20153             :   Handle<Module> requested_module(
   20154             :       Module::cast(module->requested_modules()->get(module_request)), isolate);
   20155             :   return Module::ResolveExport(requested_module, name, loc, must_resolve,
   20156        1227 :                                resolve_set);
   20157             : }
   20158             : 
   20159        1407 : MaybeHandle<Cell> Module::ResolveExport(Handle<Module> module,
   20160             :                                         Handle<String> name,
   20161             :                                         MessageLocation loc, bool must_resolve,
   20162         314 :                                         Module::ResolveSet* resolve_set) {
   20163             :   DCHECK_EQ(module->status(), kPrepared);
   20164             :   Isolate* isolate = module->GetIsolate();
   20165        2814 :   Handle<Object> object(module->exports()->Lookup(name), isolate);
   20166        1407 :   if (object->IsCell()) {
   20167             :     // Already resolved (e.g. because it's a local export).
   20168             :     return Handle<Cell>::cast(object);
   20169             :   }
   20170             : 
   20171             :   // Check for cycle before recursing.
   20172             :   {
   20173             :     // Attempt insertion with a null string set.
   20174         329 :     auto result = resolve_set->insert({module, nullptr});
   20175             :     UnorderedStringSet*& name_set = result.first->second;
   20176         329 :     if (result.second) {
   20177             :       // |module| wasn't in the map previously, so allocate a new name set.
   20178             :       Zone* zone = resolve_set->zone();
   20179             :       name_set =
   20180         314 :           new (zone->New(sizeof(UnorderedStringSet))) UnorderedStringSet(zone);
   20181          30 :     } else if (name_set->count(name)) {
   20182             :       // Cycle detected.
   20183          15 :       if (must_resolve) {
   20184             :         return isolate->Throw<Cell>(
   20185             :             isolate->factory()->NewSyntaxError(
   20186             :                 MessageTemplate::kCyclicModuleDependency, name),
   20187           0 :             &loc);
   20188             :       }
   20189             :       return MaybeHandle<Cell>();
   20190             :     }
   20191         314 :     name_set->insert(name);
   20192             :   }
   20193             : 
   20194         314 :   if (object->IsModuleInfoEntry()) {
   20195             :     // Not yet resolved indirect export.
   20196             :     Handle<ModuleInfoEntry> entry = Handle<ModuleInfoEntry>::cast(object);
   20197             :     Handle<String> import_name(String::cast(entry->import_name()), isolate);
   20198             :     Handle<Script> script(
   20199             :         Script::cast(JSFunction::cast(module->code())->shared()->script()),
   20200             :         isolate);
   20201         180 :     MessageLocation new_loc(script, entry->beg_pos(), entry->end_pos());
   20202             : 
   20203             :     Handle<Cell> cell;
   20204         180 :     if (!ResolveImport(module, import_name, entry->module_request(), new_loc,
   20205             :                        true, resolve_set)
   20206         360 :              .ToHandle(&cell)) {
   20207             :       DCHECK(isolate->has_pending_exception());
   20208             :       return MaybeHandle<Cell>();
   20209             :     }
   20210             : 
   20211             :     // The export table may have changed but the entry in question should be
   20212             :     // unchanged.
   20213             :     Handle<ObjectHashTable> exports(module->exports(), isolate);
   20214             :     DCHECK(exports->Lookup(name)->IsModuleInfoEntry());
   20215             : 
   20216         180 :     exports = ObjectHashTable::Put(exports, name, cell);
   20217         180 :     module->set_exports(*exports);
   20218             :     return cell;
   20219             :   }
   20220             : 
   20221             :   DCHECK(object->IsTheHole(isolate));
   20222             :   return Module::ResolveExportUsingStarExports(module, name, loc, must_resolve,
   20223         134 :                                                resolve_set);
   20224             : }
   20225             : 
   20226         134 : MaybeHandle<Cell> Module::ResolveExportUsingStarExports(
   20227             :     Handle<Module> module, Handle<String> name, MessageLocation loc,
   20228             :     bool must_resolve, Module::ResolveSet* resolve_set) {
   20229             :   Isolate* isolate = module->GetIsolate();
   20230         268 :   if (!name->Equals(isolate->heap()->default_string())) {
   20231             :     // Go through all star exports looking for the given name.  If multiple star
   20232             :     // exports provide the name, make sure they all map it to the same cell.
   20233             :     Handle<Cell> unique_cell;
   20234             :     Handle<FixedArray> special_exports(module->info()->special_exports(),
   20235         120 :                                        isolate);
   20236         360 :     for (int i = 0, n = special_exports->length(); i < n; ++i) {
   20237             :       i::Handle<i::ModuleInfoEntry> entry(
   20238             :           i::ModuleInfoEntry::cast(special_exports->get(i)), isolate);
   20239         240 :       if (!entry->export_name()->IsUndefined(isolate)) {
   20240          90 :         continue;  // Indirect export.
   20241             :       }
   20242             : 
   20243             :       Handle<Script> script(
   20244             :           Script::cast(JSFunction::cast(module->code())->shared()->script()),
   20245             :           isolate);
   20246         150 :       MessageLocation new_loc(script, entry->beg_pos(), entry->end_pos());
   20247             : 
   20248             :       Handle<Cell> cell;
   20249         150 :       if (ResolveImport(module, name, entry->module_request(), new_loc, false,
   20250             :                         resolve_set)
   20251         300 :               .ToHandle(&cell)) {
   20252          90 :         if (unique_cell.is_null()) unique_cell = cell;
   20253          90 :         if (*unique_cell != *cell) {
   20254             :           return isolate->Throw<Cell>(
   20255             :               isolate->factory()->NewSyntaxError(
   20256             :                   MessageTemplate::kAmbiguousExport, name),
   20257           0 :               &loc);
   20258             :         }
   20259          60 :       } else if (isolate->has_pending_exception()) {
   20260             :         return MaybeHandle<Cell>();
   20261             :       }
   20262             :     }
   20263             : 
   20264         120 :     if (!unique_cell.is_null()) {
   20265             :       // Found a unique star export for this name.
   20266             :       Handle<ObjectHashTable> exports(module->exports(), isolate);
   20267             :       DCHECK(exports->Lookup(name)->IsTheHole(isolate));
   20268          75 :       exports = ObjectHashTable::Put(exports, name, unique_cell);
   20269          75 :       module->set_exports(*exports);
   20270             :       return unique_cell;
   20271             :     }
   20272             :   }
   20273             : 
   20274             :   // Unresolvable.
   20275          59 :   if (must_resolve) {
   20276             :     return isolate->Throw<Cell>(isolate->factory()->NewSyntaxError(
   20277             :                                     MessageTemplate::kUnresolvableExport, name),
   20278          28 :                                 &loc);
   20279             :   }
   20280             :   return MaybeHandle<Cell>();
   20281             : }
   20282             : 
   20283        1216 : bool Module::Instantiate(Handle<Module> module, v8::Local<v8::Context> context,
   20284             :                          v8::Module::ResolveCallback callback) {
   20285        2418 :   return PrepareInstantiate(module, context, callback) &&
   20286        2418 :          FinishInstantiate(module, context);
   20287             : }
   20288             : 
   20289        2362 : bool Module::PrepareInstantiate(Handle<Module> module,
   20290             :                                 v8::Local<v8::Context> context,
   20291             :                                 v8::Module::ResolveCallback callback) {
   20292        2362 :   if (module->status() == kPrepared) return true;
   20293             : 
   20294             :   // Obtain requested modules.
   20295             :   Isolate* isolate = module->GetIsolate();
   20296        1917 :   Handle<ModuleInfo> module_info(module->info(), isolate);
   20297             :   Handle<FixedArray> module_requests(module_info->module_requests(), isolate);
   20298             :   Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
   20299        3070 :   for (int i = 0, length = module_requests->length(); i < length; ++i) {
   20300             :     Handle<String> specifier(String::cast(module_requests->get(i)), isolate);
   20301             :     v8::Local<v8::Module> api_requested_module;
   20302        1167 :     if (!callback(context, v8::Utils::ToLocal(specifier),
   20303             :                   v8::Utils::ToLocal(module))
   20304        2334 :              .ToLocal(&api_requested_module)) {
   20305          14 :       isolate->PromoteScheduledException();
   20306             :       return false;
   20307             :     }
   20308             :     Handle<Module> requested_module = Utils::OpenHandle(*api_requested_module);
   20309        1153 :     requested_modules->set(i, *requested_module);
   20310             :   }
   20311             : 
   20312             :   // Recurse.
   20313             :   module->set_status(kPrepared);
   20314        3049 :   for (int i = 0, length = requested_modules->length(); i < length; ++i) {
   20315             :     Handle<Module> requested_module(Module::cast(requested_modules->get(i)),
   20316             :                                     isolate);
   20317        1146 :     if (!PrepareInstantiate(requested_module, context, callback)) return false;
   20318             :   }
   20319             : 
   20320             :   // Set up local exports.
   20321             :   // TODO(neis): Create regular_exports array here instead of in factory method?
   20322        3879 :   for (int i = 0, n = module_info->RegularExportCount(); i < n; ++i) {
   20323        1976 :     int cell_index = module_info->RegularExportCellIndex(i);
   20324             :     Handle<FixedArray> export_names(module_info->RegularExportExportNames(i),
   20325        1976 :                                     isolate);
   20326        1976 :     CreateExport(module, cell_index, export_names);
   20327             :   }
   20328             : 
   20329             :   // Partially set up indirect exports.
   20330             :   // For each indirect export, we create the appropriate slot in the export
   20331             :   // table and store its ModuleInfoEntry there.  When we later find the correct
   20332             :   // Cell in the module that actually provides the value, we replace the
   20333             :   // ModuleInfoEntry by that Cell (see ResolveExport).
   20334             :   Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
   20335        2290 :   for (int i = 0, n = special_exports->length(); i < n; ++i) {
   20336             :     Handle<ModuleInfoEntry> entry(
   20337             :         ModuleInfoEntry::cast(special_exports->get(i)), isolate);
   20338             :     Handle<Object> export_name(entry->export_name(), isolate);
   20339         387 :     if (export_name->IsUndefined(isolate)) continue;  // Star export.
   20340         180 :     CreateIndirectExport(module, Handle<String>::cast(export_name), entry);
   20341             :   }
   20342             : 
   20343             :   DCHECK_EQ(module->status(), kPrepared);
   20344             :   DCHECK(!module->instantiated());
   20345             :   return true;
   20346             : }
   20347             : 
   20348        2348 : bool Module::FinishInstantiate(Handle<Module> module,
   20349             :                                v8::Local<v8::Context> context) {
   20350             :   DCHECK_EQ(module->status(), kPrepared);
   20351        2348 :   if (module->instantiated()) return true;
   20352             : 
   20353             :   // Instantiate SharedFunctionInfo and mark module as instantiated for
   20354             :   // the recursion.
   20355        1903 :   Isolate* isolate = module->GetIsolate();
   20356             :   Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(module->code()),
   20357             :                                     isolate);
   20358             :   Handle<JSFunction> function =
   20359             :       isolate->factory()->NewFunctionFromSharedFunctionInfo(
   20360             :           shared,
   20361        1903 :           handle(Utils::OpenHandle(*context)->native_context(), isolate));
   20362        1903 :   module->set_code(*function);
   20363             :   DCHECK(module->instantiated());
   20364             : 
   20365             :   // Recurse.
   20366             :   Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
   20367        3049 :   for (int i = 0, length = requested_modules->length(); i < length; ++i) {
   20368             :     Handle<Module> requested_module(Module::cast(requested_modules->get(i)),
   20369             :                                     isolate);
   20370        1146 :     if (!FinishInstantiate(requested_module, context)) return false;
   20371             :   }
   20372             : 
   20373        1903 :   Zone zone(isolate->allocator(), ZONE_NAME);
   20374             : 
   20375             :   // Resolve imports.
   20376             :   Handle<ModuleInfo> module_info(shared->scope_info()->ModuleDescriptorInfo(),
   20377        1903 :                                  isolate);
   20378             :   Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
   20379        2786 :   for (int i = 0, n = regular_imports->length(); i < n; ++i) {
   20380             :     Handle<ModuleInfoEntry> entry(
   20381             :         ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
   20382             :     Handle<String> name(String::cast(entry->import_name()), isolate);
   20383             :     Handle<Script> script(
   20384             :         Script::cast(JSFunction::cast(module->code())->shared()->script()),
   20385             :         isolate);
   20386         897 :     MessageLocation loc(script, entry->beg_pos(), entry->end_pos());
   20387         897 :     ResolveSet resolve_set(&zone);
   20388             :     Handle<Cell> cell;
   20389         897 :     if (!ResolveImport(module, name, entry->module_request(), loc, true,
   20390             :                        &resolve_set)
   20391        1794 :              .ToHandle(&cell)) {
   20392             :       return false;
   20393             :     }
   20394         883 :     module->regular_imports()->set(ImportIndex(entry->cell_index()), *cell);
   20395             :   }
   20396             : 
   20397             :   // Resolve indirect exports.
   20398             :   Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
   20399        2276 :   for (int i = 0, n = special_exports->length(); i < n; ++i) {
   20400             :     Handle<ModuleInfoEntry> entry(
   20401             :         ModuleInfoEntry::cast(special_exports->get(i)), isolate);
   20402             :     Handle<Object> name(entry->export_name(), isolate);
   20403         594 :     if (name->IsUndefined(isolate)) continue;  // Star export.
   20404             :     Handle<Script> script(
   20405             :         Script::cast(JSFunction::cast(module->code())->shared()->script()),
   20406             :         isolate);
   20407         180 :     MessageLocation loc(script, entry->beg_pos(), entry->end_pos());
   20408         180 :     ResolveSet resolve_set(&zone);
   20409         180 :     if (ResolveExport(module, Handle<String>::cast(name), loc, true,
   20410             :                       &resolve_set)
   20411         360 :             .is_null()) {
   20412             :       return false;
   20413             :     }
   20414             :   }
   20415             : 
   20416        1903 :   return true;
   20417             : }
   20418             : 
   20419        2320 : MaybeHandle<Object> Module::Evaluate(Handle<Module> module) {
   20420             :   DCHECK(module->instantiated());
   20421             : 
   20422             :   // Each module can only be evaluated once.
   20423             :   Isolate* isolate = module->GetIsolate();
   20424        2320 :   if (module->evaluated()) return isolate->factory()->undefined_value();
   20425             :   Handle<JSFunction> function(JSFunction::cast(module->code()), isolate);
   20426        1875 :   module->set_evaluated();
   20427             : 
   20428             :   // Initialization.
   20429             :   DCHECK_EQ(MODULE_SCOPE, function->shared()->scope_info()->scope_type());
   20430             :   Handle<Object> receiver = isolate->factory()->undefined_value();
   20431             :   Handle<Object> argv[] = {module};
   20432             :   Handle<Object> generator;
   20433        3750 :   ASSIGN_RETURN_ON_EXCEPTION(
   20434             :       isolate, generator,
   20435             :       Execution::Call(isolate, function, receiver, arraysize(argv), argv),
   20436             :       Object);
   20437             : 
   20438             :   // Recursion.
   20439             :   Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
   20440        3007 :   for (int i = 0, length = requested_modules->length(); i < length; ++i) {
   20441             :     Handle<Module> import(Module::cast(requested_modules->get(i)), isolate);
   20442        2264 :     RETURN_ON_EXCEPTION(isolate, Evaluate(import), Object);
   20443             :   }
   20444             : 
   20445             :   // Evaluation of module body.
   20446             :   Handle<JSFunction> resume(
   20447        3750 :       isolate->native_context()->generator_next_internal(), isolate);
   20448             :   Handle<Object> result;
   20449        3750 :   ASSIGN_RETURN_ON_EXCEPTION(
   20450             :       isolate, result, Execution::Call(isolate, resume, generator, 0, nullptr),
   20451             :       Object);
   20452             :   DCHECK(static_cast<JSIteratorResult*>(JSObject::cast(*result))
   20453             :              ->done()
   20454             :              ->BooleanValue());
   20455             :   return handle(
   20456             :       static_cast<JSIteratorResult*>(JSObject::cast(*result))->value(),
   20457             :       isolate);
   20458             : }
   20459             : 
   20460             : namespace {
   20461             : 
   20462         403 : void FetchStarExports(Handle<Module> module, Zone* zone,
   20463             :                       UnorderedModuleSet* visited) {
   20464             :   DCHECK(module->instantiated());
   20465             : 
   20466         403 :   bool cycle = !visited->insert(module).second;
   20467         418 :   if (cycle) return;
   20468             : 
   20469             :   Isolate* isolate = module->GetIsolate();
   20470             :   Handle<ObjectHashTable> exports(module->exports(), isolate);
   20471         388 :   UnorderedStringMap more_exports(zone);
   20472             : 
   20473             :   // TODO(neis): Only allocate more_exports if there are star exports.
   20474             :   // Maybe split special_exports into indirect_exports and star_exports.
   20475             : 
   20476             :   Handle<FixedArray> special_exports(module->info()->special_exports(),
   20477         388 :                                      isolate);
   20478         536 :   for (int i = 0, n = special_exports->length(); i < n; ++i) {
   20479             :     Handle<ModuleInfoEntry> entry(
   20480             :         ModuleInfoEntry::cast(special_exports->get(i)), isolate);
   20481         148 :     if (!entry->export_name()->IsUndefined(isolate)) {
   20482             :       continue;  // Indirect export.
   20483             :     }
   20484             : 
   20485             :     Handle<Module> requested_module(
   20486             :         Module::cast(module->requested_modules()->get(entry->module_request())),
   20487             :         isolate);
   20488             : 
   20489             :     // Recurse.
   20490         103 :     FetchStarExports(requested_module, zone, visited);
   20491             : 
   20492             :     // Collect all of [requested_module]'s exports that must be added to
   20493             :     // [module]'s exports (i.e. to [exports]).  We record these in
   20494             :     // [more_exports].  Ambiguities (conflicting exports) are marked by mapping
   20495             :     // the name to undefined instead of a Cell.
   20496             :     Handle<ObjectHashTable> requested_exports(requested_module->exports(),
   20497             :                                               isolate);
   20498         815 :     for (int i = 0, n = requested_exports->Capacity(); i < n; ++i) {
   20499             :       Handle<Object> key(requested_exports->KeyAt(i), isolate);
   20500         712 :       if (!requested_exports->IsKey(isolate, *key)) continue;
   20501             :       Handle<String> name = Handle<String>::cast(key);
   20502             : 
   20503         298 :       if (name->Equals(isolate->heap()->default_string())) continue;
   20504         506 :       if (!exports->Lookup(name)->IsTheHole(isolate)) continue;
   20505             : 
   20506             :       Handle<Cell> cell(Cell::cast(requested_exports->ValueAt(i)), isolate);
   20507         446 :       auto insert_result = more_exports.insert(std::make_pair(name, cell));
   20508         223 :       if (!insert_result.second) {
   20509             :         auto it = insert_result.first;
   20510          45 :         if (*it->second == *cell || it->second->IsUndefined(isolate)) {
   20511             :           // We already recorded this mapping before, or the name is already
   20512             :           // known to be ambiguous.  In either case, there's nothing to do.
   20513             :         } else {
   20514             :           DCHECK(it->second->IsCell());
   20515             :           // Different star exports provide different cells for this name, hence
   20516             :           // mark the name as ambiguous.
   20517          15 :           it->second = isolate->factory()->undefined_value();
   20518             :         }
   20519             :       }
   20520             :     }
   20521             :   }
   20522             : 
   20523             :   // Copy [more_exports] into [exports].
   20524         969 :   for (const auto& elem : more_exports) {
   20525         193 :     if (elem.second->IsUndefined(isolate)) continue;  // Ambiguous export.
   20526             :     DCHECK(!elem.first->Equals(isolate->heap()->default_string()));
   20527             :     DCHECK(elem.second->IsCell());
   20528         178 :     exports = ObjectHashTable::Put(exports, elem.first, elem.second);
   20529             :   }
   20530         388 :   module->set_exports(*exports);
   20531             : }
   20532             : 
   20533             : }  // anonymous namespace
   20534             : 
   20535         161 : Handle<JSModuleNamespace> Module::GetModuleNamespace(Handle<Module> module,
   20536             :                                                      int module_request) {
   20537             :   Isolate* isolate = module->GetIsolate();
   20538             :   Handle<Module> requested_module(
   20539             :       Module::cast(module->requested_modules()->get(module_request)), isolate);
   20540         161 :   return Module::GetModuleNamespace(requested_module);
   20541             : }
   20542             : 
   20543         413 : Handle<JSModuleNamespace> Module::GetModuleNamespace(Handle<Module> module) {
   20544         300 :   Isolate* isolate = module->GetIsolate();
   20545             : 
   20546             :   Handle<HeapObject> object(module->module_namespace(), isolate);
   20547         413 :   if (!object->IsUndefined(isolate)) {
   20548             :     // Namespace object already exists.
   20549             :     return Handle<JSModuleNamespace>::cast(object);
   20550             :   }
   20551             : 
   20552             :   // Create the namespace object (initially empty).
   20553         300 :   Handle<JSModuleNamespace> ns = isolate->factory()->NewJSModuleNamespace();
   20554         300 :   ns->set_module(*module);
   20555         300 :   module->set_module_namespace(*ns);
   20556             : 
   20557             :   // Collect the export names.
   20558         300 :   Zone zone(isolate->allocator(), ZONE_NAME);
   20559         300 :   UnorderedModuleSet visited(&zone);
   20560         300 :   FetchStarExports(module, &zone, &visited);
   20561             :   Handle<ObjectHashTable> exports(module->exports(), isolate);
   20562             :   ZoneVector<Handle<String>> names(&zone);
   20563         300 :   names.reserve(exports->NumberOfElements());
   20564        1920 :   for (int i = 0, n = exports->Capacity(); i < n; ++i) {
   20565             :     Handle<Object> key(exports->KeyAt(i), isolate);
   20566        1620 :     if (!exports->IsKey(isolate, *key)) continue;
   20567             :     DCHECK(exports->ValueAt(i)->IsCell());
   20568         611 :     names.push_back(Handle<String>::cast(key));
   20569             :   }
   20570             :   DCHECK_EQ(static_cast<int>(names.size()), exports->NumberOfElements());
   20571             : 
   20572             :   // Sort them alphabetically.
   20573             :   struct {
   20574             :     bool operator()(Handle<String> a, Handle<String> b) {
   20575         712 :       return String::Compare(a, b) == ComparisonResult::kLessThan;
   20576             :     }
   20577             :   } StringLess;
   20578         300 :   std::sort(names.begin(), names.end(), StringLess);
   20579             : 
   20580             :   // Create the corresponding properties in the namespace object.
   20581             :   PropertyAttributes attr = DONT_DELETE;
   20582        1211 :   for (const auto& name : names) {
   20583             :     JSObject::SetAccessor(
   20584             :         ns, Accessors::ModuleNamespaceEntryInfo(isolate, name, attr))
   20585        1833 :         .Check();
   20586             :   }
   20587         600 :   JSObject::PreventExtensions(ns, THROW_ON_ERROR).ToChecked();
   20588             : 
   20589         600 :   return ns;
   20590             : }
   20591             : 
   20592     9377435 : MaybeHandle<Name> FunctionTemplateInfo::TryGetCachedPropertyName(
   20593             :     Isolate* isolate, Handle<Object> getter) {
   20594     9377435 :   if (getter->IsFunctionTemplateInfo()) {
   20595             :     Handle<FunctionTemplateInfo> fti =
   20596             :         Handle<FunctionTemplateInfo>::cast(getter);
   20597             :     // Check if the accessor uses a cached property.
   20598         535 :     if (!fti->cached_property_name()->IsTheHole(isolate)) {
   20599             :       return handle(Name::cast(fti->cached_property_name()));
   20600             :     }
   20601             :   }
   20602             :   return MaybeHandle<Name>();
   20603             : }
   20604             : 
   20605             : // static
   20606        1408 : ElementsKind JSArrayIterator::ElementsKindForInstanceType(InstanceType type) {
   20607             :   DCHECK_GE(type, FIRST_ARRAY_ITERATOR_TYPE);
   20608             :   DCHECK_LE(type, LAST_ARRAY_ITERATOR_TYPE);
   20609             : 
   20610        1408 :   if (type <= LAST_ARRAY_KEY_ITERATOR_TYPE) {
   20611             :     // Should be ignored for key iterators.
   20612             :     return FAST_ELEMENTS;
   20613             :   } else {
   20614             :     ElementsKind kind;
   20615        1395 :     if (type < FIRST_ARRAY_VALUE_ITERATOR_TYPE) {
   20616             :       // Convert `type` to a value iterator from an entries iterator
   20617          14 :       type = static_cast<InstanceType>(type +
   20618             :                                        (FIRST_ARRAY_VALUE_ITERATOR_TYPE -
   20619          14 :                                         FIRST_ARRAY_KEY_VALUE_ITERATOR_TYPE));
   20620             :       DCHECK_GE(type, FIRST_ARRAY_VALUE_ITERATOR_TYPE);
   20621             :       DCHECK_LE(type, LAST_ARRAY_ITERATOR_TYPE);
   20622             :     }
   20623             : 
   20624        1395 :     if (type <= JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE) {
   20625             :       kind =
   20626          14 :           static_cast<ElementsKind>(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND +
   20627          14 :                                     (type - FIRST_ARRAY_VALUE_ITERATOR_TYPE));
   20628             :       DCHECK_LE(kind, LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND);
   20629        1381 :     } else if (type < JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE) {
   20630             :       kind = static_cast<ElementsKind>(
   20631        1381 :           FIRST_FAST_ELEMENTS_KIND +
   20632        1381 :           (type - JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE));
   20633             :       DCHECK_LE(kind, LAST_FAST_ELEMENTS_KIND);
   20634             :     } else {
   20635             :       // For any slow element cases, the actual elements kind is not known.
   20636             :       // Simply
   20637             :       // return a slow elements kind in this case. Users of this function must
   20638             :       // not
   20639             :       // depend on this.
   20640             :       return DICTIONARY_ELEMENTS;
   20641             :     }
   20642             :     DCHECK_LE(kind, LAST_ELEMENTS_KIND);
   20643        1395 :     return kind;
   20644             :   }
   20645             : }
   20646             : 
   20647             : }  // namespace internal
   20648             : }  // namespace v8

Generated by: LCOV version 1.10