Revert relanded strong property access CL

Reason:
Regressions in various benchmarks.

Revert "Revert of Revert of [strong] Implement strong mode restrictions on property access (patchset #1 id:1 of https://codereview.chromium.org/1189153002/)"

This reverts commit 41405c0470.

Revert "X87: Revert of Revert of [strong] Implement strong mode restrictions on property access."

This reverts commit 48de5f4d6b.

Revert "Fix overlapping KeyedLoadIC bitfield."

This reverts commit 4e6c956abf.

Revert "MIPS64: Fix 'Revert of Revert of [strong] Implement strong mode restrictions on property access'."

This reverts commit 74f97b0d2a.

BUG=

Review URL: https://codereview.chromium.org/1199493002

Cr-Commit-Position: refs/heads/master@{#29166}
This commit is contained in:
conradw 2015-06-19 12:00:45 -07:00 committed by Commit bot
parent 7028e4b531
commit 4ac7be5656
82 changed files with 625 additions and 2173 deletions

View File

@ -4372,7 +4372,7 @@ void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
KeyedLoadICStub stub(isolate(), state());
KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
@ -4582,7 +4582,7 @@ void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ b(ne, &try_poly_name);
Handle<Code> megamorphic_stub =
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);

View File

@ -2242,7 +2242,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ ldr(load_name, MemOperand(sp, 2 * kPointerSize));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(r1, r0);
__ str(r1, MemOperand(sp, 2 * kPointerSize));
@ -2423,7 +2423,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL, language_mode());
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2435,14 +2435,13 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
@ -2451,10 +2450,9 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
@ -3000,7 +2998,6 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
__ ldr(scratch, MemOperand(sp, kPointerSize * 2));
__ Push(scratch);
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -3008,8 +3005,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ str(r0, MemOperand(sp, kPointerSize));
@ -3062,7 +3058,6 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
__ ldr(scratch, MemOperand(sp, kPointerSize * 2));
__ Push(scratch);
VisitForStackValue(prop->key());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -3070,8 +3065,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ str(r0, MemOperand(sp, kPointerSize));

View File

@ -2956,7 +2956,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3052,10 +3052,9 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
// Name is always in r2.
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
@ -3362,9 +3361,9 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic =
CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}

View File

@ -4494,7 +4494,7 @@ void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
KeyedLoadICStub stub(isolate(), state());
KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
@ -4703,7 +4703,7 @@ void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
__ JumpIfNotRoot(feedback, Heap::kmegamorphic_symbolRootIndex,
&try_poly_name);
Handle<Code> megamorphic_stub =
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
__ Bind(&try_poly_name);

View File

@ -2091,7 +2091,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ Mov(LoadDescriptor::NameRegister(), Operand(key->value()));
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL, language_mode());
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2103,15 +2103,14 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
// Call keyed load IC. It has arguments key and receiver in x0 and x1.
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallIC(ic);
@ -2120,10 +2119,9 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
@ -2685,15 +2683,14 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
__ Peek(scratch, kPointerSize);
__ Push(x0, scratch);
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver)
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - language_mode
__ CallRuntime(Runtime::kLoadFromSuper, 4);
// - key
__ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ Poke(x0, kPointerSize);
@ -2746,7 +2743,6 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
__ Peek(scratch, kPointerSize);
__ Push(x0, scratch);
VisitForStackValue(prop->key());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -2754,8 +2750,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ Poke(x0, kPointerSize);
@ -5203,7 +5198,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ Peek(load_name, 2 * kPointerSize);
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ Mov(x1, x0);
__ Poke(x1, 2 * kPointerSize);

View File

@ -3306,7 +3306,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
__ Mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3576,9 +3576,9 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic =
CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
DCHECK(ToRegister(instr->result()).Is(x0));
@ -3632,10 +3632,10 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
__ Mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
DCHECK(ToRegister(instr->result()).is(x0));

View File

