diff options
author | Myles Borins <mylesborins@google.com> | 2018-04-10 21:39:51 -0400 |
---|---|---|
committer | Myles Borins <mylesborins@google.com> | 2018-04-11 13:22:42 -0400 |
commit | 12a1b9b8049462e47181a298120243dc83e81c55 (patch) | |
tree | 8605276308c8b4e3597516961266bae1af57557a /deps/v8/src/ic | |
parent | 78cd8263354705b767ef8c6a651740efe4931ba0 (diff) | |
download | android-node-v8-12a1b9b8049462e47181a298120243dc83e81c55.tar.gz android-node-v8-12a1b9b8049462e47181a298120243dc83e81c55.tar.bz2 android-node-v8-12a1b9b8049462e47181a298120243dc83e81c55.zip |
deps: update V8 to 6.6.346.23
PR-URL: https://github.com/nodejs/node/pull/19201
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'deps/v8/src/ic')
-rw-r--r-- | deps/v8/src/ic/accessor-assembler.cc | 95 | ||||
-rw-r--r-- | deps/v8/src/ic/accessor-assembler.h | 6 | ||||
-rw-r--r-- | deps/v8/src/ic/binary-op-assembler.h | 6 | ||||
-rw-r--r-- | deps/v8/src/ic/ic-inl.h | 6 | ||||
-rw-r--r-- | deps/v8/src/ic/ic.cc | 206 | ||||
-rw-r--r-- | deps/v8/src/ic/ic.h | 66 | ||||
-rw-r--r-- | deps/v8/src/ic/keyed-store-generic.cc | 30 | ||||
-rw-r--r-- | deps/v8/src/ic/keyed-store-generic.h | 6 | ||||
-rw-r--r-- | deps/v8/src/ic/stub-cache.h | 6 |
9 files changed, 236 insertions, 191 deletions
diff --git a/deps/v8/src/ic/accessor-assembler.cc b/deps/v8/src/ic/accessor-assembler.cc index dfd88862bd..9800149ae1 100644 --- a/deps/v8/src/ic/accessor-assembler.cc +++ b/deps/v8/src/ic/accessor-assembler.cc @@ -300,18 +300,18 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( Comment("out of bounds elements access"); Label return_undefined(this); - // Negative indices aren't valid array indices (according to - // the ECMAScript specification), and are stored as properties - // in V8, not elements. So we cannot handle them here. - GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), miss); - // Check if we're allowed to handle OOB accesses. Node* allow_out_of_bounds = IsSetWord<LoadHandler::AllowOutOfBoundsBits>(handler_word); GotoIfNot(allow_out_of_bounds, miss); - // For typed arrays we never lookup elements in the prototype chain. + // Negative indices aren't valid array indices (according to + // the ECMAScript specification), and are stored as properties + // in V8, not elements. So we cannot handle them here, except + // in case of typed arrays, where integer indexed properties + // aren't looked up in the prototype chain. GotoIf(IsJSTypedArray(holder), &return_undefined); + GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), miss); // For all other receivers we need to check that the prototype chain // doesn't contain any elements. @@ -1350,7 +1350,7 @@ void AccessorAssembler::ExtendPropertiesBackingStore(Node* object, BIND(&if_smi_hash); { - Node* hash = SmiToWord32(properties); + Node* hash = SmiToInt32(properties); Node* encoded_hash = Word32Shl(hash, Int32Constant(PropertyArray::HashField::kShift)); var_encoded_hash.Bind(encoded_hash); @@ -1368,7 +1368,7 @@ void AccessorAssembler::ExtendPropertiesBackingStore(Node* object, Node* length_intptr = ChangeInt32ToIntPtr( Word32And(length_and_hash_int32, Int32Constant(PropertyArray::LengthField::kMask))); - Node* length = WordToParameter(length_intptr, mode); + Node* length = IntPtrToParameter(length_intptr, mode); var_length.Bind(length); Goto(&extend_store); } @@ -1412,11 +1412,11 @@ void AccessorAssembler::ExtendPropertiesBackingStore(Node* object, // TODO(gsathya): Clean up the type conversions by creating smarter // helpers that do the correct op based on the mode. Node* new_capacity_int32 = - TruncateWordToWord32(ParameterToWord(new_capacity, mode)); + TruncateIntPtrToInt32(ParameterToIntPtr(new_capacity, mode)); Node* new_length_and_hash_int32 = Word32Or(var_encoded_hash.value(), new_capacity_int32); StoreObjectField(new_properties, PropertyArray::kLengthAndHashOffset, - SmiFromWord32(new_length_and_hash_int32)); + SmiFromInt32(new_length_and_hash_int32)); StoreObjectField(object, JSObject::kPropertiesOrHashOffset, new_properties); Comment("] Extend storage"); Goto(&done); @@ -1614,26 +1614,22 @@ void AccessorAssembler::EmitElementLoad( SmiUntag(CAST(LoadObjectField(object, JSTypedArray::kLengthOffset))); GotoIfNot(UintPtrLessThan(intptr_index, length), out_of_bounds); - // Backing store = external_pointer + base_pointer. - Node* external_pointer = - LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, - MachineType::Pointer()); - Node* base_pointer = - LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); - Node* backing_store = - IntPtrAdd(external_pointer, BitcastTaggedToWord(base_pointer)); + Node* backing_store = LoadFixedTypedArrayBackingStore(CAST(elements)); Label uint8_elements(this), int8_elements(this), uint16_elements(this), int16_elements(this), uint32_elements(this), int32_elements(this), - float32_elements(this), float64_elements(this); + float32_elements(this), float64_elements(this), bigint64_elements(this), + biguint64_elements(this); Label* elements_kind_labels[] = { - &uint8_elements, &uint8_elements, &int8_elements, - &uint16_elements, &int16_elements, &uint32_elements, - &int32_elements, &float32_elements, &float64_elements}; + &uint8_elements, &uint8_elements, &int8_elements, + &uint16_elements, &int16_elements, &uint32_elements, + &int32_elements, &float32_elements, &float64_elements, + &bigint64_elements, &biguint64_elements}; int32_t elements_kinds[] = { - UINT8_ELEMENTS, UINT8_CLAMPED_ELEMENTS, INT8_ELEMENTS, - UINT16_ELEMENTS, INT16_ELEMENTS, UINT32_ELEMENTS, - INT32_ELEMENTS, FLOAT32_ELEMENTS, FLOAT64_ELEMENTS}; + UINT8_ELEMENTS, UINT8_CLAMPED_ELEMENTS, INT8_ELEMENTS, + UINT16_ELEMENTS, INT16_ELEMENTS, UINT32_ELEMENTS, + INT32_ELEMENTS, FLOAT32_ELEMENTS, FLOAT64_ELEMENTS, + BIGINT64_ELEMENTS, BIGUINT64_ELEMENTS}; const size_t kTypedElementsKindCount = LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND - FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND + 1; @@ -1645,27 +1641,27 @@ void AccessorAssembler::EmitElementLoad( { Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too. Node* element = Load(MachineType::Uint8(), backing_store, intptr_index); - exit_point->Return(SmiFromWord32(element)); + exit_point->Return(SmiFromInt32(element)); } BIND(&int8_elements); { Comment("INT8_ELEMENTS"); Node* element = Load(MachineType::Int8(), backing_store, intptr_index); - exit_point->Return(SmiFromWord32(element)); + exit_point->Return(SmiFromInt32(element)); } BIND(&uint16_elements); { Comment("UINT16_ELEMENTS"); Node* index = WordShl(intptr_index, IntPtrConstant(1)); Node* element = Load(MachineType::Uint16(), backing_store, index); - exit_point->Return(SmiFromWord32(element)); + exit_point->Return(SmiFromInt32(element)); } BIND(&int16_elements); { Comment("INT16_ELEMENTS"); Node* index = WordShl(intptr_index, IntPtrConstant(1)); Node* element = Load(MachineType::Int16(), backing_store, index); - exit_point->Return(SmiFromWord32(element)); + exit_point->Return(SmiFromInt32(element)); } BIND(&uint32_elements); { @@ -1697,6 +1693,18 @@ void AccessorAssembler::EmitElementLoad( var_double_value->Bind(element); Goto(rebox_double); } + BIND(&bigint64_elements); + { + Comment("BIGINT64_ELEMENTS"); + exit_point->Return(LoadFixedTypedArrayElementAsTagged( + backing_store, intptr_index, BIGINT64_ELEMENTS, INTPTR_PARAMETERS)); + } + BIND(&biguint64_elements); + { + Comment("BIGUINT64_ELEMENTS"); + exit_point->Return(LoadFixedTypedArrayElementAsTagged( + backing_store, intptr_index, BIGUINT64_ELEMENTS, INTPTR_PARAMETERS)); + } } } @@ -1718,13 +1726,13 @@ void AccessorAssembler::BranchIfStrictMode(Node* vector, Node* slot, LoadObjectField(vector, FeedbackVector::kSharedFunctionInfoOffset); Node* metadata = LoadObjectField(sfi, SharedFunctionInfo::kFeedbackMetadataOffset); - Node* slot_int = SmiToWord32(slot); + Node* slot_int = SmiToInt32(slot); // See VectorICComputer::index(). const int kItemsPerWord = FeedbackMetadata::VectorICComputer::kItemsPerWord; Node* word_index = Int32Div(slot_int, Int32Constant(kItemsPerWord)); Node* word_offset = Int32Mod(slot_int, Int32Constant(kItemsPerWord)); - Node* data = SmiToWord32(LoadFixedArrayElement( + Node* data = SmiToInt32(LoadFixedArrayElement( metadata, ChangeInt32ToIntPtr(word_index), FeedbackMetadata::kReservedIndexCount * kPointerSize, INTPTR_PARAMETERS)); // See VectorICComputer::decode(). @@ -1803,10 +1811,12 @@ void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map, BIND(&if_oob); { Comment("out of bounds"); - // Negative keys can't take the fast OOB path. - GotoIf(IntPtrLessThan(index, IntPtrConstant(0)), slow); // Positive OOB indices are effectively the same as hole loads. - Goto(&if_element_hole); + GotoIf(IntPtrGreaterThanOrEqual(index, IntPtrConstant(0)), + &if_element_hole); + // Negative keys can't take the fast OOB path, except for typed arrays. + GotoIfNot(InstanceTypeEqual(instance_type, JS_TYPED_ARRAY_TYPE), slow); + Return(UndefinedConstant()); } BIND(&if_element_hole); @@ -1977,6 +1987,9 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, // TODO(jkummerow): Consider supporting JSModuleNamespace. GotoIfNot(InstanceTypeEqual(instance_type, JS_PROXY_TYPE), slow); + // Private field/symbol lookup is not supported. + GotoIf(IsPrivateSymbol(p->name), slow); + direct_exit.ReturnCallStub( Builtins::CallableFor(isolate(), Builtins::kProxyGetProperty), p->context, receiver /*holder is the same as receiver*/, p->name, @@ -2004,7 +2017,7 @@ Node* AccessorAssembler::StubCachePrimaryOffset(Node* name, Node* map) { // Using only the low bits in 64-bit mode is unlikely to increase the // risk of collision even if the heap is spread over an area larger than // 4Gb (and not at all if it isn't). - Node* map32 = TruncateWordToWord32(BitcastTaggedToWord(map)); + Node* map32 = TruncateIntPtrToInt32(BitcastTaggedToWord(map)); // Base the offset on a simple combination of name and map. Node* hash = Int32Add(hash_field, map32); uint32_t mask = (StubCache::kPrimaryTableSize - 1) @@ -2016,8 +2029,8 @@ Node* AccessorAssembler::StubCacheSecondaryOffset(Node* name, Node* seed) { // See v8::internal::StubCache::SecondaryOffset(). // Use the seed from the primary cache in the secondary cache. - Node* name32 = TruncateWordToWord32(BitcastTaggedToWord(name)); - Node* hash = Int32Sub(TruncateWordToWord32(seed), name32); + Node* name32 = TruncateIntPtrToInt32(BitcastTaggedToWord(name)); + Node* hash = Int32Sub(TruncateIntPtrToInt32(seed), name32); hash = Int32Add(hash, Int32Constant(StubCache::kSecondaryMagic)); int32_t mask = (StubCache::kSecondaryTableSize - 1) << StubCache::kCacheIndexShift; @@ -2340,9 +2353,9 @@ void AccessorAssembler::LoadGlobalIC_TryPropertyCellCase( Comment("Load lexical variable"); TNode<IntPtrT> lexical_handler = SmiUntag(CAST(maybe_weak_cell)); TNode<IntPtrT> context_index = - Signed(DecodeWord<GlobalICNexus::ContextIndexBits>(lexical_handler)); + Signed(DecodeWord<FeedbackNexus::ContextIndexBits>(lexical_handler)); TNode<IntPtrT> slot_index = - Signed(DecodeWord<GlobalICNexus::SlotIndexBits>(lexical_handler)); + Signed(DecodeWord<FeedbackNexus::SlotIndexBits>(lexical_handler)); TNode<Context> context = lazy_context(); TNode<Context> script_context = LoadScriptContext(context, context_index); TNode<Object> result = LoadContextElement(script_context, slot_index); @@ -2685,9 +2698,9 @@ void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { Comment("Store lexical variable"); TNode<IntPtrT> lexical_handler = SmiUntag(maybe_weak_cell); TNode<IntPtrT> context_index = - Signed(DecodeWord<GlobalICNexus::ContextIndexBits>(lexical_handler)); + Signed(DecodeWord<FeedbackNexus::ContextIndexBits>(lexical_handler)); TNode<IntPtrT> slot_index = - Signed(DecodeWord<GlobalICNexus::SlotIndexBits>(lexical_handler)); + Signed(DecodeWord<FeedbackNexus::SlotIndexBits>(lexical_handler)); TNode<Context> script_context = LoadScriptContext(CAST(pp->context), context_index); StoreContextElement(script_context, slot_index, CAST(pp->value)); diff --git a/deps/v8/src/ic/accessor-assembler.h b/deps/v8/src/ic/accessor-assembler.h index 46376dd6a8..3e4f551c14 100644 --- a/deps/v8/src/ic/accessor-assembler.h +++ b/deps/v8/src/ic/accessor-assembler.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef V8_SRC_IC_ACCESSOR_ASSEMBLER_H_ -#define V8_SRC_IC_ACCESSOR_ASSEMBLER_H_ +#ifndef V8_IC_ACCESSOR_ASSEMBLER_H_ +#define V8_IC_ACCESSOR_ASSEMBLER_H_ #include "src/code-stub-assembler.h" @@ -335,4 +335,4 @@ class ExitPoint { } // namespace internal } // namespace v8 -#endif // V8_SRC_IC_ACCESSOR_ASSEMBLER_H_ +#endif // V8_IC_ACCESSOR_ASSEMBLER_H_ diff --git a/deps/v8/src/ic/binary-op-assembler.h b/deps/v8/src/ic/binary-op-assembler.h index d7afd7b655..420f66c174 100644 --- a/deps/v8/src/ic/binary-op-assembler.h +++ b/deps/v8/src/ic/binary-op-assembler.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef V8_SRC_IC_BINARY_OP_ASSEMBLER_H_ -#define V8_SRC_IC_BINARY_OP_ASSEMBLER_H_ +#ifndef V8_IC_BINARY_OP_ASSEMBLER_H_ +#define V8_IC_BINARY_OP_ASSEMBLER_H_ #include <functional> #include "src/code-stub-assembler.h" @@ -60,4 +60,4 @@ class BinaryOpAssembler : public CodeStubAssembler { } // namespace internal } // namespace v8 -#endif // V8_SRC_IC_BINARY_OP_ASSEMBLER_H_ +#endif // V8_IC_BINARY_OP_ASSEMBLER_H_ diff --git a/deps/v8/src/ic/ic-inl.h b/deps/v8/src/ic/ic-inl.h index d6fa23611e..83ab9d86b8 100644 --- a/deps/v8/src/ic/ic-inl.h +++ b/deps/v8/src/ic/ic-inl.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef V8_IC_INL_H_ -#define V8_IC_INL_H_ +#ifndef V8_IC_IC_INL_H_ +#define V8_IC_IC_INL_H_ #include "src/ic/ic.h" @@ -59,4 +59,4 @@ bool IC::AddressIsDeoptimizedCode(Isolate* isolate, Address address) { } // namespace internal } // namespace v8 -#endif // V8_IC_INL_H_ +#endif // V8_IC_IC_INL_H_ diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc index 62a2e7cf59..e6fa0b1ceb 100644 --- a/deps/v8/src/ic/ic.cc +++ b/deps/v8/src/ic/ic.cc @@ -58,12 +58,18 @@ const char* GetModifier(KeyedAccessLoadMode mode) { } const char* GetModifier(KeyedAccessStoreMode mode) { - if (mode == STORE_NO_TRANSITION_HANDLE_COW) return ".COW"; - if (mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { - return ".IGNORE_OOB"; + switch (mode) { + case STORE_NO_TRANSITION_HANDLE_COW: + return ".COW"; + case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW: + return ".STORE+COW"; + case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS: + return ".IGNORE_OOB"; + default: + break; } - if (IsGrowStoreMode(mode)) return ".GROW"; - return ""; + DCHECK(!IsCOWHandlingStoreMode(mode)); + return IsGrowStoreMode(mode) ? ".GROW" : ""; } } // namespace @@ -89,12 +95,10 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state, const char* modifier = ""; if (IsKeyedLoadIC()) { - KeyedAccessLoadMode mode = - casted_nexus<KeyedLoadICNexus>()->GetKeyedAccessLoadMode(); + KeyedAccessLoadMode mode = nexus()->GetKeyedAccessLoadMode(); modifier = GetModifier(mode); } else if (IsKeyedStoreIC()) { - KeyedAccessStoreMode mode = - casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode(); + KeyedAccessStoreMode mode = nexus()->GetKeyedAccessStoreMode(); modifier = GetModifier(mode); } @@ -147,13 +151,14 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state, #define TRACE_IC(type, name) TraceIC(type, name) -IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus) +IC::IC(FrameDepth depth, Isolate* isolate, Handle<FeedbackVector> vector, + FeedbackSlot slot) : isolate_(isolate), vector_set_(false), kind_(FeedbackSlotKind::kInvalid), target_maps_set_(false), slow_stub_reason_(nullptr), - nexus_(nexus) { + nexus_(vector, slot) { // To improve the performance of the (much used) IC code, we unfold a few // levels of the stack frame iteration code. This yields a ~35% speedup when // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. @@ -199,9 +204,8 @@ IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus) constant_pool_address_ = constant_pool; } pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); - DCHECK_NOT_NULL(nexus); - kind_ = nexus->kind(); - state_ = nexus->StateFromFeedback(); + kind_ = nexus_.kind(); + state_ = nexus_.StateFromFeedback(); old_state_ = state_; } @@ -251,12 +255,12 @@ static void LookupForRead(LookupIterator* it) { bool IC::ShouldRecomputeHandler(Handle<String> name) { if (!RecomputeHandlerForName(name)) return false; - maybe_handler_ = nexus()->FindHandlerForMap(receiver_map()); - // This is a contextual access, always just update the handler and stay // monomorphic. if (IsGlobalIC()) return true; + maybe_handler_ = nexus()->FindHandlerForMap(receiver_map()); + // The current map wasn't handled yet. There's no reason to stay monomorphic, // *unless* we're moving from a deprecated map to its replacement, or // to a more general elements kind. @@ -315,6 +319,13 @@ MaybeHandle<Object> IC::ReferenceError(Handle<Name> name) { isolate(), NewReferenceError(MessageTemplate::kNotDefined, name), Object); } +// static +void IC::OnFeedbackChanged(Isolate* isolate, FeedbackNexus* nexus, + JSFunction* host_function, const char* reason) { + FeedbackVector* vector = nexus->vector(); + FeedbackSlot slot = nexus->slot(); + OnFeedbackChanged(isolate, vector, slot, host_function, reason); +} // static void IC::OnFeedbackChanged(Isolate* isolate, FeedbackVector* vector, @@ -385,21 +396,15 @@ bool IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) { vector_set_ = true; OnFeedbackChanged( - isolate(), *vector(), slot(), GetHostFunction(), + isolate(), nexus(), GetHostFunction(), new_state == PREMONOMORPHIC ? "Premonomorphic" : "Megamorphic"); return changed; } void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, Handle<Object> handler) { - if (IsLoadGlobalIC()) { - LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); - nexus->ConfigureHandlerMode(handler); - - } else if (IsStoreGlobalIC()) { - StoreGlobalICNexus* nexus = casted_nexus<StoreGlobalICNexus>(); - nexus->ConfigureHandlerMode(handler); - + if (IsGlobalIC()) { + nexus()->ConfigureHandlerMode(handler); } else { // Non-keyed ICs don't track the name explicitly. if (!is_keyed()) name = Handle<Name>::null(); @@ -407,7 +412,7 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, } vector_set_ = true; - OnFeedbackChanged(isolate(), *vector(), slot(), GetHostFunction(), + OnFeedbackChanged(isolate(), nexus(), GetHostFunction(), IsLoadGlobalIC() ? "LoadGlobal" : "Monomorphic"); } @@ -419,8 +424,7 @@ void IC::ConfigureVectorState(Handle<Name> name, MapHandles const& maps, nexus()->ConfigurePolymorphic(name, maps, handlers); vector_set_ = true; - OnFeedbackChanged(isolate(), *vector(), slot(), GetHostFunction(), - "Polymorphic"); + OnFeedbackChanged(isolate(), nexus(), GetHostFunction(), "Polymorphic"); } MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { @@ -451,6 +455,19 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { LookupIterator it(object, name); LookupForRead(&it); + if (name->IsPrivate()) { + if (name->IsPrivateField() && !it.IsFound()) { + return TypeError(MessageTemplate::kInvalidPrivateFieldAccess, object, + name); + } + + // IC handling of private symbols/fields lookup on JSProxy is not + // supported. + if (object->IsJSProxy()) { + use_ic = false; + } + } + if (it.IsFound() || !ShouldThrowReferenceError()) { // Update inline cache and stub cache. if (use_ic) UpdateCaches(&it); @@ -492,9 +509,8 @@ MaybeHandle<Object> LoadGlobalIC::Load(Handle<Name> name) { } if (FLAG_use_ic) { - LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); - if (nexus->ConfigureLexicalVarMode(lookup_result.context_index, - lookup_result.slot_index)) { + if (nexus()->ConfigureLexicalVarMode(lookup_result.context_index, + lookup_result.slot_index)) { TRACE_HANDLER_STATS(isolate(), LoadGlobalIC_LoadScriptContextField); } else { // Given combination of indices can't be encoded, so use slow stub. @@ -638,14 +654,14 @@ void IC::PatchCache(Handle<Name> name, Handle<Object> handler) { UpdateMonomorphicIC(handler, name); break; } - // Fall through. + V8_FALLTHROUGH; case POLYMORPHIC: if (UpdatePolymorphicIC(name, handler)) break; if (!is_keyed() || state() == RECOMPUTE_HANDLER) { CopyICToMegamorphicCache(name); } ConfigureVectorState(MEGAMORPHIC, name); - // Fall through. + V8_FALLTHROUGH; case MEGAMORPHIC: UpdateMegamorphicCache(*receiver_map(), *name, *handler); // Indicate that we've handled this case. @@ -685,8 +701,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { lookup->GetReceiver().is_identical_to(lookup->GetHolder<Object>())) { DCHECK(lookup->GetReceiver()->IsJSGlobalObject()); // Now update the cell in the feedback vector. - LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); - nexus->ConfigurePropertyCellMode(lookup->GetPropertyCell()); + nexus()->ConfigurePropertyCellMode(lookup->GetPropertyCell()); TRACE_IC("LoadGlobalIC", lookup->name()); return; } @@ -1199,8 +1214,14 @@ MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, Object); } else if (FLAG_use_ic && !object->IsAccessCheckNeeded() && !object->IsJSValue()) { - if ((object->IsJSReceiver() || object->IsString()) && - key->ToArrayIndex(&index)) { + // For regular JSReceiver or String {object}s the {key} must be a positive + // array index, for JSTypedArray {object}s we can also support negative + // {key}s which we just map into the [2*31,2*32-1] range (via a bit_cast). + // This is valid since JSTypedArray::length is always a Smi. + if (((object->IsJSReceiver() || object->IsString()) && + key->ToArrayIndex(&index)) || + (object->IsJSTypedArray() && + key->ToInt32(bit_cast<int32_t*>(&index)))) { KeyedAccessLoadMode load_mode = GetLoadMode(object, index); UpdateLoadElement(Handle<HeapObject>::cast(object), load_mode); if (is_vector_set()) { @@ -1287,7 +1308,7 @@ bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value, } } - receiver = it->GetStoreTarget(); + receiver = it->GetStoreTarget<JSObject>(); if (it->ExtendingNonExtensible(receiver)) return false; created_new_transition_ = it->PrepareTransitionToDataProperty(receiver, value, NONE, store_mode); @@ -1322,9 +1343,8 @@ MaybeHandle<Object> StoreGlobalIC::Store(Handle<Name> name, } if (FLAG_use_ic) { - StoreGlobalICNexus* nexus = casted_nexus<StoreGlobalICNexus>(); - if (nexus->ConfigureLexicalVarMode(lookup_result.context_index, - lookup_result.slot_index)) { + if (nexus()->ConfigureLexicalVarMode(lookup_result.context_index, + lookup_result.slot_index)) { TRACE_HANDLER_STATS(isolate(), StoreGlobalIC_StoreScriptContextField); } else { // Given combination of indices can't be encoded, so use slow stub. @@ -1383,7 +1403,23 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, LookupIterator it = LookupIterator::ForTransitionHandler( isolate(), object, name, value, cached_handler, transition_map); - if (FLAG_use_ic) UpdateCaches(&it, value, store_mode, cached_handler); + + bool use_ic = FLAG_use_ic; + + if (name->IsPrivate()) { + if (name->IsPrivateField() && !it.IsFound()) { + return TypeError(MessageTemplate::kInvalidPrivateFieldAccess, object, + name); + } + + // IC handling of private fields/symbols stores on JSProxy is not + // supported. + if (object->IsJSProxy()) { + use_ic = false; + } + } + + if (use_ic) UpdateCaches(&it, value, store_mode, cached_handler); MAYBE_RETURN_NULL( Object::SetProperty(&it, value, language_mode(), store_mode)); @@ -1411,8 +1447,7 @@ void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, lookup->GetReceiver().is_identical_to(lookup->GetHolder<Object>())) { DCHECK(lookup->GetReceiver()->IsJSGlobalObject()); // Now update the cell in the feedback vector. - StoreGlobalICNexus* nexus = casted_nexus<StoreGlobalICNexus>(); - nexus->ConfigurePropertyCellMode(lookup->GetPropertyCell()); + nexus()->ConfigurePropertyCellMode(lookup->GetPropertyCell()); TRACE_IC("StoreGlobalIC", lookup->name()); return; } @@ -1439,7 +1474,7 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) { case LookupIterator::TRANSITION: { Handle<JSObject> holder = lookup->GetHolder<JSObject>(); - Handle<JSObject> store_target = lookup->GetStoreTarget(); + Handle<JSObject> store_target = lookup->GetStoreTarget<JSObject>(); if (store_target->IsJSGlobalObject()) { TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransitionDH); @@ -1692,7 +1727,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, } if (receiver_map.is_identical_to(previous_receiver_map) && old_store_mode == STANDARD_STORE && - (store_mode == STORE_AND_GROW_NO_TRANSITION || + (store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW || store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { // A "normal" IC that handles stores can switch to a version that can @@ -1787,10 +1822,10 @@ Handle<Map> KeyedStoreIC::ComputeTransitionedMap( } case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS: DCHECK(map->has_fixed_typed_array_elements()); - // Fall through + V8_FALLTHROUGH; case STORE_NO_TRANSITION_HANDLE_COW: case STANDARD_STORE: - case STORE_AND_GROW_NO_TRANSITION: + case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW: return map; } UNREACHABLE(); @@ -1799,7 +1834,7 @@ Handle<Map> KeyedStoreIC::ComputeTransitionedMap( Handle<Object> KeyedStoreIC::StoreElementHandler( Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) { DCHECK(store_mode == STANDARD_STORE || - store_mode == STORE_AND_GROW_NO_TRANSITION || + store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW || store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || store_mode == STORE_NO_TRANSITION_HANDLE_COW); DCHECK(!receiver_map->DictionaryElementsInPrototypeChainOnly()); @@ -1840,7 +1875,7 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers( MapHandles* receiver_maps, ObjectHandles* handlers, KeyedAccessStoreMode store_mode) { DCHECK(store_mode == STANDARD_STORE || - store_mode == STORE_AND_GROW_NO_TRANSITION || + store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW || store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || store_mode == STORE_NO_TRANSITION_HANDLE_COW); @@ -1915,7 +1950,7 @@ static KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver, return STORE_AND_GROW_TRANSITION_TO_OBJECT; } } - return STORE_AND_GROW_NO_TRANSITION; + return STORE_AND_GROW_NO_TRANSITION_HANDLE_COW; } else { // Handle only in-bounds elements accesses. if (receiver->HasSmiElements()) { @@ -2005,7 +2040,13 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, old_receiver_map = handle(receiver->map(), isolate()); is_arguments = receiver->IsJSArgumentsObject(); bool is_proxy = receiver->IsJSProxy(); - key_is_valid_index = key->IsSmi() && Smi::ToInt(*key) >= 0; + // For JSTypedArray {object}s we can handle negative indices as OOB + // accesses, since integer indexed properties are never looked up + // on the prototype chain. For this we simply map the negative {key}s + // to the [2**31,2**32-1] range, which is safe since JSTypedArray::length + // is always an unsigned Smi. + key_is_valid_index = + key->IsSmi() && (Smi::ToInt(*key) >= 0 || object->IsJSTypedArray()); if (!is_arguments && !is_proxy) { if (key_is_valid_index) { uint32_t index = static_cast<uint32_t>(Smi::ToInt(*key)); @@ -2071,29 +2112,26 @@ RUNTIME_FUNCTION(Runtime_LoadIC_Miss) { Handle<Name> key = args.at<Name>(1); Handle<Smi> slot = args.at<Smi>(2); Handle<FeedbackVector> vector = args.at<FeedbackVector>(3); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); // A monomorphic or polymorphic KeyedLoadIC with a string key can call the // LoadIC miss handler if the handler misses. Since the vector Nexus is // set up outside the IC, handle that here. FeedbackSlotKind kind = vector->GetKind(vector_slot); if (IsLoadICKind(kind)) { - LoadICNexus nexus(vector, vector_slot); - LoadIC ic(isolate, &nexus); + LoadIC ic(isolate, vector, vector_slot); ic.UpdateState(receiver, key); RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); } else if (IsLoadGlobalICKind(kind)) { DCHECK_EQ(isolate->native_context()->global_proxy(), *receiver); receiver = isolate->global_object(); - LoadGlobalICNexus nexus(vector, vector_slot); - LoadGlobalIC ic(isolate, &nexus); + LoadGlobalIC ic(isolate, vector, vector_slot); ic.UpdateState(receiver, key); RETURN_RESULT_OR_FAILURE(isolate, ic.Load(key)); } else { DCHECK(IsKeyedLoadICKind(kind)); - KeyedLoadICNexus nexus(vector, vector_slot); - KeyedLoadIC ic(isolate, &nexus); + KeyedLoadIC ic(isolate, vector, vector_slot); ic.UpdateState(receiver, key); RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); } @@ -2108,10 +2146,9 @@ RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Miss) { Handle<String> name = args.at<String>(0); Handle<Smi> slot = args.at<Smi>(1); Handle<FeedbackVector> vector = args.at<FeedbackVector>(2); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); - LoadGlobalICNexus nexus(vector, vector_slot); - LoadGlobalIC ic(isolate, &nexus); + LoadGlobalIC ic(isolate, vector, vector_slot); ic.UpdateState(global, name); Handle<Object> result; @@ -2150,7 +2187,7 @@ RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Slow) { if (!is_found) { Handle<Smi> slot = args.at<Smi>(1); Handle<FeedbackVector> vector = args.at<FeedbackVector>(2); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); FeedbackSlotKind kind = vector->GetKind(vector_slot); // It is actually a LoadGlobalICs here but the predicate handles this case // properly. @@ -2171,9 +2208,8 @@ RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) { Handle<Object> key = args.at(1); Handle<Smi> slot = args.at<Smi>(2); Handle<FeedbackVector> vector = args.at<FeedbackVector>(3); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); - KeyedLoadICNexus nexus(vector, vector_slot); - KeyedLoadIC ic(isolate, &nexus); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); + KeyedLoadIC ic(isolate, vector, vector_slot); ic.UpdateState(receiver, key); RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); } @@ -2188,24 +2224,21 @@ RUNTIME_FUNCTION(Runtime_StoreIC_Miss) { Handle<FeedbackVector> vector = args.at<FeedbackVector>(2); Handle<Object> receiver = args.at(3); Handle<Name> key = args.at<Name>(4); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); FeedbackSlotKind kind = vector->GetKind(vector_slot); if (IsStoreICKind(kind) || IsStoreOwnICKind(kind)) { - StoreICNexus nexus(vector, vector_slot); - StoreIC ic(isolate, &nexus); + StoreIC ic(isolate, vector, vector_slot); ic.UpdateState(receiver, key); RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); } else if (IsStoreGlobalICKind(kind)) { DCHECK_EQ(isolate->native_context()->global_proxy(), *receiver); receiver = isolate->global_object(); - StoreGlobalICNexus nexus(vector, vector_slot); - StoreGlobalIC ic(isolate, &nexus); + StoreGlobalIC ic(isolate, vector, vector_slot); ic.UpdateState(receiver, key); RETURN_RESULT_OR_FAILURE(isolate, ic.Store(key, value)); } else { DCHECK(IsKeyedStoreICKind(kind)); - KeyedStoreICNexus nexus(vector, vector_slot); - KeyedStoreIC ic(isolate, &nexus); + KeyedStoreIC ic(isolate, vector, vector_slot); ic.UpdateState(receiver, key); RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); } @@ -2219,9 +2252,8 @@ RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Miss) { Handle<Smi> slot = args.at<Smi>(1); Handle<FeedbackVector> vector = args.at<FeedbackVector>(2); Handle<Name> key = args.at<Name>(3); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); - StoreGlobalICNexus nexus(vector, vector_slot); - StoreGlobalIC ic(isolate, &nexus); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); + StoreGlobalIC ic(isolate, vector, vector_slot); Handle<JSGlobalObject> global = isolate->global_object(); ic.UpdateState(global, key); RETURN_RESULT_OR_FAILURE(isolate, ic.Store(key, value)); @@ -2238,7 +2270,7 @@ RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Slow) { #ifdef DEBUG { - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); FeedbackSlotKind slot_kind = vector->GetKind(vector_slot); DCHECK(IsStoreGlobalICKind(slot_kind)); Handle<Object> receiver = args.at(3); @@ -2272,7 +2304,7 @@ RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Slow) { return *value; } - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); LanguageMode language_mode = vector->GetLanguageMode(vector_slot); RETURN_RESULT_OR_FAILURE( isolate, @@ -2289,9 +2321,8 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) { Handle<FeedbackVector> vector = args.at<FeedbackVector>(2); Handle<Object> receiver = args.at(3); Handle<Object> key = args.at(4); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); - KeyedStoreICNexus nexus(vector, vector_slot); - KeyedStoreIC ic(isolate, &nexus); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); + KeyedStoreIC ic(isolate, vector, vector_slot); ic.UpdateState(receiver, key); RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); } @@ -2306,7 +2337,7 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { Handle<FeedbackVector> vector = args.at<FeedbackVector>(2); Handle<Object> object = args.at(3); Handle<Object> key = args.at(4); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); LanguageMode language_mode = vector->GetLanguageMode(vector_slot); RETURN_RESULT_OR_FAILURE( isolate, @@ -2324,7 +2355,7 @@ RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { Handle<Map> map = args.at<Map>(3); Handle<Smi> slot = args.at<Smi>(4); Handle<FeedbackVector> vector = args.at<FeedbackVector>(5); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); LanguageMode language_mode = vector->GetLanguageMode(vector_slot); if (object->IsJSObject()) { JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), @@ -2336,11 +2367,6 @@ RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { } -RUNTIME_FUNCTION(Runtime_Unreachable) { - UNREACHABLE(); -} - - RUNTIME_FUNCTION(Runtime_StoreCallbackProperty) { Handle<JSObject> receiver = args.at<JSObject>(0); Handle<JSObject> holder = args.at<JSObject>(1); @@ -2413,7 +2439,7 @@ RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) { Handle<Smi> slot = args.at<Smi>(3); Handle<FeedbackVector> vector = args.at<FeedbackVector>(4); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); FeedbackSlotKind slot_kind = vector->GetKind(vector_slot); // It could actually be any kind of load IC slot here but the predicate // handles all the cases properly. @@ -2436,7 +2462,7 @@ RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { Handle<FeedbackVector> vector = args.at<FeedbackVector>(2); Handle<JSObject> receiver = args.at<JSObject>(3); Handle<Name> name = args.at<Name>(4); - FeedbackSlot vector_slot = vector->ToSlot(slot->value()); + FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value()); LanguageMode language_mode = vector->GetLanguageMode(vector_slot); // TODO(ishell): Cache interceptor_holder in the store handler like we do diff --git a/deps/v8/src/ic/ic.h b/deps/v8/src/ic/ic.h index a63202395b..8a47d8d19c 100644 --- a/deps/v8/src/ic/ic.h +++ b/deps/v8/src/ic/ic.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef V8_IC_H_ -#define V8_IC_H_ +#ifndef V8_IC_IC_H_ +#define V8_IC_IC_H_ #include <vector> @@ -36,7 +36,8 @@ class IC { // Construct the IC structure with the given number of extra // JavaScript frames on the stack. - IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = nullptr); + IC(FrameDepth depth, Isolate* isolate, Handle<FeedbackVector> vector, + FeedbackSlot slot); virtual ~IC() {} State state() const { return state_; } @@ -67,6 +68,9 @@ class IC { FeedbackSlot slot, JSFunction* host_function, const char* reason); + static void OnFeedbackChanged(Isolate* isolate, FeedbackNexus* nexus, + JSFunction* host_function, const char* reason); + protected: Address fp() const { return fp_; } Address pc() const { return *pc_address_; } @@ -151,17 +155,12 @@ class IC { return !target_maps_.empty() ? *target_maps_[0] : nullptr; } - Handle<FeedbackVector> vector() const { return nexus()->vector_handle(); } - FeedbackSlot slot() const { return nexus()->slot(); } State saved_state() const { return state() == RECOMPUTE_HANDLER ? old_state_ : state(); } - template <class NexusClass> - NexusClass* casted_nexus() { - return static_cast<NexusClass*>(nexus_); - } - FeedbackNexus* nexus() const { return nexus_; } + const FeedbackNexus* nexus() const { return &nexus_; } + FeedbackNexus* nexus() { return &nexus_; } private: inline Address constant_pool() const; @@ -200,7 +199,7 @@ class IC { const char* slow_stub_reason_; - FeedbackNexus* nexus_; + FeedbackNexus nexus_; DISALLOW_IMPLICIT_CONSTRUCTORS(IC); }; @@ -208,18 +207,15 @@ class IC { class CallIC : public IC { public: - CallIC(Isolate* isolate, CallICNexus* nexus) - : IC(EXTRA_CALL_FRAME, isolate, nexus) { - DCHECK_NOT_NULL(nexus); - } + CallIC(Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot slot) + : IC(EXTRA_CALL_FRAME, isolate, vector, slot) {} }; class LoadIC : public IC { public: - LoadIC(Isolate* isolate, FeedbackNexus* nexus) - : IC(NO_EXTRA_FRAME, isolate, nexus) { - DCHECK_NOT_NULL(nexus); + LoadIC(Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot slot) + : IC(NO_EXTRA_FRAME, isolate, vector, slot) { DCHECK(IsAnyLoad()); } @@ -252,8 +248,9 @@ class LoadIC : public IC { class LoadGlobalIC : public LoadIC { public: - LoadGlobalIC(Isolate* isolate, FeedbackNexus* nexus) - : LoadIC(isolate, nexus) {} + LoadGlobalIC(Isolate* isolate, Handle<FeedbackVector> vector, + FeedbackSlot slot) + : LoadIC(isolate, vector, slot) {} MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Name> name); @@ -265,10 +262,9 @@ class LoadGlobalIC : public LoadIC { class KeyedLoadIC : public LoadIC { public: - KeyedLoadIC(Isolate* isolate, KeyedLoadICNexus* nexus) - : LoadIC(isolate, nexus) { - DCHECK_NOT_NULL(nexus); - } + KeyedLoadIC(Isolate* isolate, Handle<FeedbackVector> vector, + FeedbackSlot slot) + : LoadIC(isolate, vector, slot) {} MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, Handle<Object> key); @@ -297,14 +293,12 @@ class KeyedLoadIC : public LoadIC { class StoreIC : public IC { public: - StoreIC(Isolate* isolate, FeedbackNexus* nexus) - : IC(NO_EXTRA_FRAME, isolate, nexus) { + StoreIC(Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot slot) + : IC(NO_EXTRA_FRAME, isolate, vector, slot) { DCHECK(IsAnyStore()); } - LanguageMode language_mode() const { - return nexus()->vector()->GetLanguageMode(nexus()->slot()); - } + LanguageMode language_mode() const { return nexus()->GetLanguageMode(); } MUST_USE_RESULT MaybeHandle<Object> Store( Handle<Object> object, Handle<Name> name, Handle<Object> value, @@ -337,8 +331,9 @@ class StoreIC : public IC { class StoreGlobalIC : public StoreIC { public: - StoreGlobalIC(Isolate* isolate, FeedbackNexus* nexus) - : StoreIC(isolate, nexus) {} + StoreGlobalIC(Isolate* isolate, Handle<FeedbackVector> vector, + FeedbackSlot slot) + : StoreIC(isolate, vector, slot) {} MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Name> name, Handle<Object> value); @@ -358,11 +353,12 @@ enum KeyedStoreIncrementLength { kDontIncrementLength, kIncrementLength }; class KeyedStoreIC : public StoreIC { public: KeyedAccessStoreMode GetKeyedAccessStoreMode() { - return casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode(); + return nexus()->GetKeyedAccessStoreMode(); } - KeyedStoreIC(Isolate* isolate, KeyedStoreICNexus* nexus) - : StoreIC(isolate, nexus) {} + KeyedStoreIC(Isolate* isolate, Handle<FeedbackVector> vector, + FeedbackSlot slot) + : StoreIC(isolate, vector, slot) {} MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object, Handle<Object> name, @@ -389,4 +385,4 @@ class KeyedStoreIC : public StoreIC { } // namespace internal } // namespace v8 -#endif // V8_IC_H_ +#endif // V8_IC_IC_H_ diff --git a/deps/v8/src/ic/keyed-store-generic.cc b/deps/v8/src/ic/keyed-store-generic.cc index b9a11c2ec7..4997267ddd 100644 --- a/deps/v8/src/ic/keyed-store-generic.cc +++ b/deps/v8/src/ic/keyed-store-generic.cc @@ -428,9 +428,10 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( void KeyedStoreGenericAssembler::EmitGenericElementStore( Node* receiver, Node* receiver_map, Node* instance_type, Node* intptr_index, Node* value, Node* context, Label* slow) { - Label if_fast(this), if_in_bounds(this), if_increment_length_by_one(this), - if_bump_length_with_gap(this), if_grow(this), if_nonfast(this), - if_typed_array(this), if_dictionary(this); + Label if_fast(this), if_in_bounds(this), if_out_of_bounds(this), + if_increment_length_by_one(this), if_bump_length_with_gap(this), + if_grow(this), if_nonfast(this), if_typed_array(this), + if_dictionary(this); Node* elements = LoadElements(receiver); Node* elements_kind = LoadMapElementsKind(receiver_map); Branch(IsFastElementsKind(elements_kind), &if_fast, &if_nonfast); @@ -440,7 +441,8 @@ void KeyedStoreGenericAssembler::EmitGenericElementStore( GotoIf(InstanceTypeEqual(instance_type, JS_ARRAY_TYPE), &if_array); { Node* capacity = SmiUntag(LoadFixedArrayBaseLength(elements)); - Branch(UintPtrLessThan(intptr_index, capacity), &if_in_bounds, &if_grow); + Branch(UintPtrLessThan(intptr_index, capacity), &if_in_bounds, + &if_out_of_bounds); } BIND(&if_array); { @@ -459,6 +461,16 @@ void KeyedStoreGenericAssembler::EmitGenericElementStore( kDontChangeLength); } + BIND(&if_out_of_bounds); + { + // Integer indexed out-of-bounds accesses to typed arrays are simply + // ignored, since we never look up integer indexed properties on the + // prototypes of typed arrays. For all other types, we may need to + // grow the backing store. + GotoIfNot(InstanceTypeEqual(instance_type, JS_TYPED_ARRAY_TYPE), &if_grow); + Return(value); + } + BIND(&if_increment_length_by_one); { StoreElementWithCapacity(receiver, receiver_map, elements, elements_kind, @@ -911,9 +923,8 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( BIND(&strict); { - Node* message = SmiConstant(MessageTemplate::kNoSetterInCallback); - TailCallRuntime(Runtime::kThrowTypeError, p->context, message, p->name, - var_accessor_holder.value()); + ThrowTypeError(p->context, MessageTemplate::kNoSetterInCallback, + p->name, var_accessor_holder.value()); } } } @@ -926,10 +937,9 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( BIND(&strict); { - Node* message = SmiConstant(MessageTemplate::kStrictReadOnlyProperty); Node* type = Typeof(p->receiver); - TailCallRuntime(Runtime::kThrowTypeError, p->context, message, p->name, - type, p->receiver); + ThrowTypeError(p->context, MessageTemplate::kStrictReadOnlyProperty, + p->name, type, p->receiver); } } diff --git a/deps/v8/src/ic/keyed-store-generic.h b/deps/v8/src/ic/keyed-store-generic.h index 4d82840be3..1a0de3b2b4 100644 --- a/deps/v8/src/ic/keyed-store-generic.h +++ b/deps/v8/src/ic/keyed-store-generic.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef V8_SRC_IC_KEYED_STORE_GENERIC_H_ -#define V8_SRC_IC_KEYED_STORE_GENERIC_H_ +#ifndef V8_IC_KEYED_STORE_GENERIC_H_ +#define V8_IC_KEYED_STORE_GENERIC_H_ #include "src/globals.h" @@ -27,4 +27,4 @@ class StoreICUninitializedGenerator { } // namespace internal } // namespace v8 -#endif // V8_SRC_IC_KEYED_STORE_GENERIC_H_ +#endif // V8_IC_KEYED_STORE_GENERIC_H_ diff --git a/deps/v8/src/ic/stub-cache.h b/deps/v8/src/ic/stub-cache.h index cd081edfb2..870266eefd 100644 --- a/deps/v8/src/ic/stub-cache.h +++ b/deps/v8/src/ic/stub-cache.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef V8_STUB_CACHE_H_ -#define V8_STUB_CACHE_H_ +#ifndef V8_IC_STUB_CACHE_H_ +#define V8_IC_STUB_CACHE_H_ #include "src/macro-assembler.h" #include "src/objects/name.h" @@ -140,4 +140,4 @@ class StubCache { } // namespace internal } // namespace v8 -#endif // V8_STUB_CACHE_H_ +#endif // V8_IC_STUB_CACHE_H_ |