void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
- KeyedLoadICStub stub(isolate(), state());
+ KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ b(ne, &try_poly_name);
Handle<Code> megamorphic_stub =
- KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
+ KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);
__ ldr(load_name, MemOperand(sp, 2 * kPointerSize));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(r1, r0);
__ str(r1, MemOperand(sp, 2 * kPointerSize));
__ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_CONTEXTUAL);
}
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
- __ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
__ ldr(scratch, MemOperand(sp, kPointerSize * 2));
__ Push(scratch);
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ str(r0, MemOperand(sp, kPointerSize));
__ ldr(scratch, MemOperand(sp, kPointerSize * 2));
__ Push(scratch);
VisitForStackValue(prop->key());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ str(r0, MemOperand(sp, kPointerSize));
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
// Name is always in r2.
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
- Handle<Code> ic =
- CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
+ isolate(), NOT_CONTEXTUAL,
+ instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
- Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
- isolate(), instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic =
+ CodeFactory::KeyedLoadICInOptimizedCode(
+ isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
- KeyedLoadICStub stub(isolate(), state());
+ KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
__ JumpIfNotRoot(feedback, Heap::kmegamorphic_symbolRootIndex,
&try_poly_name);
Handle<Code> megamorphic_stub =
- KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
+ KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
__ Bind(&try_poly_name);
__ Mov(LoadDescriptor::NameRegister(), Operand(key->value()));
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_CONTEXTUAL);
}
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
// Call keyed load IC. It has arguments key and receiver in x0 and x1.
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallIC(ic);
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
- __ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
__ Peek(scratch, kPointerSize);
__ Push(x0, scratch);
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver)
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
- // - language_mode
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ // - key
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ Poke(x0, kPointerSize);
__ Peek(scratch, kPointerSize);
__ Push(x0, scratch);
VisitForStackValue(prop->key());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ Poke(x0, kPointerSize);
__ Peek(load_name, 2 * kPointerSize);
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ Mov(x1, x0);
__ Poke(x1, 2 * kPointerSize);
__ Mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
- Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
- isolate(), instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic =
+ CodeFactory::KeyedLoadICInOptimizedCode(
+ isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
DCHECK(ToRegister(instr->result()).Is(x0));
DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
__ Mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
- Handle<Code> ic =
- CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
+ isolate(), NOT_CONTEXTUAL,
+ instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
DCHECK(ToRegister(instr->result()).is(x0));
static void Generate_LoadIC_Slow(MacroAssembler* masm) {
- NamedLoadHandlerCompiler::GenerateSlow(masm);
+ LoadIC::GenerateRuntimeGetProperty(masm);
+}
+
+
+static void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) {
+ KeyedLoadIC::GenerateInitialize(masm);
}
static void Generate_KeyedLoadIC_Slow(MacroAssembler* masm) {
- ElementHandlerCompiler::GenerateLoadSlow(masm);
+ KeyedLoadIC::GenerateRuntimeGetProperty(masm);
}
static void Generate_KeyedLoadIC_Megamorphic(MacroAssembler* masm) {
- KeyedLoadIC::GenerateMegamorphic(masm, SLOPPY);
-}
-
-
-static void Generate_KeyedLoadIC_Megamorphic_Strong(MacroAssembler* masm) {
- KeyedLoadIC::GenerateMegamorphic(masm, STRONG);
+ KeyedLoadIC::GenerateMegamorphic(masm);
}
V(StoreIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(KeyedStoreIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(LoadIC_Getter_ForDeopt, LOAD_IC, MONOMORPHIC, kNoExtraICState) \
+ V(KeyedLoadIC_Initialize, KEYED_LOAD_IC, UNINITIALIZED, kNoExtraICState) \
V(KeyedLoadIC_Megamorphic, KEYED_LOAD_IC, MEGAMORPHIC, kNoExtraICState) \
\
- V(KeyedLoadIC_Megamorphic_Strong, KEYED_LOAD_IC, MEGAMORPHIC, \
- LoadICState::kStrongModeState) \
- \
V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC, \
StoreICState::kStrictModeState) \
\
V(KeyedStoreIC_Megamorphic_Strict, KEYED_STORE_IC, MEGAMORPHIC, \
StoreICState::kStrictModeState) \
\
+ /* Uses KeyedLoadIC_Initialize; must be after in list. */ \
V(FunctionCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(FunctionApply, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(ReflectApply, BUILTIN, UNINITIALIZED, kNoExtraICState) \
CODE_AGE_LIST_WITH_ARG(DECLARE_CODE_AGE_BUILTIN, V)
// Define list of builtin handlers implemented in assembly.
-#define BUILTIN_LIST_H(V) \
- V(LoadIC_Slow, LOAD_IC) \
- V(KeyedLoadIC_Slow, KEYED_LOAD_IC) \
- V(StoreIC_Slow, STORE_IC) \
- V(KeyedStoreIC_Slow, KEYED_STORE_IC) \
- V(LoadIC_Normal, LOAD_IC) \
- V(StoreIC_Normal, STORE_IC)
+#define BUILTIN_LIST_H(V) \
+ V(LoadIC_Slow, LOAD_IC) \
+ V(KeyedLoadIC_Slow, KEYED_LOAD_IC) \
+ V(StoreIC_Slow, STORE_IC) \
+ V(KeyedStoreIC_Slow, KEYED_STORE_IC) \
+ V(LoadIC_Normal, LOAD_IC) \
+ V(StoreIC_Normal, STORE_IC)
// Define list of builtins used by the debugger implemented in assembly.
#define BUILTIN_LIST_DEBUG_A(V) \
// static
-Callable CodeFactory::LoadIC(Isolate* isolate, ContextualMode mode,
- LanguageMode language_mode) {
+Callable CodeFactory::LoadIC(Isolate* isolate, ContextualMode mode) {
return Callable(
- LoadIC::initialize_stub(
- isolate, LoadICState(mode, language_mode).GetExtraICState()),
+ LoadIC::initialize_stub(isolate, LoadICState(mode).GetExtraICState()),
LoadDescriptor(isolate));
}
// static
Callable CodeFactory::LoadICInOptimizedCode(
- Isolate* isolate, ContextualMode mode, LanguageMode language_mode,
+ Isolate* isolate, ContextualMode mode,
InlineCacheState initialization_state) {
auto code = LoadIC::initialize_stub_in_optimized_code(
- isolate, LoadICState(mode, language_mode).GetExtraICState(),
- initialization_state);
+ isolate, LoadICState(mode).GetExtraICState(), initialization_state);
return Callable(code, LoadWithVectorDescriptor(isolate));
}
// static
-Callable CodeFactory::KeyedLoadIC(Isolate* isolate,
- LanguageMode language_mode) {
- ExtraICState state =
- is_strong(language_mode) ? LoadICState::kStrongModeState : 0;
- return Callable(KeyedLoadIC::initialize_stub(isolate, state),
+Callable CodeFactory::KeyedLoadIC(Isolate* isolate) {
+ return Callable(KeyedLoadIC::initialize_stub(isolate),
LoadDescriptor(isolate));
}
// static
Callable CodeFactory::KeyedLoadICInOptimizedCode(
- Isolate* isolate, LanguageMode language_mode,
- InlineCacheState initialization_state) {
- ExtraICState state =
- is_strong(language_mode) ? LoadICState::kStrongModeState : 0;
+ Isolate* isolate, InlineCacheState initialization_state) {
auto code = KeyedLoadIC::initialize_stub_in_optimized_code(
- isolate, initialization_state, state);
+ isolate, initialization_state);
if (initialization_state != MEGAMORPHIC) {
return Callable(code, LoadWithVectorDescriptor(isolate));
}
class CodeFactory final {
public:
// Initial states for ICs.
- static Callable LoadIC(Isolate* isolate, ContextualMode mode,
- LanguageMode language_mode);
+ static Callable LoadIC(Isolate* isolate, ContextualMode mode);
static Callable LoadICInOptimizedCode(Isolate* isolate, ContextualMode mode,
- LanguageMode language_mode,
InlineCacheState initialization_state);
- static Callable KeyedLoadIC(Isolate* isolate, LanguageMode language_mode);
+ static Callable KeyedLoadIC(Isolate* isolate);
static Callable KeyedLoadICInOptimizedCode(
- Isolate* isolate, LanguageMode language_mode,
- InlineCacheState initialization_state);
+ Isolate* isolate, InlineCacheState initialization_state);
static Callable CallIC(Isolate* isolate, int argc,
CallICState::CallType call_type);
static Callable CallICInOptimizedCode(Isolate* isolate, int argc,
HContext* context() { return context_; }
Isolate* isolate() { return info_->isolate(); }
- HLoadNamedField* BuildLoadNamedField(HValue* object, FieldIndex index);
+ HLoadNamedField* BuildLoadNamedField(HValue* object,
+ FieldIndex index);
void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index,
Representation representation,
bool transition_to_field);
HValue* hash = BuildElementIndexHash(key);
- return BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash,
- casted_stub()->language_mode());
+ return BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash);
}
HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() {
HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
HValue* key = GetParameter(LoadDescriptor::kNameIndex);
+
// Split into a smi/integer case and unique string case.
HIfContinuation index_name_split_continuation(graph()->CreateBasicBlock(),
graph()->CreateBasicBlock());
HValue* hash = BuildElementIndexHash(key);
- Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash,
- casted_stub()->language_mode()));
+ Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash));
}
kind_if.Else();
hash = AddUncasted<HShr>(hash, Add<HConstant>(Name::kHashShift));
- HValue* value = BuildUncheckedDictionaryElementLoad(
- receiver, properties, key, hash, casted_stub()->language_mode());
+ HValue* value = BuildUncheckedDictionaryElementLoad(receiver,
+ properties,
+ key,
+ hash);
Push(value);
}
if_dict_properties.Else();
inline_or_runtime.Else();
{
// KeyedLookupCache miss; call runtime.
- Add<HPushArguments>(receiver, key,
- Add<HConstant>(casted_stub()->language_mode()));
+ Add<HPushArguments>(receiver, key);
Push(Add<HCallRuntime>(
isolate()->factory()->empty_string(),
- Runtime::FunctionForId(Runtime::kKeyedGetProperty), 3));
+ Runtime::FunctionForId(Runtime::kKeyedGetProperty), 2));
}
inline_or_runtime.End();
}
// Create the code object.
CodeDesc desc;
masm.GetCode(&desc);
+
// Copy the generated code into a heap object.
Code::Flags flags = Code::ComputeFlags(
GetCodeKind(),
class LoadDictionaryElementStub : public HydrogenCodeStub {
public:
- explicit LoadDictionaryElementStub(Isolate* isolate, const LoadICState& state)
- : HydrogenCodeStub(isolate) {
- minor_key_ = state.GetExtraICState();
- }
+ explicit LoadDictionaryElementStub(Isolate* isolate)
+ : HydrogenCodeStub(isolate) {}
CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
return LoadWithVectorDescriptor(isolate());
}
- LanguageMode language_mode() const {
- return LoadICState::GetLanguageMode(MinorKey());
- }
-
DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub);
};
class KeyedLoadGenericStub : public HydrogenCodeStub {
public:
- explicit KeyedLoadGenericStub(Isolate* isolate, const LoadICState& state)
- : HydrogenCodeStub(isolate) {
- minor_key_ = state.GetExtraICState();
- }
+ explicit KeyedLoadGenericStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
InlineCacheState GetICState() const override { return GENERIC; }
- LanguageMode language_mode() const {
- return LoadICState::GetLanguageMode(MinorKey());
- }
-
DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
DEFINE_HYDROGEN_CODE_STUB(KeyedLoadGeneric, HydrogenCodeStub);
return static_cast<ExtraICState>(minor_key_);
}
- protected:
+ private:
LoadICState state() const {
return LoadICState(static_cast<ExtraICState>(minor_key_));
}
class KeyedLoadICTrampolineStub : public LoadICTrampolineStub {
public:
- explicit KeyedLoadICTrampolineStub(Isolate* isolate, const LoadICState& state)
- : LoadICTrampolineStub(isolate, state) {}
+ explicit KeyedLoadICTrampolineStub(Isolate* isolate)
+ : LoadICTrampolineStub(isolate, LoadICState(0)) {}
Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
class KeyedLoadICStub : public PlatformCodeStub {
public:
- explicit KeyedLoadICStub(Isolate* isolate, const LoadICState& state)
- : PlatformCodeStub(isolate) {
- minor_key_ = state.GetExtraICState();
- }
+ explicit KeyedLoadICStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
void GenerateForTrampoline(MacroAssembler* masm);
Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
InlineCacheState GetICState() const final { return DEFAULT; }
- ExtraICState GetExtraICState() const final {
- return static_cast<ExtraICState>(minor_key_);
- }
DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
DEFINE_PLATFORM_CODE_STUB(KeyedLoadIC, PlatformCodeStub);
Code::Kind GetCodeKind() const final { return Code::KEYED_STORE_IC; }
InlineCacheState GetICState() const final { return DEFAULT; }
- virtual ExtraICState GetExtraICState() const final {
- return static_cast<ExtraICState>(minor_key_);
- }
DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreIC);
DEFINE_PLATFORM_CODE_STUB(VectorKeyedStoreIC, PlatformCodeStub);
Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
const ResolvedFeedbackSlot& feedback) {
- const Operator* op = javascript()->LoadProperty(feedback, language_mode());
+ const Operator* op = javascript()->LoadProperty(feedback);
return Record(js_type_feedback_,
NewNode(op, object, key, GetFeedbackVector()), feedback.slot());
}
Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
const ResolvedFeedbackSlot& feedback,
ContextualMode mode) {
- const Operator* op = javascript()->LoadNamed(MakeUnique(name), feedback,
- language_mode(), mode);
+ const Operator* op =
+ javascript()->LoadNamed(MakeUnique(name), feedback, mode);
return Record(js_type_feedback_, NewNode(op, object, GetFeedbackVector()),
feedback.slot());
}
Node* receiver, Node* home_object, Handle<Name> name,
const ResolvedFeedbackSlot& feedback) {
Node* name_node = jsgraph()->Constant(name);
- Node* language = jsgraph()->Constant(language_mode());
- const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 4);
- Node* value = NewNode(op, receiver, home_object, name_node, language);
+ const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3);
+ Node* value = NewNode(op, receiver, home_object, name_node);
return Record(js_type_feedback_, value, feedback.slot());
}
Node* AstGraphBuilder::BuildKeyedSuperLoad(
Node* receiver, Node* home_object, Node* key,
const ResolvedFeedbackSlot& feedback) {
- Node* language = jsgraph()->Constant(language_mode());
const Operator* op =
- javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
- Node* value = NewNode(op, receiver, home_object, key, language);
+ javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+ Node* value = NewNode(op, receiver, home_object, key);
return Record(js_type_feedback_, value, feedback.slot());
}
void JSGenericLowering::LowerJSLoadProperty(Node* node) {
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op());
- Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(
- isolate(), p.language_mode(), UNINITIALIZED);
+ Callable callable =
+ CodeFactory::KeyedLoadICInOptimizedCode(isolate(), UNINITIALIZED);
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
ReplaceWithStubCall(node, callable, flags);
}
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
Callable callable = CodeFactory::LoadICInOptimizedCode(
- isolate(), p.contextual_mode(), p.language_mode(), UNINITIALIZED);
+ isolate(), p.contextual_mode(), UNINITIALIZED);
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
ReplaceWithStubCall(node, callable, flags);
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();
}
size_t hash_value(LoadNamedParameters const& p) {
- return base::hash_combine(p.name(), p.language_mode(), p.contextual_mode(),
- p.feedback());
+ return base::hash_combine(p.name(), p.contextual_mode(), p.feedback());
}
std::ostream& operator<<(std::ostream& os, LoadNamedParameters const& p) {
- return os << Brief(*p.name().handle()) << ", " << p.language_mode() << ", "
- << p.contextual_mode();
+ return os << Brief(*p.name().handle()) << ", " << p.contextual_mode();
}
std::ostream& operator<<(std::ostream& os, LoadPropertyParameters const& p) {
- return os << p.language_mode();
+ // Nothing special to print.
+ return os;
}
bool operator==(LoadPropertyParameters const& lhs,
LoadPropertyParameters const& rhs) {
- return lhs.language_mode() == rhs.language_mode() &&
- lhs.feedback() == rhs.feedback();
+ return lhs.feedback() == rhs.feedback();
}
size_t hash_value(LoadPropertyParameters const& p) {
- return base::hash_combine(p.language_mode(), p.feedback());
+ return hash_value(p.feedback());
}
const Operator* JSOperatorBuilder::LoadNamed(
const Unique<Name>& name, const ResolvedFeedbackSlot& feedback,
- LanguageMode language_mode, ContextualMode contextual_mode) {
- LoadNamedParameters parameters(name, feedback, language_mode,
- contextual_mode);
+ ContextualMode contextual_mode) {
+ LoadNamedParameters parameters(name, feedback, contextual_mode);
return new (zone()) Operator1<LoadNamedParameters>( // --
IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
"JSLoadNamed", // name
const Operator* JSOperatorBuilder::LoadProperty(
- const ResolvedFeedbackSlot& feedback, LanguageMode language_mode) {
- LoadPropertyParameters parameters(feedback, language_mode);
+ const ResolvedFeedbackSlot& feedback) {
+ LoadPropertyParameters parameters(feedback);
return new (zone()) Operator1<LoadPropertyParameters>( // --
IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode
"JSLoadProperty", // name
public:
LoadNamedParameters(const Unique<Name>& name,
const ResolvedFeedbackSlot& feedback,
- LanguageMode language_mode,
ContextualMode contextual_mode)
- : name_(name),
- feedback_(feedback),
- language_mode_(language_mode),
- contextual_mode_(contextual_mode) {}
+ : name_(name), feedback_(feedback), contextual_mode_(contextual_mode) {}
const Unique<Name>& name() const { return name_; }
- LanguageMode language_mode() const { return language_mode_; }
ContextualMode contextual_mode() const { return contextual_mode_; }
const ResolvedFeedbackSlot& feedback() const { return feedback_; }
private:
const Unique<Name> name_;
const ResolvedFeedbackSlot feedback_;
- const LanguageMode language_mode_;
const ContextualMode contextual_mode_;
};
// used as a parameter by JSLoadProperty operators.
class LoadPropertyParameters final {
public:
- explicit LoadPropertyParameters(const ResolvedFeedbackSlot& feedback,
- LanguageMode language_mode)
- : feedback_(feedback), language_mode_(language_mode) {}
+ explicit LoadPropertyParameters(const ResolvedFeedbackSlot& feedback)
+ : feedback_(feedback) {}
const ResolvedFeedbackSlot& feedback() const { return feedback_; }
- LanguageMode language_mode() const { return language_mode_; }
-
private:
const ResolvedFeedbackSlot feedback_;
- const LanguageMode language_mode_;
};
bool operator==(LoadPropertyParameters const&, LoadPropertyParameters const&);
const Operator* CallConstruct(int arguments);
- const Operator* LoadProperty(const ResolvedFeedbackSlot& feedback,
- LanguageMode language_mode);
+ const Operator* LoadProperty(const ResolvedFeedbackSlot& feedback);
const Operator* LoadNamed(const Unique<Name>& name,
const ResolvedFeedbackSlot& feedback,
- LanguageMode language_mode,
ContextualMode contextual_mode = NOT_CONTEXTUAL);
const Operator* StoreProperty(LanguageMode language_mode);
javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true), context,
context, effect);
Node* fast = graph()->NewNode(
- javascript()->LoadNamed(name, access.feedback(), SLOPPY, access.mode()),
- global, vector, context, state1, state2, global, check_true);
+ javascript()->LoadNamed(name, access.feedback(), access.mode()), global,
+ vector, context, state1, state2, global, check_true);
// Slow case, because variable potentially shadowed. Perform dynamic lookup.
uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired;
void FullCodeGenerator::CallLoadIC(ContextualMode contextual_mode,
- LanguageMode language_mode,
TypeFeedbackId id) {
- Handle<Code> ic =
- CodeFactory::LoadIC(isolate(), contextual_mode, language_mode).code();
+ Handle<Code> ic = CodeFactory::LoadIC(isolate(), contextual_mode).code();
CallIC(ic, id);
}
void CallIC(Handle<Code> code,
TypeFeedbackId id = TypeFeedbackId::None());
- void CallLoadIC(ContextualMode mode, LanguageMode language_mode = SLOPPY,
+ void CallLoadIC(ContextualMode mode,
TypeFeedbackId id = TypeFeedbackId::None());
void CallGlobalLoadIC(Handle<String> name);
void CallStoreIC(TypeFeedbackId id = TypeFeedbackId::None());
class HLoadNamedGeneric final : public HTemplateInstruction<2> {
public:
- DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HLoadNamedGeneric, HValue*,
- Handle<Object>, LanguageMode,
- InlineCacheState);
+ DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HLoadNamedGeneric, HValue*,
+ Handle<Object>, InlineCacheState);
HValue* context() const { return OperandAt(0); }
HValue* object() const { return OperandAt(1); }
DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
- LanguageMode language_mode() const { return language_mode_; }
-
private:
HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name,
- LanguageMode language_mode,
InlineCacheState initialization_state)
: name_(name),
slot_(FeedbackVectorICSlot::Invalid()),
- language_mode_(language_mode),
initialization_state_(initialization_state) {
SetOperandAt(0, context);
SetOperandAt(1, object);
Handle<Object> name_;
Handle<TypeFeedbackVector> feedback_vector_;
FeedbackVectorICSlot slot_;
- LanguageMode language_mode_;
InlineCacheState initialization_state_;
};
class HLoadKeyedGeneric final : public HTemplateInstruction<3> {
public:
- DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HLoadKeyedGeneric, HValue*,
- HValue*, LanguageMode,
- InlineCacheState);
+ DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HLoadKeyedGeneric, HValue*,
+ HValue*, InlineCacheState);
HValue* object() const { return OperandAt(0); }
HValue* key() const { return OperandAt(1); }
HValue* context() const { return OperandAt(2); }
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
- LanguageMode language_mode() const { return language_mode_; }
-
private:
HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key,
- LanguageMode language_mode,
InlineCacheState initialization_state)
: slot_(FeedbackVectorICSlot::Invalid()),
- initialization_state_(initialization_state),
- language_mode_(language_mode) {
+ initialization_state_(initialization_state) {
set_representation(Representation::Tagged());
SetOperandAt(0, obj);
SetOperandAt(1, key);
Handle<TypeFeedbackVector> feedback_vector_;
FeedbackVectorICSlot slot_;
InlineCacheState initialization_state_;
- LanguageMode language_mode_;
};
}
-HConstant* HGraph::GetConstantBool(bool value) {
- return value ? GetConstantTrue() : GetConstantFalse();
-}
-
-
#define DEFINE_GET_CONSTANT(Name, name, type, htype, boolean_value) \
HConstant* HGraph::GetConstant##Name() { \
if (!constant_##name##_.is_set()) { \
}
-HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(
- HValue* receiver, HValue* elements, HValue* key, HValue* hash,
- LanguageMode language_mode) {
+HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver,
+ HValue* elements,
+ HValue* key,
+ HValue* hash) {
HValue* capacity =
Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex),
nullptr, FAST_ELEMENTS);
{
// element == undefined means "not found". Call the runtime.
// TODO(jkummerow): walk the prototype chain instead.
- Add<HPushArguments>(receiver, key, Add<HConstant>(language_mode));
+ Add<HPushArguments>(receiver, key);
Push(Add<HCallRuntime>(isolate()->factory()->empty_string(),
Runtime::FunctionForId(Runtime::kKeyedGetProperty),
- 3));
+ 2));
}
if_undefined.Else();
{
result_index->ClearFlag(HValue::kCanOverflow);
Push(Add<HLoadKeyed>(elements, result_index, nullptr, FAST_ELEMENTS));
details_compare.Else();
- Add<HPushArguments>(receiver, key, Add<HConstant>(language_mode));
+ Add<HPushArguments>(receiver, key);
Push(Add<HCallRuntime>(isolate()->factory()->empty_string(),
Runtime::FunctionForId(Runtime::kKeyedGetProperty),
- 3));
+ 2));
details_compare.End();
found_key_match.Else();
if (IsFound()) return IsLoad() || !IsReadOnly();
if (IsIntegerIndexedExotic()) return false;
if (!LookupInPrototypes()) return false;
- if (IsLoad()) return !is_strong(builder_->function_language_mode());
+ if (IsLoad()) return true;
if (IsAccessorConstant()) return true;
LookupTransition(*map_, *name_, NONE);
// use a generic Keyed Load if we are using the type vector, because
// it has to share information with full code.
HConstant* key = Add<HConstant>(name);
- HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>(
- object, key, function_language_mode(), PREMONOMORPHIC);
+ HLoadKeyedGeneric* result =
+ New<HLoadKeyedGeneric>(object, key, PREMONOMORPHIC);
result->SetVectorAndSlot(vector, slot);
return result;
}
- HLoadNamedGeneric* result = New<HLoadNamedGeneric>(
- object, name, function_language_mode(), PREMONOMORPHIC);
+ HLoadNamedGeneric* result =
+ New<HLoadNamedGeneric>(object, name, PREMONOMORPHIC);
result->SetVectorAndSlot(vector, slot);
return result;
} else {
HValue* value) {
if (access_type == LOAD) {
InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState();
- HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>(
- object, key, function_language_mode(), initial_state);
+ HLoadKeyedGeneric* result =
+ New<HLoadKeyedGeneric>(object, key, initial_state);
// HLoadKeyedGeneric with vector ics benefits from being encoded as
// MEGAMORPHIC because the vector/slot combo becomes unnecessary.
if (initial_state != MEGAMORPHIC) {
HConstant* GetConstantMinus1();
HConstant* GetConstantTrue();
HConstant* GetConstantFalse();
- HConstant* GetConstantBool(bool value);
HConstant* GetConstantHole();
HConstant* GetConstantNull();
HConstant* GetInvalidContext();
HValue* key);
HValue* BuildUncheckedDictionaryElementLoad(HValue* receiver,
- HValue* elements, HValue* key,
- HValue* hash,
- LanguageMode language_mode);
+ HValue* elements,
+ HValue* key,
+ HValue* hash);
HValue* BuildRegExpConstructResult(HValue* length,
HValue* index,
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
- KeyedLoadICStub stub(isolate(), state());
+ KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ j(not_equal, &try_poly_name);
Handle<Code> megamorphic_stub =
- KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
+ KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);
__ mov(load_receiver, Operand(esp, kPointerSize));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(edi, eax);
__ mov(Operand(esp, 2 * kPointerSize), edi);
__ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_CONTEXTUAL);
}
DCHECK(prop->IsSuperAccess());
__ push(Immediate(key->value()));
- __ push(Immediate(Smi::FromInt(language_mode())));
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
- __ push(Immediate(Smi::FromInt(language_mode())));
SetSourcePosition(prop->position());
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
__ push(eax);
__ push(Operand(esp, kPointerSize * 2));
__ push(Immediate(key->value()));
- __ push(Immediate(Smi::FromInt(language_mode())));
// Stack here:
// - home_object
// - this (receiver)
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ mov(Operand(esp, kPointerSize), eax);
__ push(eax);
__ push(Operand(esp, kPointerSize * 2));
VisitForStackValue(prop->key());
- __ push(Immediate(Smi::FromInt(language_mode())));
// Stack here:
// - home_object
// - this (receiver)
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ mov(Operand(esp, kPointerSize), eax);
__ mov(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
__ mov(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
- Handle<Code> ic =
- CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
+ isolate(), NOT_CONTEXTUAL,
+ instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
- Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
- isolate(), instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic =
+ CodeFactory::KeyedLoadICInOptimizedCode(
+ isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
#define __ ACCESS_MASM(masm)
-void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
- // Push receiver and key for runtime call.
- __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // The slow case calls into the runtime to complete the load without causing
- // an IC miss that would otherwise cause a transition to the generic stub.
- ExternalReference ref =
- ExternalReference(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
-void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
- // Push receiver and key for runtime call.
- __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // The slow case calls into the runtime to complete the load without causing
- // an IC miss that would otherwise cause a transition to the generic stub.
- ExternalReference ref =
- ExternalReference(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
- Register result, Label* slow,
- LanguageMode language_mode) {
+ Register result, Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
//
// scratch2 - used to hold maps, prototypes, and the loaded value.
Label check_prototypes, check_next_prototype;
- Label done, in_bounds, absent;
+ Label done, in_bounds, return_undefined;
__ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(elements);
__ ldr(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ CompareRoot(scratch2, Heap::kNullValueRootIndex);
- __ b(eq, &absent);
+ __ b(eq, &return_undefined);
__ ldr(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
__ ldr(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
// elements: elements of current prototype
__ b(ne, slow);
__ jmp(&check_next_prototype);
- __ bind(&absent);
- if (is_strong(language_mode)) {
- // Strong mode accesses must throw in this case, so call the runtime.
- __ jmp(slow);
- } else {
- __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
- __ jmp(&done);
- }
+ __ bind(&return_undefined);
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+ __ jmp(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
}
}
-void LoadIC::GenerateSlow(MacroAssembler* masm) {
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
__ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
- // Perform tail call to the entry.
- ExternalReference ref =
- ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
}
-void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
- // Perform tail call to the entry.
- ExternalReference ref =
- ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
-void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
- LanguageMode language_mode) {
+void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is in lr.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(r0, r3, &check_number_dictionary);
- GenerateFastArrayLoad(masm, receiver, key, r0, r3, r4, r0, &slow,
- language_mode);
+ GenerateFastArrayLoad(masm, receiver, key, r0, r3, r4, r0, &slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r4, r3);
__ Ret();
__ bind(&slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r4,
r3);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, r0, r3, &index_name, &slow);
}
-void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
- // Push receiver and key for runtime call.
- __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // The slow case calls into the runtime to complete the load without causing
- // an IC miss that would otherwise cause a transition to the generic stub.
- ExternalReference ref =
- ExternalReference(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
-void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
- // Push receiver and key for runtime call.
- __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // The slow case calls into the runtime to complete the load without causing
- // an IC miss that would otherwise cause a transition to the generic stub.
- ExternalReference ref =
- ExternalReference(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
- Register result, Label* slow,
- LanguageMode language_mode) {
+ Register result, Label* slow) {
DCHECK(!AreAliased(receiver, key, elements, scratch1, scratch2));
Label check_prototypes, check_next_prototype;
- Label done, in_bounds, absent;
+ Label done, in_bounds, return_undefined;
// Check for fast array.
__ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ Bind(&check_next_prototype);
__ Ldr(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
- __ JumpIfRoot(scratch2, Heap::kNullValueRootIndex, &absent);
+ __ JumpIfRoot(scratch2, Heap::kNullValueRootIndex, &return_undefined);
__ Ldr(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
__ Ldr(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
// elements: elements of current prototype
__ JumpIfNotRoot(elements, Heap::kEmptyFixedArrayRootIndex, slow);
__ B(&check_next_prototype);
- __ Bind(&absent);
- if (is_strong(language_mode)) {
- // Strong mode accesses must throw in this case, so call the runtime.
- __ B(slow);
- } else {
- __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
- __ B(&done);
- }
+ __ Bind(&return_undefined);
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+ __ B(&done);
__ Bind(&in_bounds);
// Fast case: Do the load.
// Dictionary load failed, go slow (but don't miss).
__ Bind(&slow);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
}
}
-void LoadIC::GenerateSlow(MacroAssembler* masm) {
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // Perform tail call to the entry.
- ExternalReference ref =
- ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
}
-void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // Perform tail call to the entry.
- ExternalReference ref =
- ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
Register receiver, Register scratch1,
Register scratch2, Register scratch3,
Register scratch4, Register scratch5,
- Label* slow,
- LanguageMode language_mode) {
+ Label* slow) {
DCHECK(!AreAliased(key, receiver, scratch1, scratch2, scratch3, scratch4,
scratch5));
__ CheckFastElements(scratch1, scratch2, &check_number_dictionary);
GenerateFastArrayLoad(masm, receiver, key, scratch3, scratch2, scratch1,
- result, slow, language_mode);
+ result, slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1,
scratch1, scratch2);
__ Ret();
}
-void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
- LanguageMode language_mode) {
+void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is in lr.
Label slow, check_name, index_smi, index_name;
__ Bind(&index_smi);
// Now the key is known to be a smi. This place is also jumped to from below
// where a numeric string is converted to a smi.
- GenerateKeyedLoadWithSmiKey(masm, key, receiver, x7, x3, x4, x5, x6, &slow,
- language_mode);
+ GenerateKeyedLoadWithSmiKey(masm, key, receiver, x7, x3, x4, x5, x6, &slow);
// Slow case.
__ Bind(&slow);
__ IncrementCounter(masm->isolate()->counters()->keyed_load_generic_slow(), 1,
x4, x3);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
__ Bind(&check_name);
GenerateKeyNameCheck(masm, key, x0, x3, &index_name, &slow);
void ElementHandlerCompiler::CompileElementHandlers(
- MapHandleList* receiver_maps, CodeHandleList* handlers,
- LanguageMode language_mode) {
+ MapHandleList* receiver_maps, CodeHandleList* handlers) {
for (int i = 0; i < receiver_maps->length(); ++i) {
Handle<Map> receiver_map = receiver_maps->at(i);
Handle<Code> cached_stub;
// No need to check for an elements-free prototype chain here, the
// generated stub code needs to check that dynamically anyway.
bool convert_hole_to_undefined =
- (is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
- *receiver_map ==
- isolate()->get_initial_js_array_map(elements_kind)) &&
- !is_strong(language_mode);
+ is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
+ *receiver_map == isolate()->get_initial_js_array_map(elements_kind);
if (receiver_map->has_indexed_interceptor()) {
cached_stub = LoadIndexedInterceptorStub(isolate()).GetCode();
convert_hole_to_undefined).GetCode();
} else {
DCHECK(elements_kind == DICTIONARY_ELEMENTS);
- LoadICState state = LoadICState(
- is_strong(language_mode) ? LoadICState::kStrongModeState : 0);
- cached_stub = LoadDictionaryElementStub(isolate(), state).GetCode();
+ cached_stub = LoadDictionaryElementStub(isolate()).GetCode();
}
}
static Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
Handle<Map> map);
- static void GenerateSlow(MacroAssembler* masm);
-
static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<Map> map,
Register receiver, Register holder,
int accessor_index, int expected_arguments,
virtual ~ElementHandlerCompiler() {}
void CompileElementHandlers(MapHandleList* receiver_maps,
- CodeHandleList* handlers,
- LanguageMode language_mode);
+ CodeHandleList* handlers);
- static void GenerateLoadSlow(MacroAssembler* masm);
static void GenerateStoreSlow(MacroAssembler* masm);
};
}
#define __ ACCESS_MASM(masm)
-static void LoadIC_PushArgs(MacroAssembler* masm) {
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register name = LoadDescriptor::NameRegister();
-
- DCHECK(!ebx.is(receiver) && !ebx.is(name));
-
- __ pop(ebx);
- __ push(receiver);
- __ push(name);
- __ push(ebx);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
- // Return address is on the stack.
- LoadIC_PushArgs(masm);
-
- // Do tail-call to runtime routine.
- ExternalReference ref(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
-void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
- // Return address is on the stack.
- LoadIC_PushArgs(masm);
-
- // Do tail-call to runtime routine.
- ExternalReference ref(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register scratch,
Register scratch2, Register result,
- Label* slow, LanguageMode language_mode) {
+ Label* slow) {
// Register use:
// receiver - holds the receiver and is unchanged.
// key - holds the key and is unchanged (must be a smi).
// result - holds the result on exit if the load succeeds and
// we fall through.
Label check_prototypes, check_next_prototype;
- Label done, in_bounds, absent;
+ Label done, in_bounds, return_undefined;
__ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(scratch);
__ mov(scratch2, FieldOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ cmp(scratch2, masm->isolate()->factory()->null_value());
- __ j(equal, &absent);
+ __ j(equal, &return_undefined);
__ mov(scratch, FieldOperand(scratch2, JSObject::kElementsOffset));
__ mov(scratch2, FieldOperand(scratch2, HeapObject::kMapOffset));
// scratch: elements of current prototype
__ j(not_equal, slow);
__ jmp(&check_next_prototype);
- __ bind(&absent);
- if (is_strong(language_mode)) {
- // Strong mode accesses must throw in this case, so call the runtime.
- __ jmp(slow);
- } else {
- __ mov(result, masm->isolate()->factory()->undefined_value());
- __ jmp(&done);
- }
+ __ bind(&return_undefined);
+ __ mov(result, masm->isolate()->factory()->undefined_value());
+ __ jmp(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
}
-void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
- LanguageMode language_mode) {
+void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is on the stack.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(eax, &check_number_dictionary);
- GenerateFastArrayLoad(masm, receiver, key, eax, ebx, eax, &slow,
- language_mode);
+ GenerateFastArrayLoad(masm, receiver, key, eax, ebx, eax, &slow);
Isolate* isolate = masm->isolate();
Counters* counters = isolate->counters();
__ IncrementCounter(counters->keyed_load_generic_smi(), 1);
__ bind(&slow);
// Slow case: jump to runtime.
__ IncrementCounter(counters->keyed_load_generic_slow(), 1);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, eax, ebx, &index_name, &slow);
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
}
}
-void LoadIC::GenerateSlow(MacroAssembler* masm) {
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
__ push(ebx);
// Perform tail call to the entry.
- ExternalReference ref =
- ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
}
-void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
__ push(ebx);
// Perform tail call to the entry.
- ExternalReference ref =
- ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
- Handle<Map> receiver_map, ExtraICState extra_ic_state) {
+ Handle<Map> receiver_map) {
Isolate* isolate = receiver_map->GetIsolate();
bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
ElementsKind elements_kind = receiver_map->elements_kind();
// stub code needs to check that dynamically anyway.
bool convert_hole_to_undefined =
is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
- *receiver_map == isolate->get_initial_js_array_map(elements_kind) &&
- !(is_strong(LoadICState::GetLanguageMode(extra_ic_state)));
+ *receiver_map == isolate->get_initial_js_array_map(elements_kind);
+
Handle<Code> stub;
if (receiver_map->has_indexed_interceptor()) {
stub = LoadIndexedInterceptorStub(isolate).GetCode();
stub = LoadFastElementStub(isolate, is_js_array, elements_kind,
convert_hole_to_undefined).GetCode();
} else {
- stub = LoadDictionaryElementStub(isolate, LoadICState(extra_ic_state))
- .GetCode();
+ stub = LoadDictionaryElementStub(isolate).GetCode();
}
return stub;
}
Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
- MapHandleList* receiver_maps, LanguageMode language_mode) {
+ MapHandleList* receiver_maps) {
Isolate* isolate = receiver_maps->at(0)->GetIsolate();
DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
CodeHandleList handlers(receiver_maps->length());
ElementHandlerCompiler compiler(isolate);
- compiler.CompileElementHandlers(receiver_maps, &handlers, language_mode);
+ compiler.CompileElementHandlers(receiver_maps, &handlers);
PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC);
Handle<Code> code = ic_compiler.CompilePolymorphic(
receiver_maps, &handlers, isolate->factory()->empty_string(),
// Keyed
static Handle<Code> ComputeKeyedLoadMonomorphicHandler(
- Handle<Map> receiver_map, ExtraICState extra_ic_state);
+ Handle<Map> receiver_map);
static Handle<Code> ComputeKeyedStoreMonomorphic(
Handle<Map> receiver_map, LanguageMode language_mode,
KeyedAccessStoreMode store_mode);
- static Handle<Code> ComputeKeyedLoadPolymorphic(MapHandleList* receiver_maps,
- LanguageMode language_mode);
+ static Handle<Code> ComputeKeyedLoadPolymorphic(MapHandleList* receiver_maps);
static Handle<Code> ComputeKeyedStorePolymorphic(
MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode,
LanguageMode language_mode);
// The contextual mode must be preserved across IC patching.
DCHECK(LoadICState::GetContextualMode(code->extra_ic_state()) ==
LoadICState::GetContextualMode(target()->extra_ic_state()));
- // Strongness must be preserved across IC patching.
- DCHECK(LoadICState::GetLanguageMode(code->extra_ic_state()) ==
- LoadICState::GetLanguageMode(target()->extra_ic_state()));
IC::set_target(code);
}
class LoadICState final BASE_EMBEDDED {
- private:
- class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
- class LanguageModeBits : public BitField<LanguageMode, 1, 2> {};
- STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
- const ExtraICState state_;
-
public:
- static const ExtraICState kStrongModeState = STRONG
- << LanguageModeBits::kShift;
-
explicit LoadICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
- explicit LoadICState(ContextualMode mode, LanguageMode language_mode)
- : state_(ContextualModeBits::encode(mode) |
- LanguageModeBits::encode(language_mode)) {}
+ explicit LoadICState(ContextualMode mode)
+ : state_(ContextualModeBits::encode(mode)) {}
ExtraICState GetExtraICState() const { return state_; }
return ContextualModeBits::decode(state_);
}
- LanguageMode language_mode() const {
- return LanguageModeBits::decode(state_);
- }
-
static ContextualMode GetContextualMode(ExtraICState state) {
return LoadICState(state).contextual_mode();
}
- static LanguageMode GetLanguageMode(ExtraICState state) {
- return LoadICState(state).language_mode();
- }
+ private:
+ class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
+ STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
+
+ const ExtraICState state_;
};
// static
-Handle<Code> KeyedLoadIC::ChooseMegamorphicStub(Isolate* isolate,
- ExtraICState extra_state) {
+Handle<Code> KeyedLoadIC::ChooseMegamorphicStub(Isolate* isolate) {
if (FLAG_compiled_keyed_generic_loads) {
- return KeyedLoadGenericStub(isolate, LoadICState(extra_state)).GetCode();
+ return KeyedLoadGenericStub(isolate).GetCode();
} else {
- return is_strong(LoadICState::GetLanguageMode(extra_state))
- ? isolate->builtins()->KeyedLoadIC_Megamorphic_Strong()
- : isolate->builtins()->KeyedLoadIC_Megamorphic();
+ return isolate->builtins()->KeyedLoadIC_Megamorphic();
}
}
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate(), result,
- Runtime::GetElementOrCharAt(isolate(), object, index, language_mode()),
- Object);
+ Runtime::GetElementOrCharAt(isolate(), object, index), Object);
return result;
}
// Get the property.
Handle<Object> result;
-
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate(), result, Object::GetProperty(&it, language_mode()), Object);
+ ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, Object::GetProperty(&it),
+ Object);
if (it.IsFound()) {
return result;
} else if (!IsUndeclaredGlobal(object)) {
}
-Handle<Code> KeyedLoadIC::initialize_stub(Isolate* isolate,
- ExtraICState extra_state) {
- return KeyedLoadICTrampolineStub(isolate, LoadICState(extra_state)).GetCode();
+Handle<Code> KeyedLoadIC::initialize_stub(Isolate* isolate) {
+ return KeyedLoadICTrampolineStub(isolate).GetCode();
}
Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code(
- Isolate* isolate, State initialization_state, ExtraICState extra_state) {
+ Isolate* isolate, State initialization_state) {
if (initialization_state != MEGAMORPHIC) {
- return KeyedLoadICStub(isolate, LoadICState(extra_state)).GetCode();
+ return KeyedLoadICStub(isolate).GetCode();
}
- return is_strong(LoadICState::GetLanguageMode(extra_state))
- ? isolate->builtins()->KeyedLoadIC_Megamorphic_Strong()
- : isolate->builtins()->KeyedLoadIC_Megamorphic();
+ switch (initialization_state) {
+ case UNINITIALIZED:
+ return isolate->builtins()->KeyedLoadIC_Initialize();
+ case MEGAMORPHIC:
+ return isolate->builtins()->KeyedLoadIC_Megamorphic();
+ default:
+ UNREACHABLE();
+ }
+ return Handle<Code>();
}
Handle<Code> LoadIC::megamorphic_stub() {
DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
- return KeyedLoadIC::ChooseMegamorphicStub(isolate(), extra_ic_state());
+ return KeyedLoadIC::ChooseMegamorphicStub(isolate());
}
lookup->state() == LookupIterator::ACCESS_CHECK) {
code = slow_stub();
} else if (!lookup->IsFound()) {
- if (kind() == Code::LOAD_IC && !is_strong(language_mode())) {
+ if (kind() == Code::LOAD_IC) {
code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(),
receiver_map());
// TODO(jkummerow/verwaest): Introduce a builtin that handles this case.
if (target_receiver_maps.length() == 0) {
Handle<Code> handler =
- PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
- receiver_map, extra_ic_state());
+ PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
return null_handle;
}
target_receiver_maps.at(0)->elements_kind(),
Handle<JSObject>::cast(receiver)->GetElementsKind())) {
Handle<Code> handler =
- PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
- receiver_map, extra_ic_state());
+ PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
return null_handle;
}
CodeHandleList handlers(target_receiver_maps.length());
ElementHandlerCompiler compiler(isolate());
- compiler.CompileElementHandlers(&target_receiver_maps, &handlers,
- language_mode());
+ compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
ConfigureVectorState(Handle<Name>::null(), &target_receiver_maps, &handlers);
return null_handle;
}
if (MigrateDeprecated(object)) {
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
- isolate(), result,
- Runtime::GetObjectProperty(isolate(), object, key, language_mode()),
+ isolate(), result, Runtime::GetObjectProperty(isolate(), object, key),
Object);
return result;
}
}
if (!load_handle.is_null()) return load_handle;
-
Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate(), result,
- Runtime::GetObjectProperty(isolate(), object, key, language_mode()),
- Object);
+ ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
+ Runtime::GetObjectProperty(isolate(), object, key),
+ Object);
return result;
}
Handle<Object> result;
LookupIterator it(receiver, name, holder);
- // TODO(conradw): Investigate strong mode semantics for this.
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
JSObject::GetProperty(&it));
DCHECK(args.smi_at(1) >= 0);
uint32_t index = args.smi_at(1);
Handle<Object> result;
- // TODO(conradw): Investigate strong mode semantics for this.
- LanguageMode language_mode = SLOPPY;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- Object::GetElement(isolate, receiver, index, language_mode));
+ isolate, result, Object::GetElement(isolate, receiver, index));
return *result;
}
}
-RUNTIME_FUNCTION(LoadIC_Slow) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
-
- Handle<Object> receiver = args.at<Object>(0);
- Handle<Name> name = args.at<Name>(1);
- LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- Runtime::GetObjectProperty(isolate, receiver, name, ic.language_mode()));
- return *result;
-}
-
-
-RUNTIME_FUNCTION(KeyedLoadIC_Slow) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
-
- Handle<Object> receiver = args.at<Object>(0);
- Handle<Object> key = args.at<Object>(1);
- LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, Runtime::KeyedGetObjectProperty(isolate, receiver, key,
- ic.language_mode()));
- return *result;
-}
-
-
static const Address IC_utilities[] = {
#define ADDR(name) FUNCTION_ADDR(name),
IC_UTIL_LIST(ADDR) NULL
Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
-}
-} // namespace v8::internal
+} // namespace internal
+} // namespace v8
#define IC_UTIL_LIST(ICU) \
ICU(LoadIC_Miss) \
ICU(KeyedLoadIC_Miss) \
- ICU(LoadIC_Slow) \
- ICU(KeyedLoadIC_Slow) \
ICU(CallIC_Miss) \
ICU(CallIC_Customization_Miss) \
ICU(StoreIC_Miss) \
class LoadIC : public IC {
public:
- static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
- LanguageMode language_mode) {
- return LoadICState(contextual_mode, language_mode).GetExtraICState();
+ static ExtraICState ComputeExtraICState(ContextualMode contextual_mode) {
+ return LoadICState(contextual_mode).GetExtraICState();
}
ContextualMode contextual_mode() const {
return LoadICState::GetContextualMode(extra_ic_state());
}
- LanguageMode language_mode() const {
- return LoadICState::GetLanguageMode(extra_ic_state());
- }
-
LoadIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
: IC(depth, isolate, nexus) {
DCHECK(nexus != NULL);
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
static void GenerateMiss(MacroAssembler* masm);
static void GenerateNormal(MacroAssembler* masm);
- static void GenerateSlow(MacroAssembler* masm);
+ static void GenerateRuntimeGetProperty(MacroAssembler* masm);
static Handle<Code> initialize_stub(Isolate* isolate,
ExtraICState extra_state);
class KeyedLoadIC : public LoadIC {
public:
// ExtraICState bits (building on IC)
- class IcCheckTypeField : public BitField<IcCheckType, 2, 1> {};
+ class IcCheckTypeField : public BitField<IcCheckType, 1, 1> {};
static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
- LanguageMode language_mode,
IcCheckType key_type) {
- return LoadICState(contextual_mode, language_mode).GetExtraICState() |
+ return LoadICState(contextual_mode).GetExtraICState() |
IcCheckTypeField::encode(key_type);
}
// Code generator routines.
static void GenerateMiss(MacroAssembler* masm);
- static void GenerateSlow(MacroAssembler* masm);
+ static void GenerateRuntimeGetProperty(MacroAssembler* masm);
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
- static void GenerateMegamorphic(MacroAssembler* masm,
- LanguageMode languageMode);
+ static void GenerateMegamorphic(MacroAssembler* masm);
// Bit mask to be tested against bit field for the cases when
// generic stub should go into slow case.
static const int kSlowCaseBitFieldMask =
(1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
- static Handle<Code> initialize_stub(Isolate* isolate,
- ExtraICState extra_state);
+ static Handle<Code> initialize_stub(Isolate* isolate);
static Handle<Code> initialize_stub_in_optimized_code(
- Isolate* isolate, State initialization_state, ExtraICState extra_state);
- static Handle<Code> ChooseMegamorphicStub(Isolate* isolate,
- ExtraICState extra_state);
+ Isolate* isolate, State initialization_state);
+ static Handle<Code> ChooseMegamorphicStub(Isolate* isolate);
static void Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus);
#define __ ACCESS_MASM(masm)
-void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
- // Push receiver and key for runtime call.
- __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // The slow case calls into the runtime to complete the store without causing
- // an IC miss that would otherwise cause a transition to the generic stub.
- ExternalReference ref =
- ExternalReference(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
-void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
- // Push receiver and key for runtime call.
- __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // The slow case calls into the runtime to complete the store without causing
- // an IC miss that would otherwise cause a transition to the generic stub.
- ExternalReference ref =
- ExternalReference(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
- Register result, Label* slow,
- LanguageMode language_mode) {
+ Register result, Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
//
// scratch2 - used to hold maps, prototypes, and the loaded value.
Label check_prototypes, check_next_prototype;
- Label done, in_bounds, absent;
+ Label done, in_bounds, return_undefined;
__ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(elements);
__ lw(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ LoadRoot(at, Heap::kNullValueRootIndex);
- __ Branch(&absent, eq, scratch2, Operand(at));
+ __ Branch(&return_undefined, eq, scratch2, Operand(at));
__ lw(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
__ lw(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
// elements: elements of current prototype
__ Branch(slow, ne, elements, Operand(at));
__ Branch(&check_next_prototype);
- __ bind(&absent);
- if (is_strong(language_mode)) {
- // Strong mode accesses must throw in this case, so call the runtime.
- __ Branch(slow);
- } else {
- __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
- __ Branch(&done);
- }
+ __ bind(&return_undefined);
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+ __ Branch(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
}
}
-void LoadIC::GenerateSlow(MacroAssembler* masm) {
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in ra.
__ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
__ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
- ExternalReference ref =
- ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
}
-void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in ra.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
- ExternalReference ref =
- ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
-void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
- LanguageMode language_mode) {
+void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is in ra.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(a0, a3, &check_number_dictionary);
- GenerateFastArrayLoad(masm, receiver, key, a0, a3, t0, v0, &slow,
- language_mode);
+ GenerateFastArrayLoad(masm, receiver, key, a0, a3, t0, v0, &slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, t0, a3);
__ Ret();
__ bind(&slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, t0,
a3);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow);
#define __ ACCESS_MASM(masm)
-void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
- // Push receiver and key for runtime call.
- __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // The slow case calls into the runtime to complete the store without causing
- // an IC miss that would otherwise cause a transition to the generic stub.
- ExternalReference ref =
- ExternalReference(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
-void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
- // Push receiver and key for runtime call.
- __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // The slow case calls into the runtime to complete the store without causing
- // an IC miss that would otherwise cause a transition to the generic stub.
- ExternalReference ref =
- ExternalReference(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
- Register result, Label* slow,
- LanguageMode language_mode) {
+ Register result, Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
//
// scratch2 - used to hold maps, prototypes, and the loaded value.
Label check_prototypes, check_next_prototype;
- Label done, in_bounds, absent;
+ Label done, in_bounds, return_undefined;
__ ld(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(elements);
__ ld(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ LoadRoot(at, Heap::kNullValueRootIndex);
- __ Branch(&absent, eq, scratch2, Operand(at));
+ __ Branch(&return_undefined, eq, scratch2, Operand(at));
__ ld(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
__ ld(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
// elements: elements of current prototype
__ Branch(slow, ne, elements, Operand(at));
__ Branch(&check_next_prototype);
- __ bind(&absent);
- if (is_strong(language_mode)) {
- __ Branch(slow);
- } else {
- __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
- __ Branch(&done);
- }
+ __ bind(&return_undefined);
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+ __ Branch(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
}
}
-void LoadIC::GenerateSlow(MacroAssembler* masm) {
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in ra.
__ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
}
-void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in ra.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
}
-void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
- LanguageMode language_mode) {
+void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is in ra.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(a0, a3, &check_number_dictionary);
- GenerateFastArrayLoad(masm, receiver, key, a0, a3, a4, v0, &slow,
- language_mode);
+ GenerateFastArrayLoad(masm, receiver, key, a0, a3, a4, v0, &slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, a4, a3);
__ Ret();
__ bind(&slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, a4,
a3);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow);
#define __ ACCESS_MASM(masm)
-void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
- // Push receiver and key for runtime call.
- __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // The slow case calls into the runtime to complete the store without causing
- // an IC miss that would otherwise cause a transition to the generic stub.
- ExternalReference ref =
- ExternalReference(IC_Utility(IC::LoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
- // Push receiver and key for runtime call.
- __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
-
- // The slow case calls into the runtime to complete the store without causing
- // an IC miss that would otherwise cause a transition to the generic stub.
- ExternalReference ref =
- ExternalReference(IC_Utility(IC::KeyedLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
- Register result, Label* slow,
- LanguageMode language_mode) {
+ Register result, Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
//
// scratch2 - used to hold maps, prototypes, and the loaded value.
Label check_prototypes, check_next_prototype;
- Label done, in_bounds, absent;
+ Label done, in_bounds, return_undefined;
__ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(elements);
__ LoadP(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ CompareRoot(scratch2, Heap::kNullValueRootIndex);
- __ beq(&absent);
+ __ beq(&return_undefined);
__ LoadP(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
__ LoadP(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
// elements: elements of current prototype
__ bne(slow);
__ jmp(&check_next_prototype);
- __ bind(&absent);
- if (is_strong(language_mode)) {
- // Strong mode accesses must throw in this case, so call the runtime.
- __ jmp(slow);
- } else {
- __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
- __ jmp(&done);
- }
+ __ bind(&return_undefined);
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+ __ jmp(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
}
}
-void LoadIC::GenerateSlow(MacroAssembler* masm) {
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
__ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
- ExternalReference ref =
- ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
}
-void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
- ExternalReference ref =
- ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
-void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
- LanguageMode language_mode) {
+void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is in lr.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(r3, r6, &check_number_dictionary);
- GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, &slow,
- language_mode);
+ GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, &slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r7, r6);
__ Ret();
__ bind(&slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r7,
r6);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, r3, r6, &index_name, &slow);
}
-static void LoadIC_PushArgs(MacroAssembler* masm) {
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register name = LoadDescriptor::NameRegister();
-
- DCHECK(!rbx.is(receiver) && !rbx.is(name));
-
- __ PopReturnAddressTo(rbx);
- __ Push(receiver);
- __ Push(name);
- __ PushReturnAddressFrom(rbx);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
- // Return address is on the stack.
- LoadIC_PushArgs(masm);
-
- // Do tail-call to runtime routine.
- ExternalReference ref(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
-void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
- // Return address is on the stack.
- LoadIC_PushArgs(masm);
-
- // Do tail-call to runtime routine.
- ExternalReference ref(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch, Register result,
- Label* slow, LanguageMode language_mode) {
+ Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
//
// scratch - used to hold maps, prototypes, and the loaded value.
Label check_prototypes, check_next_prototype;
- Label done, in_bounds, absent;
+ Label done, in_bounds, return_undefined;
__ movp(elements, FieldOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(elements);
__ movp(scratch, FieldOperand(scratch, Map::kPrototypeOffset));
// scratch: current prototype
__ CompareRoot(scratch, Heap::kNullValueRootIndex);
- __ j(equal, &absent);
+ __ j(equal, &return_undefined);
__ movp(elements, FieldOperand(scratch, JSObject::kElementsOffset));
__ movp(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
// elements: elements of current prototype
__ j(not_equal, slow);
__ jmp(&check_next_prototype);
- __ bind(&absent);
- if (is_strong(language_mode)) {
- // Strong mode accesses must throw in this case, so call the runtime.
- __ jmp(slow);
- } else {
- __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
- __ jmp(&done);
- }
+ __ bind(&return_undefined);
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+ __ jmp(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
}
-void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
- LanguageMode language_mode) {
+void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is on the stack.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(rax, &check_number_dictionary);
- GenerateFastArrayLoad(masm, receiver, key, rax, rbx, rax, &slow,
- language_mode);
+ GenerateFastArrayLoad(masm, receiver, key, rax, rbx, rax, &slow);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->keyed_load_generic_smi(), 1);
__ ret(0);
__ bind(&slow);
// Slow case: Jump to runtime.
__ IncrementCounter(counters->keyed_load_generic_slow(), 1);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, rax, rbx, &index_name, &slow);
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
}
}
-void LoadIC::GenerateSlow(MacroAssembler* masm) {
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
__ PushReturnAddressFrom(rbx);
// Perform tail call to the entry.
- ExternalReference ref =
- ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
}
-void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
__ PushReturnAddressFrom(rbx);
// Perform tail call to the entry.
- ExternalReference ref =
- ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
#define __ ACCESS_MASM(masm)
-static void LoadIC_PushArgs(MacroAssembler* masm) {
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register name = LoadDescriptor::NameRegister();
-
- DCHECK(!ebx.is(receiver) && !ebx.is(name));
-
- __ pop(ebx);
- __ push(receiver);
- __ push(name);
- __ push(ebx);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
- // Return address is on the stack.
- LoadIC_PushArgs(masm);
-
- // Do tail-call to runtime routine.
- ExternalReference ref(IC_Utility(IC::kLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
-void ElementHandlerCompiler::GenerateLoadSlow(MacroAssembler* masm) {
- // Return address is on the stack.
- LoadIC_PushArgs(masm);
-
- // Do tail-call to runtime routine.
- ExternalReference ref(IC_Utility(IC::kKeyedLoadIC_Slow), masm->isolate());
- __ TailCallExternalReference(ref, 2, 1);
-}
-
-
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register scratch,
Register scratch2, Register result,
- Label* slow, LanguageMode language_mode) {
+ Label* slow) {
// Register use:
// receiver - holds the receiver and is unchanged.
// key - holds the key and is unchanged (must be a smi).
// result - holds the result on exit if the load succeeds and
// we fall through.
Label check_prototypes, check_next_prototype;
- Label done, in_bounds, absent;
+ Label done, in_bounds, return_undefined;
__ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset));
__ AssertFastElements(scratch);
__ mov(scratch2, FieldOperand(scratch2, Map::kPrototypeOffset));
// scratch2: current prototype
__ cmp(scratch2, masm->isolate()->factory()->null_value());
- __ j(equal, &absent);
+ __ j(equal, &return_undefined);
__ mov(scratch, FieldOperand(scratch2, JSObject::kElementsOffset));
__ mov(scratch2, FieldOperand(scratch2, HeapObject::kMapOffset));
// scratch: elements of current prototype
__ j(not_equal, slow);
__ jmp(&check_next_prototype);
- __ bind(&absent);
- if (is_strong(language_mode)) {
- // Strong mode accesses must throw in this case, so call the runtime.
- __jmp(slow);
- } else {
- __ mov(result, masm->isolate()->factory()->undefined_value());
- __ jmp(&done);
- }
+ __ bind(&return_undefined);
+ __ mov(result, masm->isolate()->factory()->undefined_value());
+ __ jmp(&done);
__ bind(&in_bounds);
// Fast case: Do the load.
}
-void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
- LanguageMode language_mode) {
+void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// The return address is on the stack.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(eax, &check_number_dictionary);
- GenerateFastArrayLoad(masm, receiver, key, eax, ebx, eax, &slow,
- language_mode);
+ GenerateFastArrayLoad(masm, receiver, key, eax, ebx, eax, &slow);
Isolate* isolate = masm->isolate();
Counters* counters = isolate->counters();
__ IncrementCounter(counters->keyed_load_generic_smi(), 1);
__ bind(&slow);
// Slow case: jump to runtime.
__ IncrementCounter(counters->keyed_load_generic_slow(), 1);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
GenerateKeyNameCheck(masm, key, eax, ebx, &index_name, &slow);
// Dictionary load failed, go slow (but don't miss).
__ bind(&slow);
- GenerateSlow(masm);
+ GenerateRuntimeGetProperty(masm);
}
}
-void LoadIC::GenerateSlow(MacroAssembler* masm) {
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
__ push(ebx);
// Perform tail call to the entry.
- ExternalReference ref =
- ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
}
-void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
__ push(ebx);
// Perform tail call to the entry.
- ExternalReference ref =
- ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
- int arg_count = 2;
- __ TailCallExternalReference(ref, arg_count, 1);
+ __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
}
"instead") \
T(StrongForIn, \
"In strong mode, 'for'-'in' loops are deprecated, use 'for'-'of' instead") \
- T(StrongPropertyAccess, \
- "In strong mode, accessing missing property '%' of % is deprecated") \
T(StrongSuperCallDuplicate, \
"In strong mode, invoking the super constructor multiple times is " \
"deprecated") \
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
- KeyedLoadICStub stub(isolate(), state());
+ KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
__ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
__ Branch(&try_poly_name, ne, at, Operand(feedback));
Handle<Code> megamorphic_stub =
- KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
+ KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);
__ lw(load_name, MemOperand(sp, 2 * kPointerSize));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(a0, v0);
__ mov(a1, a0);
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_CONTEXTUAL);
}
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
- __ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, v0, v0, scratch);
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ sw(v0, MemOperand(sp, kPointerSize));
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, v0, v0, scratch);
VisitForStackValue(prop->key());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ sw(v0, MemOperand(sp, kPointerSize));
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
// Name is always in a2.
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
- Handle<Code> ic =
- CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
+ isolate(), NOT_CONTEXTUAL,
+ instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
- Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
- isolate(), instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic =
+ CodeFactory::KeyedLoadICInOptimizedCode(
+ isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
- KeyedLoadICStub stub(isolate(), state());
+ KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
__ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
__ Branch(&try_poly_name, ne, feedback, Operand(at));
Handle<Code> megamorphic_stub =
- KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
+ KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);
__ ld(load_name, MemOperand(sp, 2 * kPointerSize));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(a0, v0);
__ mov(a1, a0);
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_CONTEXTUAL);
}
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
// Call keyed load IC. It has register arguments receiver and key.
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
- __ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, v0, v0, scratch);
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ sd(v0, MemOperand(sp, kPointerSize));
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, v0, v0, scratch);
VisitForStackValue(prop->key());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ sd(v0, MemOperand(sp, kPointerSize));
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
// Name is always in a2.
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
- Handle<Code> ic =
- CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
+ isolate(), NOT_CONTEXTUAL,
+ instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
- Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
- isolate(), instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic =
+ CodeFactory::KeyedLoadICInOptimizedCode(
+ isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
- Handle<Name> name,
- LanguageMode language_mode) {
+ Handle<Name> name) {
LookupIterator it(object, name);
- return GetProperty(&it, language_mode);
+ return GetProperty(&it);
}
-MaybeHandle<Object> Object::GetElement(Isolate* isolate, Handle<Object> object,
- uint32_t index,
- LanguageMode language_mode) {
+MaybeHandle<Object> Object::GetElement(Isolate* isolate,
+ Handle<Object> object,
+ uint32_t index) {
LookupIterator it(isolate, object, index);
- return GetProperty(&it, language_mode);
+ return GetProperty(&it);
}
}
-MaybeHandle<Object> Object::GetProperty(Isolate* isolate, Handle<Object> object,
- const char* name,
- LanguageMode language_mode) {
+MaybeHandle<Object> Object::GetProperty(Isolate* isolate,
+ Handle<Object> object,
+ const char* name) {
Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
- return GetProperty(object, str, language_mode);
+ return GetProperty(object, str);
}
MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object,
- Handle<Name> name,
- LanguageMode language_mode) {
+ Handle<Name> name) {
LookupIterator it =
LookupIterator::PropertyOrElement(name->GetIsolate(), object, name);
- return GetProperty(&it, language_mode);
+ return GetProperty(&it);
}
}
-MaybeHandle<Object> Object::GetProperty(LookupIterator* it,
- LanguageMode language_mode) {
+MaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
for (; it->IsFound(); it->Next()) {
switch (it->state()) {
case LookupIterator::NOT_FOUND:
}
case LookupIterator::ACCESS_CHECK:
if (it->HasAccess()) break;
- return JSObject::GetPropertyWithFailedAccessCheck(it, language_mode);
+ return JSObject::GetPropertyWithFailedAccessCheck(it);
case LookupIterator::ACCESSOR:
- return GetPropertyWithAccessor(it, language_mode);
+ return GetPropertyWithAccessor(it);
case LookupIterator::INTEGER_INDEXED_EXOTIC:
- return ReadAbsentProperty(it, language_mode);
+ return it->factory()->undefined_value();
case LookupIterator::DATA:
return it->GetDataValue();
}
}
- return ReadAbsentProperty(it, language_mode);
+ return it->factory()->undefined_value();
}
}
-MaybeHandle<Object> Object::GetPropertyWithAccessor(
- LookupIterator* it, LanguageMode language_mode) {
+MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
Isolate* isolate = it->isolate();
Handle<Object> structure = it->GetAccessors();
Handle<Object> receiver = it->GetReceiver();
args.Call(call_fun, v8::Utils::ToLocal(name));
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (result.IsEmpty()) {
- return ReadAbsentProperty(isolate, receiver, name, language_mode);
+ return isolate->factory()->undefined_value();
}
Handle<Object> return_value = v8::Utils::OpenHandle(*result);
return_value->VerifyApiCallResultType();
receiver, Handle<JSReceiver>::cast(getter));
}
// Getter is not a function.
- return ReadAbsentProperty(isolate, receiver, it->GetName(), language_mode);
+ return isolate->factory()->undefined_value();
}
MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
- LookupIterator* it, LanguageMode language_mode) {
+ LookupIterator* it) {
Handle<JSObject> checked = it->GetHolder<JSObject>();
while (FindAllCanReadHolder(it)) {
if (it->state() == LookupIterator::ACCESSOR) {
- return GetPropertyWithAccessor(it, language_mode);
+ return GetPropertyWithAccessor(it);
}
DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
bool done;
}
-MaybeHandle<Object> Object::ReadAbsentProperty(LookupIterator* it,
- LanguageMode language_mode) {
- return ReadAbsentProperty(it->isolate(), it->GetReceiver(), it->GetName(),
- language_mode);
-}
-
-MaybeHandle<Object> Object::ReadAbsentProperty(Isolate* isolate,
- Handle<Object> receiver,
- Handle<Object> name,
- LanguageMode language_mode) {
- if (is_strong(language_mode)) {
- THROW_NEW_ERROR(
- isolate,
- NewTypeError(MessageTemplate::kStrongPropertyAccess, name, receiver),
- Object);
- }
- return isolate->factory()->undefined_value();
-}
-
-
MaybeHandle<Object> Object::WriteToReadOnlyProperty(
LookupIterator* it, Handle<Object> value, LanguageMode language_mode) {
return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
MUST_USE_RESULT static inline MaybeHandle<Smi> ToSmi(Isolate* isolate,
Handle<Object> object);
- MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
- LookupIterator* it, LanguageMode language_mode = SLOPPY);
+ MUST_USE_RESULT static MaybeHandle<Object> GetProperty(LookupIterator* it);
// Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5.
MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
StoreFromKeyed store_mode);
- MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
- LookupIterator* it, LanguageMode language_mode);
- MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
- Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
- LanguageMode language_mode);
MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
LookupIterator* it, Handle<Object> value, LanguageMode language_mode);
MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
- Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
+ Isolate* isolate, Handle<Object> reciever, Handle<Object> name,
Handle<Object> value, LanguageMode language_mode);
MUST_USE_RESULT static MaybeHandle<Object> RedefineNonconfigurableProperty(
Isolate* isolate, Handle<Object> name, Handle<Object> value,
LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
LanguageMode language_mode, StoreFromKeyed store_mode);
MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
- Handle<Object> object, Handle<Name> name,
- LanguageMode language_mode = SLOPPY);
+ Handle<Object> object, Handle<Name> name);
MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
- Isolate* isolate, Handle<Object> object, const char* key,
- LanguageMode language_mode = SLOPPY);
+ Isolate* isolate,
+ Handle<Object> object,
+ const char* key);
MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
- Handle<Object> object, Handle<Name> name,
- LanguageMode language_mode = SLOPPY);
+ Handle<Object> object, Handle<Name> name);
MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
- LookupIterator* it, LanguageMode language_mode);
+ LookupIterator* it);
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithAccessor(
LookupIterator* it, Handle<Object> value, LanguageMode language_mode);
Handle<Object> value);
MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
- Isolate* isolate, Handle<Object> object, uint32_t index,
- LanguageMode language_mode = SLOPPY);
+ Isolate* isolate,
+ Handle<Object> object,
+ uint32_t index);
static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
Isolate* isolate, Handle<Object> receiver);
// Used from Object::GetProperty().
MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
- LookupIterator* it, LanguageMode language_mode);
+ LookupIterator* it);
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
LookupIterator* it, Handle<Object> value);
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
- KeyedLoadICStub stub(isolate(), state());
+ KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ bne(&try_poly_name);
Handle<Code> megamorphic_stub =
- KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
+ KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);
__ LoadP(load_name, MemOperand(sp, 2 * kPointerSize));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mr(r4, r3);
__ StoreP(r4, MemOperand(sp, 2 * kPointerSize));
__ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_CONTEXTUAL);
}
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
- __ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, r3, r3, scratch);
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ StoreP(r3, MemOperand(sp, kPointerSize));
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, r3, r3, scratch);
VisitForStackValue(prop->key());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ StoreP(r3, MemOperand(sp, kPointerSize));
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
// Name is always in r5.
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
- Handle<Code> ic =
- CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
+ isolate(), NOT_CONTEXTUAL,
+ instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
- Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
- isolate(), instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic =
+ CodeFactory::KeyedLoadICInOptimizedCode(
+ isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, prototype_parent,
Runtime::GetObjectProperty(isolate, super_class,
- isolate->factory()->prototype_string(),
- SLOPPY));
+ isolate->factory()->prototype_string()));
if (!prototype_parent->IsNull() && !prototype_parent->IsSpecObject()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kPrototypeParentNotAnObject,
}
-static MaybeHandle<Object> LoadFromSuper(Isolate* isolate,
- Handle<Object> receiver,
- Handle<JSObject> home_object,
- Handle<Name> name,
- LanguageMode language_mode) {
+static Object* LoadFromSuper(Isolate* isolate, Handle<Object> receiver,
+ Handle<JSObject> home_object, Handle<Name> name) {
if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
isolate->ReportFailedAccessCheck(home_object);
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
PrototypeIterator iter(isolate, home_object);
Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
- if (!proto->IsJSReceiver()) {
- return Object::ReadAbsentProperty(isolate, proto, name, language_mode);
- }
+ if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
- Object::GetProperty(&it, language_mode), Object);
- return result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
+ return *result;
}
-static MaybeHandle<Object> LoadElementFromSuper(Isolate* isolate,
- Handle<Object> receiver,
- Handle<JSObject> home_object,
- uint32_t index,
- LanguageMode language_mode) {
+static Object* LoadElementFromSuper(Isolate* isolate, Handle<Object> receiver,
+ Handle<JSObject> home_object,
+ uint32_t index) {
if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
isolate->ReportFailedAccessCheck(home_object);
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
PrototypeIterator iter(isolate, home_object);
Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
- if (!proto->IsJSReceiver()) {
- Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
- return Object::ReadAbsentProperty(isolate, proto, name, language_mode);
- }
+ if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
LookupIterator it(isolate, receiver, index, Handle<JSReceiver>::cast(proto));
Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
- Object::GetProperty(&it, language_mode), Object);
- return result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
+ return *result;
}
RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
HandleScope scope(isolate);
- DCHECK(args.length() == 4);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
- CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- LoadFromSuper(isolate, receiver, home_object, name, language_mode));
- return *result;
+ return LoadFromSuper(isolate, receiver, home_object, name);
}
RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) {
HandleScope scope(isolate);
- DCHECK(args.length() == 4);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
- CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3);
uint32_t index = 0;
- Handle<Object> result;
-
if (key->ToArrayIndex(&index)) {
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, LoadElementFromSuper(isolate, receiver, home_object,
- index, language_mode));
- return *result;
+ return LoadElementFromSuper(isolate, receiver, home_object, index);
}
Handle<Name> name;
Runtime::ToName(isolate, key));
// TODO(verwaest): Unify using LookupIterator.
if (name->AsArrayIndex(&index)) {
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, LoadElementFromSuper(isolate, receiver, home_object,
- index, language_mode));
- return *result;
+ return LoadElementFromSuper(isolate, receiver, home_object, index);
}
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- LoadFromSuper(isolate, receiver, home_object, name, language_mode));
- return *result;
+ return LoadFromSuper(isolate, receiver, home_object, name);
}
return it->isolate()->factory()->undefined_value();
}
MaybeHandle<Object> maybe_result =
- JSObject::GetPropertyWithAccessor(it, SLOPPY);
+ JSObject::GetPropertyWithAccessor(it);
Handle<Object> result;
if (!maybe_result.ToHandle(&result)) {
result = handle(it->isolate()->pending_exception(), it->isolate());
MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
Handle<Object> object,
- uint32_t index,
- LanguageMode language_mode) {
+ uint32_t index) {
// Handle [] indexing on Strings
if (object->IsString() &&
index < static_cast<uint32_t>(String::cast(*object)->length())) {
if (!result->IsUndefined()) return result;
}
- return Object::GetElement(isolate, object, index, language_mode);
+ return Object::GetElement(isolate, object, index);
}
MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
Handle<Object> object,
- Handle<Object> key,
- LanguageMode language_mode) {
+ Handle<Object> key) {
if (object->IsUndefined() || object->IsNull()) {
THROW_NEW_ERROR(
isolate,
// Check if the given key is an array index.
uint32_t index = 0;
if (key->ToArrayIndex(&index)) {
- return GetElementOrCharAt(isolate, object, index, language_mode);
+ return GetElementOrCharAt(isolate, object, index);
}
// Convert the key to a name - possibly by calling back into JavaScript.
if (name->AsArrayIndex(&index)) {
return GetElementOrCharAt(isolate, object, index);
} else {
- return Object::GetProperty(object, name, language_mode);
- }
-}
-
-
-MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
- Handle<Object> object, ElementsKind to_kind, Isolate* isolate) {
- HandleScope scope(isolate);
- if (!object->IsJSObject()) {
- isolate->ThrowIllegalOperation();
- return MaybeHandle<Object>();
- }
- ElementsKind from_kind =
- Handle<JSObject>::cast(object)->map()->elements_kind();
- if (Map::IsValidElementsTransition(from_kind, to_kind)) {
- JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
- return object;
+ return Object::GetProperty(object, name);
}
- isolate->ThrowIllegalOperation();
- return MaybeHandle<Object>();
-}
-
-
-MaybeHandle<Object> Runtime::KeyedGetObjectProperty(
- Isolate* isolate, Handle<Object> receiver_obj, Handle<Object> key_obj,
- LanguageMode language_mode) {
- // Fast cases for getting named properties of the receiver JSObject
- // itself.
- //
- // The global proxy objects has to be excluded since LookupOwn on
- // the global proxy object can return a valid result even though the
- // global proxy object never has properties. This is the case
- // because the global proxy object forwards everything to its hidden
- // prototype including own lookups.
- //
- // Additionally, we need to make sure that we do not cache results
- // for objects that require access checks.
- if (receiver_obj->IsJSObject()) {
- if (!receiver_obj->IsJSGlobalProxy() &&
- !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
- DisallowHeapAllocation no_allocation;
- Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
- Handle<Name> key = Handle<Name>::cast(key_obj);
- if (receiver->IsGlobalObject()) {
- // Attempt dictionary lookup.
- GlobalDictionary* dictionary = receiver->global_dictionary();
- int entry = dictionary->FindEntry(key);
- if (entry != GlobalDictionary::kNotFound) {
- DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
- PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
- if (cell->property_details().type() == DATA) {
- Object* value = cell->value();
- if (!value->IsTheHole()) return Handle<Object>(value, isolate);
- // If value is the hole (meaning, absent) do the general lookup.
- }
- }
- } else if (!receiver->HasFastProperties()) {
- // Attempt dictionary lookup.
- NameDictionary* dictionary = receiver->property_dictionary();
- int entry = dictionary->FindEntry(key);
- if ((entry != NameDictionary::kNotFound) &&
- (dictionary->DetailsAt(entry).type() == DATA)) {
- Object* value = dictionary->ValueAt(entry);
- return Handle<Object>(value, isolate);
- }
- }
- } else if (key_obj->IsSmi()) {
- // JSObject without a name key. If the key is a Smi, check for a
- // definite out-of-bounds access to elements, which is a strong indicator
- // that subsequent accesses will also call the runtime. Proactively
- // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
- // doubles for those future calls in the case that the elements would
- // become FAST_DOUBLE_ELEMENTS.
- Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
- ElementsKind elements_kind = js_object->GetElementsKind();
- if (IsFastDoubleElementsKind(elements_kind)) {
- Handle<Smi> key = Handle<Smi>::cast(key_obj);
- if (key->value() >= js_object->elements()->length()) {
- if (IsFastHoleyElementsKind(elements_kind)) {
- elements_kind = FAST_HOLEY_ELEMENTS;
- } else {
- elements_kind = FAST_ELEMENTS;
- }
- RETURN_ON_EXCEPTION(
- isolate, TransitionElements(js_object, elements_kind, isolate),
- Object);
- }
- } else {
- DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
- !IsFastElementsKind(elements_kind));
- }
- }
- } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
- // Fast case for string indexing using [] with a smi index.
- Handle<String> str = Handle<String>::cast(receiver_obj);
- int index = Handle<Smi>::cast(key_obj)->value();
- if (index >= 0 && index < str->length()) {
- return GetCharAt(str, index);
- }
- }
-
- // Fall back to GetObjectProperty.
- return GetObjectProperty(isolate, receiver_obj, key_obj, language_mode);
}
RUNTIME_FUNCTION(Runtime_GetProperty) {
HandleScope scope(isolate);
- DCHECK(args.length() == 3);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2);
-
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- Runtime::GetObjectProperty(isolate, object, key, language_mode));
+ isolate, result, Runtime::GetObjectProperty(isolate, object, key));
return *result;
}
+MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
+ Handle<Object> object, ElementsKind to_kind, Isolate* isolate) {
+ HandleScope scope(isolate);
+ if (!object->IsJSObject()) {
+ isolate->ThrowIllegalOperation();
+ return MaybeHandle<Object>();
+ }
+ ElementsKind from_kind =
+ Handle<JSObject>::cast(object)->map()->elements_kind();
+ if (Map::IsValidElementsTransition(from_kind, to_kind)) {
+ JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
+ return object;
+ }
+ isolate->ThrowIllegalOperation();
+ return MaybeHandle<Object>();
+}
+
+
+// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
HandleScope scope(isolate);
- DCHECK(args.length() == 3);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
- CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2);
+ // Fast cases for getting named properties of the receiver JSObject
+ // itself.
+ //
+ // The global proxy objects has to be excluded since LookupOwn on
+ // the global proxy object can return a valid result even though the
+ // global proxy object never has properties. This is the case
+ // because the global proxy object forwards everything to its hidden
+ // prototype including own lookups.
+ //
+ // Additionally, we need to make sure that we do not cache results
+ // for objects that require access checks.
+ if (receiver_obj->IsJSObject()) {
+ if (!receiver_obj->IsJSGlobalProxy() &&
+ !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
+ DisallowHeapAllocation no_allocation;
+ Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
+ Handle<Name> key = Handle<Name>::cast(key_obj);
+ if (receiver->IsGlobalObject()) {
+ // Attempt dictionary lookup.
+ GlobalDictionary* dictionary = receiver->global_dictionary();
+ int entry = dictionary->FindEntry(key);
+ if (entry != GlobalDictionary::kNotFound) {
+ DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
+ PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
+ if (cell->property_details().type() == DATA) {
+ Object* value = cell->value();
+ if (!value->IsTheHole()) return value;
+ // If value is the hole (meaning, absent) do the general lookup.
+ }
+ }
+ } else if (!receiver->HasFastProperties()) {
+ // Attempt dictionary lookup.
+ NameDictionary* dictionary = receiver->property_dictionary();
+ int entry = dictionary->FindEntry(key);
+ if ((entry != NameDictionary::kNotFound) &&
+ (dictionary->DetailsAt(entry).type() == DATA)) {
+ Object* value = dictionary->ValueAt(entry);
+ return value;
+ }
+ }
+ } else if (key_obj->IsSmi()) {
+ // JSObject without a name key. If the key is a Smi, check for a
+ // definite out-of-bounds access to elements, which is a strong indicator
+ // that subsequent accesses will also call the runtime. Proactively
+ // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
+ // doubles for those future calls in the case that the elements would
+ // become FAST_DOUBLE_ELEMENTS.
+ Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
+ ElementsKind elements_kind = js_object->GetElementsKind();
+ if (IsFastDoubleElementsKind(elements_kind)) {
+ Handle<Smi> key = Handle<Smi>::cast(key_obj);
+ if (key->value() >= js_object->elements()->length()) {
+ if (IsFastHoleyElementsKind(elements_kind)) {
+ elements_kind = FAST_HOLEY_ELEMENTS;
+ } else {
+ elements_kind = FAST_ELEMENTS;
+ }
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, TransitionElements(js_object, elements_kind, isolate));
+ }
+ } else {
+ DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
+ !IsFastElementsKind(elements_kind));
+ }
+ }
+ } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
+ // Fast case for string indexing using [] with a smi index.
+ Handle<String> str = Handle<String>::cast(receiver_obj);
+ int index = args.smi_at(1);
+ if (index >= 0 && index < str->length()) {
+ return *GetCharAt(str, index);
+ }
+ }
+
+ // Fall back to GetObjectProperty.
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, Runtime::KeyedGetObjectProperty(isolate, receiver_obj,
- key_obj, language_mode));
+ isolate, result,
+ Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
return *result;
}
F(DefineClass, 6, 1) \
F(DefineClassMethod, 3, 1) \
F(ClassGetSourceCode, 1, 1) \
- F(LoadFromSuper, 4, 1) \
- F(LoadKeyedFromSuper, 4, 1) \
+ F(LoadFromSuper, 3, 1) \
+ F(LoadKeyedFromSuper, 3, 1) \
F(StoreToSuper_Strict, 4, 1) \
F(StoreToSuper_Sloppy, 4, 1) \
F(StoreKeyedToSuper_Strict, 4, 1) \
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
F(ObjectFreeze, 1, 1) \
F(ObjectSeal, 1, 1) \
- F(GetProperty, 3, 1) \
- F(KeyedGetProperty, 3, 1) \
+ F(GetProperty, 2, 1) \
+ F(KeyedGetProperty, 2, 1) \
F(AddNamedProperty, 4, 1) \
F(SetProperty, 4, 1) \
F(AddElement, 3, 1) \
// Support getting the characters in a string using [] notation as
// in Firefox/SpiderMonkey, Safari and Opera.
MUST_USE_RESULT static MaybeHandle<Object> GetElementOrCharAt(
- Isolate* isolate, Handle<Object> object, uint32_t index,
- LanguageMode language_mode = SLOPPY);
+ Isolate* isolate, Handle<Object> object, uint32_t index);
MUST_USE_RESULT static MaybeHandle<Object> SetObjectProperty(
Isolate* isolate, Handle<Object> object, Handle<Object> key,
Handle<Object> value, LanguageMode language_mode);
MUST_USE_RESULT static MaybeHandle<Object> GetObjectProperty(
- Isolate* isolate, Handle<Object> object, Handle<Object> key,
- LanguageMode language_mode = SLOPPY);
-
- MUST_USE_RESULT static MaybeHandle<Object> KeyedGetObjectProperty(
- Isolate* isolate, Handle<Object> receiver_obj, Handle<Object> key_obj,
- LanguageMode language_mode);
+ Isolate* isolate, Handle<Object> object, Handle<Object> key);
MUST_USE_RESULT static MaybeHandle<Object> GetPrototype(
Isolate* isolate, Handle<Object> object);
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
- KeyedLoadICStub stub(isolate(), state());
+ KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ j(not_equal, &try_poly_name);
Handle<Code> megamorphic_stub =
- KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
+ KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);
__ movp(load_receiver, Operand(rsp, kPointerSize));
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ movp(rdi, rax);
__ movp(Operand(rsp, 2 * kPointerSize), rdi);
__ Move(LoadDescriptor::NameRegister(), key->value());
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_CONTEXTUAL);
}
DCHECK(prop->IsSuperAccess());
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallIC(ic);
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
- __ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
__ Push(rax);
__ Push(Operand(rsp, kPointerSize * 2));
__ Push(key->value());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ movp(Operand(rsp, kPointerSize), rax);
__ Push(rax);
__ Push(Operand(rsp, kPointerSize * 2));
VisitForStackValue(prop->key());
- __ Push(Smi::FromInt(language_mode()));
// Stack here:
// - home_object
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ movp(Operand(rsp, kPointerSize), rax);
__ Move(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
__ Move(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
- Handle<Code> ic =
- CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
+ isolate(), NOT_CONTEXTUAL,
+ instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
- Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(
- isolate(), instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic =
+ CodeFactory::KeyedLoadICInOptimizedCode(
+ isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister());
- KeyedLoadICStub stub(isolate(), state());
+ KeyedLoadICStub stub(isolate());
stub.GenerateForTrampoline(masm);
}
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ j(not_equal, &try_poly_name);
Handle<Code> megamorphic_stub =
- KeyedLoadIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
+ KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
__ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
__ bind(&try_poly_name);
__ mov(load_receiver, Operand(esp, kPointerSize));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(edi, eax);
__ mov(Operand(esp, 2 * kPointerSize), edi);
__ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_CONTEXTUAL);
}
DCHECK(prop->IsSuperAccess());
__ push(Immediate(key->value()));
- __ push(Immediate(Smi::FromInt(language_mode())));
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
- __ push(Immediate(Smi::FromInt(language_mode())));
SetSourcePosition(prop->position());
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
}
__ push(eax);
__ push(Operand(esp, kPointerSize * 2));
__ push(Immediate(key->value()));
- __ push(Immediate(Smi::FromInt(language_mode())));
// Stack here:
// - home_object
// - this (receiver)
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ mov(Operand(esp, kPointerSize), eax);
__ push(eax);
__ push(Operand(esp, kPointerSize * 2));
VisitForStackValue(prop->key());
- __ push(Immediate(Smi::FromInt(language_mode())));
// Stack here:
// - home_object
// - this (receiver)
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
- // - language_mode
- __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
// Replace home_object with target function.
__ mov(Operand(esp, kPointerSize), eax);
__ mov(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
__ mov(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
- Handle<Code> ic =
- CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
+ isolate(), NOT_CONTEXTUAL,
+ instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
- Handle<Code> ic = Handle<Code> ic =
+ Handle<Code> ic =
CodeFactory::KeyedLoadICInOptimizedCode(
- isolate(), instr->hydrogen()->language_mode(),
- instr->hydrogen()->initialization_state()).code();
+ isolate(), instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
CheckCorrectThrow("other[1]");
CheckCorrectThrow("JSON.stringify(other)");
CheckCorrectThrow("has_own_property(other, 'x')");
- CheckCorrectThrow("%GetProperty(other, 'x', 0)");
+ CheckCorrectThrow("%GetProperty(other, 'x')");
CheckCorrectThrow("%SetProperty(other, 'x', 'foo', 0)");
CheckCorrectThrow("%AddNamedProperty(other, 'x', 'foo', 1)");
CheckCorrectThrow("%DeleteProperty(other, 'x', 0)");
(function LexicalBindings(global) {
assertEquals('function', typeof f);
assertEquals('function', typeof g);
- assertFalse(global.hasOwnProperty("f"));
- assertFalse(global.hasOwnProperty("g"));
+ assertEquals(undefined, global.f);
+ assertEquals(undefined, global.g);
})(this);
(function ImmutableBindings() {
+++ /dev/null
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --strong-mode --allow-natives-syntax
-
-function getGlobal() {
- return this;
-}
-
-function polluteGlobal() {
- bar = 0;
-}
-
-(function() {
- "use strict";
-
- let builtins = [
- Array,
- Object,
- Function,
- getGlobal()
- ];
-
- for (let builtin of builtins) {
- assertThrows(function(){"use strong"; builtin.foo}, TypeError);
- assertThrows(function(){"use strong"; builtin[0]}, TypeError);
- assertThrows(function(){"use strong"; builtin[10000]}, TypeError);
- builtin.foo = 1;
- assertDoesNotThrow(function(){"use strong"; builtin.foo});
- assertThrows(function(){"use strong"; builtin.bar});
- assertThrows(function(){"use strong"; builtin[0]}, TypeError);
- assertThrows(function(){"use strong"; builtin[10000]}, TypeError);
- builtin[0] = 1;
- assertDoesNotThrow(function(){"use strong"; builtin.foo});
- assertThrows(function(){"use strong"; builtin.bar});
- assertDoesNotThrow(function(){"use strong"; builtin[0]});
- assertThrows(function(){"use strong"; builtin[10000]}, TypeError);
- }
- polluteGlobal();
- assertDoesNotThrow(function(){"use strong"; getGlobal().bar});
-})();
+++ /dev/null
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --strong-mode --allow-natives-syntax
-
-function getSloppyArguments() {
- return arguments;
-}
-
-function getObjects() {
- "use strict";
- return [
- {},
- Object(""),
- [],
- (function(){}),
- (class Foo {}),
- getSloppyArguments(),
- arguments,
- new Date(),
- ];
-}
-
-// TODO(conradw): add tests for non-inheritance once semantics are implemented.
-function getNonInheritingObjects() {
- "use strong";
- return [
- Object(""),
- [],
- // TODO(conradw): uncomment and correct test once Object.defineProperty is
- // fixed.
- // new Uint32Array(0)
- ];
-}
-
-function readFromObjectElementSloppy(o) {
- return o[0];
-}
-
-function readFromObjectElementSparseSloppy(o) {
- return o[100000];
-}
-
-function readFromObjectElementNonSmiSloppy(o) {
- return o[3000000000];
-}
-
-function readFromObjectNonIndexSloppy(o) {
- return o[5000000000];
-}
-
-function readFromObjectElementVarSloppy(o) {
- var a = 0;
- return o[a];
-}
-
-function readFromObjectElementSparseVarSloppy(o) {
- var a = 100000;
- return o[a];
-}
-
-function readFromObjectElementNonSmiVarSloppy(o) {
- var a = 3000000000;
- return o[a];
-}
-
-function readFromObjectNonIndexVarSloppy(o) {
- var a = 5000000000;
- return o[a];
-}
-
-function readFromObjectElementStrong(o) {
- "use strong";
- return o[0];
-}
-
-function readFromObjectElementSparseStrong(o) {
- "use strong";
- return o[100000];
-}
-
-function readFromObjectElementNonSmiStrong(o) {
- "use strong";
- return o[3000000000];
-}
-
-function readFromObjectNonIndexStrong(o) {
- "use strong";
- return o[5000000000];
-}
-
-function readFromObjectElementLetStrong(o) {
- "use strong";
- let a = 0;
- return o[a];
-}
-
-function readFromObjectElementSparseLetStrong(o) {
- "use strong";
- let a = 100000;
- return o[a];
-}
-
-function readFromObjectElementNonSmiLetStrong(o) {
- "use strong";
- let a = 3000000000;
- return o[a];
-}
-
-function readFromObjectNonIndexLetStrong(o) {
- "use strong";
- let a = 5000000000;
- return o[a];
-}
-
-function getDescs(x) {
- return [
- {value: x},
- {configurable: true, enumerable: true, writable: true, value: x},
- {configurable: true, enumerable: true, get: (function() {return x}) },
- ];
-}
-
-function assertStrongSemantics(func, object) {
- %DeoptimizeFunction(func);
- %ClearFunctionTypeFeedback(func);
- assertThrows(function(){func(object)}, TypeError);
- assertThrows(function(){func(object)}, TypeError);
- assertThrows(function(){func(object)}, TypeError);
- %OptimizeFunctionOnNextCall(func);
- assertThrows(function(){func(object)}, TypeError);
- %DeoptimizeFunction(func);
- assertThrows(function(){func(object)}, TypeError);
-}
-
-function assertSloppySemantics(func, object) {
- %DeoptimizeFunction(func);
- %ClearFunctionTypeFeedback(func);
- assertDoesNotThrow(function(){func(object)});
- assertDoesNotThrow(function(){func(object)});
- assertDoesNotThrow(function(){func(object)});
- %OptimizeFunctionOnNextCall(func);
- assertDoesNotThrow(function(){func(object)});
- %DeoptimizeFunction(func);
- assertDoesNotThrow(function(){func(object)});
-}
-
-(function () {
- "use strict";
-
- let goodKeys = [
- "0",
- "100000",
- "3000000000",
- "5000000000"
- ]
-
- let badKeys = [
- "bar",
- "1",
- "100001",
- "3000000001",
- "5000000001"
- ];
-
- let values = [
- "string",
- 1,
- 100001,
- 30000000001,
- 50000000001,
- NaN,
- {},
- undefined
- ];
-
- let badAccessorDescs = [
- { set: (function(){}) },
- { configurable: true, enumerable: true, set: (function(){}) }
- ];
-
- let readSloppy = [
- readFromObjectElementSloppy,
- readFromObjectElementSparseSloppy,
- readFromObjectElementNonSmiSloppy,
- readFromObjectNonIndexSloppy,
- readFromObjectElementVarSloppy,
- readFromObjectElementSparseVarSloppy,
- readFromObjectElementNonSmiVarSloppy,
- readFromObjectNonIndexVarSloppy
- ];
-
- let readStrong = [
- readFromObjectElementStrong,
- readFromObjectElementSparseStrong,
- readFromObjectElementNonSmiStrong,
- readFromObjectNonIndexStrong,
- readFromObjectElementLetStrong,
- readFromObjectElementSparseLetStrong,
- readFromObjectElementNonSmiLetStrong,
- readFromObjectNonIndexLetStrong
- ];
-
- let dummyProto = {};
- for (let key of goodKeys) {
- Object.defineProperty(dummyProto, key, { value: undefined });
- }
-
- // After altering the backing store, accessing a missing property should still
- // throw.
- for (let key of badKeys) {
- for (let value of values) {
- for (let desc of getDescs(value)) {
- let objects = getObjects();
- let nonInheritingObjects = getNonInheritingObjects();
- for (let object of objects.concat(nonInheritingObjects)) {
- Object.defineProperty(object, key, desc);
- for (let func of readStrong) {
- assertStrongSemantics(func, object);
- }
- for (let func of readSloppy) {
- assertSloppySemantics(func, object);
- }
- }
- for (let object of objects) {
- // Accessing a property which is on the prototype chain of the object
- // should not throw.
- object.__proto__ = dummyProto;
- for (let key of goodKeys) {
- for (let func of readStrong.concat(readSloppy)) {
- assertSloppySemantics(func, object);
- }
- }
- }
- }
- }
- }
-})();
+++ /dev/null
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --strong-mode --allow-natives-syntax
-
-function getSloppyArguments() {
- return arguments;
-}
-
-function getObjects() {
- "use strict";
- return [
- {},
- Object(""),
- [],
- (function(){}),
- (class Foo {}),
- getSloppyArguments(),
- arguments,
- new Date()
- ];
-}
-
-//TODO(conradw): add tests for non-inheritance once semantics are implemented.
-function getNonInheritingObjects() {
- "use strong";
- return [
- Object(""),
- [],
- new Uint32Array(0)
- ];
-}
-
-function readFromObjectElementSloppy(o) {
- return o[0];
-}
-
-function readFromObjectElementSparseSloppy(o) {
- return o[100000];
-}
-
-function readFromObjectElementNonSmiSloppy(o) {
- return o[3000000000];
-}
-
-function readFromObjectNonIndexSloppy(o) {
- return o[5000000000];
-}
-
-function readFromObjectElementVarSloppy(o) {
- var a = 0;
- return o[a];
-}
-
-function readFromObjectElementSparseVarSloppy(o) {
- var a = 100000;
- return o[a];
-}
-
-function readFromObjectElementNonSmiVarSloppy(o) {
- var a = 3000000000;
- return o[a];
-}
-
-function readFromObjectNonIndexVarSloppy(o) {
- var a = 5000000000;
- return o[a];
-}
-
-function readFromObjectElementStrong(o) {
- "use strong";
- return o[0];
-}
-
-function readFromObjectElementSparseStrong(o) {
- "use strong";
- return o[100000];
-}
-
-function readFromObjectElementNonSmiStrong(o) {
- "use strong";
- return o[3000000000];
-}
-
-function readFromObjectNonIndexStrong(o) {
- "use strong";
- return o[5000000000];
-}
-
-function readFromObjectElementLetStrong(o) {
- "use strong";
- let a = 0;
- return o[a];
-}
-
-function readFromObjectElementSparseLetStrong(o) {
- "use strong";
- let a = 100000;
- return o[a];
-}
-
-function readFromObjectElementNonSmiLetStrong(o) {
- "use strong";
- let a = 3000000000;
- return o[a];
-}
-
-function readFromObjectNonIndexLetStrong(o) {
- "use strong";
- let a = 5000000000;
- return o[a];
-}
-
-function getDescs(x) {
- return [
- {value: x},
- {configurable: true, enumerable: true, writable: true, value: x},
- {configurable: true, enumerable: true, get: (function() {return x}) },
- ];
-}
-
-function assertStrongSemantics(func, object) {
- %DeoptimizeFunction(func);
- %ClearFunctionTypeFeedback(func);
- assertThrows(function(){func(object)}, TypeError);
- assertThrows(function(){func(object)}, TypeError);
- assertThrows(function(){func(object)}, TypeError);
- %OptimizeFunctionOnNextCall(func);
- assertThrows(function(){func(object)}, TypeError);
- %DeoptimizeFunction(func);
- assertThrows(function(){func(object)}, TypeError);
-}
-
-function assertSloppySemantics(func, object) {
- %DeoptimizeFunction(func);
- %ClearFunctionTypeFeedback(func);
- assertDoesNotThrow(function(){func(object)});
- assertDoesNotThrow(function(){func(object)});
- assertDoesNotThrow(function(){func(object)});
- %OptimizeFunctionOnNextCall(func);
- assertDoesNotThrow(function(){func(object)});
- %DeoptimizeFunction(func);
- assertDoesNotThrow(function(){func(object)});
-}
-
-(function () {
- "use strict";
-
- let goodKeys = [
- "0",
- "100000",
- "3000000000",
- "5000000000"
- ]
-
- let badKeys = [
- "bar",
- "1",
- "100001",
- "3000000001",
- "5000000001"
- ];
-
- let values = [
- "string",
- 1,
- 100001,
- 30000000001,
- 50000000001,
- NaN,
- {},
- undefined
- ];
-
- let literals = [0, NaN, true, ""];
-
- let badAccessorDescs = [
- { set: (function(){}) },
- { configurable: true, enumerable: true, set: (function(){}) }
- ];
-
- let readSloppy = [
- readFromObjectElementSloppy,
- readFromObjectElementSparseSloppy,
- readFromObjectElementNonSmiSloppy,
- readFromObjectNonIndexSloppy,
- readFromObjectElementVarSloppy,
- readFromObjectElementSparseVarSloppy,
- readFromObjectElementNonSmiVarSloppy,
- readFromObjectNonIndexVarSloppy
- ];
-
- let readStrong = [
- readFromObjectElementStrong,
- readFromObjectElementSparseStrong,
- readFromObjectElementNonSmiStrong,
- readFromObjectNonIndexStrong,
- readFromObjectElementLetStrong,
- readFromObjectElementSparseLetStrong,
- readFromObjectElementNonSmiLetStrong,
- readFromObjectNonIndexLetStrong
- ];
-
- let dummyProto = {};
- for (let key of goodKeys) {
- Object.defineProperty(dummyProto, key, { value: undefined });
- }
-
- let dummyAccessorProto = {};
- for (let key of goodKeys) {
- Object.defineProperty(dummyAccessorProto, key, { set: (function(){}) })
- }
-
- // String literals/objects should not throw on character index access
- assertDoesNotThrow(function() {"use strong"; return "string"[0]; });
- assertDoesNotThrow(function() {"use strong"; return Object("string")[0]; });
-
- // Attempting to access a property on an object with no defined properties
- // should throw.
- for (let object of getObjects().concat(getNonInheritingObjects(), literals)) {
- for (let func of readStrong) {
- assertStrongSemantics(func, object);
- }
- for (let func of readSloppy) {
- assertSloppySemantics(func, object);
- }
- }
- for (let object of getObjects()) {
- // Accessing a property which is on the prototype chain of the object should
- // not throw.
- object.__proto__ = dummyProto;
- for (let key of goodKeys) {
- for (let func of readStrong.concat(readSloppy)) {
- assertSloppySemantics(func, object);
- }
- }
- }
- // Properties with accessor descriptors missing 'get' should throw on access.
- for (let desc of badAccessorDescs) {
- for (let key of goodKeys) {
- for (let object of getObjects()) {
- Object.defineProperty(object, key, desc);
- for (let func of readStrong) {
- assertStrongSemantics(func, object);
- }
- for (let func of readSloppy) {
- assertSloppySemantics(func, object);
- }
- }
- }
- }
- // The same behaviour should be expected for bad accessor properties on the
- // prototype chain.
- for (let object of getObjects()) {
- object.__proto__ = dummyAccessorProto;
- for (let func of readStrong) {
- assertStrongSemantics(func, object);
- }
- for (let func of readSloppy) {
- assertSloppySemantics(func, object);
- }
- }
-})();
+++ /dev/null
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --strong-mode --allow-natives-syntax
-
-function getSloppyArguments() {
- return arguments;
-}
-
-function getObjects() {
- "use strict";
- return [
- {},
- Object(""),
- [],
- (function(){}),
- (class Foo {}),
- getSloppyArguments(),
- arguments,
- new Date(),
- // TODO(conradw): uncomment once Object.defineProperty is fixed.
- // new Uint32Array(0)
- ];
-}
-
-function readFromObjectSloppy(o) {
- return o.foo;
-}
-
-function readFromObjectKeyedSloppy(o) {
- return o["foo"];
-}
-
-function readFromObjectKeyedVarSloppy(o) {
- var a = "foo";
- return o[a];
-}
-
-function readFromObjectKeyedComputedSloppy(o) {
- var a = "o";
- return o["fo" + a];
-}
-
-function readFromObjectStrong(o) {
- "use strong";
- return o.foo;
-}
-
-function readFromObjectKeyedStrong(o) {
- "use strong";
- return o["foo"];
-}
-
-function readFromObjectKeyedLetStrong(o) {
- "use strong";
- let a = "foo";
- return o[a];
-}
-
-function readFromObjectKeyedComputedStrong(o) {
- "use strong";
- let a = "o";
- return o["fo" + a];
-}
-
-function getDescs(x) {
- return [
- {value: x},
- {configurable: true, enumerable: true, writable: true, value: x},
- {configurable: true, enumerable: true, get: (function() {return x}) },
- ];
-}
-
-function assertStrongSemantics(func, object) {
- %DeoptimizeFunction(func);
- %ClearFunctionTypeFeedback(func);
- assertThrows(function(){func(object)}, TypeError);
- assertThrows(function(){func(object)}, TypeError);
- assertThrows(function(){func(object)}, TypeError);
- %OptimizeFunctionOnNextCall(func);
- assertThrows(function(){func(object)}, TypeError);
- %DeoptimizeFunction(func);
- assertThrows(function(){func(object)}, TypeError);
-}
-
-function assertSloppySemantics(func, object) {
- %DeoptimizeFunction(func);
- %ClearFunctionTypeFeedback(func);
- assertDoesNotThrow(function(){func(object)});
- assertDoesNotThrow(function(){func(object)});
- assertDoesNotThrow(function(){func(object)});
- %OptimizeFunctionOnNextCall(func);
- assertDoesNotThrow(function(){func(object)});
- %DeoptimizeFunction(func);
- assertDoesNotThrow(function(){func(object)});
-}
-
-(function () {
- "use strict";
-
- let goodKeys = [
- "foo"
- ]
-
- let badKeys = [
- "bar",
- "1",
- "100001",
- "3000000001",
- "5000000001"
- ];
-
- let values = [
- "string",
- 1,
- 100001,
- 30000000001,
- 50000000001,
- NaN,
- {},
- undefined
- ];
-
- let badAccessorDescs = [
- { set: (function(){}) },
- { configurable: true, enumerable: true, set: (function(){}) }
- ];
-
- let readSloppy = [
- readFromObjectSloppy,
- readFromObjectKeyedSloppy,
- readFromObjectKeyedVarSloppy,
- readFromObjectKeyedComputedSloppy
- ];
-
- let readStrong = [
- readFromObjectStrong,
- readFromObjectKeyedStrong,
- readFromObjectKeyedLetStrong,
- readFromObjectKeyedComputedStrong
- ];
-
- let dummyProto = {};
- for (let key of goodKeys) {
- Object.defineProperty(dummyProto, key, { value: undefined });
- }
-
- // After altering the backing store, accessing a missing property should still
- // throw.
- for (let key of badKeys) {
- for (let value of values) {
- for (let desc of getDescs(value)) {
- for (let object of getObjects()) {
- Object.defineProperty(object, key, desc);
- for (let func of readStrong) {
- assertStrongSemantics(func, object);
- }
- for (let func of readSloppy) {
- assertSloppySemantics(func, object);
- }
- // Accessing a property which is on the prototype chain of the object
- // should not throw.
- object.__proto__ = dummyProto;
- for (let key of goodKeys) {
- for (let func of readStrong.concat(readSloppy)) {
- assertSloppySemantics(func, object);
- }
- }
- }
- }
- }
- }
-})();
+++ /dev/null
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --strong-mode --allow-natives-syntax
-
-function getSloppyArguments() {
- return arguments;
-}
-
-function getObjects() {
- "use strict";
- return [
- {},
- Object(""),
- [],
- (function(){}),
- (class Foo {}),
- getSloppyArguments(),
- arguments,
- new Date(),
- new Uint32Array(0)
- ];
-}
-
-function readFromObjectSloppy(o) {
- return o.foo;
-}
-
-function readFromObjectKeyedSloppy(o) {
- return o["foo"];
-}
-
-function readFromObjectKeyedVarSloppy(o) {
- var a = "foo";
- return o[a];
-}
-
-function readFromObjectKeyedComputedSloppy(o) {
- var a = "o";
- return o["fo" + a];
-}
-
-function readFromObjectStrong(o) {
- "use strong";
- return o.foo;
-}
-
-function readFromObjectKeyedStrong(o) {
- "use strong";
- return o["foo"];
-}
-
-function readFromObjectKeyedLetStrong(o) {
- "use strong";
- let a = "foo";
- return o[a];
-}
-
-function readFromObjectKeyedComputedStrong(o) {
- "use strong";
- let a = "o";
- return o["fo" + a];
-}
-
-function getDescs(x) {
- return [
- {value: x},
- {configurable: true, enumerable: true, writable: true, value: x},
- {configurable: true, enumerable: true, get: (function() {return x}) },
- ];
-}
-
-function assertStrongSemantics(func, object) {
- %DeoptimizeFunction(func);
- %ClearFunctionTypeFeedback(func);
- assertThrows(function(){func(object)}, TypeError);
- assertThrows(function(){func(object)}, TypeError);
- assertThrows(function(){func(object)}, TypeError);
- %OptimizeFunctionOnNextCall(func);
- assertThrows(function(){func(object)}, TypeError);
- %DeoptimizeFunction(func);
- assertThrows(function(){func(object)}, TypeError);
-}
-
-function assertSloppySemantics(func, object) {
- %DeoptimizeFunction(func);
- %ClearFunctionTypeFeedback(func);
- assertDoesNotThrow(function(){func(object)});
- assertDoesNotThrow(function(){func(object)});
- assertDoesNotThrow(function(){func(object)});
- %OptimizeFunctionOnNextCall(func);
- assertDoesNotThrow(function(){func(object)});
- %DeoptimizeFunction(func);
- assertDoesNotThrow(function(){func(object)});
-}
-
-(function () {
- "use strict";
-
- let goodKeys = [
- "foo"
- ]
-
- let badKeys = [
- "bar",
- "1",
- "100001",
- "3000000001",
- "5000000001"
- ];
-
- let values = [
- "string",
- 1,
- 100001,
- 30000000001,
- 50000000001,
- NaN,
- {},
- undefined
- ];
-
- let literals = [0, NaN, true, "string"];
-
- let badAccessorDescs = [
- { set: (function(){}) },
- { configurable: true, enumerable: true, set: (function(){}) }
- ];
-
- let readSloppy = [
- readFromObjectSloppy,
- readFromObjectKeyedSloppy,
- readFromObjectKeyedVarSloppy,
- readFromObjectKeyedComputedSloppy
- ];
-
- let readStrong = [
- readFromObjectStrong,
- readFromObjectKeyedStrong,
- readFromObjectKeyedLetStrong,
- readFromObjectKeyedComputedStrong
- ];
-
- let dummyProto = {};
- for (let key of goodKeys) {
- Object.defineProperty(dummyProto, key, { value: undefined });
- }
-
- let dummyAccessorProto = {};
- for (let key of goodKeys) {
- Object.defineProperty(dummyAccessorProto, key, { set: (function(){}) })
- }
-
- // Attempting to access a property on an object with no defined properties
- // should throw.
- for (let object of getObjects().concat(literals)) {
- for (let func of readStrong) {
- assertStrongSemantics(func, object);
- }
- for (let func of readSloppy) {
- assertSloppySemantics(func, object);
- }
- }
- for (let object of getObjects()) {
- // Accessing a property which is on the prototype chain of the object should
- // not throw.
- object.__proto__ = dummyProto;
- for (let key of goodKeys) {
- for (let func of readStrong.concat(readSloppy)) {
- assertSloppySemantics(func, object);
- }
- }
- }
- // Properties with accessor descriptors missing 'get' should throw on access.
- for (let desc of badAccessorDescs) {
- for (let key of goodKeys) {
- for (let object of getObjects()) {
- Object.defineProperty(object, key, desc);
- for (let func of readStrong) {
- assertStrongSemantics(func, object);
- }
- for (let func of readSloppy) {
- assertSloppySemantics(func, object);
- }
- }
- }
- }
- // The same behaviour should be expected for bad accessor properties on the
- // prototype chain.
- for (let object of getObjects()) {
- object.__proto__ = dummyAccessorProto;
- for (let func of readStrong) {
- assertStrongSemantics(func, object);
- }
- for (let func of readSloppy) {
- assertSloppySemantics(func, object);
- }
- }
-})();
Unique<Name> name = Unique<Name>::CreateUninitialized(
isolate()->factory()->InternalizeUtf8String(string));
- const Operator* op = javascript()->LoadNamed(name, feedback, SLOPPY);
+ const Operator* op = javascript()->LoadNamed(name, feedback);
Node* load = graph()->NewNode(op, global, vector, context);
if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) {
for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op);
NewArrayBuffer(backing_store, sizeof(backing_store));
ResolvedFeedbackSlot feedback;
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
- TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
- Handle<JSTypedArray> array =
- factory()->NewJSTypedArray(type, buffer, 0, kLength);
- int const element_size = static_cast<int>(array->element_size());
-
- Node* key = Parameter(
- Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
- Node* base = HeapConstant(array);
- Node* vector = UndefinedConstant();
- Node* context = UndefinedConstant();
- Node* effect = graph()->start();
- Node* control = graph()->start();
- Reduction r = Reduce(
- graph()->NewNode(javascript()->LoadProperty(feedback, language_mode),
- base, key, vector, context, EmptyFrameState(),
- EmptyFrameState(), effect, control));
+ Handle<JSTypedArray> array =
+ factory()->NewJSTypedArray(type, buffer, 0, kLength);
+ int const element_size = static_cast<int>(array->element_size());
+
+ Node* key = Parameter(
+ Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
+ Node* base = HeapConstant(array);
+ Node* vector = UndefinedConstant();
+ Node* context = UndefinedConstant();
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->LoadProperty(feedback), base, key, vector, context,
+ EmptyFrameState(), EmptyFrameState(), effect, control));
- Matcher<Node*> offset_matcher =
- element_size == 1
- ? key
- : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
+ Matcher<Node*> offset_matcher =
+ element_size == 1
+ ? key
+ : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(
- r.replacement(),
- IsLoadBuffer(BufferAccess(type),
- IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
- offset_matcher,
- IsNumberConstant(array->byte_length()->Number()), effect,
- control));
- }
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsLoadBuffer(BufferAccess(type),
+ IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
+ offset_matcher,
+ IsNumberConstant(array->byte_length()->Number()), effect,
+ control));
}
}
NewArrayBuffer(backing_store, sizeof(backing_store));
ResolvedFeedbackSlot feedback;
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
- TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
- Handle<JSTypedArray> array =
- factory()->NewJSTypedArray(type, buffer, 0, kLength);
- ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
-
- int min = random_number_generator()->NextInt(static_cast<int>(kLength));
- int max = random_number_generator()->NextInt(static_cast<int>(kLength));
- if (min > max) std::swap(min, max);
- Node* key = Parameter(Type::Range(min, max, zone()));
- Node* base = HeapConstant(array);
- Node* vector = UndefinedConstant();
- Node* context = UndefinedConstant();
- Node* effect = graph()->start();
- Node* control = graph()->start();
- Reduction r = Reduce(
- graph()->NewNode(javascript()->LoadProperty(feedback, language_mode),
- base, key, vector, context, EmptyFrameState(),
- EmptyFrameState(), effect, control));
+ Handle<JSTypedArray> array =
+ factory()->NewJSTypedArray(type, buffer, 0, kLength);
+ ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
+
+ int min = random_number_generator()->NextInt(static_cast<int>(kLength));
+ int max = random_number_generator()->NextInt(static_cast<int>(kLength));
+ if (min > max) std::swap(min, max);
+ Node* key = Parameter(Type::Range(min, max, zone()));
+ Node* base = HeapConstant(array);
+ Node* vector = UndefinedConstant();
+ Node* context = UndefinedConstant();
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->LoadProperty(feedback), base, key, vector, context,
+ EmptyFrameState(), EmptyFrameState(), effect, control));
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(
- r.replacement(),
- IsLoadElement(access,
- IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
- key, effect, control));
- }
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsLoadElement(access,
+ IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
+ key, effect, control));
}
}
Node* effect = graph()->start();
Node* control = graph()->start();
- TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
- for (size_t i = 0; i < arraysize(names); i++) {
- Unique<Name> name = Unique<Name>::CreateImmovable(names[i]);
- Reduction r = Reduce(graph()->NewNode(
- javascript()->LoadNamed(name, feedback, language_mode), global,
- vector, context, EmptyFrameState(), EmptyFrameState(), effect,
- control));
+ for (size_t i = 0; i < arraysize(names); i++) {
+ Unique<Name> name = Unique<Name>::CreateImmovable(names[i]);
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->LoadNamed(name, feedback), global, vector, context,
+ EmptyFrameState(), EmptyFrameState(), effect, control));
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), matches[i]);
- }
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), matches[i]);
}
}