@ -1275,12 +1275,17 @@ static void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) {
static void Generate_LoadIC_Slow(MacroAssembler* masm) {
NamedLoadHandlerCompiler::GenerateSlow(masm);
LoadIC::GenerateRuntimeGetProperty(masm);
}
static void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) {
KeyedLoadIC::GenerateInitialize(masm);
}
static void Generate_KeyedLoadIC_Slow(MacroAssembler* masm) {
ElementHandlerCompiler::GenerateLoadSlow(masm);
KeyedLoadIC::GenerateRuntimeGetProperty(masm);
}
@ -1290,12 +1295,7 @@ static void Generate_KeyedLoadIC_Miss(MacroAssembler* masm) {
static void Generate_KeyedLoadIC_Megamorphic(MacroAssembler* masm) {
KeyedLoadIC::GenerateMegamorphic(masm, SLOPPY);
}
static void Generate_KeyedLoadIC_Megamorphic_Strong(MacroAssembler* masm) {
KeyedLoadIC::GenerateMegamorphic(masm, STRONG);
KeyedLoadIC::GenerateMegamorphic(masm);
}

View File

@ -86,11 +86,9 @@ enum BuiltinExtraArguments {
V(StoreIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(KeyedStoreIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(LoadIC_Getter_ForDeopt, LOAD_IC, MONOMORPHIC, kNoExtraICState) \
V(KeyedLoadIC_Initialize, KEYED_LOAD_IC, UNINITIALIZED, kNoExtraICState) \
V(KeyedLoadIC_Megamorphic, KEYED_LOAD_IC, MEGAMORPHIC, kNoExtraICState) \
\
V(KeyedLoadIC_Megamorphic_Strong, KEYED_LOAD_IC, MEGAMORPHIC, \
LoadICState::kStrongModeState) \
\
V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC, \
StoreICState::kStrictModeState) \
\
@ -106,6 +104,7 @@ enum BuiltinExtraArguments {
V(KeyedStoreIC_Megamorphic_Strict, KEYED_STORE_IC, MEGAMORPHIC, \
StoreICState::kStrictModeState) \
\
/* Uses KeyedLoadIC_Initialize; must be after in list. */ \
V(FunctionCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(FunctionApply, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(ReflectApply, BUILTIN, UNINITIALIZED, kNoExtraICState) \
@ -127,13 +126,13 @@ enum BuiltinExtraArguments {
CODE_AGE_LIST_WITH_ARG(DECLARE_CODE_AGE_BUILTIN, V)
// Define list of builtin handlers implemented in assembly.
#define BUILTIN_LIST_H(V) \
V(LoadIC_Slow, LOAD_IC) \
V(KeyedLoadIC_Slow, KEYED_LOAD_IC) \
V(StoreIC_Slow, STORE_IC) \
V(KeyedStoreIC_Slow, KEYED_STORE_IC) \
V(LoadIC_Normal, LOAD_IC) \
V(StoreIC_Normal, STORE_IC)
#define BUILTIN_LIST_H(V) \
V(LoadIC_Slow, LOAD_IC) \
V(KeyedLoadIC_Slow, KEYED_LOAD_IC) \
V(StoreIC_Slow, STORE_IC) \
V(KeyedStoreIC_Slow, KEYED_STORE_IC) \
V(LoadIC_Normal, LOAD_IC) \
V(StoreIC_Normal, STORE_IC)
// Define list of builtins used by the debugger implemented in assembly.
#define BUILTIN_LIST_DEBUG_A(V) \

View File

@ -13,44 +13,35 @@ namespace internal {
// static
Callable CodeFactory::LoadIC(Isolate* isolate, ContextualMode mode,
LanguageMode language_mode) {
Callable CodeFactory::LoadIC(Isolate* isolate, ContextualMode mode) {
return Callable(
LoadIC::initialize_stub(
isolate, LoadICState(mode, language_mode).GetExtraICState()),
LoadIC::initialize_stub(isolate, LoadICState(mode).GetExtraICState()),
LoadDescriptor(isolate));
}
// static
Callable CodeFactory::LoadICInOptimizedCode(
Isolate* isolate, ContextualMode mode, LanguageMode language_mode,
Isolate* isolate, ContextualMode mode,
InlineCacheState initialization_state) {
auto code = LoadIC::initialize_stub_in_optimized_code(
isolate, LoadICState(mode, language_mode).GetExtraICState(),
initialization_state);
isolate, LoadICState(mode).GetExtraICState(), initialization_state);
return Callable(code, LoadWithVectorDescriptor(isolate));
}
// static
Callable CodeFactory::KeyedLoadIC(Isolate* isolate,
LanguageMode language_mode) {
ExtraICState state =
is_strong(language_mode) ? LoadICState::kStrongModeState : 0;
return Callable(KeyedLoadIC::initialize_stub(isolate, state),
Callable CodeFactory::KeyedLoadIC(Isolate* isolate) {
return Callable(KeyedLoadIC::initialize_stub(isolate),
LoadDescriptor(isolate));
}
// static
Callable CodeFactory::KeyedLoadICInOptimizedCode(
Isolate* isolate, LanguageMode language_mode,
InlineCacheState initialization_state) {
ExtraICState state =
is_strong(language_mode) ? LoadICState::kStrongModeState : 0;
Isolate* isolate, InlineCacheState initialization_state) {
auto code = KeyedLoadIC::initialize_stub_in_optimized_code(
isolate, initialization_state, state);
isolate, initialization_state);
if (initialization_state != MEGAMORPHIC) {
return Callable(code, LoadWithVectorDescriptor(isolate));
}

View File

@ -32,15 +32,12 @@ class Callable final BASE_EMBEDDED {
class CodeFactory final {
public:
// Initial states for ICs.
static Callable LoadIC(Isolate* isolate, ContextualMode mode,
LanguageMode language_mode);
static Callable LoadIC(Isolate* isolate, ContextualMode mode);
static Callable LoadICInOptimizedCode(Isolate* isolate, ContextualMode mode,
LanguageMode language_mode,
InlineCacheState initialization_state);
static Callable KeyedLoadIC(Isolate* isolate, LanguageMode language_mode);
static Callable KeyedLoadIC(Isolate* isolate);
static Callable KeyedLoadICInOptimizedCode(
Isolate* isolate, LanguageMode language_mode,
InlineCacheState initialization_state);
Isolate* isolate, InlineCacheState initialization_state);
static Callable CallIC(Isolate* isolate, int argc,
CallICState::CallType call_type);
static Callable CallICInOptimizedCode(Isolate* isolate, int argc,

View File

@ -62,7 +62,8 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
HContext* context() { return context_; }
Isolate* isolate() { return info_->isolate(); }
HLoadNamedField* BuildLoadNamedField(HValue* object, FieldIndex index);
HLoadNamedField* BuildLoadNamedField(HValue* object,
FieldIndex index);
void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index,
Representation representation,
bool transition_to_field);
@ -1900,8 +1901,7 @@ HValue* CodeStubGraphBuilder<LoadDictionaryElementStub>::BuildCodeStub() {
HValue* hash = BuildElementIndexHash(key);
return BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash,
casted_stub()->language_mode());
return BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash);
}
@ -2015,6 +2015,7 @@ void CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildExternalElementLoad(
HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() {
HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
HValue* key = GetParameter(LoadDescriptor::kNameIndex);
// Split into a smi/integer case and unique string case.
HIfContinuation index_name_split_continuation(graph()->CreateBasicBlock(),
graph()->CreateBasicBlock());
@ -2058,8 +2059,7 @@ HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() {
HValue* hash = BuildElementIndexHash(key);
Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash,
casted_stub()->language_mode()));
Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash));
}
kind_if.Else();
@ -2137,8 +2137,10 @@ HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() {
hash = AddUncasted<HShr>(hash, Add<HConstant>(Name::kHashShift));
HValue* value = BuildUncheckedDictionaryElementLoad(
receiver, properties, key, hash, casted_stub()->language_mode());
HValue* value = BuildUncheckedDictionaryElementLoad(receiver,
properties,
key,
hash);
Push(value);
}
if_dict_properties.Else();
@ -2213,11 +2215,10 @@ HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() {
inline_or_runtime.Else();
{
// KeyedLookupCache miss; call runtime.
Add<HPushArguments>(receiver, key,
Add<HConstant>(casted_stub()->language_mode()));
Add<HPushArguments>(receiver, key);
Push(Add<HCallRuntime>(
isolate()->factory()->empty_string(),
Runtime::FunctionForId(Runtime::kKeyedGetProperty), 3));
Runtime::FunctionForId(Runtime::kKeyedGetProperty), 2));
}
inline_or_runtime.End();
}

View File

@ -123,6 +123,7 @@ Handle<Code> PlatformCodeStub::GenerateCode() {
// Create the code object.
CodeDesc desc;
masm.GetCode(&desc);
// Copy the generated code into a heap object.
Code::Flags flags = Code::ComputeFlags(
GetCodeKind(),

View File

@ -2114,37 +2114,24 @@ class StringCharAtGenerator {
class LoadDictionaryElementStub : public HydrogenCodeStub {
public:
explicit LoadDictionaryElementStub(Isolate* isolate, const LoadICState& state)
: HydrogenCodeStub(isolate) {
minor_key_ = state.GetExtraICState();
}
explicit LoadDictionaryElementStub(Isolate* isolate)
: HydrogenCodeStub(isolate) {}
CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
return LoadWithVectorDescriptor(isolate());
}
LanguageMode language_mode() const {
return LoadICState::GetLanguageMode(MinorKey());
}
DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub);
};
class KeyedLoadGenericStub : public HydrogenCodeStub {
public:
explicit KeyedLoadGenericStub(Isolate* isolate, const LoadICState& state)
: HydrogenCodeStub(isolate) {
minor_key_ = state.GetExtraICState();
}
explicit KeyedLoadGenericStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
InlineCacheState GetICState() const override { return GENERIC; }
LanguageMode language_mode() const {
return LoadICState::GetLanguageMode(MinorKey());
}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
DEFINE_HYDROGEN_CODE_STUB(KeyedLoadGeneric, HydrogenCodeStub);
@ -2166,7 +2153,7 @@ class LoadICTrampolineStub : public PlatformCodeStub {
return static_cast<ExtraICState>(minor_key_);
}
protected:
private:
LoadICState state() const {
return LoadICState(static_cast<ExtraICState>(minor_key_));
}
@ -2178,8 +2165,8 @@ class LoadICTrampolineStub : public PlatformCodeStub {
class KeyedLoadICTrampolineStub : public LoadICTrampolineStub {
public:
explicit KeyedLoadICTrampolineStub(Isolate* isolate, const LoadICState& state)
: LoadICTrampolineStub(isolate, state) {}
explicit KeyedLoadICTrampolineStub(Isolate* isolate)
: LoadICTrampolineStub(isolate, LoadICState(0)) {}
Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
@ -2285,18 +2272,12 @@ class LoadICStub : public PlatformCodeStub {
class KeyedLoadICStub : public PlatformCodeStub {
public:
explicit KeyedLoadICStub(Isolate* isolate, const LoadICState& state)
: PlatformCodeStub(isolate) {
minor_key_ = state.GetExtraICState();
}
explicit KeyedLoadICStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
void GenerateForTrampoline(MacroAssembler* masm);
Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
InlineCacheState GetICState() const final { return DEFAULT; }
ExtraICState GetExtraICState() const final {
return static_cast<ExtraICState>(minor_key_);
}
DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
DEFINE_PLATFORM_CODE_STUB(KeyedLoadIC, PlatformCodeStub);
@ -2340,9 +2321,6 @@ class VectorKeyedStoreICStub : public PlatformCodeStub {
Code::Kind GetCodeKind() const final { return Code::KEYED_STORE_IC; }
InlineCacheState GetICState() const final { return DEFAULT; }
virtual ExtraICState GetExtraICState() const final {
return static_cast<ExtraICState>(minor_key_);
}
DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreIC);
DEFINE_PLATFORM_CODE_STUB(VectorKeyedStoreIC, PlatformCodeStub);

View File

@ -3455,7 +3455,7 @@ static inline Node* Record(JSTypeFeedbackTable* js_type_feedback, Node* node,
Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
const ResolvedFeedbackSlot& feedback) {
const Operator* op = javascript()->LoadProperty(feedback, language_mode());
const Operator* op = javascript()->LoadProperty(feedback);
return Record(js_type_feedback_,
NewNode(op, object, key, GetFeedbackVector()), feedback.slot());
}
@ -3464,8 +3464,8 @@ Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
const ResolvedFeedbackSlot& feedback,
ContextualMode mode) {
const Operator* op = javascript()->LoadNamed(MakeUnique(name), feedback,
language_mode(), mode);
const Operator* op =
javascript()->LoadNamed(MakeUnique(name), feedback, mode);
return Record(js_type_feedback_, NewNode(op, object, GetFeedbackVector()),
feedback.slot());
}
@ -3490,9 +3490,8 @@ Node* AstGraphBuilder::BuildNamedSuperLoad(
Node* receiver, Node* home_object, Handle<Name> name,
const ResolvedFeedbackSlot& feedback) {
Node* name_node = jsgraph()->Constant(name);
Node* language = jsgraph()->Constant(language_mode());
const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 4);
Node* value = NewNode(op, receiver, home_object, name_node, language);
const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3);
Node* value = NewNode(op, receiver, home_object, name_node);
return Record(js_type_feedback_, value, feedback.slot());
}
@ -3500,10 +3499,9 @@ Node* AstGraphBuilder::BuildNamedSuperLoad(
Node* AstGraphBuilder::BuildKeyedSuperLoad(
Node* receiver, Node* home_object, Node* key,
const ResolvedFeedbackSlot& feedback) {
Node* language = jsgraph()->Constant(language_mode());
const Operator* op =
javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
Node* value = NewNode(op, receiver, home_object, key, language);
javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
Node* value = NewNode(op, receiver, home_object, key);
return Record(js_type_feedback_, value, feedback.slot());
}

View File

@ -314,8 +314,8 @@ void JSGenericLowering::LowerJSToObject(Node* node) {
void JSGenericLowering::LowerJSLoadProperty(Node* node) {
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op());
Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), p.language_mode(), UNINITIALIZED);
Callable callable =
CodeFactory::KeyedLoadICInOptimizedCode(isolate(), UNINITIALIZED);
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
ReplaceWithStubCall(node, callable, flags);
}
@ -325,7 +325,7 @@ void JSGenericLowering::LowerJSLoadNamed(Node* node) {
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
Callable callable = CodeFactory::LoadICInOptimizedCode(
isolate(), p.contextual_mode(), p.language_mode(), UNINITIALIZED);
isolate(), p.contextual_mode(), UNINITIALIZED);
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
ReplaceWithStubCall(node, callable, flags);

View File

@ -190,7 +190,6 @@ size_t hash_value(ResolvedFeedbackSlot const& p) {
bool operator==(LoadNamedParameters const& lhs,
LoadNamedParameters const& rhs) {
return lhs.name() == rhs.name() &&
lhs.language_mode() == rhs.language_mode() &&
lhs.contextual_mode() == rhs.contextual_mode() &&
lhs.feedback() == rhs.feedback();
}
@ -203,26 +202,24 @@ bool operator!=(LoadNamedParameters const& lhs,
size_t hash_value(LoadNamedParameters const& p) {
return base::hash_combine(p.name(), p.language_mode(), p.contextual_mode(),
p.feedback());
return base::hash_combine(p.name(), p.contextual_mode(), p.feedback());
}
std::ostream& operator<<(std::ostream& os, LoadNamedParameters const& p) {
return os << Brief(*p.name().handle()) << ", " << p.language_mode() << ", "
<< p.contextual_mode();
return os << Brief(*p.name().handle()) << ", " << p.contextual_mode();
}
std::ostream& operator<<(std::ostream& os, LoadPropertyParameters const& p) {
return os << p.language_mode();
// Nothing special to print.
return os;
}
bool operator==(LoadPropertyParameters const& lhs,
LoadPropertyParameters const& rhs) {
return lhs.language_mode() == rhs.language_mode() &&
lhs.feedback() == rhs.feedback();
return lhs.feedback() == rhs.feedback();
}
@ -239,7 +236,7 @@ const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op) {
size_t hash_value(LoadPropertyParameters const& p) {
return base::hash_combine(p.language_mode(), p.feedback());
return hash_value(p.feedback());
}
@ -462,9 +459,8 @@ const Operator* JSOperatorBuilder::CallConstruct(int arguments) {
const Operator* JSOperatorBuilder::LoadNamed(
const Unique<Name>& name, const ResolvedFeedbackSlot& feedback,
LanguageMode language_mode, ContextualMode contextual_mode) {
LoadNamedParameters parameters(name, feedback, language_mode,
contextual_mode);
ContextualMode contextual_mode) {
LoadNamedParameters parameters(name, feedback, contextual_mode);
return new (zone()) Operator1<LoadNamedParameters>( // --
IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
"JSLoadNamed", // name
@ -474,8 +470,8 @@ const Operator* JSOperatorBuilder::LoadNamed(
const Operator* JSOperatorBuilder::LoadProperty(
const ResolvedFeedbackSlot& feedback, LanguageMode language_mode) {
LoadPropertyParameters parameters(feedback, language_mode);
const ResolvedFeedbackSlot& feedback) {
LoadPropertyParameters parameters(feedback);
return new (zone()) Operator1<LoadPropertyParameters>( // --
IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode
"JSLoadProperty", // name

View File

@ -223,15 +223,10 @@ class LoadNamedParameters final {
public:
LoadNamedParameters(const Unique<Name>& name,
const ResolvedFeedbackSlot& feedback,
LanguageMode language_mode,
ContextualMode contextual_mode)
: name_(name),
feedback_(feedback),
language_mode_(language_mode),
contextual_mode_(contextual_mode) {}
: name_(name), feedback_(feedback), contextual_mode_(contextual_mode) {}
const Unique<Name>& name() const { return name_; }
LanguageMode language_mode() const { return language_mode_; }
ContextualMode contextual_mode() const { return contextual_mode_; }
const ResolvedFeedbackSlot& feedback() const { return feedback_; }
@ -239,7 +234,6 @@ class LoadNamedParameters final {
private:
const Unique<Name> name_;
const ResolvedFeedbackSlot feedback_;
const LanguageMode language_mode_;
const ContextualMode contextual_mode_;
};
@ -257,17 +251,13 @@ const LoadNamedParameters& LoadNamedParametersOf(const Operator* op);
// used as a parameter by JSLoadProperty operators.
class LoadPropertyParameters final {
public:
explicit LoadPropertyParameters(const ResolvedFeedbackSlot& feedback,
LanguageMode language_mode)
: feedback_(feedback), language_mode_(language_mode) {}
explicit LoadPropertyParameters(const ResolvedFeedbackSlot& feedback)
: feedback_(feedback) {}
const ResolvedFeedbackSlot& feedback() const { return feedback_; }
LanguageMode language_mode() const { return language_mode_; }
private:
const ResolvedFeedbackSlot feedback_;
const LanguageMode language_mode_;
};
bool operator==(LoadPropertyParameters const&, LoadPropertyParameters const&);
@ -378,11 +368,9 @@ class JSOperatorBuilder final : public ZoneObject {
const Operator* CallConstruct(int arguments);
const Operator* LoadProperty(const ResolvedFeedbackSlot& feedback,
LanguageMode language_mode);
const Operator* LoadProperty(const ResolvedFeedbackSlot& feedback);
const Operator* LoadNamed(const Unique<Name>& name,
const ResolvedFeedbackSlot& feedback,
LanguageMode language_mode,
ContextualMode contextual_mode = NOT_CONTEXTUAL);
const Operator* StoreProperty(LanguageMode language_mode);

View File

@ -1025,8 +1025,8 @@ Reduction JSTypedLowering::ReduceJSLoadDynamicGlobal(Node* node) {
javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true), context,
context, effect);
Node* fast = graph()->NewNode(
javascript()->LoadNamed(name, access.feedback(), SLOPPY, access.mode()),
global, vector, context, state1, state2, global, check_true);
javascript()->LoadNamed(name, access.feedback(), access.mode()), global,
vector, context, state1, state2, global, check_true);
// Slow case, because variable potentially shadowed. Perform dynamic lookup.
uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired;

View File

@ -469,10 +469,8 @@ void FullCodeGenerator::PrepareForBailout(Expression* node, State state) {
void FullCodeGenerator::CallLoadIC(ContextualMode contextual_mode,
LanguageMode language_mode,
TypeFeedbackId id) {
Handle<Code> ic =
CodeFactory::LoadIC(isolate(), contextual_mode, language_mode).code();
Handle<Code> ic = CodeFactory::LoadIC(isolate(), contextual_mode).code();
CallIC(ic, id);
}

View File

@ -683,7 +683,7 @@ class FullCodeGenerator: public AstVisitor {
void CallIC(Handle<Code> code,
TypeFeedbackId id = TypeFeedbackId::None());
void CallLoadIC(ContextualMode mode, LanguageMode language_mode = SLOPPY,
void CallLoadIC(ContextualMode mode,
TypeFeedbackId id = TypeFeedbackId::None());
void CallGlobalLoadIC(Handle<String> name);
void CallStoreIC(TypeFeedbackId id = TypeFeedbackId::None());

View File

@ -6392,9 +6392,8 @@ class HLoadNamedField final : public HTemplateInstruction<2> {
class HLoadNamedGeneric final : public HTemplateInstruction<2> {
public:
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HLoadNamedGeneric, HValue*,
Handle<Object>, LanguageMode,
InlineCacheState);
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HLoadNamedGeneric, HValue*,
Handle<Object>, InlineCacheState);
HValue* context() const { return OperandAt(0); }
HValue* object() const { return OperandAt(1); }
@ -6422,15 +6421,11 @@ class HLoadNamedGeneric final : public HTemplateInstruction<2> {
DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
LanguageMode language_mode() const { return language_mode_; }
private:
HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name,
LanguageMode language_mode,
InlineCacheState initialization_state)
: name_(name),
slot_(FeedbackVectorICSlot::Invalid()),
language_mode_(language_mode),
initialization_state_(initialization_state) {
SetOperandAt(0, context);
SetOperandAt(1, object);
@ -6441,7 +6436,6 @@ class HLoadNamedGeneric final : public HTemplateInstruction<2> {
Handle<Object> name_;
Handle<TypeFeedbackVector> feedback_vector_;
FeedbackVectorICSlot slot_;
LanguageMode language_mode_;
InlineCacheState initialization_state_;
};
@ -6681,9 +6675,8 @@ class HLoadKeyed final : public HTemplateInstruction<3>,
class HLoadKeyedGeneric final : public HTemplateInstruction<3> {
public:
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HLoadKeyedGeneric, HValue*,
HValue*, LanguageMode,
InlineCacheState);
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HLoadKeyedGeneric, HValue*,
HValue*, InlineCacheState);
HValue* object() const { return OperandAt(0); }
HValue* key() const { return OperandAt(1); }
HValue* context() const { return OperandAt(2); }
@ -6715,15 +6708,11 @@ class HLoadKeyedGeneric final : public HTemplateInstruction<3> {
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
LanguageMode language_mode() const { return language_mode_; }
private:
HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key,
LanguageMode language_mode,
InlineCacheState initialization_state)
: slot_(FeedbackVectorICSlot::Invalid()),
initialization_state_(initialization_state),
language_mode_(language_mode) {
initialization_state_(initialization_state) {
set_representation(Representation::Tagged());
SetOperandAt(0, obj);
SetOperandAt(1, key);
@ -6734,7 +6723,6 @@ class HLoadKeyedGeneric final : public HTemplateInstruction<3> {
Handle<TypeFeedbackVector> feedback_vector_;
FeedbackVectorICSlot slot_;
InlineCacheState initialization_state_;
LanguageMode language_mode_;
};

View File

@ -683,11 +683,6 @@ HConstant* HGraph::GetConstantMinus1() {
}
HConstant* HGraph::GetConstantBool(bool value) {
return value ? GetConstantTrue() : GetConstantFalse();
}
#define DEFINE_GET_CONSTANT(Name, name, type, htype, boolean_value) \
HConstant* HGraph::GetConstant##Name() { \
if (!constant_##name##_.is_set()) { \
@ -1672,9 +1667,10 @@ HValue* HGraphBuilder::BuildElementIndexHash(HValue* index) {
}
HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(
HValue* receiver, HValue* elements, HValue* key, HValue* hash,
LanguageMode language_mode) {
HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver,
HValue* elements,
HValue* key,
HValue* hash) {
HValue* capacity =
Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex),
nullptr, FAST_ELEMENTS);
@ -1716,10 +1712,10 @@ HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(
{
// element == undefined means "not found". Call the runtime.
// TODO(jkummerow): walk the prototype chain instead.
Add<HPushArguments>(receiver, key, Add<HConstant>(language_mode));
Add<HPushArguments>(receiver, key);
Push(Add<HCallRuntime>(isolate()->factory()->empty_string(),
Runtime::FunctionForId(Runtime::kKeyedGetProperty),
3));
2));
}
if_undefined.Else();
{
@ -1776,10 +1772,10 @@ HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(
result_index->ClearFlag(HValue::kCanOverflow);
Push(Add<HLoadKeyed>(elements, result_index, nullptr, FAST_ELEMENTS));
details_compare.Else();
Add<HPushArguments>(receiver, key, Add<HConstant>(language_mode));
Add<HPushArguments>(receiver, key);
Push(Add<HCallRuntime>(isolate()->factory()->empty_string(),
Runtime::FunctionForId(Runtime::kKeyedGetProperty),
3));
2));
details_compare.End();
found_key_match.Else();
@ -6224,7 +6220,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() {
if (IsFound()) return IsLoad() || !IsReadOnly();
if (IsIntegerIndexedExotic()) return false;
if (!LookupInPrototypes()) return false;
if (IsLoad()) return !is_strong(builder_->function_language_mode());
if (IsLoad()) return true;
if (IsAccessorConstant()) return true;
LookupTransition(*map_, *name_, NONE);
@ -7042,14 +7038,14 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
// use a generic Keyed Load if we are using the type vector, because
// it has to share information with full code.
HConstant* key = Add<HConstant>(name);
HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>(
object, key, function_language_mode(), PREMONOMORPHIC);
HLoadKeyedGeneric* result =
New<HLoadKeyedGeneric>(object, key, PREMONOMORPHIC);
result->SetVectorAndSlot(vector, slot);
return result;
}
HLoadNamedGeneric* result = New<HLoadNamedGeneric>(
object, name, function_language_mode(), PREMONOMORPHIC);
HLoadNamedGeneric* result =
New<HLoadNamedGeneric>(object, name, PREMONOMORPHIC);
result->SetVectorAndSlot(vector, slot);
return result;
} else {
@ -7068,8 +7064,8 @@ HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric(
HValue* value) {
if (access_type == LOAD) {
InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState();
HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>(
object, key, function_language_mode(), initial_state);
HLoadKeyedGeneric* result =
New<HLoadKeyedGeneric>(object, key, initial_state);
// HLoadKeyedGeneric with vector ics benefits from being encoded as
// MEGAMORPHIC because the vector/slot combo becomes unnecessary.
if (initial_state != MEGAMORPHIC) {

View File

@ -331,7 +331,6 @@ class HGraph final : public ZoneObject {
HConstant* GetConstantMinus1();
HConstant* GetConstantTrue();
HConstant* GetConstantFalse();
HConstant* GetConstantBool(bool value);
HConstant* GetConstantHole();
HConstant* GetConstantNull();
HConstant* GetInvalidContext();
@ -1353,9 +1352,9 @@ class HGraphBuilder {
HValue* key);
HValue* BuildUncheckedDictionaryElementLoad(HValue* receiver,
HValue* elements, HValue* key,
HValue* hash,
LanguageMode language_mode);
HValue* elements,
HValue* key,
HValue* hash);
HValue* BuildRegExpConstructResult(HValue* length,
HValue* index,

View File

@ -4430,7 +4430,7 @@ void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
KeyedLoadICStub stub(isolate(), state());
KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
@ -4634,7 +4634,7 @@ void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ j(not_equal, &try_poly_name);
Handle<Code> megamorphic_stub =
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);

View File

@ -2166,7 +2166,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ mov(load_receiver, Operand(esp, kPointerSize));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(edi, eax);
__ mov(Operand(esp, 2 * kPointerSize), edi);
@ -2335,7 +2335,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL, language_mode());
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2347,14 +2347,13 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
DCHECK(prop->IsSuperAccess());
__ push(Immediate(key->value()));
__ push(Immediate(Smi::FromInt(language_mode())));
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
@ -2363,10 +2362,9 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
__ push(Immediate(Smi::FromInt(language_mode())));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
@ -2896,15 +2894,13 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
__ push(eax);
__ push(Operand(esp, kPointerSize * 2));
__ push(Immediate(key->value()));
__ push(Immediate(Smi::FromInt(language_mode())));
// Stack here:
// - home_object
// - this (receiver)
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ mov(Operand(esp, kPointerSize), eax);
@ -2954,15 +2950,13 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
__ push(eax);
__ push(Operand(esp, kPointerSize * 2));
VisitForStackValue(prop->key());
__ push(Immediate(Smi::FromInt(language_mode())));
// Stack here:
// - home_object
// - this (receiver)
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ mov(Operand(esp, kPointerSize), eax);

View File

@ -2836,7 +2836,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
__ mov(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -2952,10 +2952,9 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
__ mov(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3197,9 +3196,9 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic =
CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}

View File

@ -16,30 +16,6 @@ namespace internal {
#define __ ACCESS_MASM(masm)
void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
// Push receiver and key for runtime call.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// The slow case calls into the runtime to complete the load without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
// Push receiver and key for runtime call.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// The slow case calls into the runtime to complete the load without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {

View File

@ -161,8 +161,7 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
Register result, Label* slow,
LanguageMode language_mode) {
Register result, Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
@ -184,7 +183,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
//
// scratch2 - used to hold maps, prototypes, and the loaded value.
Label check_prototypes, check_next_prototype;
Label done, in_bounds, absent;
Label done, in_bounds, return_undefined;
__ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(elements);
@ -203,7 +202,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ ldr(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ CompareRoot(scratch2, Heap::kNullValueRootIndex);
__ b(eq, &absent);
__ b(eq, &return_undefined);
__ ldr(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
__ ldr(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
// elements: elements of current prototype
@ -218,14 +217,9 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ b(ne, slow);
__ jmp(&check_next_prototype);
__ bind(&absent);
if (is_strong(language_mode)) {
// Strong mode accesses must throw in this case, so call the runtime.
__ jmp(slow);
} else {
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ jmp(&done);
}
__ bind(&return_undefined);
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ jmp(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
@ -284,7 +278,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
}
@ -319,17 +313,13 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
}
void LoadIC::GenerateSlow(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
__ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
@ -351,21 +341,16 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
LanguageMode language_mode) {
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is in lr.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
@ -389,8 +374,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(r0, r3, &check_number_dictionary);
GenerateFastArrayLoad(masm, receiver, key, r0, r3, r4, r0, &slow,
language_mode);
GenerateFastArrayLoad(masm, receiver, key, r0, r3, r4, r0, &slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r4, r3);
__ Ret();
@ -412,7 +396,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
__ bind(&slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r4,
r3);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, r0, r3, &index_name, &slow);

View File

@ -267,30 +267,6 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
}
void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
// Push receiver and key for runtime call.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// The slow case calls into the runtime to complete the load without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
// Push receiver and key for runtime call.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// The slow case calls into the runtime to complete the load without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {

View File

@ -167,12 +167,11 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
Register result, Label* slow,
LanguageMode language_mode) {
Register result, Label* slow) {
DCHECK(!AreAliased(receiver, key, elements, scratch1, scratch2));
Label check_prototypes, check_next_prototype;
Label done, in_bounds, absent;
Label done, in_bounds, return_undefined;
// Check for fast array.
__ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
@ -192,7 +191,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ Bind(&check_next_prototype);
__ Ldr(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ JumpIfRoot(scratch2, Heap::kNullValueRootIndex, &absent);
__ JumpIfRoot(scratch2, Heap::kNullValueRootIndex, &return_undefined);
__ Ldr(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
__ Ldr(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
// elements: elements of current prototype
@ -205,14 +204,9 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ JumpIfNotRoot(elements, Heap::kEmptyFixedArrayRootIndex, slow);
__ B(&check_next_prototype);
__ Bind(&absent);
if (is_strong(language_mode)) {
// Strong mode accesses must throw in this case, so call the runtime.
__ B(slow);
} else {
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ B(&done);
}
__ Bind(&return_undefined);
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ B(&done);
__ Bind(&in_bounds);
// Fast case: Do the load.
@ -278,7 +272,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// Dictionary load failed, go slow (but don't miss).
__ Bind(&slow);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
}
@ -302,15 +296,10 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
}
void LoadIC::GenerateSlow(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
@ -335,15 +324,10 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
@ -351,8 +335,7 @@ static void GenerateKeyedLoadWithSmiKey(MacroAssembler* masm, Register key,
Register receiver, Register scratch1,
Register scratch2, Register scratch3,
Register scratch4, Register scratch5,
Label* slow,
LanguageMode language_mode) {
Label* slow) {
DCHECK(!AreAliased(key, receiver, scratch1, scratch2, scratch3, scratch4,
scratch5));
@ -368,7 +351,7 @@ static void GenerateKeyedLoadWithSmiKey(MacroAssembler* masm, Register key,
__ CheckFastElements(scratch1, scratch2, &check_number_dictionary);
GenerateFastArrayLoad(masm, receiver, key, scratch3, scratch2, scratch1,
result, slow, language_mode);
result, slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1,
scratch1, scratch2);
__ Ret();
@ -439,8 +422,7 @@ static void GenerateKeyedLoadWithNameKey(MacroAssembler* masm, Register key,
}
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
LanguageMode language_mode) {
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is in lr.
Label slow, check_name, index_smi, index_name;
@ -453,14 +435,13 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
__ Bind(&index_smi);
// Now the key is known to be a smi. This place is also jumped to from below
// where a numeric string is converted to a smi.
GenerateKeyedLoadWithSmiKey(masm, key, receiver, x7, x3, x4, x5, x6, &slow,
language_mode);
GenerateKeyedLoadWithSmiKey(masm, key, receiver, x7, x3, x4, x5, x6, &slow);
// Slow case.
__ Bind(&slow);
__ IncrementCounter(masm->isolate()->counters()->keyed_load_generic_slow(), 1,
x4, x3);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
__ Bind(&check_name);
GenerateKeyNameCheck(masm, key, x0, x3, &index_name, &slow);

View File

@ -537,8 +537,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
void ElementHandlerCompiler::CompileElementHandlers(
MapHandleList* receiver_maps, CodeHandleList* handlers,
LanguageMode language_mode) {
MapHandleList* receiver_maps, CodeHandleList* handlers) {
for (int i = 0; i < receiver_maps->length(); ++i) {
Handle<Map> receiver_map = receiver_maps->at(i);
Handle<Code> cached_stub;
@ -554,10 +553,8 @@ void ElementHandlerCompiler::CompileElementHandlers(
// No need to check for an elements-free prototype chain here, the
// generated stub code needs to check that dynamically anyway.
bool convert_hole_to_undefined =
(is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
*receiver_map ==
isolate()->get_initial_js_array_map(elements_kind)) &&
!is_strong(language_mode);
is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
*receiver_map == isolate()->get_initial_js_array_map(elements_kind);
if (receiver_map->has_indexed_interceptor()) {
cached_stub = LoadIndexedInterceptorStub(isolate()).GetCode();
@ -570,9 +567,7 @@ void ElementHandlerCompiler::CompileElementHandlers(
convert_hole_to_undefined).GetCode();
} else {
DCHECK(elements_kind == DICTIONARY_ELEMENTS);
LoadICState state = LoadICState(
is_strong(language_mode) ? LoadICState::kStrongModeState : 0);
cached_stub = LoadDictionaryElementStub(isolate(), state).GetCode();
cached_stub = LoadDictionaryElementStub(isolate()).GetCode();
}
}

View File

@ -146,8 +146,6 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
static Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
Handle<Map> map);
static void GenerateSlow(MacroAssembler* masm);
static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<Map> map,
Register receiver, Register holder,
int accessor_index, int expected_arguments,
@ -292,10 +290,8 @@ class ElementHandlerCompiler : public PropertyHandlerCompiler {
virtual ~ElementHandlerCompiler() {}
void CompileElementHandlers(MapHandleList* receiver_maps,
CodeHandleList* handlers,
LanguageMode language_mode);
CodeHandleList* handlers);
static void GenerateLoadSlow(MacroAssembler* masm);
static void GenerateStoreSlow(MacroAssembler* masm);
};
}

View File

@ -16,39 +16,6 @@ namespace internal {
#define __ ACCESS_MASM(masm)
static void LoadIC_PushArgs(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
DCHECK(!ebx.is(receiver) && !ebx.is(name));
__ pop(ebx);
__ push(receiver);
__ push(name);
__ push(ebx);
}
void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
// Return address is on the stack.
LoadIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
// Return address is on the stack.
LoadIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {

View File

@ -172,7 +172,7 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register scratch,
Register scratch2, Register result,
Label* slow, LanguageMode language_mode) {
Label* slow) {
// Register use:
// receiver - holds the receiver and is unchanged.
// key - holds the key and is unchanged (must be a smi).
@ -182,7 +182,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
// result - holds the result on exit if the load succeeds and
// we fall through.
Label check_prototypes, check_next_prototype;
Label done, in_bounds, absent;
Label done, in_bounds, return_undefined;
__ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(scratch);
@ -200,7 +200,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ mov(scratch2, FieldOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ cmp(scratch2, masm->isolate()->factory()->null_value());
__ j(equal, &absent);
__ j(equal, &return_undefined);
__ mov(scratch, FieldOperand(scratch2, JSObject::kElementsOffset));
__ mov(scratch2, FieldOperand(scratch2, HeapObject::kMapOffset));
// scratch: elements of current prototype
@ -215,14 +215,9 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ j(not_equal, slow);
__ jmp(&check_next_prototype);
__ bind(&absent);
if (is_strong(language_mode)) {
// Strong mode accesses must throw in this case, so call the runtime.
__ jmp(slow);
} else {
__ mov(result, masm->isolate()->factory()->undefined_value());
__ jmp(&done);
}
__ bind(&return_undefined);
__ mov(result, masm->isolate()->factory()->undefined_value());
__ jmp(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
@ -268,8 +263,7 @@ static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
}
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
LanguageMode language_mode) {
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is on the stack.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
@ -291,8 +285,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(eax, &check_number_dictionary);
GenerateFastArrayLoad(masm, receiver, key, eax, ebx, eax, &slow,
language_mode);
GenerateFastArrayLoad(masm, receiver, key, eax, ebx, eax, &slow);
Isolate* isolate = masm->isolate();
Counters* counters = isolate->counters();
__ IncrementCounter(counters->keyed_load_generic_smi(), 1);
@ -324,7 +317,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
__ bind(&slow);
// Slow case: jump to runtime.
__ IncrementCounter(counters->keyed_load_generic_slow(), 1);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, eax, ebx, &index_name, &slow);
@ -630,7 +623,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
}
@ -665,7 +658,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
}
void LoadIC::GenerateSlow(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
@ -677,10 +670,7 @@ void LoadIC::GenerateSlow(MacroAssembler* masm) {
__ push(ebx);
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
@ -698,7 +688,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
@ -710,10 +700,7 @@ void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
__ push(ebx);
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}

View File

@ -88,7 +88,7 @@ Handle<Code> PropertyICCompiler::ComputeMonomorphic(
Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
Handle<Map> receiver_map, ExtraICState extra_ic_state) {
Handle<Map> receiver_map) {
Isolate* isolate = receiver_map->GetIsolate();
bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
ElementsKind elements_kind = receiver_map->elements_kind();
@ -97,8 +97,8 @@ Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
// stub code needs to check that dynamically anyway.
bool convert_hole_to_undefined =
is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
*receiver_map == isolate->get_initial_js_array_map(elements_kind) &&
!(is_strong(LoadICState::GetLanguageMode(extra_ic_state)));
*receiver_map == isolate->get_initial_js_array_map(elements_kind);
Handle<Code> stub;
if (receiver_map->has_indexed_interceptor()) {
stub = LoadIndexedInterceptorStub(isolate).GetCode();
@ -113,8 +113,7 @@ Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
stub = LoadFastElementStub(isolate, is_js_array, elements_kind,
convert_hole_to_undefined).GetCode();
} else {
stub = LoadDictionaryElementStub(isolate, LoadICState(extra_ic_state))
.GetCode();
stub = LoadDictionaryElementStub(isolate).GetCode();
}
return stub;
}
@ -222,7 +221,7 @@ Handle<Code> PropertyICCompiler::ComputeCompareNil(Handle<Map> receiver_map,
Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
MapHandleList* receiver_maps, LanguageMode language_mode) {
MapHandleList* receiver_maps) {
Isolate* isolate = receiver_maps->at(0)->GetIsolate();
DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
@ -233,7 +232,7 @@ Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
CodeHandleList handlers(receiver_maps->length());
ElementHandlerCompiler compiler(isolate);
compiler.CompileElementHandlers(receiver_maps, &handlers, language_mode);
compiler.CompileElementHandlers(receiver_maps, &handlers);
PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC);
Handle<Code> code = ic_compiler.CompilePolymorphic(
receiver_maps, &handlers, isolate->factory()->empty_string(),

View File

@ -32,13 +32,12 @@ class PropertyICCompiler : public PropertyAccessCompiler {
// Keyed
static Handle<Code> ComputeKeyedLoadMonomorphicHandler(
Handle<Map> receiver_map, ExtraICState extra_ic_state);
Handle<Map> receiver_map);
static Handle<Code> ComputeKeyedStoreMonomorphic(
Handle<Map> receiver_map, LanguageMode language_mode,
KeyedAccessStoreMode store_mode);
static Handle<Code> ComputeKeyedLoadPolymorphic(MapHandleList* receiver_maps,
LanguageMode language_mode);
static Handle<Code> ComputeKeyedLoadPolymorphic(MapHandleList* receiver_maps);
static Handle<Code> ComputeKeyedStorePolymorphic(
MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode,
LanguageMode language_mode);

View File

@ -135,9 +135,6 @@ void LoadIC::set_target(Code* code) {
// The contextual mode must be preserved across IC patching.
DCHECK(LoadICState::GetContextualMode(code->extra_ic_state()) ==
LoadICState::GetContextualMode(target()->extra_ic_state()));
// Strongness must be preserved across IC patching.
DCHECK(LoadICState::GetLanguageMode(code->extra_ic_state()) ==
LoadICState::GetLanguageMode(target()->extra_ic_state()));
IC::set_target(code);
}

View File

@ -201,24 +201,11 @@ class CompareICState {
class LoadICState final BASE_EMBEDDED {
private:
class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
class LanguageModeBits
: public BitField<LanguageMode, ContextualModeBits::kNext, 2> {};
STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
const ExtraICState state_;
public:
static const uint32_t kNextBitFieldOffset = LanguageModeBits::kNext;
static const ExtraICState kStrongModeState = STRONG
<< LanguageModeBits::kShift;
explicit LoadICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
explicit LoadICState(ContextualMode mode, LanguageMode language_mode)
: state_(ContextualModeBits::encode(mode) |
LanguageModeBits::encode(language_mode)) {}
explicit LoadICState(ContextualMode mode)
: state_(ContextualModeBits::encode(mode)) {}
ExtraICState GetExtraICState() const { return state_; }
@ -226,17 +213,15 @@ class LoadICState final BASE_EMBEDDED {
return ContextualModeBits::decode(state_);
}
LanguageMode language_mode() const {
return LanguageModeBits::decode(state_);
}
static ContextualMode GetContextualMode(ExtraICState state) {
return LoadICState(state).contextual_mode();
}
static LanguageMode GetLanguageMode(ExtraICState state) {
return LoadICState(state).language_mode();
}
private:
class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
const ExtraICState state_;
};

View File

@ -571,14 +571,11 @@ void CompareIC::Clear(Isolate* isolate, Address address, Code* target,
// static
Handle<Code> KeyedLoadIC::ChooseMegamorphicStub(Isolate* isolate,
ExtraICState extra_state) {
Handle<Code> KeyedLoadIC::ChooseMegamorphicStub(Isolate* isolate) {
if (FLAG_compiled_keyed_generic_loads) {
return KeyedLoadGenericStub(isolate, LoadICState(extra_state)).GetCode();
return KeyedLoadGenericStub(isolate).GetCode();
} else {
return is_strong(LoadICState::GetLanguageMode(extra_state))
? isolate->builtins()->KeyedLoadIC_Megamorphic_Strong()
: isolate->builtins()->KeyedLoadIC_Megamorphic();
return isolate->builtins()->KeyedLoadIC_Megamorphic();
}
}
@ -682,8 +679,7 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate(), result,
Runtime::GetElementOrCharAt(isolate(), object, index, language_mode()),
Object);
Runtime::GetElementOrCharAt(isolate(), object, index), Object);
return result;
}
@ -726,9 +722,8 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
// Get the property.
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate(), result, Object::GetProperty(&it, language_mode()), Object);
ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, Object::GetProperty(&it),
Object);
if (it.IsFound()) {
return result;
} else if (!IsUndeclaredGlobal(object)) {
@ -920,20 +915,25 @@ Handle<Code> LoadIC::initialize_stub_in_optimized_code(
}
Handle<Code> KeyedLoadIC::initialize_stub(Isolate* isolate,
ExtraICState extra_state) {
return KeyedLoadICTrampolineStub(isolate, LoadICState(extra_state)).GetCode();
Handle<Code> KeyedLoadIC::initialize_stub(Isolate* isolate) {
return KeyedLoadICTrampolineStub(isolate).GetCode();
}
Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code(
Isolate* isolate, State initialization_state, ExtraICState extra_state) {
Isolate* isolate, State initialization_state) {
if (initialization_state != MEGAMORPHIC) {
return KeyedLoadICStub(isolate, LoadICState(extra_state)).GetCode();
return KeyedLoadICStub(isolate).GetCode();
}
return is_strong(LoadICState::GetLanguageMode(extra_state))
? isolate->builtins()->KeyedLoadIC_Megamorphic_Strong()
: isolate->builtins()->KeyedLoadIC_Megamorphic();
switch (initialization_state) {
case UNINITIALIZED:
return isolate->builtins()->KeyedLoadIC_Initialize();
case MEGAMORPHIC:
return isolate->builtins()->KeyedLoadIC_Megamorphic();
default:
UNREACHABLE();
}
return Handle<Code>();
}
@ -962,7 +962,7 @@ Handle<Code> KeyedStoreIC::initialize_stub(Isolate* isolate,
Handle<Code> LoadIC::megamorphic_stub() {
DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
return KeyedLoadIC::ChooseMegamorphicStub(isolate(), extra_ic_state());
return KeyedLoadIC::ChooseMegamorphicStub(isolate());
}
@ -986,7 +986,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
lookup->state() == LookupIterator::ACCESS_CHECK) {
code = slow_stub();
} else if (!lookup->IsFound()) {
if (kind() == Code::LOAD_IC && !is_strong(language_mode())) {
if (kind() == Code::LOAD_IC) {
code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(),
receiver_map());
// TODO(jkummerow/verwaest): Introduce a builtin that handles this case.
@ -1245,8 +1245,7 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
if (target_receiver_maps.length() == 0) {
Handle<Code> handler =
PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
receiver_map, extra_ic_state());
PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
return null_handle;
}
@ -1263,8 +1262,7 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
target_receiver_maps.at(0)->elements_kind(),
Handle<JSObject>::cast(receiver)->GetElementsKind())) {
Handle<Code> handler =
PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
receiver_map, extra_ic_state());
PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
return null_handle;
}
@ -1289,8 +1287,7 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
CodeHandleList handlers(target_receiver_maps.length());
ElementHandlerCompiler compiler(isolate());
compiler.CompileElementHandlers(&target_receiver_maps, &handlers,
language_mode());
compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
ConfigureVectorState(Handle<Name>::null(), &target_receiver_maps, &handlers);
return null_handle;
}
@ -1301,8 +1298,7 @@ MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
if (MigrateDeprecated(object)) {
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate(), result,
Runtime::GetObjectProperty(isolate(), object, key, language_mode()),
isolate(), result, Runtime::GetObjectProperty(isolate(), object, key),
Object);
return result;
}
@ -1350,12 +1346,10 @@ MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
}
if (!load_handle.is_null()) return load_handle;
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate(), result,
Runtime::GetObjectProperty(isolate(), object, key, language_mode()),
Object);
ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
Runtime::GetObjectProperty(isolate(), object, key),
Object);
return result;
}
@ -2818,7 +2812,6 @@ RUNTIME_FUNCTION(LoadPropertyWithInterceptor) {
Handle<Object> result;
LookupIterator it(receiver, name, holder);
// TODO(conradw): Investigate strong mode semantics for this.
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
JSObject::GetProperty(&it));
@ -2864,11 +2857,8 @@ RUNTIME_FUNCTION(LoadElementWithInterceptor) {
DCHECK(args.smi_at(1) >= 0);
uint32_t index = args.smi_at(1);
Handle<Object> result;
// TODO(conradw): Investigate strong mode semantics for this.
LanguageMode language_mode = SLOPPY;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
Object::GetElement(isolate, receiver, index, language_mode));
isolate, result, Object::GetElement(isolate, receiver, index));
return *result;
}
@ -2904,36 +2894,6 @@ RUNTIME_FUNCTION(LoadIC_MissFromStubFailure) {
}
RUNTIME_FUNCTION(LoadIC_Slow) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
Handle<Object> receiver = args.at<Object>(0);
Handle<Name> name = args.at<Name>(1);
LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
Runtime::GetObjectProperty(isolate, receiver, name, ic.language_mode()));
return *result;
}
RUNTIME_FUNCTION(KeyedLoadIC_Slow) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
Handle<Object> receiver = args.at<Object>(0);
Handle<Object> key = args.at<Object>(1);
LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, Runtime::KeyedGetObjectProperty(isolate, receiver, key,
ic.language_mode()));
return *result;
}
static const Address IC_utilities[] = {
#define ADDR(name) FUNCTION_ADDR(name),
IC_UTIL_LIST(ADDR) NULL
@ -2942,5 +2902,5 @@ static const Address IC_utilities[] = {
Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
}
} // namespace v8::internal
} // namespace internal
} // namespace v8

View File

@ -18,8 +18,6 @@ namespace internal {
#define IC_UTIL_LIST(ICU) \
ICU(LoadIC_Miss) \
ICU(KeyedLoadIC_Miss) \
ICU(LoadIC_Slow) \
ICU(KeyedLoadIC_Slow) \
ICU(CallIC_Miss) \
ICU(CallIC_Customization_Miss) \
ICU(StoreIC_Miss) \
@ -354,19 +352,14 @@ class CallIC : public IC {
class LoadIC : public IC {
public:
static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
LanguageMode language_mode) {
return LoadICState(contextual_mode, language_mode).GetExtraICState();
static ExtraICState ComputeExtraICState(ContextualMode contextual_mode) {
return LoadICState(contextual_mode).GetExtraICState();
}
ContextualMode contextual_mode() const {
return LoadICState::GetContextualMode(extra_ic_state());
}
LanguageMode language_mode() const {
return LoadICState::GetLanguageMode(extra_ic_state());
}
LoadIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
: IC(depth, isolate, nexus) {
DCHECK(nexus != NULL);
@ -397,7 +390,7 @@ class LoadIC : public IC {
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
static void GenerateMiss(MacroAssembler* masm);
static void GenerateNormal(MacroAssembler* masm);
static void GenerateSlow(MacroAssembler* masm);
static void GenerateRuntimeGetProperty(MacroAssembler* masm);
static Handle<Code> initialize_stub(Isolate* isolate,
ExtraICState extra_state);
@ -444,13 +437,11 @@ class LoadIC : public IC {
class KeyedLoadIC : public LoadIC {
public:
// ExtraICState bits (building on IC)
class IcCheckTypeField
: public BitField<IcCheckType, LoadICState::kNextBitFieldOffset, 1> {};
class IcCheckTypeField : public BitField<IcCheckType, 1, 1> {};
static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
LanguageMode language_mode,
IcCheckType key_type) {
return LoadICState(contextual_mode, language_mode).GetExtraICState() |
return LoadICState(contextual_mode).GetExtraICState() |
IcCheckTypeField::encode(key_type);
}
@ -470,10 +461,9 @@ class KeyedLoadIC : public LoadIC {
// Code generator routines.
static void GenerateMiss(MacroAssembler* masm);
static void GenerateSlow(MacroAssembler* masm);
static void GenerateRuntimeGetProperty(MacroAssembler* masm);
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
static void GenerateMegamorphic(MacroAssembler* masm,
LanguageMode languageMode);
static void GenerateMegamorphic(MacroAssembler* masm);
// Bit mask to be tested against bit field for the cases when
// generic stub should go into slow case.
@ -482,12 +472,10 @@ class KeyedLoadIC : public LoadIC {
static const int kSlowCaseBitFieldMask =
(1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
static Handle<Code> initialize_stub(Isolate* isolate,
ExtraICState extra_state);
static Handle<Code> initialize_stub(Isolate* isolate);
static Handle<Code> initialize_stub_in_optimized_code(
Isolate* isolate, State initialization_state, ExtraICState extra_state);
static Handle<Code> ChooseMegamorphicStub(Isolate* isolate,
ExtraICState extra_state);
Isolate* isolate, State initialization_state);
static Handle<Code> ChooseMegamorphicStub(Isolate* isolate);
static void Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus);

View File

@ -16,30 +16,6 @@ namespace internal {
#define __ ACCESS_MASM(masm)
void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
// Push receiver and key for runtime call.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// The slow case calls into the runtime to complete the store without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
// Push receiver and key for runtime call.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// The slow case calls into the runtime to complete the store without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {

View File

@ -163,8 +163,7 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
Register result, Label* slow,
LanguageMode language_mode) {
Register result, Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
@ -186,7 +185,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
//
// scratch2 - used to hold maps, prototypes, and the loaded value.
Label check_prototypes, check_next_prototype;
Label done, in_bounds, absent;
Label done, in_bounds, return_undefined;
__ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(elements);
@ -204,7 +203,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ lw(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ LoadRoot(at, Heap::kNullValueRootIndex);
__ Branch(&absent, eq, scratch2, Operand(at));
__ Branch(&return_undefined, eq, scratch2, Operand(at));
__ lw(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
__ lw(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
// elements: elements of current prototype
@ -219,14 +218,9 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ Branch(slow, ne, elements, Operand(at));
__ Branch(&check_next_prototype);
__ bind(&absent);
if (is_strong(language_mode)) {
// Strong mode accesses must throw in this case, so call the runtime.
__ Branch(slow);
} else {
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ Branch(&done);
}
__ bind(&return_undefined);
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ Branch(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
@ -291,7 +285,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
}
@ -326,16 +320,13 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
}
void LoadIC::GenerateSlow(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in ra.
__ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
__ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
@ -358,20 +349,16 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in ra.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
LanguageMode language_mode) {
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is in ra.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
@ -395,8 +382,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(a0, a3, &check_number_dictionary);
GenerateFastArrayLoad(masm, receiver, key, a0, a3, t0, v0, &slow,
language_mode);
GenerateFastArrayLoad(masm, receiver, key, a0, a3, t0, v0, &slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, t0, a3);
__ Ret();
@ -417,7 +403,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
__ bind(&slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, t0,
a3);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow);

View File

@ -16,30 +16,6 @@ namespace internal {
#define __ ACCESS_MASM(masm)
void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
// Push receiver and key for runtime call.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// The slow case calls into the runtime to complete the store without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
// Push receiver and key for runtime call.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// The slow case calls into the runtime to complete the store without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {

View File

@ -162,8 +162,7 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
Register result, Label* slow,
LanguageMode language_mode) {
Register result, Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
@ -185,7 +184,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
//
// scratch2 - used to hold maps, prototypes, and the loaded value.
Label check_prototypes, check_next_prototype;
Label done, in_bounds, absent;
Label done, in_bounds, return_undefined;
__ ld(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(elements);
@ -203,7 +202,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ ld(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ LoadRoot(at, Heap::kNullValueRootIndex);
__ Branch(&absent, eq, scratch2, Operand(at));
__ Branch(&return_undefined, eq, scratch2, Operand(at));
__ ld(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
__ ld(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
// elements: elements of current prototype
@ -218,13 +217,9 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ Branch(slow, ne, elements, Operand(at));
__ Branch(&check_next_prototype);
__ bind(&absent);
if (is_strong(language_mode)) {
__ Branch(slow);
} else {
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ Branch(&done);
}
__ bind(&return_undefined);
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ Branch(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
@ -288,7 +283,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
}
@ -323,16 +318,13 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
}
void LoadIC::GenerateSlow(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in ra.
__ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
__ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
@ -355,20 +347,16 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in ra.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
LanguageMode language_mode) {
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is in ra.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
@ -392,8 +380,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(a0, a3, &check_number_dictionary);
GenerateFastArrayLoad(masm, receiver, key, a0, a3, a4, v0, &slow,
language_mode);
GenerateFastArrayLoad(masm, receiver, key, a0, a3, a4, v0, &slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, a4, a3);
__ Ret();
@ -414,7 +401,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
__ bind(&slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, a4,
a3);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow);

View File

@ -16,30 +16,6 @@ namespace internal {
#define __ ACCESS_MASM(masm)
void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
// Push receiver and key for runtime call.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// The slow case calls into the runtime to complete the store without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(IC::LoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void NamedLoadHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
// Push receiver and key for runtime call.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
// The slow case calls into the runtime to complete the store without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(IC::KeyedLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {

View File

@ -167,8 +167,7 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
Register result, Label* slow,
LanguageMode language_mode) {
Register result, Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
@ -190,7 +189,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
//
// scratch2 - used to hold maps, prototypes, and the loaded value.
Label check_prototypes, check_next_prototype;
Label done, in_bounds, absent;
Label done, in_bounds, return_undefined;
__ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(elements);
@ -209,7 +208,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ LoadP(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ CompareRoot(scratch2, Heap::kNullValueRootIndex);
__ beq(&absent);
__ beq(&return_undefined);
__ LoadP(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
__ LoadP(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
// elements: elements of current prototype
@ -224,14 +223,9 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ bne(slow);
__ jmp(&check_next_prototype);
__ bind(&absent);
if (is_strong(language_mode)) {
// Strong mode accesses must throw in this case, so call the runtime.
__ jmp(slow);
} else {
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ jmp(&done);
}
__ bind(&return_undefined);
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ jmp(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
@ -294,7 +288,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
}
@ -329,16 +323,13 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
}
void LoadIC::GenerateSlow(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
__ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
@ -360,20 +351,16 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
LanguageMode language_mode) {
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is in lr.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
@ -397,8 +384,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(r3, r6, &check_number_dictionary);
GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, &slow,
language_mode);
GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, &slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r7, r6);
__ Ret();
@ -420,7 +406,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
__ bind(&slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r7,
r6);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, r3, r6, &index_name, &slow);

View File

@ -261,39 +261,6 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
}
static void LoadIC_PushArgs(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
DCHECK(!rbx.is(receiver) && !rbx.is(name));
__ PopReturnAddressTo(rbx);
__ Push(receiver);
__ Push(name);
__ PushReturnAddressFrom(rbx);
}
void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
// Return address is on the stack.
LoadIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
// Return address is on the stack.
LoadIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {

View File

@ -171,7 +171,7 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch, Register result,
Label* slow, LanguageMode language_mode) {
Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
@ -191,7 +191,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
//
// scratch - used to hold maps, prototypes, and the loaded value.
Label check_prototypes, check_next_prototype;
Label done, in_bounds, absent;
Label done, in_bounds, return_undefined;
__ movp(elements, FieldOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(elements);
@ -210,7 +210,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ movp(scratch, FieldOperand(scratch, Map::kPrototypeOffset));
// scratch: current prototype
__ CompareRoot(scratch, Heap::kNullValueRootIndex);
__ j(equal, &absent);
__ j(equal, &return_undefined);
__ movp(elements, FieldOperand(scratch, JSObject::kElementsOffset));
__ movp(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
// elements: elements of current prototype
@ -225,14 +225,9 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ j(not_equal, slow);
__ jmp(&check_next_prototype);
__ bind(&absent);
if (is_strong(language_mode)) {
// Strong mode accesses must throw in this case, so call the runtime.
__ jmp(slow);
} else {
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ jmp(&done);
}
__ bind(&return_undefined);
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
__ jmp(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
@ -279,8 +274,7 @@ static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
}
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
LanguageMode language_mode) {
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is on the stack.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
@ -302,8 +296,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(rax, &check_number_dictionary);
GenerateFastArrayLoad(masm, receiver, key, rax, rbx, rax, &slow,
language_mode);
GenerateFastArrayLoad(masm, receiver, key, rax, rbx, rax, &slow);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->keyed_load_generic_smi(), 1);
__ ret(0);
@ -324,7 +317,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
__ bind(&slow);
// Slow case: Jump to runtime.
__ IncrementCounter(counters->keyed_load_generic_slow(), 1);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, rax, rbx, &index_name, &slow);
@ -630,7 +623,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
}
@ -667,7 +660,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
}
void LoadIC::GenerateSlow(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
@ -679,10 +672,7 @@ void LoadIC::GenerateSlow(MacroAssembler* masm) {
__ PushReturnAddressFrom(rbx);
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
@ -701,7 +691,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
@ -713,10 +703,7 @@ void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
__ PushReturnAddressFrom(rbx);
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}

View File

@ -16,39 +16,6 @@ namespace internal {
#define __ ACCESS_MASM(masm)
static void LoadIC_PushArgs(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
DCHECK(!ebx.is(receiver) && !ebx.is(name));
__ pop(ebx);
__ push(receiver);
__ push(name);
__ push(ebx);
}
void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
// Return address is on the stack.
LoadIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
// Return address is on the stack.
LoadIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {

View File

@ -172,7 +172,7 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register scratch,
Register scratch2, Register result,
Label* slow, LanguageMode language_mode) {
Label* slow) {
// Register use:
// receiver - holds the receiver and is unchanged.
// key - holds the key and is unchanged (must be a smi).
@ -182,7 +182,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
// result - holds the result on exit if the load succeeds and
// we fall through.
Label check_prototypes, check_next_prototype;
Label done, in_bounds, absent;
Label done, in_bounds, return_undefined;
__ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(scratch);
@ -200,7 +200,7 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ mov(scratch2, FieldOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ cmp(scratch2, masm->isolate()->factory()->null_value());
__ j(equal, &absent);
__ j(equal, &return_undefined);
__ mov(scratch, FieldOperand(scratch2, JSObject::kElementsOffset));
__ mov(scratch2, FieldOperand(scratch2, HeapObject::kMapOffset));
// scratch: elements of current prototype
@ -215,14 +215,9 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
__ j(not_equal, slow);
__ jmp(&check_next_prototype);
__ bind(&absent);
if (is_strong(language_mode)) {
// Strong mode accesses must throw in this case, so call the runtime.
__ jmp(slow);
} else {
__ mov(result, masm->isolate()->factory()->undefined_value());
__ jmp(&done);
}
__ bind(&return_undefined);
__ mov(result, masm->isolate()->factory()->undefined_value());
__ jmp(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
@ -268,8 +263,7 @@ static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
}
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
LanguageMode language_mode) {
void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is on the stack.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
@ -291,8 +285,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(eax, &check_number_dictionary);
GenerateFastArrayLoad(masm, receiver, key, eax, ebx, eax, &slow,
language_mode);
GenerateFastArrayLoad(masm, receiver, key, eax, ebx, eax, &slow);
Isolate* isolate = masm->isolate();
Counters* counters = isolate->counters();
__ IncrementCounter(counters->keyed_load_generic_smi(), 1);
@ -324,7 +317,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
__ bind(&slow);
// Slow case: jump to runtime.
__ IncrementCounter(counters->keyed_load_generic_slow(), 1);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, eax, ebx, &index_name, &slow);
@ -630,7 +623,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
GenerateSlow(masm);
GenerateRuntimeGetProperty(masm);
}
@ -665,7 +658,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
}
void LoadIC::GenerateSlow(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
@ -677,10 +670,7 @@ void LoadIC::GenerateSlow(MacroAssembler* masm) {
__ push(ebx);
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
@ -698,7 +688,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
@ -710,10 +700,7 @@ void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
__ push(ebx);
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
int arg_count = 2;
__ TailCallExternalReference(ref, arg_count, 1);
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}

View File

@ -375,8 +375,6 @@ class CallSite {
"instead") \
T(StrongForIn, \
"In strong mode, 'for'-'in' loops are deprecated, use 'for'-'of' instead") \
T(StrongPropertyAccess, \
"In strong mode, accessing missing property '%' of % is deprecated") \
T(StrongSuperCallDuplicate, \
"In strong mode, invoking the super constructor multiple times is " \
"deprecated") \

View File

@ -4592,7 +4592,7 @@ void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
KeyedLoadICStub stub(isolate(), state());
KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
@ -4805,7 +4805,7 @@ void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
__ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
__ Branch(&try_poly_name, ne, at, Operand(feedback));
Handle<Code> megamorphic_stub =
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);

View File

@ -2229,7 +2229,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ lw(load_name, MemOperand(sp, 2 * kPointerSize));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(a0, v0);
__ mov(a1, a0);
@ -2400,7 +2400,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL, language_mode());
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2412,14 +2412,13 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
@ -2428,10 +2427,9 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
@ -2977,7 +2975,6 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, v0, v0, scratch);
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -2985,8 +2982,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ sw(v0, MemOperand(sp, kPointerSize));
@ -3037,7 +3033,6 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, v0, v0, scratch);
VisitForStackValue(prop->key());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -3045,8 +3040,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ sw(v0, MemOperand(sp, kPointerSize));

View File

@ -2866,7 +2866,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -2966,10 +2966,9 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
// Name is always in a2.
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3294,9 +3293,9 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic =
CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}

View File

@ -4636,7 +4636,7 @@ void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
KeyedLoadICStub stub(isolate(), state());
KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
@ -4847,7 +4847,7 @@ void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
__ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
__ Branch(&try_poly_name, ne, feedback, Operand(at));
Handle<Code> megamorphic_stub =
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);

View File

@ -2226,7 +2226,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ ld(load_name, MemOperand(sp, 2 * kPointerSize));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(a0, v0);
__ mov(a1, a0);
@ -2399,7 +2399,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL, language_mode());
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2411,15 +2411,14 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
// Call keyed load IC. It has register arguments receiver and key.
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
@ -2428,10 +2427,9 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
@ -2980,7 +2978,6 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, v0, v0, scratch);
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -2988,8 +2985,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ sd(v0, MemOperand(sp, kPointerSize));
@ -3040,7 +3036,6 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, v0, v0, scratch);
VisitForStackValue(prop->key());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -3048,8 +3043,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ sd(v0, MemOperand(sp, kPointerSize));

View File

@ -2970,7 +2970,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3085,10 +3085,9 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
// Name is always in a2.
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3455,9 +3454,9 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic =
CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}

View File

@ -1162,18 +1162,17 @@ bool Object::HasSpecificClassOf(String* name) {
MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
Handle<Name> name,
LanguageMode language_mode) {
Handle<Name> name) {
LookupIterator it(object, name);
return GetProperty(&it, language_mode);
return GetProperty(&it);
}
MaybeHandle<Object> Object::GetElement(Isolate* isolate, Handle<Object> object,
uint32_t index,
LanguageMode language_mode) {
MaybeHandle<Object> Object::GetElement(Isolate* isolate,
Handle<Object> object,
uint32_t index) {
LookupIterator it(isolate, object, index);
return GetProperty(&it, language_mode);
return GetProperty(&it);
}
@ -1190,11 +1189,11 @@ Handle<Object> Object::GetPrototypeSkipHiddenPrototypes(
}
MaybeHandle<Object> Object::GetProperty(Isolate* isolate, Handle<Object> object,
const char* name,
LanguageMode language_mode) {
MaybeHandle<Object> Object::GetProperty(Isolate* isolate,
Handle<Object> object,
const char* name) {
Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
return GetProperty(object, str, language_mode);
return GetProperty(object, str);
}
@ -6551,11 +6550,10 @@ String* String::GetForwardedInternalizedString() {
MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object,
Handle<Name> name,
LanguageMode language_mode) {
Handle<Name> name) {
LookupIterator it =
LookupIterator::PropertyOrElement(name->GetIsolate(), object, name);
return GetProperty(&it, language_mode);
return GetProperty(&it);
}

View File

@ -127,8 +127,7 @@ bool Object::IsPromise(Handle<Object> object) {
}
MaybeHandle<Object> Object::GetProperty(LookupIterator* it,
LanguageMode language_mode) {
MaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
for (; it->IsFound(); it->Next()) {
switch (it->state()) {
case LookupIterator::NOT_FOUND:
@ -148,16 +147,16 @@ MaybeHandle<Object> Object::GetProperty(LookupIterator* it,
}
case LookupIterator::ACCESS_CHECK:
if (it->HasAccess()) break;
return JSObject::GetPropertyWithFailedAccessCheck(it, language_mode);
return JSObject::GetPropertyWithFailedAccessCheck(it);
case LookupIterator::ACCESSOR:
return GetPropertyWithAccessor(it, language_mode);
return GetPropertyWithAccessor(it);
case LookupIterator::INTEGER_INDEXED_EXOTIC:
return ReadAbsentProperty(it, language_mode);
return it->factory()->undefined_value();
case LookupIterator::DATA:
return it->GetDataValue();
}
}
return ReadAbsentProperty(it, language_mode);
return it->factory()->undefined_value();
}
@ -305,8 +304,7 @@ MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy,
}
MaybeHandle<Object> Object::GetPropertyWithAccessor(
LookupIterator* it, LanguageMode language_mode) {
MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
Isolate* isolate = it->isolate();
Handle<Object> structure = it->GetAccessors();
Handle<Object> receiver = it->GetReceiver();
@ -338,7 +336,7 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(
args.Call(call_fun, v8::Utils::ToLocal(name));
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (result.IsEmpty()) {
return ReadAbsentProperty(isolate, receiver, name, language_mode);
return isolate->factory()->undefined_value();
}
Handle<Object> return_value = v8::Utils::OpenHandle(*result);
return_value->VerifyApiCallResultType();
@ -354,7 +352,7 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(
receiver, Handle<JSReceiver>::cast(getter));
}
// Getter is not a function.
return ReadAbsentProperty(isolate, receiver, it->GetName(), language_mode);
return isolate->factory()->undefined_value();
}
@ -490,11 +488,11 @@ static bool FindAllCanReadHolder(LookupIterator* it) {
MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
LookupIterator* it, LanguageMode language_mode) {
LookupIterator* it) {
Handle<JSObject> checked = it->GetHolder<JSObject>();
while (FindAllCanReadHolder(it)) {
if (it->state() == LookupIterator::ACCESSOR) {
return GetPropertyWithAccessor(it, language_mode);
return GetPropertyWithAccessor(it);
}
DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
bool done;
@ -3225,26 +3223,6 @@ MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it,
}
MaybeHandle<Object> Object::ReadAbsentProperty(LookupIterator* it,
LanguageMode language_mode) {
return ReadAbsentProperty(it->isolate(), it->GetReceiver(), it->GetName(),
language_mode);
}
MaybeHandle<Object> Object::ReadAbsentProperty(Isolate* isolate,
Handle<Object> receiver,
Handle<Object> name,
LanguageMode language_mode) {
if (is_strong(language_mode)) {
THROW_NEW_ERROR(
isolate,
NewTypeError(MessageTemplate::kStrongPropertyAccess, name, receiver),
Object);
}
return isolate->factory()->undefined_value();
}
MaybeHandle<Object> Object::WriteToReadOnlyProperty(
LookupIterator* it, Handle<Object> value, LanguageMode language_mode) {
return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),

View File

@ -1162,8 +1162,7 @@ class Object {
MUST_USE_RESULT static inline MaybeHandle<Smi> ToSmi(Isolate* isolate,
Handle<Object> object);
MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
LookupIterator* it, LanguageMode language_mode = SLOPPY);
MUST_USE_RESULT static MaybeHandle<Object> GetProperty(LookupIterator* it);
// Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5.
MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
@ -1179,15 +1178,10 @@ class Object {
LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
StoreFromKeyed store_mode);
MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
LookupIterator* it, LanguageMode language_mode);
MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
LanguageMode language_mode);
MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
LookupIterator* it, Handle<Object> value, LanguageMode language_mode);
MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
Isolate* isolate, Handle<Object> reciever, Handle<Object> name,
Handle<Object> value, LanguageMode language_mode);
MUST_USE_RESULT static MaybeHandle<Object> RedefineNonconfigurableProperty(
Isolate* isolate, Handle<Object> name, Handle<Object> value,
@ -1198,17 +1192,16 @@ class Object {
LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
LanguageMode language_mode, StoreFromKeyed store_mode);
MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
Handle<Object> object, Handle<Name> name,
LanguageMode language_mode = SLOPPY);
Handle<Object> object, Handle<Name> name);
MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
Isolate* isolate, Handle<Object> object, const char* key,
LanguageMode language_mode = SLOPPY);
Isolate* isolate,
Handle<Object> object,
const char* key);
MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
Handle<Object> object, Handle<Name> name,
LanguageMode language_mode = SLOPPY);
Handle<Object> object, Handle<Name> name);
MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
LookupIterator* it, LanguageMode language_mode);
LookupIterator* it);
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithAccessor(
LookupIterator* it, Handle<Object> value, LanguageMode language_mode);
@ -1221,8 +1214,9 @@ class Object {
Handle<Object> value);
MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
Isolate* isolate, Handle<Object> object, uint32_t index,
LanguageMode language_mode = SLOPPY);
Isolate* isolate,
Handle<Object> object,
uint32_t index);
static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
Isolate* isolate, Handle<Object> receiver);
@ -2338,7 +2332,7 @@ class JSObject: public JSReceiver {
// Used from Object::GetProperty().
MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
LookupIterator* it, LanguageMode language_mode);
LookupIterator* it);
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
LookupIterator* it, Handle<Object> value);

View File

@ -4612,7 +4612,7 @@ void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
KeyedLoadICStub stub(isolate(), state());
KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
@ -4829,7 +4829,7 @@ void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ bne(&try_poly_name);
Handle<Code> megamorphic_stub =
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);

View File

@ -2200,7 +2200,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ LoadP(load_name, MemOperand(sp, 2 * kPointerSize));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mr(r4, r3);
__ StoreP(r4, MemOperand(sp, 2 * kPointerSize));
@ -2389,7 +2389,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL, language_mode());
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2401,14 +2401,13 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
@ -2417,10 +2416,9 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
@ -2992,7 +2990,6 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, r3, r3, scratch);
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -3000,8 +2997,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ StoreP(r3, MemOperand(sp, kPointerSize));
@ -3051,7 +3047,6 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, r3, r3, scratch);
VisitForStackValue(prop->key());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -3059,8 +3054,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ StoreP(r3, MemOperand(sp, kPointerSize));

