Commit 937b8cb6 authored by ishell's avatar ishell Committed by Commit bot

[ic] Support data handlers in LoadGlobalIC.

Also fixed handling of load non-existent handlers outside typeof.

BUG=v8:5561, chromium:662854

Review-Url: https://codereview.chromium.org/2511603002
Cr-Commit-Position: refs/heads/master@{#41073}
parent 48bbd1a7
...@@ -439,9 +439,6 @@ Handle<Code> TurboFanCodeStub::GenerateCode() { ...@@ -439,9 +439,6 @@ Handle<Code> TurboFanCodeStub::GenerateCode() {
ACCESSOR_ASSEMBLER(LoadIC) ACCESSOR_ASSEMBLER(LoadIC)
ACCESSOR_ASSEMBLER(LoadICTrampoline) ACCESSOR_ASSEMBLER(LoadICTrampoline)
ACCESSOR_ASSEMBLER(LoadICProtoArray)
ACCESSOR_ASSEMBLER(LoadGlobalIC)
ACCESSOR_ASSEMBLER(LoadGlobalICTrampoline)
ACCESSOR_ASSEMBLER(KeyedLoadICTF) ACCESSOR_ASSEMBLER(KeyedLoadICTF)
ACCESSOR_ASSEMBLER(KeyedLoadICTrampolineTF) ACCESSOR_ASSEMBLER(KeyedLoadICTrampolineTF)
ACCESSOR_ASSEMBLER(StoreIC) ACCESSOR_ASSEMBLER(StoreIC)
...@@ -449,16 +446,28 @@ ACCESSOR_ASSEMBLER(StoreICTrampoline) ...@@ -449,16 +446,28 @@ ACCESSOR_ASSEMBLER(StoreICTrampoline)
#undef ACCESSOR_ASSEMBLER #undef ACCESSOR_ASSEMBLER
void LoadICProtoArrayStub::GenerateAssembly(CodeAssemblerState* state) const {
AccessorAssembler::GenerateLoadICProtoArray(
state, throw_reference_error_if_nonexistent());
}
void LoadGlobalICStub::GenerateAssembly(CodeAssemblerState* state) const {
AccessorAssembler::GenerateLoadGlobalIC(state, typeof_mode());
}
void LoadGlobalICTrampolineStub::GenerateAssembly(
CodeAssemblerState* state) const {
AccessorAssembler::GenerateLoadGlobalICTrampoline(state, typeof_mode());
}
void KeyedStoreICTrampolineTFStub::GenerateAssembly( void KeyedStoreICTrampolineTFStub::GenerateAssembly(
CodeAssemblerState* state) const { CodeAssemblerState* state) const {
LanguageMode language_mode = StoreICState::GetLanguageMode(GetExtraICState()); AccessorAssembler::GenerateKeyedStoreICTrampolineTF(state, language_mode());
AccessorAssembler::GenerateKeyedStoreICTrampolineTF(state, language_mode);
} }
void KeyedStoreICTFStub::GenerateAssembly( void KeyedStoreICTFStub::GenerateAssembly(
compiler::CodeAssemblerState* state) const { compiler::CodeAssemblerState* state) const {
LanguageMode language_mode = StoreICState::GetLanguageMode(GetExtraICState()); AccessorAssembler::GenerateKeyedStoreICTF(state, language_mode());
AccessorAssembler::GenerateKeyedStoreICTF(state, language_mode);
} }
void StoreMapStub::GenerateAssembly(compiler::CodeAssemblerState* state) const { void StoreMapStub::GenerateAssembly(compiler::CodeAssemblerState* state) const {
......
...@@ -1956,6 +1956,11 @@ class LoadGlobalICTrampolineStub : public TurboFanCodeStub { ...@@ -1956,6 +1956,11 @@ class LoadGlobalICTrampolineStub : public TurboFanCodeStub {
Code::Kind GetCodeKind() const override { return Code::LOAD_GLOBAL_IC; } Code::Kind GetCodeKind() const override { return Code::LOAD_GLOBAL_IC; }
TypeofMode typeof_mode() const {
LoadGlobalICState state(GetExtraICState());
return state.typeof_mode();
}
ExtraICState GetExtraICState() const final { ExtraICState GetExtraICState() const final {
return static_cast<ExtraICState>(minor_key_); return static_cast<ExtraICState>(minor_key_);
} }
...@@ -2022,6 +2027,10 @@ class KeyedStoreICTrampolineTFStub : public StoreICTrampolineStub { ...@@ -2022,6 +2027,10 @@ class KeyedStoreICTrampolineTFStub : public StoreICTrampolineStub {
Code::Kind GetCodeKind() const override { return Code::KEYED_STORE_IC; } Code::Kind GetCodeKind() const override { return Code::KEYED_STORE_IC; }
LanguageMode language_mode() const {
return StoreICState(GetExtraICState()).language_mode();
}
DEFINE_TURBOFAN_CODE_STUB(KeyedStoreICTrampolineTF, StoreICTrampolineStub); DEFINE_TURBOFAN_CODE_STUB(KeyedStoreICTrampolineTF, StoreICTrampolineStub);
}; };
...@@ -2059,7 +2068,23 @@ class LoadICStub : public TurboFanCodeStub { ...@@ -2059,7 +2068,23 @@ class LoadICStub : public TurboFanCodeStub {
class LoadICProtoArrayStub : public TurboFanCodeStub { class LoadICProtoArrayStub : public TurboFanCodeStub {
public: public:
explicit LoadICProtoArrayStub(Isolate* isolate) : TurboFanCodeStub(isolate) {} explicit LoadICProtoArrayStub(Isolate* isolate,
bool throw_reference_error_if_nonexistent)
: TurboFanCodeStub(isolate) {
minor_key_ = ThrowReferenceErrorIfNonexistentBits::encode(
throw_reference_error_if_nonexistent);
}
bool throw_reference_error_if_nonexistent() const {
return ThrowReferenceErrorIfNonexistentBits::decode(minor_key_);
}
ExtraICState GetExtraICState() const final {
return static_cast<ExtraICState>(minor_key_);
}
private:
class ThrowReferenceErrorIfNonexistentBits : public BitField<bool, 0, 1> {};
DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadICProtoArray); DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadICProtoArray);
DEFINE_TURBOFAN_CODE_STUB(LoadICProtoArray, TurboFanCodeStub); DEFINE_TURBOFAN_CODE_STUB(LoadICProtoArray, TurboFanCodeStub);
...@@ -2074,6 +2099,11 @@ class LoadGlobalICStub : public TurboFanCodeStub { ...@@ -2074,6 +2099,11 @@ class LoadGlobalICStub : public TurboFanCodeStub {
Code::Kind GetCodeKind() const override { return Code::LOAD_GLOBAL_IC; } Code::Kind GetCodeKind() const override { return Code::LOAD_GLOBAL_IC; }
TypeofMode typeof_mode() const {
LoadGlobalICState state(GetExtraICState());
return state.typeof_mode();
}
ExtraICState GetExtraICState() const final { ExtraICState GetExtraICState() const final {
return static_cast<ExtraICState>(minor_key_); return static_cast<ExtraICState>(minor_key_);
} }
...@@ -2099,6 +2129,11 @@ class StoreICStub : public TurboFanCodeStub { ...@@ -2099,6 +2129,11 @@ class StoreICStub : public TurboFanCodeStub {
} }
Code::Kind GetCodeKind() const override { return Code::STORE_IC; } Code::Kind GetCodeKind() const override { return Code::STORE_IC; }
LanguageMode language_mode() const {
return StoreICState(GetExtraICState()).language_mode();
}
ExtraICState GetExtraICState() const final { ExtraICState GetExtraICState() const final {
return static_cast<ExtraICState>(minor_key_); return static_cast<ExtraICState>(minor_key_);
} }
...@@ -2136,6 +2171,10 @@ class KeyedStoreICTFStub : public StoreICStub { ...@@ -2136,6 +2171,10 @@ class KeyedStoreICTFStub : public StoreICStub {
Code::Kind GetCodeKind() const override { return Code::KEYED_STORE_IC; } Code::Kind GetCodeKind() const override { return Code::KEYED_STORE_IC; }
LanguageMode language_mode() const {
return StoreICState(GetExtraICState()).language_mode();
}
DEFINE_TURBOFAN_CODE_STUB(KeyedStoreICTF, StoreICStub); DEFINE_TURBOFAN_CODE_STUB(KeyedStoreICTF, StoreICStub);
}; };
......
...@@ -508,6 +508,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, ...@@ -508,6 +508,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
proxy->VariableFeedbackSlot()); proxy->VariableFeedbackSlot());
Handle<Code> code = CodeFactory::LoadGlobalIC(isolate(), typeof_mode).code(); Handle<Code> code = CodeFactory::LoadGlobalIC(isolate(), typeof_mode).code();
__ Call(code, RelocInfo::CODE_TARGET); __ Call(code, RelocInfo::CODE_TARGET);
RestoreContext();
} }
void FullCodeGenerator::VisitSloppyBlockFunctionStatement( void FullCodeGenerator::VisitSloppyBlockFunctionStatement(
......
...@@ -314,26 +314,24 @@ inline std::ostream& operator<<(std::ostream& os, const LanguageMode& mode) { ...@@ -314,26 +314,24 @@ inline std::ostream& operator<<(std::ostream& os, const LanguageMode& mode) {
return os; return os;
} }
inline bool is_sloppy(LanguageMode language_mode) { inline bool is_sloppy(LanguageMode language_mode) {
return language_mode == SLOPPY; return language_mode == SLOPPY;
} }
inline bool is_strict(LanguageMode language_mode) { inline bool is_strict(LanguageMode language_mode) {
return language_mode != SLOPPY; return language_mode != SLOPPY;
} }
inline bool is_valid_language_mode(int language_mode) { inline bool is_valid_language_mode(int language_mode) {
return language_mode == SLOPPY || language_mode == STRICT; return language_mode == SLOPPY || language_mode == STRICT;
} }
inline LanguageMode construct_language_mode(bool strict_bit) { inline LanguageMode construct_language_mode(bool strict_bit) {
return static_cast<LanguageMode>(strict_bit); return static_cast<LanguageMode>(strict_bit);
} }
enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
// This constant is used as an undefined value when passing source positions. // This constant is used as an undefined value when passing source positions.
const int kNoSourcePosition = -1; const int kNoSourcePosition = -1;
......
...@@ -19,16 +19,13 @@ using compiler::Node; ...@@ -19,16 +19,13 @@ using compiler::Node;
#define ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(V) \ #define ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(V) \
V(LoadIC) \ V(LoadIC) \
V(LoadICTrampoline) \ V(LoadICTrampoline) \
V(LoadICProtoArray) \
V(LoadGlobalIC) \
V(LoadGlobalICTrampoline) \
V(KeyedLoadICTF) \ V(KeyedLoadICTF) \
V(KeyedLoadICTrampolineTF) \ V(KeyedLoadICTrampolineTF) \
V(KeyedLoadICMegamorphic) \ V(KeyedLoadICMegamorphic) \
V(StoreIC) \ V(StoreIC) \
V(StoreICTrampoline) V(StoreICTrampoline)
// KeyedStoreIC and KeyedStoreICTrampoline need custom handling because of // The other IC entry points need custom handling because of additional
// their "language_mode" parameter. // parameters like "typeof_mode" or "language_mode".
class AccessorAssemblerImpl : public CodeStubAssembler { class AccessorAssemblerImpl : public CodeStubAssembler {
public: public:
...@@ -40,6 +37,11 @@ class AccessorAssemblerImpl : public CodeStubAssembler { ...@@ -40,6 +37,11 @@ class AccessorAssemblerImpl : public CodeStubAssembler {
ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(DECLARE_PUBLIC_METHOD) ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(DECLARE_PUBLIC_METHOD)
#undef DECLARE_PUBLIC_METHOD #undef DECLARE_PUBLIC_METHOD
void GenerateLoadICProtoArray(bool throw_reference_error_if_nonexistent);
void GenerateLoadGlobalIC(TypeofMode typeof_mode);
void GenerateLoadGlobalICTrampoline(TypeofMode typeof_mode);
void GenerateKeyedStoreICTF(LanguageMode language_mode); void GenerateKeyedStoreICTF(LanguageMode language_mode);
void GenerateKeyedStoreICTrampolineTF(LanguageMode language_mode); void GenerateKeyedStoreICTrampolineTF(LanguageMode language_mode);
...@@ -88,8 +90,9 @@ class AccessorAssemblerImpl : public CodeStubAssembler { ...@@ -88,8 +90,9 @@ class AccessorAssemblerImpl : public CodeStubAssembler {
// Stub generation entry points. // Stub generation entry points.
void LoadIC(const LoadICParameters* p); void LoadIC(const LoadICParameters* p);
void LoadICProtoArray(const LoadICParameters* p, Node* handler); void LoadICProtoArray(const LoadICParameters* p, Node* handler,
void LoadGlobalIC(const LoadICParameters* p); bool throw_reference_error_if_nonexistent);
void LoadGlobalIC(const LoadICParameters* p, TypeofMode typeof_mode);
void KeyedLoadIC(const LoadICParameters* p); void KeyedLoadIC(const LoadICParameters* p);
void KeyedLoadICGeneric(const LoadICParameters* p); void KeyedLoadICGeneric(const LoadICParameters* p);
void StoreIC(const StoreICParameters* p); void StoreIC(const StoreICParameters* p);
...@@ -120,13 +123,22 @@ class AccessorAssemblerImpl : public CodeStubAssembler { ...@@ -120,13 +123,22 @@ class AccessorAssemblerImpl : public CodeStubAssembler {
Node* smi_handler, Label* miss, Node* smi_handler, Label* miss,
ElementSupport support_elements); ElementSupport support_elements);
void HandleLoadICProtoHandler(const LoadICParameters* p, Node* handler, void HandleLoadICProtoHandlerCase(const LoadICParameters* p, Node* handler,
Variable* var_holder, Variable* var_smi_handler, Variable* var_holder,
Label* if_smi_handler, Label* miss); Variable* var_smi_handler,
Label* if_smi_handler, Label* miss,
bool throw_reference_error_if_nonexistent);
Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler, Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler,
Node* handler_length, Node* handler_flags, Node* handler_length, Node* handler_flags,
Label* miss); Label* miss,
bool throw_reference_error_if_nonexistent);
// LoadGlobalIC implementation.
void HandleLoadGlobalICHandlerCase(const LoadICParameters* p, Node* handler,
Label* miss,
bool throw_reference_error_if_nonexistent);
// StoreIC implementation. // StoreIC implementation.
......
This diff is collapsed.
...@@ -18,10 +18,13 @@ class AccessorAssembler { ...@@ -18,10 +18,13 @@ class AccessorAssembler {
public: public:
static void GenerateLoadIC(compiler::CodeAssemblerState* state); static void GenerateLoadIC(compiler::CodeAssemblerState* state);
static void GenerateLoadICTrampoline(compiler::CodeAssemblerState* state); static void GenerateLoadICTrampoline(compiler::CodeAssemblerState* state);
static void GenerateLoadICProtoArray(compiler::CodeAssemblerState* state); static void GenerateLoadICProtoArray(
static void GenerateLoadGlobalIC(compiler::CodeAssemblerState* state); compiler::CodeAssemblerState* state,
bool throw_reference_error_if_nonexistent);
static void GenerateLoadGlobalIC(compiler::CodeAssemblerState* state,
TypeofMode typeof_mode);
static void GenerateLoadGlobalICTrampoline( static void GenerateLoadGlobalICTrampoline(
compiler::CodeAssemblerState* state); compiler::CodeAssemblerState* state, TypeofMode typeof_mode);
static void GenerateKeyedLoadICTF(compiler::CodeAssemblerState* state); static void GenerateKeyedLoadICTF(compiler::CodeAssemblerState* state);
static void GenerateKeyedLoadICTrampolineTF( static void GenerateKeyedLoadICTrampolineTF(
compiler::CodeAssemblerState* state); compiler::CodeAssemblerState* state);
......
...@@ -564,7 +564,7 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, ...@@ -564,7 +564,7 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
nexus->ConfigureMonomorphic(map, handler); nexus->ConfigureMonomorphic(map, handler);
} else if (kind() == Code::LOAD_GLOBAL_IC) { } else if (kind() == Code::LOAD_GLOBAL_IC) {
LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>();
nexus->ConfigureHandlerMode(Handle<Code>::cast(handler)); nexus->ConfigureHandlerMode(handler);
} else if (kind() == Code::KEYED_LOAD_IC) { } else if (kind() == Code::KEYED_LOAD_IC) {
KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
nexus->ConfigureMonomorphic(name, map, handler); nexus->ConfigureMonomorphic(name, map, handler);
...@@ -794,6 +794,7 @@ void IC::PatchCache(Handle<Name> name, Handle<Object> handler) { ...@@ -794,6 +794,7 @@ void IC::PatchCache(Handle<Name> name, Handle<Object> handler) {
DCHECK(IsHandler(*handler)); DCHECK(IsHandler(*handler));
// Currently only LoadIC and KeyedLoadIC support non-code handlers. // Currently only LoadIC and KeyedLoadIC support non-code handlers.
DCHECK_IMPLIES(!handler->IsCode(), kind() == Code::LOAD_IC || DCHECK_IMPLIES(!handler->IsCode(), kind() == Code::LOAD_IC ||
kind() == Code::LOAD_GLOBAL_IC ||
kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_LOAD_IC ||
kind() == Code::STORE_IC || kind() == Code::STORE_IC ||
kind() == Code::KEYED_STORE_IC); kind() == Code::KEYED_STORE_IC);
...@@ -858,10 +859,6 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, ...@@ -858,10 +859,6 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
Handle<Name> name, int first_index) { Handle<Name> name, int first_index) {
DCHECK(holder.is_null() || holder->HasFastProperties()); DCHECK(holder.is_null() || holder->HasFastProperties());
// The following kinds of receiver maps require custom handler compilation.
if (receiver_map->IsJSGlobalObjectMap()) {
return -1;
}
// We don't encode the requirement to check access rights because we already // We don't encode the requirement to check access rights because we already
// passed the access check for current native context and the access // passed the access check for current native context and the access
// can't be revoked. // can't be revoked.
...@@ -882,6 +879,17 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, ...@@ -882,6 +879,17 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
native_context->self_weak_cell()); native_context->self_weak_cell());
} }
checks_count++; checks_count++;
} else if (receiver_map->IsJSGlobalObjectMap()) {
if (fill_array) {
Handle<JSGlobalObject> global = isolate->global_object();
Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell(
global, name, PropertyCellType::kInvalidated);
DCHECK(cell->value()->IsTheHole(isolate));
Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell);
array->set(LoadHandler::kFirstPrototypeIndex + checks_count, *weak_cell);
}
checks_count++;
} }
// Create/count entries for each global or dictionary prototype appeared in // Create/count entries for each global or dictionary prototype appeared in
...@@ -937,14 +945,14 @@ Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map, ...@@ -937,14 +945,14 @@ Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
Handle<Object> smi_handler) { Handle<Object> smi_handler) {
int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder); int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder);
DCHECK_LE(0, checks_count); DCHECK_LE(0, checks_count);
DCHECK(!receiver_map->IsJSGlobalObjectMap());
if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) {
DCHECK(!receiver_map->is_dictionary_map()); DCHECK(!receiver_map->is_dictionary_map());
DCHECK_LE(1, checks_count); // For native context. DCHECK_LE(1, checks_count); // For native context.
smi_handler = smi_handler =
LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler); LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler);
} else if (receiver_map->is_dictionary_map()) { } else if (receiver_map->is_dictionary_map() &&
!receiver_map->IsJSGlobalObjectMap()) {
smi_handler = smi_handler =
LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler);
} }
...@@ -975,10 +983,11 @@ Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map, ...@@ -975,10 +983,11 @@ Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map,
Handle<JSObject> holder; // null handle Handle<JSObject> holder; // null handle
int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder); int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder);
DCHECK_LE(0, checks_count); DCHECK_LE(0, checks_count);
DCHECK(!receiver_map->IsJSGlobalObjectMap());
Handle<Object> smi_handler = LoadHandler::LoadNonExistent( bool do_negative_lookup_on_receiver =
isolate(), receiver_map->is_dictionary_map()); receiver_map->is_dictionary_map() && !receiver_map->IsJSGlobalObjectMap();
Handle<Object> smi_handler =
LoadHandler::LoadNonExistent(isolate(), do_negative_lookup_on_receiver);
if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) {
DCHECK(!receiver_map->is_dictionary_map()); DCHECK(!receiver_map->is_dictionary_map());
...@@ -1066,14 +1075,16 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { ...@@ -1066,14 +1075,16 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
lookup->state() == LookupIterator::ACCESS_CHECK) { lookup->state() == LookupIterator::ACCESS_CHECK) {
code = slow_stub(); code = slow_stub();
} else if (!lookup->IsFound()) { } else if (!lookup->IsFound()) {
if (kind() == Code::LOAD_IC) { if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH); if (FLAG_tf_load_ic_stub) {
code = LoadNonExistent(receiver_map(), lookup->name()); TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH);
} else if (kind() == Code::LOAD_GLOBAL_IC) { code = LoadNonExistent(receiver_map(), lookup->name());
code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), } else {
receiver_map()); code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(),
// TODO(jkummerow/verwaest): Introduce a builtin that handles this case. receiver_map());
if (code.is_null()) code = slow_stub(); // TODO(jkummerow/verwaest): Introduce a builtin that handles this case.
if (code.is_null()) code = slow_stub();
}
} else { } else {
code = slow_stub(); code = slow_stub();
} }
...@@ -1394,7 +1405,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { ...@@ -1394,7 +1405,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
if (receiver_is_holder) { if (receiver_is_holder) {
return smi_handler; return smi_handler;
} }
if (FLAG_tf_load_ic_stub && kind() != Code::LOAD_GLOBAL_IC) { if (FLAG_tf_load_ic_stub) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH); TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH);
return LoadFromPrototype(map, holder, lookup->name(), smi_handler); return LoadFromPrototype(map, holder, lookup->name(), smi_handler);
} }
...@@ -1410,10 +1421,8 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { ...@@ -1410,10 +1421,8 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH); TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH);
return smi_handler; return smi_handler;
} }
if (kind() != Code::LOAD_GLOBAL_IC) { TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH);
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH); return LoadFromPrototype(map, holder, lookup->name(), smi_handler);
return LoadFromPrototype(map, holder, lookup->name(), smi_handler);
}
} else { } else {
if (receiver_is_holder) { if (receiver_is_holder) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub);
......
...@@ -181,10 +181,6 @@ enum KeyedAccessStoreMode { ...@@ -181,10 +181,6 @@ enum KeyedAccessStoreMode {
STORE_NO_TRANSITION_HANDLE_COW STORE_NO_TRANSITION_HANDLE_COW
}; };
enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
enum MutableMode { enum MutableMode {
MUTABLE, MUTABLE,
IMMUTABLE IMMUTABLE
......
...@@ -713,7 +713,7 @@ void LoadGlobalICNexus::ConfigurePropertyCellMode(Handle<PropertyCell> cell) { ...@@ -713,7 +713,7 @@ void LoadGlobalICNexus::ConfigurePropertyCellMode(Handle<PropertyCell> cell) {
SKIP_WRITE_BARRIER); SKIP_WRITE_BARRIER);
} }
void LoadGlobalICNexus::ConfigureHandlerMode(Handle<Code> handler) { void LoadGlobalICNexus::ConfigureHandlerMode(Handle<Object> handler) {
SetFeedback(GetIsolate()->heap()->empty_weak_cell()); SetFeedback(GetIsolate()->heap()->empty_weak_cell());
SetFeedbackExtra(*handler); SetFeedbackExtra(*handler);
} }
......
...@@ -555,7 +555,7 @@ class LoadGlobalICNexus : public FeedbackNexus { ...@@ -555,7 +555,7 @@ class LoadGlobalICNexus : public FeedbackNexus {
void ConfigureUninitialized() override; void ConfigureUninitialized() override;
void ConfigurePropertyCellMode(Handle<PropertyCell> cell); void ConfigurePropertyCellMode(Handle<PropertyCell> cell);
void ConfigureHandlerMode(Handle<Code> handler); void ConfigureHandlerMode(Handle<Object> handler);
InlineCacheState StateFromFeedback() const override; InlineCacheState StateFromFeedback() const override;
}; };
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function f() {
typeof boom;
boom;
}
assertThrows(()=>f());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment