summaryrefslogtreecommitdiff
path: root/deps/v8/src/ic
diff options
context:
space:
mode:
authorMyles Borins <mylesborins@google.com>2018-04-10 21:39:51 -0400
committerMyles Borins <mylesborins@google.com>2018-04-11 13:22:42 -0400
commit12a1b9b8049462e47181a298120243dc83e81c55 (patch)
tree8605276308c8b4e3597516961266bae1af57557a /deps/v8/src/ic
parent78cd8263354705b767ef8c6a651740efe4931ba0 (diff)
downloadandroid-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.cc95
-rw-r--r--deps/v8/src/ic/accessor-assembler.h6
-rw-r--r--deps/v8/src/ic/binary-op-assembler.h6
-rw-r--r--deps/v8/src/ic/ic-inl.h6
-rw-r--r--deps/v8/src/ic/ic.cc206
-rw-r--r--deps/v8/src/ic/ic.h66
-rw-r--r--deps/v8/src/ic/keyed-store-generic.cc30
-rw-r--r--deps/v8/src/ic/keyed-store-generic.h6
-rw-r--r--deps/v8/src/ic/stub-cache.h6
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_