View File

@ -3025,7 +3025,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3141,10 +3141,9 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
// Name is always in r5.
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3516,9 +3515,9 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic =
CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}

View File

@ -120,8 +120,7 @@ RUNTIME_FUNCTION(Runtime_DefineClass) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, prototype_parent,
Runtime::GetObjectProperty(isolate, super_class,
isolate->factory()->prototype_string(),
SLOPPY));
isolate->factory()->prototype_string()));
if (!prototype_parent->IsNull() && !prototype_parent->IsSpecObject()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kPrototypeParentNotAnObject,
@ -245,87 +244,64 @@ RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) {
}
static MaybeHandle<Object> LoadFromSuper(Isolate* isolate,
Handle<Object> receiver,
Handle<JSObject> home_object,
Handle<Name> name,
LanguageMode language_mode) {
static Object* LoadFromSuper(Isolate* isolate, Handle<Object> receiver,
Handle<JSObject> home_object, Handle<Name> name) {
if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
isolate->ReportFailedAccessCheck(home_object);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
PrototypeIterator iter(isolate, home_object);
Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
if (!proto->IsJSReceiver()) {
return Object::ReadAbsentProperty(isolate, proto, name, language_mode);
}
if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
Object::GetProperty(&it, language_mode), Object);
return result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
return *result;
}
static MaybeHandle<Object> LoadElementFromSuper(Isolate* isolate,
Handle<Object> receiver,
Handle<JSObject> home_object,
uint32_t index,
LanguageMode language_mode) {
static Object* LoadElementFromSuper(Isolate* isolate, Handle<Object> receiver,
Handle<JSObject> home_object,
uint32_t index) {
if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
isolate->ReportFailedAccessCheck(home_object);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
PrototypeIterator iter(isolate, home_object);
Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
if (!proto->IsJSReceiver()) {
Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
return Object::ReadAbsentProperty(isolate, proto, name, language_mode);
}
if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
LookupIterator it(isolate, receiver, index, Handle<JSReceiver>::cast(proto));
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
Object::GetProperty(&it, language_mode), Object);
return result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
return *result;
}
RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
HandleScope scope(isolate);
DCHECK(args.length() == 4);
DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
LoadFromSuper(isolate, receiver, home_object, name, language_mode));
return *result;
return LoadFromSuper(isolate, receiver, home_object, name);
}
RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) {
HandleScope scope(isolate);
DCHECK(args.length() == 4);
DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3);
uint32_t index = 0;
Handle<Object> result;
if (key->ToArrayIndex(&index)) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, LoadElementFromSuper(isolate, receiver, home_object,
index, language_mode));
return *result;
return LoadElementFromSuper(isolate, receiver, home_object, index);
}
Handle<Name> name;
@ -333,15 +309,9 @@ RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) {
Runtime::ToName(isolate, key));
// TODO(verwaest): Unify using LookupIterator.
if (name->AsArrayIndex(&index)) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, LoadElementFromSuper(isolate, receiver, home_object,
index, language_mode));
return *result;
return LoadElementFromSuper(isolate, receiver, home_object, index);
}
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
LoadFromSuper(isolate, receiver, home_object, name, language_mode));
return *result;
return LoadFromSuper(isolate, receiver, home_object, name);
}

