TypeofMode replaces TypeofState and ContextualMode.
NON_CONTEXTUAL ~> INSIDE_TYPEOF CONTEXTUAL ~> NOT_INSIDE_TYPEOF Review URL: https://codereview.chromium.org/1227893005 Cr-Commit-Position: refs/heads/master@{#29611}
This commit is contained in:
parent
9f9f27c333
commit
fec3c9cba6
@ -12,9 +12,6 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
|
||||
|
||||
|
||||
class StringCharLoadGenerator : public AllStatic {
|
||||
public:
|
||||
// Generates the code for handling different string types and loading the
|
||||
|
@ -1369,7 +1369,7 @@ void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow) {
|
||||
Register current = cp;
|
||||
Register next = r1;
|
||||
@ -1418,7 +1418,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
|
||||
// All extension objects were empty and it is safe to use a normal global
|
||||
// load machinery.
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1455,9 +1455,8 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
Label* slow,
|
||||
Label* done) {
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow, Label* done) {
|
||||
// Generate fast-case code for variables that might be shadowed by
|
||||
// eval-introduced variables. Eval is used a lot without
|
||||
// introducing variables. In those cases, we do not want to
|
||||
@ -1465,7 +1464,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
// containing the eval.
|
||||
Variable* var = proxy->var();
|
||||
if (var->mode() == DYNAMIC_GLOBAL) {
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
|
||||
__ jmp(done);
|
||||
} else if (var->mode() == DYNAMIC_LOCAL) {
|
||||
Variable* local = var->local_if_not_shadowed();
|
||||
@ -1488,7 +1487,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
Variable* var = proxy->var();
|
||||
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
|
||||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
|
||||
@ -1512,15 +1511,13 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
__ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
// Inside typeof use a regular load, not a contextual load, to avoid
|
||||
// a reference error.
|
||||
CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
|
||||
CallLoadIC(typeof_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
// Record position before possible IC call.
|
||||
SetExpressionPosition(proxy);
|
||||
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
|
||||
@ -1532,7 +1529,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::GLOBAL:
|
||||
case VariableLocation::UNALLOCATED: {
|
||||
Comment cmnt(masm_, "[ Global variable");
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
context()->Plug(r0);
|
||||
break;
|
||||
}
|
||||
@ -1540,7 +1537,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::PARAMETER:
|
||||
case VariableLocation::LOCAL:
|
||||
case VariableLocation::CONTEXT: {
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
|
||||
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
|
||||
: "[ Stack variable");
|
||||
if (var->binding_needs_init()) {
|
||||
@ -1614,12 +1611,12 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
Label done, slow;
|
||||
// Generate code for loading from variables potentially shadowed
|
||||
// by eval-introduced variables.
|
||||
EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
|
||||
EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
|
||||
__ bind(&slow);
|
||||
__ mov(r1, Operand(var->name()));
|
||||
__ Push(cp, r1); // Context and name.
|
||||
Runtime::FunctionId function_id =
|
||||
typeof_state == NOT_INSIDE_TYPEOF
|
||||
typeof_mode == NOT_INSIDE_TYPEOF
|
||||
? Runtime::kLoadLookupSlot
|
||||
: Runtime::kLoadLookupSlotNoReferenceError;
|
||||
__ CallRuntime(function_id, 2);
|
||||
@ -2301,7 +2298,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // r0=result.done
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // r0=result.done
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
CallIC(bool_ic);
|
||||
__ cmp(r0, Operand(0));
|
||||
@ -2312,7 +2309,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // r0=result.value
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // r0=result.value
|
||||
context()->DropAndPlug(2, r0); // drop iter and g
|
||||
break;
|
||||
}
|
||||
@ -2464,7 +2461,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_INSIDE_TYPEOF, language_mode());
|
||||
}
|
||||
|
||||
|
||||
@ -4759,7 +4756,7 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1700,7 +1700,7 @@ class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> {
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
|
||||
|
||||
Handle<Object> name() const { return hydrogen()->name(); }
|
||||
bool for_typeof() const { return hydrogen()->for_typeof(); }
|
||||
TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -2970,9 +2970,9 @@ 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,
|
||||
PREMONOMORPHIC).code();
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
|
||||
SLOPPY, PREMONOMORPHIC).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
@ -3069,7 +3069,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
||||
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(
|
||||
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
|
||||
isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
|
||||
instr->hydrogen()->initialization_state()).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
|
||||
}
|
||||
|
@ -1357,7 +1357,7 @@ void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow) {
|
||||
Register current = cp;
|
||||
Register next = x10;
|
||||
@ -1401,7 +1401,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
|
||||
// All extension objects were empty and it is safe to use a normal global
|
||||
// load machinery.
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1436,9 +1436,8 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
Label* slow,
|
||||
Label* done) {
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow, Label* done) {
|
||||
// Generate fast-case code for variables that might be shadowed by
|
||||
// eval-introduced variables. Eval is used a lot without
|
||||
// introducing variables. In those cases, we do not want to
|
||||
@ -1446,7 +1445,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
// containing the eval.
|
||||
Variable* var = proxy->var();
|
||||
if (var->mode() == DYNAMIC_GLOBAL) {
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
|
||||
__ B(done);
|
||||
} else if (var->mode() == DYNAMIC_LOCAL) {
|
||||
Variable* local = var->local_if_not_shadowed();
|
||||
@ -1468,7 +1467,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
Variable* var = proxy->var();
|
||||
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
|
||||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
|
||||
@ -1492,15 +1491,13 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
__ Mov(LoadDescriptor::NameRegister(), Operand(var->name()));
|
||||
__ Mov(LoadDescriptor::SlotRegister(),
|
||||
SmiFromSlot(proxy->VariableFeedbackSlot()));
|
||||
// Inside typeof use a regular load, not a contextual load, to avoid
|
||||
// a reference error.
|
||||
CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
|
||||
CallLoadIC(typeof_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
// Record position before possible IC call.
|
||||
SetExpressionPosition(proxy);
|
||||
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
|
||||
@ -1512,7 +1509,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::GLOBAL:
|
||||
case VariableLocation::UNALLOCATED: {
|
||||
Comment cmnt(masm_, "Global variable");
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
context()->Plug(x0);
|
||||
break;
|
||||
}
|
||||
@ -1520,7 +1517,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::PARAMETER:
|
||||
case VariableLocation::LOCAL:
|
||||
case VariableLocation::CONTEXT: {
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
|
||||
Comment cmnt(masm_, var->IsContextSlot()
|
||||
? "Context variable"
|
||||
: "Stack variable");
|
||||
@ -1594,13 +1591,13 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
Label done, slow;
|
||||
// Generate code for loading from variables potentially shadowed by
|
||||
// eval-introduced variables.
|
||||
EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
|
||||
EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
|
||||
__ Bind(&slow);
|
||||
Comment cmnt(masm_, "Lookup variable");
|
||||
__ Mov(x1, Operand(var->name()));
|
||||
__ Push(cp, x1); // Context and name.
|
||||
Runtime::FunctionId function_id =
|
||||
typeof_state == NOT_INSIDE_TYPEOF
|
||||
typeof_mode == NOT_INSIDE_TYPEOF
|
||||
? Runtime::kLoadLookupSlot
|
||||
: Runtime::kLoadLookupSlotNoReferenceError;
|
||||
__ CallRuntime(function_id, 2);
|
||||
@ -2137,7 +2134,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_INSIDE_TYPEOF, language_mode());
|
||||
}
|
||||
|
||||
|
||||
@ -4451,7 +4448,7 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
|
||||
__ Mov(LoadDescriptor::NameRegister(), Operand(name));
|
||||
__ Mov(LoadDescriptor::SlotRegister(),
|
||||
SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF);
|
||||
}
|
||||
|
||||
|
||||
@ -5236,7 +5233,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
|
||||
__ Mov(LoadDescriptor::SlotRegister(),
|
||||
SmiFromSlot(expr->DoneFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // x0=result.done
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // x0=result.done
|
||||
// The ToBooleanStub argument (result.done) is in x0.
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
CallIC(bool_ic);
|
||||
@ -5247,7 +5244,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
|
||||
__ Mov(LoadDescriptor::SlotRegister(),
|
||||
SmiFromSlot(expr->ValueFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // x0=result.value
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // x0=result.value
|
||||
context()->DropAndPlug(2, x0); // drop iter and g
|
||||
break;
|
||||
}
|
||||
|
@ -1748,7 +1748,7 @@ class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> {
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
|
||||
|
||||
Handle<Object> name() const { return hydrogen()->name(); }
|
||||
bool for_typeof() const { return hydrogen()->for_typeof(); }
|
||||
TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -3362,9 +3362,9 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
|
||||
DCHECK(ToRegister(instr->result()).Is(x0));
|
||||
__ 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,
|
||||
PREMONOMORPHIC).code();
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
|
||||
SLOPPY, PREMONOMORPHIC).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
@ -3692,7 +3692,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
||||
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(
|
||||
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
|
||||
isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
|
||||
instr->hydrogen()->initialization_state()).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
|
||||
|
@ -13,21 +13,21 @@ namespace internal {
|
||||
|
||||
|
||||
// static
|
||||
Callable CodeFactory::LoadIC(Isolate* isolate, ContextualMode mode,
|
||||
Callable CodeFactory::LoadIC(Isolate* isolate, TypeofMode typeof_mode,
|
||||
LanguageMode language_mode) {
|
||||
return Callable(
|
||||
LoadIC::initialize_stub(
|
||||
isolate, LoadICState(mode, language_mode).GetExtraICState()),
|
||||
isolate, LoadICState(typeof_mode, language_mode).GetExtraICState()),
|
||||
LoadDescriptor(isolate));
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
Callable CodeFactory::LoadICInOptimizedCode(
|
||||
Isolate* isolate, ContextualMode mode, LanguageMode language_mode,
|
||||
Isolate* isolate, TypeofMode typeof_mode, LanguageMode language_mode,
|
||||
InlineCacheState initialization_state) {
|
||||
auto code = LoadIC::initialize_stub_in_optimized_code(
|
||||
isolate, LoadICState(mode, language_mode).GetExtraICState(),
|
||||
isolate, LoadICState(typeof_mode, language_mode).GetExtraICState(),
|
||||
initialization_state);
|
||||
return Callable(code, LoadWithVectorDescriptor(isolate));
|
||||
}
|
||||
|
@ -32,9 +32,10 @@ class Callable final BASE_EMBEDDED {
|
||||
class CodeFactory final {
|
||||
public:
|
||||
// Initial states for ICs.
|
||||
static Callable LoadIC(Isolate* isolate, ContextualMode mode,
|
||||
static Callable LoadIC(Isolate* isolate, TypeofMode typeof_mode,
|
||||
LanguageMode language_mode);
|
||||
static Callable LoadICInOptimizedCode(Isolate* isolate, ContextualMode mode,
|
||||
static Callable LoadICInOptimizedCode(Isolate* isolate,
|
||||
TypeofMode typeof_mode,
|
||||
LanguageMode language_mode,
|
||||
InlineCacheState initialization_state);
|
||||
static Callable KeyedLoadIC(Isolate* isolate, LanguageMode language_mode);
|
||||
|
@ -42,8 +42,6 @@
|
||||
// CodeForDoWhileConditionPosition
|
||||
// CodeForSourcePosition
|
||||
|
||||
enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
#include "src/ia32/codegen-ia32.h" // NOLINT
|
||||
#elif V8_TARGET_ARCH_X64
|
||||
|
@ -2948,7 +2948,7 @@ void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) {
|
||||
FrameStateBeforeAndAfter states(this, BeforeId(proxy));
|
||||
operand =
|
||||
BuildVariableLoad(proxy->var(), expr->expression()->id(), states, pair,
|
||||
OutputFrameStateCombine::Push(), NOT_CONTEXTUAL);
|
||||
OutputFrameStateCombine::Push(), INSIDE_TYPEOF);
|
||||
} else {
|
||||
VisitForValue(expr->expression());
|
||||
operand = environment()->Pop();
|
||||
@ -3260,7 +3260,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
|
||||
FrameStateBeforeAndAfter& states,
|
||||
const VectorSlotPair& feedback,
|
||||
OutputFrameStateCombine combine,
|
||||
ContextualMode contextual_mode) {
|
||||
TypeofMode typeof_mode) {
|
||||
Node* the_hole = jsgraph()->TheHoleConstant();
|
||||
VariableMode mode = variable->mode();
|
||||
switch (variable->location()) {
|
||||
@ -3283,7 +3283,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
|
||||
Node* global = BuildLoadGlobalObject();
|
||||
Handle<Name> name = variable->name();
|
||||
Node* value = BuildGlobalLoad(script_context, global, name, feedback,
|
||||
contextual_mode, slot_index);
|
||||
typeof_mode, slot_index);
|
||||
states.AddToNode(value, bailout_id, combine);
|
||||
return value;
|
||||
}
|
||||
@ -3339,7 +3339,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
|
||||
if (mode == DYNAMIC_GLOBAL) {
|
||||
uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable);
|
||||
const Operator* op = javascript()->LoadDynamicGlobal(
|
||||
name, check_bitset, feedback, contextual_mode);
|
||||
name, check_bitset, feedback, typeof_mode);
|
||||
value = NewNode(op, BuildLoadFeedbackVector(), current_context());
|
||||
states.AddToNode(value, bailout_id, combine);
|
||||
} else if (mode == DYNAMIC_LOCAL) {
|
||||
@ -3364,7 +3364,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
|
||||
} else if (mode == DYNAMIC) {
|
||||
uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired;
|
||||
const Operator* op = javascript()->LoadDynamicGlobal(
|
||||
name, check_bitset, feedback, contextual_mode);
|
||||
name, check_bitset, feedback, typeof_mode);
|
||||
value = NewNode(op, BuildLoadFeedbackVector(), current_context());
|
||||
states.AddToNode(value, bailout_id, combine);
|
||||
}
|
||||
@ -3645,9 +3645,9 @@ Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object,
|
||||
Node* AstGraphBuilder::BuildGlobalLoad(Node* script_context, Node* global,
|
||||
Handle<Name> name,
|
||||
const VectorSlotPair& feedback,
|
||||
ContextualMode mode, int slot_index) {
|
||||
const Operator* op =
|
||||
javascript()->LoadGlobal(MakeUnique(name), feedback, mode, slot_index);
|
||||
TypeofMode typeof_mode, int slot_index) {
|
||||
const Operator* op = javascript()->LoadGlobal(MakeUnique(name), feedback,
|
||||
typeof_mode, slot_index);
|
||||
Node* node = NewNode(op, script_context, global, BuildLoadFeedbackVector());
|
||||
return Record(js_type_feedback_, node, feedback.slot());
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ class AstGraphBuilder : public AstVisitor {
|
||||
FrameStateBeforeAndAfter& states,
|
||||
const VectorSlotPair& feedback,
|
||||
OutputFrameStateCombine framestate_combine,
|
||||
ContextualMode mode = CONTEXTUAL);
|
||||
TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
|
||||
|
||||
// Builders for property loads and stores.
|
||||
Node* BuildKeyedLoad(Node* receiver, Node* key,
|
||||
@ -308,7 +308,7 @@ class AstGraphBuilder : public AstVisitor {
|
||||
|
||||
// Builders for global variable loads and stores.
|
||||
Node* BuildGlobalLoad(Node* script_context, Node* global, Handle<Name> name,
|
||||
const VectorSlotPair& feedback, ContextualMode mode,
|
||||
const VectorSlotPair& feedback, TypeofMode typeof_mode,
|
||||
int slot_index);
|
||||
Node* BuildGlobalStore(Node* script_context, Node* global, Handle<Name> name,
|
||||
Node* value, const VectorSlotPair& feedback,
|
||||
|
@ -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(), NOT_INSIDE_TYPEOF, p.language_mode(), UNINITIALIZED);
|
||||
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
|
||||
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
|
||||
ReplaceWithStubCall(node, callable, flags);
|
||||
@ -346,7 +346,7 @@ void JSGenericLowering::LowerJSLoadGlobal(Node* node) {
|
||||
|
||||
} else {
|
||||
Callable callable = CodeFactory::LoadICInOptimizedCode(
|
||||
isolate(), p.contextual_mode(), SLOPPY, UNINITIALIZED);
|
||||
isolate(), p.typeof_mode(), SLOPPY, UNINITIALIZED);
|
||||
node->RemoveInput(0); // script context
|
||||
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
|
||||
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
|
||||
@ -483,8 +483,9 @@ void JSGenericLowering::LowerJSStoreContext(Node* node) {
|
||||
void JSGenericLowering::LowerJSLoadDynamicGlobal(Node* node) {
|
||||
const DynamicGlobalAccess& access = DynamicGlobalAccessOf(node->op());
|
||||
Runtime::FunctionId function_id =
|
||||
(access.mode() == CONTEXTUAL) ? Runtime::kLoadLookupSlot
|
||||
: Runtime::kLoadLookupSlotNoReferenceError;
|
||||
(access.typeof_mode() == NOT_INSIDE_TYPEOF)
|
||||
? Runtime::kLoadLookupSlot
|
||||
: Runtime::kLoadLookupSlotNoReferenceError;
|
||||
Node* projection = graph()->NewNode(common()->Projection(0), node);
|
||||
NodeProperties::ReplaceUses(node, projection, node, node, node);
|
||||
node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) + 1);
|
||||
|
@ -113,11 +113,11 @@ ContextAccess const& ContextAccessOf(Operator const* op) {
|
||||
DynamicGlobalAccess::DynamicGlobalAccess(const Handle<String>& name,
|
||||
uint32_t check_bitset,
|
||||
const VectorSlotPair& feedback,
|
||||
ContextualMode mode)
|
||||
TypeofMode typeof_mode)
|
||||
: name_(name),
|
||||
check_bitset_(check_bitset),
|
||||
feedback_(feedback),
|
||||
mode_(mode) {
|
||||
typeof_mode_(typeof_mode) {
|
||||
DCHECK(check_bitset == kFullCheckRequired || check_bitset < 0x80000000U);
|
||||
}
|
||||
|
||||
@ -143,7 +143,7 @@ size_t hash_value(DynamicGlobalAccess const& access) {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, DynamicGlobalAccess const& access) {
|
||||
return os << Brief(*access.name()) << ", " << access.check_bitset() << ", "
|
||||
<< access.mode();
|
||||
<< access.typeof_mode();
|
||||
}
|
||||
|
||||
|
||||
@ -198,7 +198,6 @@ 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();
|
||||
}
|
||||
|
||||
@ -210,14 +209,12 @@ 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.language_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.language_mode();
|
||||
}
|
||||
|
||||
|
||||
@ -259,7 +256,7 @@ const LoadNamedParameters& LoadNamedParametersOf(const Operator* op) {
|
||||
bool operator==(LoadGlobalParameters const& lhs,
|
||||
LoadGlobalParameters const& rhs) {
|
||||
return lhs.name() == rhs.name() && lhs.feedback() == rhs.feedback() &&
|
||||
lhs.contextual_mode() == rhs.contextual_mode() &&
|
||||
lhs.typeof_mode() == rhs.typeof_mode() &&
|
||||
lhs.slot_index() == rhs.slot_index();
|
||||
}
|
||||
|
||||
@ -271,12 +268,12 @@ bool operator!=(LoadGlobalParameters const& lhs,
|
||||
|
||||
|
||||
size_t hash_value(LoadGlobalParameters const& p) {
|
||||
return base::hash_combine(p.name(), p.contextual_mode(), p.slot_index());
|
||||
return base::hash_combine(p.name(), p.typeof_mode(), p.slot_index());
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) {
|
||||
return os << Brief(*p.name().handle()) << ", " << p.contextual_mode()
|
||||
return os << Brief(*p.name().handle()) << ", " << p.typeof_mode()
|
||||
<< ", slot: " << p.slot_index();
|
||||
}
|
||||
|
||||
@ -565,7 +562,7 @@ const Operator* JSOperatorBuilder::CallConstruct(int arguments) {
|
||||
const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name,
|
||||
const VectorSlotPair& feedback,
|
||||
LanguageMode language_mode) {
|
||||
LoadNamedParameters parameters(name, feedback, language_mode, NOT_CONTEXTUAL);
|
||||
LoadNamedParameters parameters(name, feedback, language_mode);
|
||||
return new (zone()) Operator1<LoadNamedParameters>( // --
|
||||
IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
|
||||
"JSLoadNamed", // name
|
||||
@ -619,9 +616,9 @@ const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) {
|
||||
|
||||
const Operator* JSOperatorBuilder::LoadGlobal(const Unique<Name>& name,
|
||||
const VectorSlotPair& feedback,
|
||||
ContextualMode contextual_mode,
|
||||
TypeofMode typeof_mode,
|
||||
int slot_index) {
|
||||
LoadGlobalParameters parameters(name, feedback, contextual_mode, slot_index);
|
||||
LoadGlobalParameters parameters(name, feedback, typeof_mode, slot_index);
|
||||
return new (zone()) Operator1<LoadGlobalParameters>( // --
|
||||
IrOpcode::kJSLoadGlobal, Operator::kNoProperties, // opcode
|
||||
"JSLoadGlobal", // name
|
||||
@ -668,8 +665,8 @@ const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
|
||||
|
||||
const Operator* JSOperatorBuilder::LoadDynamicGlobal(
|
||||
const Handle<String>& name, uint32_t check_bitset,
|
||||
const VectorSlotPair& feedback, ContextualMode mode) {
|
||||
DynamicGlobalAccess access(name, check_bitset, feedback, mode);
|
||||
const VectorSlotPair& feedback, TypeofMode typeof_mode) {
|
||||
DynamicGlobalAccess access(name, check_bitset, feedback, typeof_mode);
|
||||
return new (zone()) Operator1<DynamicGlobalAccess>( // --
|
||||
IrOpcode::kJSLoadDynamicGlobal, Operator::kNoProperties, // opcode
|
||||
"JSLoadDynamicGlobal", // name
|
||||
|
@ -158,12 +158,12 @@ ContextAccess const& ContextAccessOf(Operator const*);
|
||||
class DynamicGlobalAccess final {
|
||||
public:
|
||||
DynamicGlobalAccess(const Handle<String>& name, uint32_t check_bitset,
|
||||
const VectorSlotPair& feedback, ContextualMode mode);
|
||||
const VectorSlotPair& feedback, TypeofMode typeof_mode);
|
||||
|
||||
const Handle<String>& name() const { return name_; }
|
||||
uint32_t check_bitset() const { return check_bitset_; }
|
||||
const VectorSlotPair& feedback() const { return feedback_; }
|
||||
ContextualMode mode() const { return mode_; }
|
||||
TypeofMode typeof_mode() const { return typeof_mode_; }
|
||||
|
||||
// Indicates that an inline check is disabled.
|
||||
bool RequiresFullCheck() const {
|
||||
@ -180,7 +180,7 @@ class DynamicGlobalAccess final {
|
||||
const Handle<String> name_;
|
||||
const uint32_t check_bitset_;
|
||||
const VectorSlotPair feedback_;
|
||||
const ContextualMode mode_;
|
||||
const TypeofMode typeof_mode_;
|
||||
};
|
||||
|
||||
size_t hash_value(DynamicGlobalAccess const&);
|
||||
@ -237,16 +237,11 @@ DynamicContextAccess const& DynamicContextAccessOf(Operator const*);
|
||||
class LoadNamedParameters final {
|
||||
public:
|
||||
LoadNamedParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
|
||||
LanguageMode language_mode,
|
||||
ContextualMode contextual_mode)
|
||||
: name_(name),
|
||||
feedback_(feedback),
|
||||
language_mode_(language_mode),
|
||||
contextual_mode_(contextual_mode) {}
|
||||
LanguageMode language_mode)
|
||||
: name_(name), feedback_(feedback), language_mode_(language_mode) {}
|
||||
|
||||
const Unique<Name>& name() const { return name_; }
|
||||
LanguageMode language_mode() const { return language_mode_; }
|
||||
ContextualMode contextual_mode() const { return contextual_mode_; }
|
||||
|
||||
const VectorSlotPair& feedback() const { return feedback_; }
|
||||
|
||||
@ -254,7 +249,6 @@ class LoadNamedParameters final {
|
||||
const Unique<Name> name_;
|
||||
const VectorSlotPair feedback_;
|
||||
const LanguageMode language_mode_;
|
||||
const ContextualMode contextual_mode_;
|
||||
};
|
||||
|
||||
bool operator==(LoadNamedParameters const&, LoadNamedParameters const&);
|
||||
@ -272,14 +266,14 @@ const LoadNamedParameters& LoadNamedParametersOf(const Operator* op);
|
||||
class LoadGlobalParameters final {
|
||||
public:
|
||||
LoadGlobalParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
|
||||
ContextualMode contextual_mode, int slot_index)
|
||||
TypeofMode typeof_mode, int slot_index)
|
||||
: name_(name),
|
||||
feedback_(feedback),
|
||||
contextual_mode_(contextual_mode),
|
||||
typeof_mode_(typeof_mode),
|
||||
slot_index_(slot_index) {}
|
||||
|
||||
const Unique<Name>& name() const { return name_; }
|
||||
ContextualMode contextual_mode() const { return contextual_mode_; }
|
||||
TypeofMode typeof_mode() const { return typeof_mode_; }
|
||||
|
||||
const VectorSlotPair& feedback() const { return feedback_; }
|
||||
|
||||
@ -288,7 +282,7 @@ class LoadGlobalParameters final {
|
||||
private:
|
||||
const Unique<Name> name_;
|
||||
const VectorSlotPair feedback_;
|
||||
const ContextualMode contextual_mode_;
|
||||
const TypeofMode typeof_mode_;
|
||||
const int slot_index_;
|
||||
};
|
||||
|
||||
@ -510,7 +504,7 @@ class JSOperatorBuilder final : public ZoneObject {
|
||||
|
||||
const Operator* LoadGlobal(const Unique<Name>& name,
|
||||
const VectorSlotPair& feedback,
|
||||
ContextualMode contextual_mode = NOT_CONTEXTUAL,
|
||||
TypeofMode typeof_mode = NOT_INSIDE_TYPEOF,
|
||||
int slot_index = -1);
|
||||
const Operator* StoreGlobal(LanguageMode language_mode,
|
||||
const Unique<Name>& name,
|
||||
@ -523,7 +517,7 @@ class JSOperatorBuilder final : public ZoneObject {
|
||||
const Operator* LoadDynamicGlobal(const Handle<String>& name,
|
||||
uint32_t check_bitset,
|
||||
const VectorSlotPair& feedback,
|
||||
ContextualMode mode);
|
||||
TypeofMode typeof_mode);
|
||||
const Operator* LoadDynamicContext(const Handle<String>& name,
|
||||
uint32_t check_bitset, size_t depth,
|
||||
size_t index);
|
||||
|
@ -1023,14 +1023,14 @@ Reduction JSTypedLowering::ReduceJSLoadDynamicGlobal(Node* node) {
|
||||
javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true), context,
|
||||
context, effect);
|
||||
Node* fast = graph()->NewNode(
|
||||
javascript()->LoadGlobal(name, access.feedback(), access.mode()), context,
|
||||
global, vector, context, state1, state2, global, check_true);
|
||||
javascript()->LoadGlobal(name, access.feedback(), access.typeof_mode()),
|
||||
context, global, vector, context, state1, state2, global, check_true);
|
||||
|
||||
// Slow case, because variable potentially shadowed. Perform dynamic lookup.
|
||||
uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired;
|
||||
Node* slow = graph()->NewNode(
|
||||
javascript()->LoadDynamicGlobal(access.name(), check_bitset,
|
||||
access.feedback(), access.mode()),
|
||||
access.feedback(), access.typeof_mode()),
|
||||
vector, context, context, state1, state2, effect, check_false);
|
||||
|
||||
// Replace value, effect and control uses accordingly.
|
||||
|
@ -197,8 +197,8 @@ static int DecodeIt(Isolate* isolate, std::ostream* os,
|
||||
Code::Kind kind = code->kind();
|
||||
if (code->is_inline_cache_stub()) {
|
||||
if (kind == Code::LOAD_IC &&
|
||||
LoadICState::GetContextualMode(code->extra_ic_state()) ==
|
||||
CONTEXTUAL) {
|
||||
LoadICState::GetTypeofMode(code->extra_ic_state()) ==
|
||||
NOT_INSIDE_TYPEOF) {
|
||||
out.AddFormatted(" contextual,");
|
||||
}
|
||||
InlineCacheState ic_state = code->ic_state();
|
||||
|
@ -205,11 +205,11 @@ void FullCodeGenerator::PrepareForBailout(Expression* node, State state) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::CallLoadIC(ContextualMode contextual_mode,
|
||||
void FullCodeGenerator::CallLoadIC(TypeofMode typeof_mode,
|
||||
LanguageMode language_mode,
|
||||
TypeFeedbackId id) {
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadIC(isolate(), contextual_mode, language_mode).code();
|
||||
CodeFactory::LoadIC(isolate(), typeof_mode, language_mode).code();
|
||||
CallIC(ic, id);
|
||||
}
|
||||
|
||||
|
@ -545,16 +545,13 @@ class FullCodeGenerator: public AstVisitor {
|
||||
|
||||
// Platform-specific code for loading variables.
|
||||
void EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
Label* slow);
|
||||
TypeofMode typeof_mode, Label* slow);
|
||||
MemOperand ContextSlotOperandCheckExtensions(Variable* var, Label* slow);
|
||||
void EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
Label* slow,
|
||||
Label* done);
|
||||
void EmitGlobalVariableLoad(VariableProxy* proxy, TypeofState typeof_state);
|
||||
void EmitDynamicLookupFastCase(VariableProxy* proxy, TypeofMode typeof_mode,
|
||||
Label* slow, Label* done);
|
||||
void EmitGlobalVariableLoad(VariableProxy* proxy, TypeofMode typeof_mode);
|
||||
void EmitVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state = NOT_INSIDE_TYPEOF);
|
||||
TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
|
||||
|
||||
void EmitAccessor(Expression* expression);
|
||||
|
||||
@ -654,7 +651,8 @@ class FullCodeGenerator: public AstVisitor {
|
||||
void CallIC(Handle<Code> code,
|
||||
TypeFeedbackId id = TypeFeedbackId::None());
|
||||
|
||||
void CallLoadIC(ContextualMode mode, LanguageMode language_mode = SLOPPY,
|
||||
// Inside typeof reference errors are never thrown.
|
||||
void CallLoadIC(TypeofMode typeof_mode, LanguageMode language_mode = SLOPPY,
|
||||
TypeFeedbackId id = TypeFeedbackId::None());
|
||||
void CallStoreIC(TypeFeedbackId id = TypeFeedbackId::None());
|
||||
|
||||
|
@ -5401,12 +5401,12 @@ class HUnknownOSRValue final : public HTemplateInstruction<0> {
|
||||
class HLoadGlobalGeneric final : public HTemplateInstruction<2> {
|
||||
public:
|
||||
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HLoadGlobalGeneric, HValue*,
|
||||
Handle<String>, bool);
|
||||
Handle<String>, TypeofMode);
|
||||
|
||||
HValue* context() { return OperandAt(0); }
|
||||
HValue* global_object() { return OperandAt(1); }
|
||||
Handle<String> name() const { return name_; }
|
||||
bool for_typeof() const { return for_typeof_; }
|
||||
TypeofMode typeof_mode() const { return typeof_mode_; }
|
||||
FeedbackVectorICSlot slot() const { return slot_; }
|
||||
Handle<TypeFeedbackVector> feedback_vector() const {
|
||||
return feedback_vector_;
|
||||
@ -5428,9 +5428,9 @@ class HLoadGlobalGeneric final : public HTemplateInstruction<2> {
|
||||
|
||||
private:
|
||||
HLoadGlobalGeneric(HValue* context, HValue* global_object,
|
||||
Handle<String> name, bool for_typeof)
|
||||
Handle<String> name, TypeofMode typeof_mode)
|
||||
: name_(name),
|
||||
for_typeof_(for_typeof),
|
||||
typeof_mode_(typeof_mode),
|
||||
slot_(FeedbackVectorICSlot::Invalid()) {
|
||||
SetOperandAt(0, context);
|
||||
SetOperandAt(1, global_object);
|
||||
@ -5439,7 +5439,7 @@ class HLoadGlobalGeneric final : public HTemplateInstruction<2> {
|
||||
}
|
||||
|
||||
Handle<String> name_;
|
||||
bool for_typeof_;
|
||||
TypeofMode typeof_mode_;
|
||||
Handle<TypeFeedbackVector> feedback_vector_;
|
||||
FeedbackVectorICSlot slot_;
|
||||
};
|
||||
|
@ -4044,7 +4044,7 @@ AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind)
|
||||
: owner_(owner),
|
||||
kind_(kind),
|
||||
outer_(owner->ast_context()),
|
||||
for_typeof_(false) {
|
||||
typeof_mode_(NOT_INSIDE_TYPEOF) {
|
||||
owner->set_ast_context(this); // Push.
|
||||
#ifdef DEBUG
|
||||
DCHECK(owner->environment()->frame_type() == JS_FUNCTION);
|
||||
@ -4292,7 +4292,7 @@ void HOptimizedGraphBuilder::VisitForValue(Expression* expr,
|
||||
|
||||
void HOptimizedGraphBuilder::VisitForTypeOf(Expression* expr) {
|
||||
ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
|
||||
for_value.set_for_typeof(true);
|
||||
for_value.set_typeof_mode(INSIDE_TYPEOF);
|
||||
Visit(expr);
|
||||
}
|
||||
|
||||
@ -5563,10 +5563,8 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
|
||||
HValue* global_object = Add<HLoadNamedField>(
|
||||
context(), nullptr,
|
||||
HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
|
||||
HLoadGlobalGeneric* instr =
|
||||
New<HLoadGlobalGeneric>(global_object,
|
||||
variable->name(),
|
||||
ast_context()->is_for_typeof());
|
||||
HLoadGlobalGeneric* instr = New<HLoadGlobalGeneric>(
|
||||
global_object, variable->name(), ast_context()->typeof_mode());
|
||||
instr->SetVectorAndSlot(handle(current_feedback_vector(), isolate()),
|
||||
expr->VariableFeedbackSlot());
|
||||
return ast_context()->ReturnInstruction(instr, expr->id());
|
||||
|
@ -758,8 +758,8 @@ class AstContext {
|
||||
virtual void ReturnContinuation(HIfContinuation* continuation,
|
||||
BailoutId ast_id) = 0;
|
||||
|
||||
void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; }
|
||||
bool is_for_typeof() { return for_typeof_; }
|
||||
void set_typeof_mode(TypeofMode typeof_mode) { typeof_mode_ = typeof_mode; }
|
||||
TypeofMode typeof_mode() { return typeof_mode_; }
|
||||
|
||||
protected:
|
||||
AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind);
|
||||
@ -779,7 +779,7 @@ class AstContext {
|
||||
HOptimizedGraphBuilder* owner_;
|
||||
Expression::Context kind_;
|
||||
AstContext* outer_;
|
||||
bool for_typeof_;
|
||||
TypeofMode typeof_mode_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1297,7 +1297,7 @@ void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow) {
|
||||
Register context = esi;
|
||||
Register temp = edx;
|
||||
@ -1346,7 +1346,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
|
||||
// All extension objects were empty and it is safe to use a normal global
|
||||
// load machinery.
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1381,9 +1381,8 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
Label* slow,
|
||||
Label* done) {
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow, Label* done) {
|
||||
// Generate fast-case code for variables that might be shadowed by
|
||||
// eval-introduced variables. Eval is used a lot without
|
||||
// introducing variables. In those cases, we do not want to
|
||||
@ -1391,7 +1390,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
// containing the eval.
|
||||
Variable* var = proxy->var();
|
||||
if (var->mode() == DYNAMIC_GLOBAL) {
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
|
||||
__ jmp(done);
|
||||
} else if (var->mode() == DYNAMIC_LOCAL) {
|
||||
Variable* local = var->local_if_not_shadowed();
|
||||
@ -1413,7 +1412,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
Variable* var = proxy->var();
|
||||
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
|
||||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
|
||||
@ -1436,15 +1435,13 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
__ mov(LoadDescriptor::NameRegister(), var->name());
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
// Inside typeof use a regular load, not a contextual load, to avoid
|
||||
// a reference error.
|
||||
CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
|
||||
CallLoadIC(typeof_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
SetExpressionPosition(proxy);
|
||||
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
|
||||
Variable* var = proxy->var();
|
||||
@ -1455,7 +1452,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::GLOBAL:
|
||||
case VariableLocation::UNALLOCATED: {
|
||||
Comment cmnt(masm_, "[ Global variable");
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
context()->Plug(eax);
|
||||
break;
|
||||
}
|
||||
@ -1463,7 +1460,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::PARAMETER:
|
||||
case VariableLocation::LOCAL:
|
||||
case VariableLocation::CONTEXT: {
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
|
||||
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
|
||||
: "[ Stack variable");
|
||||
if (var->binding_needs_init()) {
|
||||
@ -1536,12 +1533,12 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
Label done, slow;
|
||||
// Generate code for loading from variables potentially shadowed
|
||||
// by eval-introduced variables.
|
||||
EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
|
||||
EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
|
||||
__ bind(&slow);
|
||||
__ push(esi); // Context.
|
||||
__ push(Immediate(var->name()));
|
||||
Runtime::FunctionId function_id =
|
||||
typeof_state == NOT_INSIDE_TYPEOF
|
||||
typeof_mode == NOT_INSIDE_TYPEOF
|
||||
? Runtime::kLoadLookupSlot
|
||||
: Runtime::kLoadLookupSlotNoReferenceError;
|
||||
__ CallRuntime(function_id, 2);
|
||||
@ -2225,7 +2222,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
isolate()->factory()->done_string()); // "done"
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // result.done in eax
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
CallIC(bool_ic);
|
||||
__ test(eax, eax);
|
||||
@ -2237,7 +2234,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
isolate()->factory()->value_string()); // "value"
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // result.value in eax
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // result.value in eax
|
||||
context()->DropAndPlug(2, eax); // drop iter and g
|
||||
break;
|
||||
}
|
||||
@ -2376,7 +2373,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_INSIDE_TYPEOF, language_mode());
|
||||
}
|
||||
|
||||
|
||||
@ -4688,7 +4685,7 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2849,9 +2849,9 @@ 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,
|
||||
PREMONOMORPHIC).code();
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
|
||||
SLOPPY, PREMONOMORPHIC).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
@ -2968,7 +2968,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
||||
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(
|
||||
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
|
||||
isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
|
||||
instr->hydrogen()->initialization_state()).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
@ -1713,7 +1713,7 @@ class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> {
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
|
||||
|
||||
Handle<Object> name() const { return hydrogen()->name(); }
|
||||
bool for_typeof() const { return hydrogen()->for_typeof(); }
|
||||
TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -134,8 +134,8 @@ void IC::set_target(Code* code) {
|
||||
|
||||
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()));
|
||||
DCHECK(LoadICState::GetTypeofMode(code->extra_ic_state()) ==
|
||||
LoadICState::GetTypeofMode(target()->extra_ic_state()));
|
||||
// Strongness must be preserved across IC patching.
|
||||
DCHECK(LoadICState::GetLanguageMode(code->extra_ic_state()) ==
|
||||
LoadICState::GetLanguageMode(target()->extra_ic_state()));
|
||||
|
@ -202,10 +202,10 @@ class CompareICState {
|
||||
|
||||
class LoadICState final BASE_EMBEDDED {
|
||||
private:
|
||||
class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
|
||||
class TypeofModeBits : public BitField<TypeofMode, 0, 1> {};
|
||||
class LanguageModeBits
|
||||
: public BitField<LanguageMode, ContextualModeBits::kNext, 2> {};
|
||||
STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
|
||||
: public BitField<LanguageMode, TypeofModeBits::kNext, 2> {};
|
||||
STATIC_ASSERT(static_cast<int>(INSIDE_TYPEOF) == 0);
|
||||
const ExtraICState state_;
|
||||
|
||||
public:
|
||||
@ -216,22 +216,20 @@ class LoadICState final BASE_EMBEDDED {
|
||||
|
||||
explicit LoadICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
|
||||
|
||||
explicit LoadICState(ContextualMode mode, LanguageMode language_mode)
|
||||
: state_(ContextualModeBits::encode(mode) |
|
||||
explicit LoadICState(TypeofMode typeof_mode, LanguageMode language_mode)
|
||||
: state_(TypeofModeBits::encode(typeof_mode) |
|
||||
LanguageModeBits::encode(language_mode)) {}
|
||||
|
||||
ExtraICState GetExtraICState() const { return state_; }
|
||||
|
||||
ContextualMode contextual_mode() const {
|
||||
return ContextualModeBits::decode(state_);
|
||||
}
|
||||
TypeofMode typeof_mode() const { return TypeofModeBits::decode(state_); }
|
||||
|
||||
LanguageMode language_mode() const {
|
||||
return LanguageModeBits::decode(state_);
|
||||
}
|
||||
|
||||
static ContextualMode GetContextualMode(ExtraICState state) {
|
||||
return LoadICState(state).contextual_mode();
|
||||
static TypeofMode GetTypeofMode(ExtraICState state) {
|
||||
return LoadICState(state).typeof_mode();
|
||||
}
|
||||
|
||||
static LanguageMode GetLanguageMode(ExtraICState state) {
|
||||
|
31
src/ic/ic.cc
31
src/ic/ic.cc
@ -734,7 +734,7 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
|
||||
LookupIterator it(object, name);
|
||||
LookupForRead(&it);
|
||||
|
||||
if (it.IsFound() || !IsUndeclaredGlobal(object)) {
|
||||
if (it.IsFound() || !ShouldThrowReferenceError(object)) {
|
||||
// Update inline cache and stub cache.
|
||||
if (use_ic) UpdateCaches(&it);
|
||||
|
||||
@ -745,7 +745,7 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
|
||||
isolate(), result, Object::GetProperty(&it, language_mode()), Object);
|
||||
if (it.IsFound()) {
|
||||
return result;
|
||||
} else if (!IsUndeclaredGlobal(object)) {
|
||||
} else if (!ShouldThrowReferenceError(object)) {
|
||||
LOG(isolate(), SuspectReadEvent(*name, *object));
|
||||
return result;
|
||||
}
|
||||
@ -2969,22 +2969,6 @@ RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) {
|
||||
}
|
||||
|
||||
|
||||
static Object* ThrowReferenceError(Isolate* isolate, Name* name) {
|
||||
// If the load is non-contextual, just return the undefined result.
|
||||
// Note that both keyed and non-keyed loads may end up here.
|
||||
HandleScope scope(isolate);
|
||||
LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
|
||||
if (ic.contextual_mode() != CONTEXTUAL) {
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
// Throw a reference error.
|
||||
Handle<Name> name_handle(name);
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewReferenceError(MessageTemplate::kNotDefined, name_handle));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads a property with an interceptor performing post interceptor
|
||||
* lookup if interceptor failed.
|
||||
@ -3007,7 +2991,16 @@ RUNTIME_FUNCTION(LoadPropertyWithInterceptor) {
|
||||
|
||||
if (it.IsFound()) return *result;
|
||||
|
||||
return ThrowReferenceError(isolate, Name::cast(args[0]));
|
||||
// Return the undefined result if the reference error should not be thrown.
|
||||
// Note that both keyed and non-keyed loads may end up here.
|
||||
LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
|
||||
if (!ic.ShouldThrowReferenceError(it.GetReceiver())) {
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
// Throw a reference error.
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name()));
|
||||
}
|
||||
|
||||
|
||||
|
23
src/ic/ic.h
23
src/ic/ic.h
@ -354,13 +354,13 @@ class CallIC : public IC {
|
||||
|
||||
class LoadIC : public IC {
|
||||
public:
|
||||
static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
|
||||
static ExtraICState ComputeExtraICState(TypeofMode typeof_mode,
|
||||
LanguageMode language_mode) {
|
||||
return LoadICState(contextual_mode, language_mode).GetExtraICState();
|
||||
return LoadICState(typeof_mode, language_mode).GetExtraICState();
|
||||
}
|
||||
|
||||
ContextualMode contextual_mode() const {
|
||||
return LoadICState::GetContextualMode(extra_ic_state());
|
||||
TypeofMode typeof_mode() const {
|
||||
return LoadICState::GetTypeofMode(extra_ic_state());
|
||||
}
|
||||
|
||||
LanguageMode language_mode() const {
|
||||
@ -382,15 +382,8 @@ class LoadIC : public IC {
|
||||
DCHECK(IsLoadStub());
|
||||
}
|
||||
|
||||
// Returns if this IC is for contextual (no explicit receiver)
|
||||
// access to properties.
|
||||
bool IsUndeclaredGlobal(Handle<Object> receiver) {
|
||||
if (receiver->IsGlobalObject()) {
|
||||
return contextual_mode() == CONTEXTUAL;
|
||||
} else {
|
||||
DCHECK(contextual_mode() != CONTEXTUAL);
|
||||
return false;
|
||||
}
|
||||
bool ShouldThrowReferenceError(Handle<Object> receiver) {
|
||||
return receiver->IsGlobalObject() && typeof_mode() == NOT_INSIDE_TYPEOF;
|
||||
}
|
||||
|
||||
// Code generator routines.
|
||||
@ -452,10 +445,10 @@ class KeyedLoadIC : public LoadIC {
|
||||
class IcCheckTypeField
|
||||
: public BitField<IcCheckType, LoadICState::kNextBitFieldOffset, 1> {};
|
||||
|
||||
static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
|
||||
static ExtraICState ComputeExtraICState(TypeofMode typeof_mode,
|
||||
LanguageMode language_mode,
|
||||
IcCheckType key_type) {
|
||||
return LoadICState(contextual_mode, language_mode).GetExtraICState() |
|
||||
return LoadICState(typeof_mode, language_mode).GetExtraICState() |
|
||||
IcCheckTypeField::encode(key_type);
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,6 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
|
||||
|
||||
|
||||
class StringCharLoadGenerator : public AllStatic {
|
||||
public:
|
||||
// Generates the code for handling different string types and loading the
|
||||
|
@ -1364,7 +1364,7 @@ void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow) {
|
||||
Register current = cp;
|
||||
Register next = a1;
|
||||
@ -1410,7 +1410,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
|
||||
// All extension objects were empty and it is safe to use a normal global
|
||||
// load machinery.
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1445,9 +1445,8 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
Label* slow,
|
||||
Label* done) {
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow, Label* done) {
|
||||
// Generate fast-case code for variables that might be shadowed by
|
||||
// eval-introduced variables. Eval is used a lot without
|
||||
// introducing variables. In those cases, we do not want to
|
||||
@ -1455,7 +1454,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
// containing the eval.
|
||||
Variable* var = proxy->var();
|
||||
if (var->mode() == DYNAMIC_GLOBAL) {
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
|
||||
__ Branch(done);
|
||||
} else if (var->mode() == DYNAMIC_LOCAL) {
|
||||
Variable* local = var->local_if_not_shadowed();
|
||||
@ -1480,7 +1479,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
Variable* var = proxy->var();
|
||||
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
|
||||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
|
||||
@ -1503,15 +1502,13 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
__ li(LoadDescriptor::NameRegister(), Operand(var->name()));
|
||||
__ li(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
// Inside typeof use a regular load, not a contextual load, to avoid
|
||||
// a reference error.
|
||||
CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
|
||||
CallLoadIC(typeof_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
// Record position before possible IC call.
|
||||
SetExpressionPosition(proxy);
|
||||
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
|
||||
@ -1523,7 +1520,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::GLOBAL:
|
||||
case VariableLocation::UNALLOCATED: {
|
||||
Comment cmnt(masm_, "[ Global variable");
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
context()->Plug(v0);
|
||||
break;
|
||||
}
|
||||
@ -1531,7 +1528,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::PARAMETER:
|
||||
case VariableLocation::LOCAL:
|
||||
case VariableLocation::CONTEXT: {
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
|
||||
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
|
||||
: "[ Stack variable");
|
||||
if (var->binding_needs_init()) {
|
||||
@ -1607,12 +1604,12 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
Label done, slow;
|
||||
// Generate code for loading from variables potentially shadowed
|
||||
// by eval-introduced variables.
|
||||
EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
|
||||
EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
|
||||
__ bind(&slow);
|
||||
__ li(a1, Operand(var->name()));
|
||||
__ Push(cp, a1); // Context and name.
|
||||
Runtime::FunctionId function_id =
|
||||
typeof_state == NOT_INSIDE_TYPEOF
|
||||
typeof_mode == NOT_INSIDE_TYPEOF
|
||||
? Runtime::kLoadLookupSlot
|
||||
: Runtime::kLoadLookupSlotNoReferenceError;
|
||||
__ CallRuntime(function_id, 2);
|
||||
@ -2296,7 +2293,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
|
||||
__ li(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // v0=result.done
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // v0=result.done
|
||||
__ mov(a0, v0);
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
CallIC(bool_ic);
|
||||
@ -2307,7 +2304,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
|
||||
__ li(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // v0=result.value
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // v0=result.value
|
||||
context()->DropAndPlug(2, v0); // drop iter and g
|
||||
break;
|
||||
}
|
||||
@ -2449,7 +2446,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_INSIDE_TYPEOF, language_mode());
|
||||
}
|
||||
|
||||
|
||||
@ -4777,7 +4774,7 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
|
||||
__ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
|
||||
__ li(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2880,9 +2880,9 @@ 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,
|
||||
PREMONOMORPHIC).code();
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
|
||||
SLOPPY, PREMONOMORPHIC).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
@ -2983,7 +2983,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
||||
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(
|
||||
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
|
||||
isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
|
||||
instr->hydrogen()->initialization_state()).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
@ -1663,7 +1663,7 @@ class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> {
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
|
||||
|
||||
Handle<Object> name() const { return hydrogen()->name(); }
|
||||
bool for_typeof() const { return hydrogen()->for_typeof(); }
|
||||
TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -14,9 +14,6 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
|
||||
|
||||
|
||||
class StringCharLoadGenerator : public AllStatic {
|
||||
public:
|
||||
// Generates the code for handling different string types and loading the
|
||||
|
@ -1361,7 +1361,7 @@ void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow) {
|
||||
Register current = cp;
|
||||
Register next = a1;
|
||||
@ -1407,7 +1407,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
|
||||
// All extension objects were empty and it is safe to use a normal global
|
||||
// load machinery.
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1442,9 +1442,8 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
Label* slow,
|
||||
Label* done) {
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow, Label* done) {
|
||||
// Generate fast-case code for variables that might be shadowed by
|
||||
// eval-introduced variables. Eval is used a lot without
|
||||
// introducing variables. In those cases, we do not want to
|
||||
@ -1452,7 +1451,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
// containing the eval.
|
||||
Variable* var = proxy->var();
|
||||
if (var->mode() == DYNAMIC_GLOBAL) {
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
|
||||
__ Branch(done);
|
||||
} else if (var->mode() == DYNAMIC_LOCAL) {
|
||||
Variable* local = var->local_if_not_shadowed();
|
||||
@ -1477,7 +1476,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
Variable* var = proxy->var();
|
||||
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
|
||||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
|
||||
@ -1500,15 +1499,13 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
__ li(LoadDescriptor::NameRegister(), Operand(var->name()));
|
||||
__ li(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
// Inside typeof use a regular load, not a contextual load, to avoid
|
||||
// a reference error.
|
||||
CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
|
||||
CallLoadIC(typeof_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
// Record position before possible IC call.
|
||||
SetExpressionPosition(proxy);
|
||||
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
|
||||
@ -1520,7 +1517,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::GLOBAL:
|
||||
case VariableLocation::UNALLOCATED: {
|
||||
Comment cmnt(masm_, "[ Global variable");
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
context()->Plug(v0);
|
||||
break;
|
||||
}
|
||||
@ -1528,7 +1525,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::PARAMETER:
|
||||
case VariableLocation::LOCAL:
|
||||
case VariableLocation::CONTEXT: {
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
|
||||
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
|
||||
: "[ Stack variable");
|
||||
if (var->binding_needs_init()) {
|
||||
@ -1604,12 +1601,12 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
Label done, slow;
|
||||
// Generate code for loading from variables potentially shadowed
|
||||
// by eval-introduced variables.
|
||||
EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
|
||||
EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
|
||||
__ bind(&slow);
|
||||
__ li(a1, Operand(var->name()));
|
||||
__ Push(cp, a1); // Context and name.
|
||||
Runtime::FunctionId function_id =
|
||||
typeof_state == NOT_INSIDE_TYPEOF
|
||||
typeof_mode == NOT_INSIDE_TYPEOF
|
||||
? Runtime::kLoadLookupSlot
|
||||
: Runtime::kLoadLookupSlotNoReferenceError;
|
||||
__ CallRuntime(function_id, 2);
|
||||
@ -2291,7 +2288,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
|
||||
__ li(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // v0=result.done
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // v0=result.done
|
||||
__ mov(a0, v0);
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
CallIC(bool_ic);
|
||||
@ -2302,7 +2299,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
|
||||
__ li(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // v0=result.value
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // v0=result.value
|
||||
context()->DropAndPlug(2, v0); // drop iter and g
|
||||
break;
|
||||
}
|
||||
@ -2446,7 +2443,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_INSIDE_TYPEOF, language_mode());
|
||||
}
|
||||
|
||||
|
||||
@ -4780,7 +4777,7 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
|
||||
__ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
|
||||
__ li(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2984,9 +2984,9 @@ 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,
|
||||
PREMONOMORPHIC).code();
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
|
||||
SLOPPY, PREMONOMORPHIC).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
@ -3102,7 +3102,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
||||
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(
|
||||
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
|
||||
isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
|
||||
instr->hydrogen()->initialization_state()).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
@ -1725,7 +1725,7 @@ class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> {
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
|
||||
|
||||
Handle<Object> name() const { return hydrogen()->name(); }
|
||||
bool for_typeof() const { return hydrogen()->for_typeof(); }
|
||||
TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -175,10 +175,7 @@ enum KeyedAccessStoreMode {
|
||||
};
|
||||
|
||||
|
||||
enum ContextualMode {
|
||||
NOT_CONTEXTUAL,
|
||||
CONTEXTUAL
|
||||
};
|
||||
enum TypeofMode { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
|
||||
|
||||
|
||||
enum MutableMode {
|
||||
|
@ -12,9 +12,6 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
|
||||
|
||||
|
||||
class StringCharLoadGenerator : public AllStatic {
|
||||
public:
|
||||
// Generates the code for handling different string types and loading the
|
||||
|
@ -1340,7 +1340,7 @@ void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow) {
|
||||
Register current = cp;
|
||||
Register next = r4;
|
||||
@ -1389,7 +1389,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
|
||||
// All extension objects were empty and it is safe to use a normal global
|
||||
// load machinery.
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1426,7 +1426,7 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow, Label* done) {
|
||||
// Generate fast-case code for variables that might be shadowed by
|
||||
// eval-introduced variables. Eval is used a lot without
|
||||
@ -1435,7 +1435,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
// containing the eval.
|
||||
Variable* var = proxy->var();
|
||||
if (var->mode() == DYNAMIC_GLOBAL) {
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
|
||||
__ b(done);
|
||||
} else if (var->mode() == DYNAMIC_LOCAL) {
|
||||
Variable* local = var->local_if_not_shadowed();
|
||||
@ -1458,7 +1458,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
Variable* var = proxy->var();
|
||||
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
|
||||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
|
||||
@ -1482,15 +1482,13 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
__ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
// Inside typeof use a regular load, not a contextual load, to avoid
|
||||
// a reference error.
|
||||
CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
|
||||
CallLoadIC(typeof_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
// Record position before possible IC call.
|
||||
SetExpressionPosition(proxy);
|
||||
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
|
||||
@ -1502,7 +1500,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::GLOBAL:
|
||||
case VariableLocation::UNALLOCATED: {
|
||||
Comment cmnt(masm_, "[ Global variable");
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
context()->Plug(r3);
|
||||
break;
|
||||
}
|
||||
@ -1510,7 +1508,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::PARAMETER:
|
||||
case VariableLocation::LOCAL:
|
||||
case VariableLocation::CONTEXT: {
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
|
||||
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
|
||||
: "[ Stack variable");
|
||||
if (var->binding_needs_init()) {
|
||||
@ -1584,12 +1582,12 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
Label done, slow;
|
||||
// Generate code for loading from variables potentially shadowed
|
||||
// by eval-introduced variables.
|
||||
EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
|
||||
EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
|
||||
__ bind(&slow);
|
||||
__ mov(r4, Operand(var->name()));
|
||||
__ Push(cp, r4); // Context and name.
|
||||
Runtime::FunctionId function_id =
|
||||
typeof_state == NOT_INSIDE_TYPEOF
|
||||
typeof_mode == NOT_INSIDE_TYPEOF
|
||||
? Runtime::kLoadLookupSlot
|
||||
: Runtime::kLoadLookupSlotNoReferenceError;
|
||||
__ CallRuntime(function_id, 2);
|
||||
@ -2267,7 +2265,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // r0=result.done
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // r0=result.done
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
CallIC(bool_ic);
|
||||
__ cmpi(r3, Operand::Zero());
|
||||
@ -2278,7 +2276,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // r3=result.value
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // r3=result.value
|
||||
context()->DropAndPlug(2, r3); // drop iter and g
|
||||
break;
|
||||
}
|
||||
@ -2439,7 +2437,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_INSIDE_TYPEOF, language_mode());
|
||||
}
|
||||
|
||||
|
||||
@ -4787,7 +4785,7 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3047,9 +3047,9 @@ 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,
|
||||
PREMONOMORPHIC).code();
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
|
||||
SLOPPY, PREMONOMORPHIC).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
@ -3166,7 +3166,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
||||
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(
|
||||
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
|
||||
isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
|
||||
instr->hydrogen()->initialization_state()).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
@ -1638,7 +1638,7 @@ class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> {
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
|
||||
|
||||
Handle<Object> name() const { return hydrogen()->name(); }
|
||||
bool for_typeof() const { return hydrogen()->for_typeof(); }
|
||||
TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -12,9 +12,6 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
|
||||
|
||||
|
||||
class StringCharLoadGenerator : public AllStatic {
|
||||
public:
|
||||
// Generates the code for handling different string types and loading the
|
||||
|
@ -1333,7 +1333,7 @@ void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow) {
|
||||
Register context = rsi;
|
||||
Register temp = rdx;
|
||||
@ -1383,7 +1383,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
|
||||
// All extension objects were empty and it is safe to use a normal global
|
||||
// load machinery.
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1418,9 +1418,8 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
Label* slow,
|
||||
Label* done) {
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow, Label* done) {
|
||||
// Generate fast-case code for variables that might be shadowed by
|
||||
// eval-introduced variables. Eval is used a lot without
|
||||
// introducing variables. In those cases, we do not want to
|
||||
@ -1428,7 +1427,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
// containing the eval.
|
||||
Variable* var = proxy->var();
|
||||
if (var->mode() == DYNAMIC_GLOBAL) {
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
|
||||
__ jmp(done);
|
||||
} else if (var->mode() == DYNAMIC_LOCAL) {
|
||||
Variable* local = var->local_if_not_shadowed();
|
||||
@ -1450,7 +1449,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
Variable* var = proxy->var();
|
||||
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
|
||||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
|
||||
@ -1473,15 +1472,13 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
__ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
|
||||
__ Move(LoadDescriptor::SlotRegister(),
|
||||
SmiFromSlot(proxy->VariableFeedbackSlot()));
|
||||
// Inside typeof use a regular load, not a contextual load, to avoid
|
||||
// a reference error.
|
||||
CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
|
||||
CallLoadIC(typeof_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
// Record position before possible IC call.
|
||||
SetExpressionPosition(proxy);
|
||||
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
|
||||
@ -1493,7 +1490,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::GLOBAL:
|
||||
case VariableLocation::UNALLOCATED: {
|
||||
Comment cmnt(masm_, "[ Global variable");
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
context()->Plug(rax);
|
||||
break;
|
||||
}
|
||||
@ -1501,7 +1498,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::PARAMETER:
|
||||
case VariableLocation::LOCAL:
|
||||
case VariableLocation::CONTEXT: {
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
|
||||
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot"
|
||||
: "[ Stack slot");
|
||||
if (var->binding_needs_init()) {
|
||||
@ -1574,12 +1571,12 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
Label done, slow;
|
||||
// Generate code for loading from variables potentially shadowed
|
||||
// by eval-introduced variables.
|
||||
EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
|
||||
EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
|
||||
__ bind(&slow);
|
||||
__ Push(rsi); // Context.
|
||||
__ Push(var->name());
|
||||
Runtime::FunctionId function_id =
|
||||
typeof_state == NOT_INSIDE_TYPEOF
|
||||
typeof_mode == NOT_INSIDE_TYPEOF
|
||||
? Runtime::kLoadLookupSlot
|
||||
: Runtime::kLoadLookupSlotNoReferenceError;
|
||||
__ CallRuntime(function_id, 2);
|
||||
@ -2259,7 +2256,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
|
||||
__ Move(LoadDescriptor::SlotRegister(),
|
||||
SmiFromSlot(expr->DoneFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // rax=result.done
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // rax=result.done
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
CallIC(bool_ic);
|
||||
__ testp(result_register(), result_register());
|
||||
@ -2270,7 +2267,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
|
||||
__ Move(LoadDescriptor::SlotRegister(),
|
||||
SmiFromSlot(expr->ValueFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // result.value in rax
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // result.value in rax
|
||||
context()->DropAndPlug(2, rax); // drop iter and g
|
||||
break;
|
||||
}
|
||||
@ -2410,7 +2407,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
||||
__ Move(LoadDescriptor::NameRegister(), key->value());
|
||||
__ Move(LoadDescriptor::SlotRegister(),
|
||||
SmiFromSlot(prop->PropertyFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL, language_mode());
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
|
||||
}
|
||||
|
||||
|
||||
@ -4714,7 +4711,7 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
|
||||
__ Move(LoadDescriptor::NameRegister(), expr->name());
|
||||
__ Move(LoadDescriptor::SlotRegister(),
|
||||
SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2877,9 +2877,9 @@ 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,
|
||||
PREMONOMORPHIC).code();
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
|
||||
SLOPPY, PREMONOMORPHIC).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
@ -2996,7 +2996,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
||||
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(
|
||||
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
|
||||
isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
|
||||
instr->hydrogen()->initialization_state()).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
@ -1690,7 +1690,7 @@ class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> {
|
||||
LOperand* temp_vector() { return temps_[0]; }
|
||||
|
||||
Handle<Object> name() const { return hydrogen()->name(); }
|
||||
bool for_typeof() const { return hydrogen()->for_typeof(); }
|
||||
TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1290,7 +1290,7 @@ void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow) {
|
||||
Register context = esi;
|
||||
Register temp = edx;
|
||||
@ -1339,7 +1339,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
|
||||
// All extension objects were empty and it is safe to use a normal global
|
||||
// load machinery.
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1374,9 +1374,8 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
TypeofState typeof_state,
|
||||
Label* slow,
|
||||
Label* done) {
|
||||
TypeofMode typeof_mode,
|
||||
Label* slow, Label* done) {
|
||||
// Generate fast-case code for variables that might be shadowed by
|
||||
// eval-introduced variables. Eval is used a lot without
|
||||
// introducing variables. In those cases, we do not want to
|
||||
@ -1384,7 +1383,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
// containing the eval.
|
||||
Variable* var = proxy->var();
|
||||
if (var->mode() == DYNAMIC_GLOBAL) {
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
|
||||
EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
|
||||
__ jmp(done);
|
||||
} else if (var->mode() == DYNAMIC_LOCAL) {
|
||||
Variable* local = var->local_if_not_shadowed();
|
||||
@ -1406,7 +1405,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
Variable* var = proxy->var();
|
||||
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
|
||||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
|
||||
@ -1429,15 +1428,13 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
|
||||
__ mov(LoadDescriptor::NameRegister(), var->name());
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
// Inside typeof use a regular load, not a contextual load, to avoid
|
||||
// a reference error.
|
||||
CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
|
||||
CallLoadIC(typeof_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
TypeofState typeof_state) {
|
||||
TypeofMode typeof_mode) {
|
||||
SetExpressionPosition(proxy);
|
||||
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
|
||||
Variable* var = proxy->var();
|
||||
@ -1448,7 +1445,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::GLOBAL:
|
||||
case VariableLocation::UNALLOCATED: {
|
||||
Comment cmnt(masm_, "[ Global variable");
|
||||
EmitGlobalVariableLoad(proxy, typeof_state);
|
||||
EmitGlobalVariableLoad(proxy, typeof_mode);
|
||||
context()->Plug(eax);
|
||||
break;
|
||||
}
|
||||
@ -1456,7 +1453,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
case VariableLocation::PARAMETER:
|
||||
case VariableLocation::LOCAL:
|
||||
case VariableLocation::CONTEXT: {
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
|
||||
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
|
||||
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
|
||||
: "[ Stack variable");
|
||||
if (var->binding_needs_init()) {
|
||||
@ -1529,12 +1526,12 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
|
||||
Label done, slow;
|
||||
// Generate code for loading from variables potentially shadowed
|
||||
// by eval-introduced variables.
|
||||
EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
|
||||
EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
|
||||
__ bind(&slow);
|
||||
__ push(esi); // Context.
|
||||
__ push(Immediate(var->name()));
|
||||
Runtime::FunctionId function_id =
|
||||
typeof_state == NOT_INSIDE_TYPEOF
|
||||
typeof_mode == NOT_INSIDE_TYPEOF
|
||||
? Runtime::kLoadLookupSlot
|
||||
: Runtime::kLoadLookupSlotNoReferenceError;
|
||||
__ CallRuntime(function_id, 2);
|
||||
@ -2215,7 +2212,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
isolate()->factory()->done_string()); // "done"
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // result.done in eax
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
CallIC(bool_ic);
|
||||
__ test(eax, eax);
|
||||
@ -2227,7 +2224,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
isolate()->factory()->value_string()); // "value"
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL); // result.value in eax
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF); // result.value in eax
|
||||
context()->DropAndPlug(2, eax); // drop iter and g
|
||||
break;
|
||||
}
|
||||
@ -2366,7 +2363,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_INSIDE_TYPEOF, language_mode());
|
||||
}
|
||||
|
||||
|
||||
@ -4677,7 +4674,7 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
|
||||
__ mov(LoadDescriptor::SlotRegister(),
|
||||
Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
CallLoadIC(NOT_INSIDE_TYPEOF);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3129,9 +3129,9 @@ 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,
|
||||
PREMONOMORPHIC).code();
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
|
||||
SLOPPY, PREMONOMORPHIC).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
@ -3242,7 +3242,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
||||
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
|
||||
Handle<Code> ic =
|
||||
CodeFactory::LoadICInOptimizedCode(
|
||||
isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
|
||||
isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
|
||||
instr->hydrogen()->initialization_state()).code();
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
@ -1721,7 +1721,7 @@ class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> {
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
|
||||
|
||||
Handle<Object> name() const { return hydrogen()->name(); }
|
||||
bool for_typeof() const { return hydrogen()->for_typeof(); }
|
||||
TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -287,7 +287,7 @@ TEST(DisasmIa320) {
|
||||
__ bind(&L2);
|
||||
__ call(Operand(ebx, ecx, times_4, 10000));
|
||||
__ nop();
|
||||
Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
|
||||
Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_INSIDE_TYPEOF));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
__ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
|
||||
|
@ -282,7 +282,7 @@ TEST(DisasmX64) {
|
||||
// TODO(mstarzinger): The following is protected.
|
||||
// __ call(Operand(rbx, rcx, times_4, 10000));
|
||||
__ nop();
|
||||
Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
|
||||
Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_INSIDE_TYPEOF));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
__ nop();
|
||||
|
@ -287,7 +287,7 @@ TEST(DisasmIa320) {
|
||||
__ bind(&L2);
|
||||
__ call(Operand(ebx, ecx, times_4, 10000));
|
||||
__ nop();
|
||||
Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
|
||||
Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_INSIDE_TYPEOF));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
__ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
|
||||
|
@ -950,7 +950,8 @@ TEST_F(JSTypedLoweringTest, JSLoadDynamicGlobal) {
|
||||
for (int i = 0; i < DynamicGlobalAccess::kMaxCheckDepth; ++i) {
|
||||
uint32_t bitset = 1 << i; // Only single check.
|
||||
Reduction r = Reduce(graph()->NewNode(
|
||||
javascript()->LoadDynamicGlobal(name, bitset, feedback, NOT_CONTEXTUAL),
|
||||
javascript()->LoadDynamicGlobal(name, bitset, feedback,
|
||||
NOT_INSIDE_TYPEOF),
|
||||
vector, context, context, frame_state, frame_state, effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(
|
||||
|
Loading…
Reference in New Issue
Block a user