View File

@ -81,7 +81,7 @@ static Handle<Object> DebugGetProperty(LookupIterator* it,
return it->isolate()->factory()->undefined_value();
}
MaybeHandle<Object> maybe_result =
JSObject::GetPropertyWithAccessor(it, SLOPPY);
JSObject::GetPropertyWithAccessor(it);
Handle<Object> result;
if (!maybe_result.ToHandle(&result)) {
result = handle(it->isolate()->pending_exception(), it->isolate());

View File

@ -26,8 +26,7 @@ static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
Handle<Object> object,
uint32_t index,
LanguageMode language_mode) {
uint32_t index) {
// Handle [] indexing on Strings
if (object->IsString() &&
index < static_cast<uint32_t>(String::cast(*object)->length())) {
@ -35,7 +34,7 @@ MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
if (!result->IsUndefined()) return result;
}
return Object::GetElement(isolate, object, index, language_mode);
return Object::GetElement(isolate, object, index);
}
@ -53,8 +52,7 @@ MaybeHandle<Name> Runtime::ToName(Isolate* isolate, Handle<Object> key) {
MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
Handle<Object> object,
Handle<Object> key,
LanguageMode language_mode) {
Handle<Object> key) {
if (object->IsUndefined() || object->IsNull()) {
THROW_NEW_ERROR(
isolate,
@ -65,7 +63,7 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
// Check if the given key is an array index.
uint32_t index = 0;
if (key->ToArrayIndex(&index)) {
return GetElementOrCharAt(isolate, object, index, language_mode);
return GetElementOrCharAt(isolate, object, index);
}
// Convert the key to a name - possibly by calling back into JavaScript.
@ -79,112 +77,11 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
if (name->AsArrayIndex(&index)) {
return GetElementOrCharAt(isolate, object, index);
} else {
return Object::GetProperty(object, name, language_mode);
return Object::GetProperty(object, name);
}
}
MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
Handle<Object> object, ElementsKind to_kind, Isolate* isolate) {
HandleScope scope(isolate);
if (!object->IsJSObject()) {
isolate->ThrowIllegalOperation();
return MaybeHandle<Object>();
}
ElementsKind from_kind =
Handle<JSObject>::cast(object)->map()->elements_kind();
if (Map::IsValidElementsTransition(from_kind, to_kind)) {
JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
return object;
}
isolate->ThrowIllegalOperation();
return MaybeHandle<Object>();
}
MaybeHandle<Object> Runtime::KeyedGetObjectProperty(
Isolate* isolate, Handle<Object> receiver_obj, Handle<Object> key_obj,
LanguageMode language_mode) {
// Fast cases for getting named properties of the receiver JSObject
// itself.
//
// The global proxy objects has to be excluded since LookupOwn on
// the global proxy object can return a valid result even though the
// global proxy object never has properties. This is the case
// because the global proxy object forwards everything to its hidden
// prototype including own lookups.
//
// Additionally, we need to make sure that we do not cache results
// for objects that require access checks.
if (receiver_obj->IsJSObject()) {
if (!receiver_obj->IsJSGlobalProxy() &&
!receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
DisallowHeapAllocation no_allocation;
Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
Handle<Name> key = Handle<Name>::cast(key_obj);
if (receiver->IsGlobalObject()) {
// Attempt dictionary lookup.
GlobalDictionary* dictionary = receiver->global_dictionary();
int entry = dictionary->FindEntry(key);
if (entry != GlobalDictionary::kNotFound) {
DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
if (cell->property_details().type() == DATA) {
Object* value = cell->value();
if (!value->IsTheHole()) return Handle<Object>(value, isolate);
// If value is the hole (meaning, absent) do the general lookup.
}
}
} else if (!receiver->HasFastProperties()) {
// Attempt dictionary lookup.
NameDictionary* dictionary = receiver->property_dictionary();
int entry = dictionary->FindEntry(key);
if ((entry != NameDictionary::kNotFound) &&
(dictionary->DetailsAt(entry).type() == DATA)) {
Object* value = dictionary->ValueAt(entry);
return Handle<Object>(value, isolate);
}
}
} else if (key_obj->IsSmi()) {
// JSObject without a name key. If the key is a Smi, check for a
// definite out-of-bounds access to elements, which is a strong indicator
// that subsequent accesses will also call the runtime. Proactively
// transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
// doubles for those future calls in the case that the elements would
// become FAST_DOUBLE_ELEMENTS.
Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
ElementsKind elements_kind = js_object->GetElementsKind();
if (IsFastDoubleElementsKind(elements_kind)) {
Handle<Smi> key = Handle<Smi>::cast(key_obj);
if (key->value() >= js_object->elements()->length()) {
if (IsFastHoleyElementsKind(elements_kind)) {
elements_kind = FAST_HOLEY_ELEMENTS;
} else {
elements_kind = FAST_ELEMENTS;
}
RETURN_ON_EXCEPTION(
isolate, TransitionElements(js_object, elements_kind, isolate),
Object);
}
} else {
DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
!IsFastElementsKind(elements_kind));
}
}
} else if (receiver_obj->IsString() && key_obj->IsSmi()) {
// Fast case for string indexing using [] with a smi index.
Handle<String> str = Handle<String>::cast(receiver_obj);
int index = Handle<Smi>::cast(key_obj)->value();
if (index >= 0 && index < str->length()) {
return GetCharAt(str, index);
}
}
// Fall back to GetObjectProperty.
return GetObjectProperty(isolate, receiver_obj, key_obj, language_mode);
}
MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
Handle<Object> object,
Handle<Object> key,
@ -486,32 +383,122 @@ RUNTIME_FUNCTION(Runtime_ObjectSeal) {
RUNTIME_FUNCTION(Runtime_GetProperty) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
Runtime::GetObjectProperty(isolate, object, key, language_mode));
isolate, result, Runtime::GetObjectProperty(isolate, object, key));
return *result;
}
MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
Handle<Object> object, ElementsKind to_kind, Isolate* isolate) {
HandleScope scope(isolate);
if (!object->IsJSObject()) {
isolate->ThrowIllegalOperation();
return MaybeHandle<Object>();
}
ElementsKind from_kind =
Handle<JSObject>::cast(object)->map()->elements_kind();
if (Map::IsValidElementsTransition(from_kind, to_kind)) {
JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
return object;
}
isolate->ThrowIllegalOperation();
return MaybeHandle<Object>();
}
// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2);
// Fast cases for getting named properties of the receiver JSObject
// itself.
//
// The global proxy objects has to be excluded since LookupOwn on
// the global proxy object can return a valid result even though the
// global proxy object never has properties. This is the case
// because the global proxy object forwards everything to its hidden
// prototype including own lookups.
//
// Additionally, we need to make sure that we do not cache results
// for objects that require access checks.
if (receiver_obj->IsJSObject()) {
if (!receiver_obj->IsJSGlobalProxy() &&
!receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
DisallowHeapAllocation no_allocation;
Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
Handle<Name> key = Handle<Name>::cast(key_obj);
if (receiver->IsGlobalObject()) {
// Attempt dictionary lookup.
GlobalDictionary* dictionary = receiver->global_dictionary();
int entry = dictionary->FindEntry(key);
if (entry != GlobalDictionary::kNotFound) {
DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
if (cell->property_details().type() == DATA) {
Object* value = cell->value();
if (!value->IsTheHole()) return value;
// If value is the hole (meaning, absent) do the general lookup.
}
}
} else if (!receiver->HasFastProperties()) {
// Attempt dictionary lookup.
NameDictionary* dictionary = receiver->property_dictionary();
int entry = dictionary->FindEntry(key);
if ((entry != NameDictionary::kNotFound) &&
(dictionary->DetailsAt(entry).type() == DATA)) {
Object* value = dictionary->ValueAt(entry);
return value;
}
}
} else if (key_obj->IsSmi()) {
// JSObject without a name key. If the key is a Smi, check for a
// definite out-of-bounds access to elements, which is a strong indicator
// that subsequent accesses will also call the runtime. Proactively
// transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
// doubles for those future calls in the case that the elements would
// become FAST_DOUBLE_ELEMENTS.
Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
ElementsKind elements_kind = js_object->GetElementsKind();
if (IsFastDoubleElementsKind(elements_kind)) {
Handle<Smi> key = Handle<Smi>::cast(key_obj);
if (key->value() >= js_object->elements()->length()) {
if (IsFastHoleyElementsKind(elements_kind)) {
elements_kind = FAST_HOLEY_ELEMENTS;
} else {
elements_kind = FAST_ELEMENTS;
}
RETURN_FAILURE_ON_EXCEPTION(
isolate, TransitionElements(js_object, elements_kind, isolate));
}
} else {
DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
!IsFastElementsKind(elements_kind));
}
}
} else if (receiver_obj->IsString() && key_obj->IsSmi()) {
// Fast case for string indexing using [] with a smi index.
Handle<String> str = Handle<String>::cast(receiver_obj);
int index = args.smi_at(1);
if (index >= 0 && index < str->length()) {
return *GetCharAt(str, index);
}
}
// Fall back to GetObjectProperty.
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, Runtime::KeyedGetObjectProperty(isolate, receiver_obj,
key_obj, language_mode));
isolate, result,
Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
return *result;
}

View File

@ -78,8 +78,8 @@ namespace internal {
F(DefineClass, 6, 1) \
F(DefineClassMethod, 3, 1) \
F(ClassGetSourceCode, 1, 1) \
F(LoadFromSuper, 4, 1) \
F(LoadKeyedFromSuper, 4, 1) \
F(LoadFromSuper, 3, 1) \
F(LoadKeyedFromSuper, 3, 1) \
F(StoreToSuper_Strict, 4, 1) \
F(StoreToSuper_Sloppy, 4, 1) \
F(StoreKeyedToSuper_Strict, 4, 1) \
@ -431,8 +431,8 @@ namespace internal {
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
F(ObjectFreeze, 1, 1) \
F(ObjectSeal, 1, 1) \
F(GetProperty, 3, 1) \
F(KeyedGetProperty, 3, 1) \
F(GetProperty, 2, 1) \
F(KeyedGetProperty, 2, 1) \
F(AddNamedProperty, 4, 1) \
F(SetProperty, 4, 1) \
F(AddElement, 3, 1) \
@ -815,20 +815,14 @@ class Runtime : public AllStatic {
// Support getting the characters in a string using [] notation as
// in Firefox/SpiderMonkey, Safari and Opera.
MUST_USE_RESULT static MaybeHandle<Object> GetElementOrCharAt(
Isolate* isolate, Handle<Object> object, uint32_t index,
LanguageMode language_mode = SLOPPY);
Isolate* isolate, Handle<Object> object, uint32_t index);
MUST_USE_RESULT static MaybeHandle<Object> SetObjectProperty(
Isolate* isolate, Handle<Object> object, Handle<Object> key,
Handle<Object> value, LanguageMode language_mode);
MUST_USE_RESULT static MaybeHandle<Object> GetObjectProperty(
Isolate* isolate, Handle<Object> object, Handle<Object> key,
LanguageMode language_mode = SLOPPY);
MUST_USE_RESULT static MaybeHandle<Object> KeyedGetObjectProperty(
Isolate* isolate, Handle<Object> receiver_obj, Handle<Object> key_obj,
LanguageMode language_mode);
Isolate* isolate, Handle<Object> object, Handle<Object> key);
MUST_USE_RESULT static MaybeHandle<Object> GetPrototype(
Isolate* isolate, Handle<Object> object);

View File

@ -4375,7 +4375,7 @@ void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
KeyedLoadICStub stub(isolate(), state());
KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
@ -4554,7 +4554,7 @@ void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ j(not_equal, &try_poly_name);
Handle<Code> megamorphic_stub =
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);

View File

@ -2196,7 +2196,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ movp(load_receiver, Operand(rsp, kPointerSize));
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ movp(rdi, rax);
__ movp(Operand(rsp, 2 * kPointerSize), rdi);
@ -2364,7 +2364,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ Move(LoadDescriptor::NameRegister(), key->value());
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL, language_mode());
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2376,14 +2376,13 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallIC(ic);
@ -2392,10 +2391,9 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
@ -2891,7 +2889,6 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
__ Push(rax);
__ Push(Operand(rsp, kPointerSize * 2));
__ Push(key->value());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -2899,8 +2896,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ movp(Operand(rsp, kPointerSize), rax);
@ -2950,7 +2946,6 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
__ Push(rax);
__ Push(Operand(rsp, kPointerSize * 2));
VisitForStackValue(prop->key());
__ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
@ -2958,8 +2953,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ movp(Operand(rsp, kPointerSize), rax);

View File

@ -2864,7 +2864,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
__ Move(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -2980,10 +2980,9 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
__ Move(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3279,9 +3278,9 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic =
CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}

View File

@ -4090,7 +4090,7 @@ void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
KeyedLoadICStub stub(isolate(), state());
KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
@ -4294,7 +4294,7 @@ void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ j(not_equal, &try_poly_name);
Handle<Code> megamorphic_stub =
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);

View File

@ -2157,7 +2157,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ mov(load_receiver, Operand(esp, kPointerSize));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(edi, eax);
__ mov(Operand(esp, 2 * kPointerSize), edi);
@ -2326,7 +2326,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL, language_mode());
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2338,14 +2338,13 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
DCHECK(prop->IsSuperAccess());
__ push(Immediate(key->value()));
__ push(Immediate(Smi::FromInt(language_mode())));
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
@ -2354,10 +2353,9 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
__ push(Immediate(Smi::FromInt(language_mode())));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
@ -2887,15 +2885,13 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
__ push(eax);
__ push(Operand(esp, kPointerSize * 2));
__ push(Immediate(key->value()));
__ push(Immediate(Smi::FromInt(language_mode())));
// Stack here:
// - home_object
// - this (receiver)
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadFromSuper, 4);
__ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ mov(Operand(esp, kPointerSize), eax);
@ -2945,15 +2941,13 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
__ push(eax);
__ push(Operand(esp, kPointerSize * 2));
VisitForStackValue(prop->key());
__ push(Immediate(Smi::FromInt(language_mode())));
// Stack here:
// - home_object
// - this (receiver)
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
// - language_mode
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ mov(Operand(esp, kPointerSize), eax);

View File

@ -3116,7 +3116,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
__ mov(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3226,10 +3226,9 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
__ mov(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3468,9 +3467,9 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
Handle<Code> ic =
CodeFactory::KeyedLoadICInOptimizedCode(
isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}

View File

@ -19356,7 +19356,7 @@ TEST(AccessCheckThrows) {
CheckCorrectThrow("other[1]");
CheckCorrectThrow("JSON.stringify(other)");
CheckCorrectThrow("has_own_property(other, 'x')");
CheckCorrectThrow("%GetProperty(other, 'x', 0)");
CheckCorrectThrow("%GetProperty(other, 'x')");
CheckCorrectThrow("%SetProperty(other, 'x', 'foo', 0)");
CheckCorrectThrow("%AddNamedProperty(other, 'x', 'foo', 1)");
CheckCorrectThrow("%DeleteProperty(other, 'x', 0)");

View File

@ -47,8 +47,8 @@ function* g() {}
(function LexicalBindings(global) {
assertEquals('function', typeof f);
assertEquals('function', typeof g);
assertFalse(global.hasOwnProperty("f"));
assertFalse(global.hasOwnProperty("g"));
assertEquals(undefined, global.f);
assertEquals(undefined, global.g);
})(this);
(function ImmutableBindings() {

View File

@ -1,42 +0,0 @@
// Copyright 2015 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.
// Flags: --strong-mode --allow-natives-syntax
function getGlobal() {
return this;
}
function polluteGlobal() {
bar = 0;
}
(function() {
"use strict";
let builtins = [
Array,
Object,
Function,
getGlobal()
];
for (let builtin of builtins) {
assertThrows(function(){"use strong"; builtin.foo}, TypeError);
assertThrows(function(){"use strong"; builtin[0]}, TypeError);
assertThrows(function(){"use strong"; builtin[10000]}, TypeError);
builtin.foo = 1;
assertDoesNotThrow(function(){"use strong"; builtin.foo});
assertThrows(function(){"use strong"; builtin.bar});
assertThrows(function(){"use strong"; builtin[0]}, TypeError);
assertThrows(function(){"use strong"; builtin[10000]}, TypeError);
builtin[0] = 1;
assertDoesNotThrow(function(){"use strong"; builtin.foo});
assertThrows(function(){"use strong"; builtin.bar});
assertDoesNotThrow(function(){"use strong"; builtin[0]});
assertThrows(function(){"use strong"; builtin[10000]}, TypeError);
}
polluteGlobal();
assertDoesNotThrow(function(){"use strong"; getGlobal().bar});
})();

View File

@ -1,239 +0,0 @@
// Copyright 2015 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.
// Flags: --strong-mode --allow-natives-syntax
function getSloppyArguments() {
return arguments;
}
function getObjects() {
"use strict";
return [
{},
Object(""),
[],
(function(){}),
(class Foo {}),
getSloppyArguments(),
arguments,
new Date(),
];
}
// TODO(conradw): add tests for non-inheritance once semantics are implemented.
function getNonInheritingObjects() {
"use strong";
return [
Object(""),
[],
// TODO(conradw): uncomment and correct test once Object.defineProperty is
// fixed.
// new Uint32Array(0)
];
}
function readFromObjectElementSloppy(o) {
return o[0];
}
function readFromObjectElementSparseSloppy(o) {
return o[100000];
}
function readFromObjectElementNonSmiSloppy(o) {
return o[3000000000];
}
function readFromObjectNonIndexSloppy(o) {
return o[5000000000];
}
function readFromObjectElementVarSloppy(o) {
var a = 0;
return o[a];
}
function readFromObjectElementSparseVarSloppy(o) {
var a = 100000;
return o[a];
}
function readFromObjectElementNonSmiVarSloppy(o) {
var a = 3000000000;
return o[a];
}
function readFromObjectNonIndexVarSloppy(o) {
var a = 5000000000;
return o[a];
}
function readFromObjectElementStrong(o) {
"use strong";
return o[0];
}
function readFromObjectElementSparseStrong(o) {
"use strong";
return o[100000];
}
function readFromObjectElementNonSmiStrong(o) {
"use strong";
return o[3000000000];
}
function readFromObjectNonIndexStrong(o) {
"use strong";
return o[5000000000];
}
function readFromObjectElementLetStrong(o) {
"use strong";
let a = 0;
return o[a];
}
function readFromObjectElementSparseLetStrong(o) {
"use strong";
let a = 100000;
return o[a];
}
function readFromObjectElementNonSmiLetStrong(o) {
"use strong";
let a = 3000000000;
return o[a];
}
function readFromObjectNonIndexLetStrong(o) {
"use strong";
let a = 5000000000;
return o[a];
}
function getDescs(x) {
return [
{value: x},
{configurable: true, enumerable: true, writable: true, value: x},
{configurable: true, enumerable: true, get: (function() {return x}) },
];
}
function assertStrongSemantics(func, object) {
%DeoptimizeFunction(func);
%ClearFunctionTypeFeedback(func);
assertThrows(function(){func(object)}, TypeError);
assertThrows(function(){func(object)}, TypeError);
assertThrows(function(){func(object)}, TypeError);
%OptimizeFunctionOnNextCall(func);
assertThrows(function(){func(object)}, TypeError);
%DeoptimizeFunction(func);
assertThrows(function(){func(object)}, TypeError);
}
function assertSloppySemantics(func, object) {
%DeoptimizeFunction(func);
%ClearFunctionTypeFeedback(func);
assertDoesNotThrow(function(){func(object)});
assertDoesNotThrow(function(){func(object)});
assertDoesNotThrow(function(){func(object)});
%OptimizeFunctionOnNextCall(func);
assertDoesNotThrow(function(){func(object)});
%DeoptimizeFunction(func);
assertDoesNotThrow(function(){func(object)});
}
(function () {
"use strict";
let goodKeys = [
"0",
"100000",
"3000000000",
"5000000000"
]
let badKeys = [
"bar",
"1",
"100001",
"3000000001",
"5000000001"
];
let values = [
"string",
1,
100001,
30000000001,
50000000001,
NaN,
{},
undefined
];
let badAccessorDescs = [
{ set: (function(){}) },
{ configurable: true, enumerable: true, set: (function(){}) }
];
let readSloppy = [
readFromObjectElementSloppy,
readFromObjectElementSparseSloppy,
readFromObjectElementNonSmiSloppy,
readFromObjectNonIndexSloppy,
readFromObjectElementVarSloppy,
readFromObjectElementSparseVarSloppy,
readFromObjectElementNonSmiVarSloppy,
readFromObjectNonIndexVarSloppy
];
let readStrong = [
readFromObjectElementStrong,
readFromObjectElementSparseStrong,
readFromObjectElementNonSmiStrong,
readFromObjectNonIndexStrong,
readFromObjectElementLetStrong,
readFromObjectElementSparseLetStrong,
readFromObjectElementNonSmiLetStrong,
readFromObjectNonIndexLetStrong
];
let dummyProto = {};
for (let key of goodKeys) {
Object.defineProperty(dummyProto, key, { value: undefined });
}
// After altering the backing store, accessing a missing property should still
// throw.
for (let key of badKeys) {
for (let value of values) {
for (let desc of getDescs(value)) {
let objects = getObjects();
let nonInheritingObjects = getNonInheritingObjects();
for (let object of objects.concat(nonInheritingObjects)) {
Object.defineProperty(object, key, desc);
for (let func of readStrong) {
assertStrongSemantics(func, object);
}
for (let func of readSloppy) {
assertSloppySemantics(func, object);
}
}
for (let object of objects) {
// Accessing a property which is on the prototype chain of the object
// should not throw.
object.__proto__ = dummyProto;
for (let key of goodKeys) {
for (let func of readStrong.concat(readSloppy)) {
assertSloppySemantics(func, object);
}
}
}
}
}
}
})();

View File

@ -1,264 +0,0 @@
// Copyright 2015 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.
// Flags: --strong-mode --allow-natives-syntax
function getSloppyArguments() {
return arguments;
}
function getObjects() {
"use strict";
return [
{},
Object(""),
[],
(function(){}),
(class Foo {}),
getSloppyArguments(),
arguments,
new Date()
];
}
//TODO(conradw): add tests for non-inheritance once semantics are implemented.
function getNonInheritingObjects() {
"use strong";
return [
Object(""),
[],
new Uint32Array(0)
];
}
function readFromObjectElementSloppy(o) {
return o[0];
}
function readFromObjectElementSparseSloppy(o) {
return o[100000];
}
function readFromObjectElementNonSmiSloppy(o) {
return o[3000000000];
}
function readFromObjectNonIndexSloppy(o) {
return o[5000000000];
}
function readFromObjectElementVarSloppy(o) {
var a = 0;
return o[a];
}
function readFromObjectElementSparseVarSloppy(o) {
var a = 100000;
return o[a];
}
function readFromObjectElementNonSmiVarSloppy(o) {
var a = 3000000000;
return o[a];
}
function readFromObjectNonIndexVarSloppy(o) {
var a = 5000000000;
return o[a];
}
function readFromObjectElementStrong(o) {
"use strong";
return o[0];
}
function readFromObjectElementSparseStrong(o) {
"use strong";
return o[100000];
}
function readFromObjectElementNonSmiStrong(o) {
"use strong";
return o[3000000000];
}
function readFromObjectNonIndexStrong(o) {
"use strong";
return o[5000000000];
}
function readFromObjectElementLetStrong(o) {
"use strong";
let a = 0;
return o[a];
}
function readFromObjectElementSparseLetStrong(o) {
"use strong";
let a = 100000;
return o[a];
}
function readFromObjectElementNonSmiLetStrong(o) {
"use strong";
let a = 3000000000;
return o[a];
}
function readFromObjectNonIndexLetStrong(o) {
"use strong";
let a = 5000000000;
return o[a];
}
function getDescs(x) {
return [
{value: x},
{configurable: true, enumerable: true, writable: true, value: x},
{configurable: true, enumerable: true, get: (function() {return x}) },
];
}
function assertStrongSemantics(func, object) {
%DeoptimizeFunction(func);
%ClearFunctionTypeFeedback(func);
assertThrows(function(){func(object)}, TypeError);
assertThrows(function(){func(object)}, TypeError);
assertThrows(function(){func(object)}, TypeError);
%OptimizeFunctionOnNextCall(func);
assertThrows(function(){func(object)}, TypeError);
%DeoptimizeFunction(func);
assertThrows(function(){func(object)}, TypeError);
}
function assertSloppySemantics(func, object) {
%DeoptimizeFunction(func);
%ClearFunctionTypeFeedback(func);
assertDoesNotThrow(function(){func(object)});
assertDoesNotThrow(function(){func(object)});
assertDoesNotThrow(function(){func(object)});
%OptimizeFunctionOnNextCall(func);
assertDoesNotThrow(function(){func(object)});
%DeoptimizeFunction(func);
assertDoesNotThrow(function(){func(object)});
}
(function () {
"use strict";
let goodKeys = [
"0",
"100000",
"3000000000",
"5000000000"
]
let badKeys = [
"bar",
"1",
"100001",
"3000000001",
"5000000001"
];
let values = [
"string",
1,
100001,
30000000001,
50000000001,
NaN,
{},
undefined
];
let literals = [0, NaN, true, ""];
let badAccessorDescs = [
{ set: (function(){}) },
{ configurable: true, enumerable: true, set: (function(){}) }
];
let readSloppy = [
readFromObjectElementSloppy,
readFromObjectElementSparseSloppy,
readFromObjectElementNonSmiSloppy,
readFromObjectNonIndexSloppy,
readFromObjectElementVarSloppy,
readFromObjectElementSparseVarSloppy,
readFromObjectElementNonSmiVarSloppy,
readFromObjectNonIndexVarSloppy
];
let readStrong = [
readFromObjectElementStrong,
readFromObjectElementSparseStrong,
readFromObjectElementNonSmiStrong,
readFromObjectNonIndexStrong,
readFromObjectElementLetStrong,
readFromObjectElementSparseLetStrong,
readFromObjectElementNonSmiLetStrong,
readFromObjectNonIndexLetStrong
];
let dummyProto = {};
for (let key of goodKeys) {
Object.defineProperty(dummyProto, key, { value: undefined });
}
let dummyAccessorProto = {};
for (let key of goodKeys) {
Object.defineProperty(dummyAccessorProto, key, { set: (function(){}) })
}
// String literals/objects should not throw on character index access
assertDoesNotThrow(function() {"use strong"; return "string"[0]; });
assertDoesNotThrow(function() {"use strong"; return Object("string")[0]; });
// Attempting to access a property on an object with no defined properties
// should throw.
for (let object of getObjects().concat(getNonInheritingObjects(), literals)) {
for (let func of readStrong) {
assertStrongSemantics(func, object);
}
for (let func of readSloppy) {
assertSloppySemantics(func, object);
}
}
for (let object of getObjects()) {
// Accessing a property which is on the prototype chain of the object should
// not throw.
object.__proto__ = dummyProto;
for (let key of goodKeys) {
for (let func of readStrong.concat(readSloppy)) {
assertSloppySemantics(func, object);
}
}
}
// Properties with accessor descriptors missing 'get' should throw on access.
for (let desc of badAccessorDescs) {
for (let key of goodKeys) {
for (let object of getObjects()) {
Object.defineProperty(object, key, desc);
for (let func of readStrong) {
assertStrongSemantics(func, object);
}
for (let func of readSloppy) {
assertSloppySemantics(func, object);
}
}
}
}
// The same behaviour should be expected for bad accessor properties on the
// prototype chain.
for (let object of getObjects()) {
object.__proto__ = dummyAccessorProto;
for (let func of readStrong) {
assertStrongSemantics(func, object);
}
for (let func of readSloppy) {
assertSloppySemantics(func, object);
}
}
})();

View File

@ -1,174 +0,0 @@
// Copyright 2015 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.
// Flags: --strong-mode --allow-natives-syntax
function getSloppyArguments() {
return arguments;
}
function getObjects() {
"use strict";
return [
{},
Object(""),
[],
(function(){}),
(class Foo {}),
getSloppyArguments(),
arguments,
new Date(),
// TODO(conradw): uncomment once Object.defineProperty is fixed.
// new Uint32Array(0)
];
}
function readFromObjectSloppy(o) {
return o.foo;
}
function readFromObjectKeyedSloppy(o) {
return o["foo"];
}
function readFromObjectKeyedVarSloppy(o) {
var a = "foo";
return o[a];
}
function readFromObjectKeyedComputedSloppy(o) {
var a = "o";
return o["fo" + a];
}
function readFromObjectStrong(o) {
"use strong";
return o.foo;
}
function readFromObjectKeyedStrong(o) {
"use strong";
return o["foo"];
}
function readFromObjectKeyedLetStrong(o) {
"use strong";
let a = "foo";
return o[a];
}
function readFromObjectKeyedComputedStrong(o) {
"use strong";
let a = "o";
return o["fo" + a];
}
function getDescs(x) {
return [
{value: x},
{configurable: true, enumerable: true, writable: true, value: x},
{configurable: true, enumerable: true, get: (function() {return x}) },
];
}
function assertStrongSemantics(func, object) {
%DeoptimizeFunction(func);
%ClearFunctionTypeFeedback(func);
assertThrows(function(){func(object)}, TypeError);
assertThrows(function(){func(object)}, TypeError);
assertThrows(function(){func(object)}, TypeError);
%OptimizeFunctionOnNextCall(func);
assertThrows(function(){func(object)}, TypeError);
%DeoptimizeFunction(func);
assertThrows(function(){func(object)}, TypeError);
}
function assertSloppySemantics(func, object) {
%DeoptimizeFunction(func);
%ClearFunctionTypeFeedback(func);
assertDoesNotThrow(function(){func(object)});
assertDoesNotThrow(function(){func(object)});
assertDoesNotThrow(function(){func(object)});
%OptimizeFunctionOnNextCall(func);
assertDoesNotThrow(function(){func(object)});
%DeoptimizeFunction(func);
assertDoesNotThrow(function(){func(object)});
}
(function () {
"use strict";
let goodKeys = [
"foo"
]
let badKeys = [
"bar",
"1",
"100001",
"3000000001",
"5000000001"
];
let values = [
"string",
1,
100001,
30000000001,
50000000001,
NaN,
{},
undefined
];
let badAccessorDescs = [
{ set: (function(){}) },
{ configurable: true, enumerable: true, set: (function(){}) }
];
let readSloppy = [
readFromObjectSloppy,
readFromObjectKeyedSloppy,
readFromObjectKeyedVarSloppy,
readFromObjectKeyedComputedSloppy
];
let readStrong = [
readFromObjectStrong,
readFromObjectKeyedStrong,
readFromObjectKeyedLetStrong,
readFromObjectKeyedComputedStrong
];
let dummyProto = {};
for (let key of goodKeys) {
Object.defineProperty(dummyProto, key, { value: undefined });
}
// After altering the backing store, accessing a missing property should still
// throw.
for (let key of badKeys) {
for (let value of values) {
for (let desc of getDescs(value)) {
for (let object of getObjects()) {
Object.defineProperty(object, key, desc);
for (let func of readStrong) {
assertStrongSemantics(func, object);
}
for (let func of readSloppy) {
assertSloppySemantics(func, object);
}
// Accessing a property which is on the prototype chain of the object
// should not throw.
object.__proto__ = dummyProto;
for (let key of goodKeys) {
for (let func of readStrong.concat(readSloppy)) {
assertSloppySemantics(func, object);
}
}
}
}
}
}
})();

View File

@ -1,200 +0,0 @@
// Copyright 2015 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.
// Flags: --strong-mode --allow-natives-syntax
function getSloppyArguments() {
return arguments;
}
function getObjects() {
"use strict";
return [
{},
Object(""),
[],
(function(){}),
(class Foo {}),
getSloppyArguments(),
arguments,
new Date(),
new Uint32Array(0)
];
}
function readFromObjectSloppy(o) {
return o.foo;
}
function readFromObjectKeyedSloppy(o) {
return o["foo"];
}
function readFromObjectKeyedVarSloppy(o) {
var a = "foo";
return o[a];
}
function readFromObjectKeyedComputedSloppy(o) {
var a = "o";
return o["fo" + a];
}
function readFromObjectStrong(o) {
"use strong";
return o.foo;
}
function readFromObjectKeyedStrong(o) {
"use strong";
return o["foo"];
}
function readFromObjectKeyedLetStrong(o) {
"use strong";
let a = "foo";
return o[a];
}
function readFromObjectKeyedComputedStrong(o) {
"use strong";
let a = "o";
return o["fo" + a];
}
function getDescs(x) {
return [
{value: x},
{configurable: true, enumerable: true, writable: true, value: x},
{configurable: true, enumerable: true, get: (function() {return x}) },
];
}
function assertStrongSemantics(func, object) {
%DeoptimizeFunction(func);
%ClearFunctionTypeFeedback(func);
assertThrows(function(){func(object)}, TypeError);
assertThrows(function(){func(object)}, TypeError);
assertThrows(function(){func(object)}, TypeError);
%OptimizeFunctionOnNextCall(func);
assertThrows(function(){func(object)}, TypeError);
%DeoptimizeFunction(func);
assertThrows(function(){func(object)}, TypeError);
}
function assertSloppySemantics(func, object) {
%DeoptimizeFunction(func);
%ClearFunctionTypeFeedback(func);
assertDoesNotThrow(function(){func(object)});
assertDoesNotThrow(function(){func(object)});
assertDoesNotThrow(function(){func(object)});
%OptimizeFunctionOnNextCall(func);
assertDoesNotThrow(function(){func(object)});
%DeoptimizeFunction(func);
assertDoesNotThrow(function(){func(object)});
}
(function () {
"use strict";
let goodKeys = [
"foo"
]
let badKeys = [
"bar",
"1",
"100001",
"3000000001",
"5000000001"
];
let values = [
"string",
1,
100001,
30000000001,
50000000001,
NaN,
{},
undefined
];
let literals = [0, NaN, true, "string"];
let badAccessorDescs = [
{ set: (function(){}) },
{ configurable: true, enumerable: true, set: (function(){}) }
];
let readSloppy = [
readFromObjectSloppy,
readFromObjectKeyedSloppy,
readFromObjectKeyedVarSloppy,
readFromObjectKeyedComputedSloppy
];
let readStrong = [
readFromObjectStrong,
readFromObjectKeyedStrong,
readFromObjectKeyedLetStrong,
readFromObjectKeyedComputedStrong
];
let dummyProto = {};
for (let key of goodKeys) {
Object.defineProperty(dummyProto, key, { value: undefined });
}
let dummyAccessorProto = {};
for (let key of goodKeys) {
Object.defineProperty(dummyAccessorProto, key, { set: (function(){}) })
}
// Attempting to access a property on an object with no defined properties
// should throw.
for (let object of getObjects().concat(literals)) {
for (let func of readStrong) {
assertStrongSemantics(func, object);
}
for (let func of readSloppy) {
assertSloppySemantics(func, object);
}
}
for (let object of getObjects()) {
// Accessing a property which is on the prototype chain of the object should
// not throw.
object.__proto__ = dummyProto;
for (let key of goodKeys) {
for (let func of readStrong.concat(readSloppy)) {
assertSloppySemantics(func, object);
}
}
}
// Properties with accessor descriptors missing 'get' should throw on access.
for (let desc of badAccessorDescs) {
for (let key of goodKeys) {
for (let object of getObjects()) {
Object.defineProperty(object, key, desc);
for (let func of readStrong) {
assertStrongSemantics(func, object);
}
for (let func of readSloppy) {
assertSloppySemantics(func, object);
}
}
}
}
// The same behaviour should be expected for bad accessor properties on the
// prototype chain.
for (let object of getObjects()) {
object.__proto__ = dummyAccessorProto;
for (let func of readStrong) {
assertStrongSemantics(func, object);
}
for (let func of readSloppy) {
assertSloppySemantics(func, object);
}
}
})();

View File

@ -84,7 +84,7 @@ class JSTypeFeedbackTest : public TypedGraphTest {
Unique<Name> name = Unique<Name>::CreateUninitialized(
isolate()->factory()->InternalizeUtf8String(string));
const Operator* op = javascript()->LoadNamed(name, feedback, SLOPPY);
const Operator* op = javascript()->LoadNamed(name, feedback);
Node* load = graph()->NewNode(op, global, vector, context);
if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) {
for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op);

View File

@ -650,37 +650,34 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
NewArrayBuffer(backing_store, sizeof(backing_store));
ResolvedFeedbackSlot feedback;
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
Handle<JSTypedArray> array =
factory()->NewJSTypedArray(type, buffer, 0, kLength);
int const element_size = static_cast<int>(array->element_size());
Handle<JSTypedArray> array =
factory()->NewJSTypedArray(type, buffer, 0, kLength);
int const element_size = static_cast<int>(array->element_size());
Node* key = Parameter(
Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
Node* base = HeapConstant(array);
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(
graph()->NewNode(javascript()->LoadProperty(feedback, language_mode),
base, key, vector, context, EmptyFrameState(),
EmptyFrameState(), effect, control));
Node* key = Parameter(
Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
Node* base = HeapConstant(array);
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(graph()->NewNode(
javascript()->LoadProperty(feedback), base, key, vector, context,
EmptyFrameState(), EmptyFrameState(), effect, control));
Matcher<Node*> offset_matcher =
element_size == 1
? key
: IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
Matcher<Node*> offset_matcher =
element_size == 1
? key
: IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(
r.replacement(),
IsLoadBuffer(BufferAccess(type),
IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
offset_matcher,
IsNumberConstant(array->byte_length()->Number()), effect,
control));
}
ASSERT_TRUE(r.Changed());
EXPECT_THAT(
r.replacement(),
IsLoadBuffer(BufferAccess(type),
IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
offset_matcher,
IsNumberConstant(array->byte_length()->Number()), effect,
control));
}
}
@ -692,32 +689,29 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
NewArrayBuffer(backing_store, sizeof(backing_store));
ResolvedFeedbackSlot feedback;
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
Handle<JSTypedArray> array =
factory()->NewJSTypedArray(type, buffer, 0, kLength);
ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
Handle<JSTypedArray> array =
factory()->NewJSTypedArray(type, buffer, 0, kLength);
ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
int min = random_number_generator()->NextInt(static_cast<int>(kLength));
int max = random_number_generator()->NextInt(static_cast<int>(kLength));
if (min > max) std::swap(min, max);
Node* key = Parameter(Type::Range(min, max, zone()));
Node* base = HeapConstant(array);
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(
graph()->NewNode(javascript()->LoadProperty(feedback, language_mode),
base, key, vector, context, EmptyFrameState(),
EmptyFrameState(), effect, control));
int min = random_number_generator()->NextInt(static_cast<int>(kLength));
int max = random_number_generator()->NextInt(static_cast<int>(kLength));
if (min > max) std::swap(min, max);
Node* key = Parameter(Type::Range(min, max, zone()));
Node* base = HeapConstant(array);
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(graph()->NewNode(
javascript()->LoadProperty(feedback), base, key, vector, context,
EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(
r.replacement(),
IsLoadElement(access,
IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
key, effect, control));
}
ASSERT_TRUE(r.Changed());
EXPECT_THAT(
r.replacement(),
IsLoadElement(access,
IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
key, effect, control));
}
}
@ -891,17 +885,14 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) {
Node* effect = graph()->start();
Node* control = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
for (size_t i = 0; i < arraysize(names); i++) {
Unique<Name> name = Unique<Name>::CreateImmovable(names[i]);
Reduction r = Reduce(graph()->NewNode(
javascript()->LoadNamed(name, feedback, language_mode), global,
vector, context, EmptyFrameState(), EmptyFrameState(), effect,
control));
for (size_t i = 0; i < arraysize(names); i++) {
Unique<Name> name = Unique<Name>::CreateImmovable(names[i]);
Reduction r = Reduce(graph()->NewNode(
javascript()->LoadNamed(name, feedback), global, vector, context,
EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), matches[i]);
}
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), matches[i]);
}
}