Revision: 24120
Author: [email protected]
Date: Mon Sep 22 13:23:27 2014 UTC
Log: Make KeyedLoads from a sloppy arguments array use a handler.
Before, a custom stub was installed.
[email protected]
Review URL: https://codereview.chromium.org/546683003
https://code.google.com/p/v8/source/detail?r=24120
Modified:
/branches/bleeding_edge/src/builtins.cc
/branches/bleeding_edge/src/builtins.h
/branches/bleeding_edge/src/code-stubs-hydrogen.cc
/branches/bleeding_edge/src/code-stubs.cc
/branches/bleeding_edge/src/code-stubs.h
/branches/bleeding_edge/src/elements-kind.h
/branches/bleeding_edge/src/ic/arm/ic-arm.cc
/branches/bleeding_edge/src/ic/arm64/ic-arm64.cc
/branches/bleeding_edge/src/ic/handler-compiler.cc
/branches/bleeding_edge/src/ic/ia32/ic-ia32.cc
/branches/bleeding_edge/src/ic/ic-compiler.cc
/branches/bleeding_edge/src/ic/ic.cc
/branches/bleeding_edge/src/ic/ic.h
/branches/bleeding_edge/src/ic/mips/ic-mips.cc
/branches/bleeding_edge/src/ic/x64/ic-x64.cc
=======================================
--- /branches/bleeding_edge/src/builtins.cc Thu Sep 18 13:28:32 2014 UTC
+++ /branches/bleeding_edge/src/builtins.cc Mon Sep 22 13:23:27 2014 UTC
@@ -1287,11 +1287,6 @@
static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
KeyedLoadIC::GeneratePreMonomorphic(masm);
}
-
-
-static void Generate_KeyedLoadIC_SloppyArguments(MacroAssembler* masm) {
- KeyedLoadIC::GenerateSloppyArguments(masm);
-}
static void Generate_StoreIC_Miss(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/builtins.h Thu Sep 18 13:28:32 2014 UTC
+++ /branches/bleeding_edge/src/builtins.h Mon Sep 22 13:23:27 2014 UTC
@@ -89,7 +89,6 @@
kNoExtraICState) \
V(KeyedLoadIC_Generic, KEYED_LOAD_IC, GENERIC,
kNoExtraICState) \
V(KeyedLoadIC_String, KEYED_LOAD_IC, MEGAMORPHIC,
kNoExtraICState) \
- V(KeyedLoadIC_SloppyArguments, KEYED_LOAD_IC, MONOMORPHIC,
kNoExtraICState) \
\
V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC,
StoreIC::kStrictModeState) \
\
=======================================
--- /branches/bleeding_edge/src/code-stubs-hydrogen.cc Tue Sep 16 12:51:33
2014 UTC
+++ /branches/bleeding_edge/src/code-stubs-hydrogen.cc Mon Sep 22 13:23:27
2014 UTC
@@ -71,6 +71,8 @@
MULTIPLE
};
+ HValue* UnmappedCase(HValue* elements, HValue* key);
+
HValue* BuildArrayConstructor(ElementsKind kind,
AllocationSiteOverrideMode override_mode,
ArgumentClass argument_class);
@@ -598,6 +600,122 @@
Handle<Code> LoadConstantStub::GenerateCode() { return
DoGenerateCode(this); }
+
+
+HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue*
key) {
+ HValue* result;
+ HInstruction* backing_store = Add<HLoadKeyed>(
+ elements, graph()->GetConstant1(), static_cast<HValue*>(NULL),
+ FAST_ELEMENTS, ALLOW_RETURN_HOLE);
+ Add<HCheckMaps>(backing_store, isolate()->factory()->fixed_array_map());
+ HValue* backing_store_length =
+ Add<HLoadNamedField>(backing_store, static_cast<HValue*>(NULL),
+ HObjectAccess::ForFixedArrayLength());
+ IfBuilder in_unmapped_range(this);
+ in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length,
+ Token::LT);
+ in_unmapped_range.Then();
+ {
+ result = Add<HLoadKeyed>(backing_store, key,
static_cast<HValue*>(NULL),
+ FAST_HOLEY_ELEMENTS, NEVER_RETURN_HOLE);
+ }
+ in_unmapped_range.ElseDeopt("Outside of range");
+ in_unmapped_range.End();
+ return result;
+}
+
+
+template <>
+HValue*
CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() {
+ HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
+ HValue* key = GetParameter(LoadDescriptor::kNameIndex);
+
+ // Mapped arguments are actual arguments. Unmapped arguments are values
added
+ // to the arguments object after it was created for the call. Mapped
arguments
+ // are stored in the context at indexes given by elements[key + 2].
Unmapped
+ // arguments are stored as regular indexed properties in the arguments
array,
+ // held at elements[1]. See NewSloppyArguments() in runtime.cc for a
detailed
+ // look at argument object construction.
+ //
+ // The sloppy arguments elements array has a special format:
+ //
+ // 0: context
+ // 1: unmapped arguments array
+ // 2: mapped_index0,
+ // 3: mapped_index1,
+ // ...
+ //
+ // length is 2 + min(number_of_actual_arguments,
number_of_formal_arguments).
+ // If key + 2 >= elements.length then attempt to look in the unmapped
+ // arguments array (given by elements[1]) and return the value at key,
missing
+ // to the runtime if the unmapped arguments array is not a fixed array
or if
+ // key >= unmapped_arguments_array.length.
+ //
+ // Otherwise, t = elements[key + 2]. If t is the hole, then look up the
value
+ // in the unmapped arguments array, as described above. Otherwise, t is
a Smi
+ // index into the context array given at elements[0]. Return the value at
+ // context[t].
+
+ key = AddUncasted<HForceRepresentation>(key, Representation::Smi());
+ IfBuilder positive_smi(this);
+ positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(),
+ Token::LT);
+ positive_smi.ThenDeopt("key is negative");
+ positive_smi.End();
+
+ HValue* constant_two = Add<HConstant>(2);
+ HValue* elements = AddLoadElements(receiver, static_cast<HValue*>(NULL));
+ HValue* elements_length =
+ Add<HLoadNamedField>(elements, static_cast<HValue*>(NULL),
+ HObjectAccess::ForFixedArrayLength());
+ HValue* adjusted_length = AddUncasted<HSub>(elements_length,
constant_two);
+ IfBuilder in_range(this);
+ in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT);
+ in_range.Then();
+ {
+ HValue* index = AddUncasted<HAdd>(key, constant_two);
+ HInstruction* mapped_index =
+ Add<HLoadKeyed>(elements, index, static_cast<HValue*>(NULL),
+ FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE);
+
+ IfBuilder is_valid(this);
+ is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index,
+ graph()->GetConstantHole());
+ is_valid.Then();
+ {
+ // TODO(mvstanton): I'd like to assert from this point, that if the
+ // mapped_index is not the hole that it is indeed, a smi. An
unnecessary
+ // smi check is being emitted.
+ HValue* the_context =
+ Add<HLoadKeyed>(elements, graph()->GetConstant0(),
+ static_cast<HValue*>(NULL), FAST_ELEMENTS);
+ DCHECK(Context::kHeaderSize == FixedArray::kHeaderSize);
+ HValue* result =
+ Add<HLoadKeyed>(the_context, mapped_index,
static_cast<HValue*>(NULL),
+ FAST_ELEMENTS, ALLOW_RETURN_HOLE);
+ environment()->Push(result);
+ }
+ is_valid.Else();
+ {
+ HValue* result = UnmappedCase(elements, key);
+ environment()->Push(result);
+ }
+ is_valid.End();
+ }
+ in_range.Else();
+ {
+ HValue* result = UnmappedCase(elements, key);
+ environment()->Push(result);
+ }
+ in_range.End();
+
+ return environment()->Pop();
+}
+
+
+Handle<Code> KeyedLoadSloppyArgumentsStub::GenerateCode() {
+ return DoGenerateCode(this);
+}
void CodeStubGraphBuilderBase::BuildStoreNamedField(
@@ -1092,7 +1210,6 @@
template <>
HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
StoreGlobalStub* stub = casted_stub();
- Handle<Object> hole(isolate()->heap()->the_hole_value(), isolate());
Handle<Object> placeholer_value(Smi::FromInt(0), isolate());
Handle<PropertyCell> placeholder_cell =
isolate()->factory()->NewPropertyCell(placeholer_value);
@@ -1124,7 +1241,7 @@
// property has been deleted and that the store must be handled by the
// runtime.
IfBuilder builder(this);
- HValue* hole_value = Add<HConstant>(hole);
+ HValue* hole_value = graph()->GetConstantHole();
builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value);
builder.Then();
builder.Deopt("Unexpected cell contents in global store");
=======================================
--- /branches/bleeding_edge/src/code-stubs.cc Wed Sep 17 12:50:17 2014 UTC
+++ /branches/bleeding_edge/src/code-stubs.cc Mon Sep 22 13:23:27 2014 UTC
@@ -586,12 +586,14 @@
void HandlerStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
if (kind() == Code::STORE_IC) {
descriptor->Initialize(FUNCTION_ADDR(StoreIC_MissFromStubFailure));
+ } else if (kind() == Code::KEYED_LOAD_IC) {
+ descriptor->Initialize(FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure));
}
}
CallInterfaceDescriptor HandlerStub::GetCallInterfaceDescriptor() {
- if (kind() == Code::LOAD_IC) {
+ if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) {
return LoadDescriptor(isolate());
} else {
DCHECK_EQ(Code::STORE_IC, kind());
=======================================
--- /branches/bleeding_edge/src/code-stubs.h Thu Sep 18 13:28:32 2014 UTC
+++ /branches/bleeding_edge/src/code-stubs.h Mon Sep 22 13:23:27 2014 UTC
@@ -82,6 +82,7 @@
/* IC Handler stubs */ \
V(LoadConstant) \
V(LoadField) \
+ V(KeyedLoadSloppyArguments) \
V(StoreField) \
V(StoreGlobal) \
V(StringLength)
@@ -914,6 +915,20 @@
};
+class KeyedLoadSloppyArgumentsStub : public HandlerStub {
+ public:
+ explicit KeyedLoadSloppyArgumentsStub(Isolate* isolate)
+ : HandlerStub(isolate) {}
+
+ protected:
+ virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
+ virtual Code::StubType GetStubType() { return Code::FAST; }
+
+ private:
+ DEFINE_HANDLER_CODE_STUB(KeyedLoadSloppyArguments, HandlerStub);
+};
+
+
class LoadConstantStub : public HandlerStub {
public:
LoadConstantStub(Isolate* isolate, int constant_index)
=======================================
--- /branches/bleeding_edge/src/elements-kind.h Mon Aug 4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/elements-kind.h Mon Sep 22 13:23:27 2014 UTC
@@ -85,6 +85,11 @@
inline bool IsDictionaryElementsKind(ElementsKind kind) {
return kind == DICTIONARY_ELEMENTS;
}
+
+
+inline bool IsSloppyArgumentsElements(ElementsKind kind) {
+ return kind == SLOPPY_ARGUMENTS_ELEMENTS;
+}
inline bool IsExternalArrayElementsKind(ElementsKind kind) {
=======================================
--- /branches/bleeding_edge/src/ic/arm/ic-arm.cc Thu Sep 18 13:28:32 2014
UTC
+++ /branches/bleeding_edge/src/ic/arm/ic-arm.cc Mon Sep 22 13:23:27 2014
UTC
@@ -367,32 +367,6 @@
__ add(scratch, scratch, Operand(FixedArray::kHeaderSize -
kHeapObjectTag));
return MemOperand(backing_store, scratch);
}
-
-
-void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
- // The return address is in lr.
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register key = LoadDescriptor::NameRegister();
- DCHECK(receiver.is(r1));
- DCHECK(key.is(r2));
-
- Label slow, notin;
- MemOperand mapped_location = GenerateMappedArgumentsLookup(
- masm, receiver, key, r0, r3, r4, ¬in, &slow);
- __ ldr(r0, mapped_location);
- __ Ret();
- __ bind(¬in);
- // The unmapped lookup expects that the parameter map is in r0.
- MemOperand unmapped_location =
- GenerateUnmappedArgumentsLookup(masm, key, r0, r3, &slow);
- __ ldr(r0, unmapped_location);
- __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
- __ cmp(r0, r3);
- __ b(eq, &slow);
- __ Ret();
- __ bind(&slow);
- GenerateMiss(masm);
-}
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/ic/arm64/ic-arm64.cc Thu Sep 18 13:28:32
2014 UTC
+++ /branches/bleeding_edge/src/ic/arm64/ic-arm64.cc Mon Sep 22 13:23:27
2014 UTC
@@ -368,35 +368,6 @@
__ Push(LoadDescriptor::ReceiverRegister(),
LoadDescriptor::NameRegister());
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
}
-
-
-void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
- // The return address is in lr.
- Register result = x0;
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register key = LoadDescriptor::NameRegister();
- DCHECK(receiver.is(x1));
- DCHECK(key.is(x2));
-
- Label miss, unmapped;
-
- Register map_scratch = x0;
- MemOperand mapped_location = GenerateMappedArgumentsLookup(
- masm, receiver, key, map_scratch, x3, x4, &unmapped, &miss);
- __ Ldr(result, mapped_location);
- __ Ret();
-
- __ Bind(&unmapped);
- // Parameter map is left in map_scratch when a jump on unmapped is done.
- MemOperand unmapped_location =
- GenerateUnmappedArgumentsLookup(masm, key, map_scratch, x3, &miss);
- __ Ldr(result, unmapped_location);
- __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss);
- __ Ret();
-
- __ Bind(&miss);
- GenerateMiss(masm);
-}
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/ic/handler-compiler.cc Thu Sep 18 13:28:32
2014 UTC
+++ /branches/bleeding_edge/src/ic/handler-compiler.cc Mon Sep 22 13:23:27
2014 UTC
@@ -390,13 +390,13 @@
ElementsKind elements_kind = receiver_map->elements_kind();
if (receiver_map->has_indexed_interceptor()) {
cached_stub = LoadIndexedInterceptorStub(isolate()).GetCode();
+ } else if (IsSloppyArgumentsElements(elements_kind)) {
+ cached_stub = KeyedLoadSloppyArgumentsStub(isolate()).GetCode();
} else if (IsFastElementsKind(elements_kind) ||
IsExternalArrayElementsKind(elements_kind) ||
IsFixedTypedArrayElementsKind(elements_kind)) {
cached_stub = LoadFastElementStub(isolate(), is_js_array,
elements_kind)
.GetCode();
- } else if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
- cached_stub = isolate()->builtins()->KeyedLoadIC_SloppyArguments();
} else {
DCHECK(elements_kind == DICTIONARY_ELEMENTS);
cached_stub = LoadDictionaryElementStub(isolate()).GetCode();
=======================================
--- /branches/bleeding_edge/src/ic/ia32/ic-ia32.cc Thu Sep 18 13:28:32 2014
UTC
+++ /branches/bleeding_edge/src/ic/ia32/ic-ia32.cc Mon Sep 22 13:23:27 2014
UTC
@@ -501,32 +501,6 @@
__ bind(&miss);
GenerateMiss(masm);
}
-
-
-void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
- // The return address is on the stack.
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register key = LoadDescriptor::NameRegister();
- DCHECK(receiver.is(edx));
- DCHECK(key.is(ecx));
-
- Label slow, notin;
- Factory* factory = masm->isolate()->factory();
- Operand mapped_location = GenerateMappedArgumentsLookup(
- masm, receiver, key, ebx, eax, ¬in, &slow);
- __ mov(eax, mapped_location);
- __ Ret();
- __ bind(¬in);
- // The unmapped lookup expects that the parameter map is in ebx.
- Operand unmapped_location =
- GenerateUnmappedArgumentsLookup(masm, key, ebx, eax, &slow);
- __ cmp(unmapped_location, factory->the_hole_value());
- __ j(equal, &slow);
- __ mov(eax, unmapped_location);
- __ Ret();
- __ bind(&slow);
- GenerateMiss(masm);
-}
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/ic/ic-compiler.cc Thu Sep 18 13:28:32 2014
UTC
+++ /branches/bleeding_edge/src/ic/ic-compiler.cc Mon Sep 22 13:23:27 2014
UTC
@@ -96,6 +96,8 @@
Handle<Code> stub;
if (receiver_map->has_indexed_interceptor()) {
stub = LoadIndexedInterceptorStub(isolate).GetCode();
+ } else if (receiver_map->has_sloppy_arguments_elements()) {
+ stub = KeyedLoadSloppyArgumentsStub(isolate).GetCode();
} else if (receiver_map->has_fast_elements() ||
receiver_map->has_external_array_elements() ||
receiver_map->has_fixed_typed_array_elements()) {
=======================================
--- /branches/bleeding_edge/src/ic/ic.cc Fri Sep 19 16:45:59 2014 UTC
+++ /branches/bleeding_edge/src/ic/ic.cc Mon Sep 22 13:23:27 2014 UTC
@@ -1187,11 +1187,7 @@
if (state() == UNINITIALIZED) stub = string_stub();
} else if (object->IsJSObject()) {
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
- if (receiver->elements()->map() ==
- isolate()->heap()->sloppy_arguments_elements_map()) {
- stub = sloppy_arguments_stub();
- } else if (!Object::ToSmi(isolate(), key).is_null() &&
- (!target().is_identical_to(sloppy_arguments_stub()))) {
+ if (!Object::ToSmi(isolate(), key).is_null()) {
stub = LoadElementStub(receiver);
}
}
=======================================
--- /branches/bleeding_edge/src/ic/ic.h Thu Sep 18 13:28:32 2014 UTC
+++ /branches/bleeding_edge/src/ic/ic.h Mon Sep 22 13:23:27 2014 UTC
@@ -414,7 +414,6 @@
}
static void GenerateGeneric(MacroAssembler* masm);
static void GenerateString(MacroAssembler* masm);
- static void GenerateSloppyArguments(MacroAssembler* masm);
// Bit mask to be tested against bit field for the cases when
// generic stub should go into slow case.
@@ -434,9 +433,6 @@
private:
Handle<Code> generic_stub() const { return generic_stub(isolate()); }
- Handle<Code> sloppy_arguments_stub() {
- return isolate()->builtins()->KeyedLoadIC_SloppyArguments();
- }
Handle<Code> string_stub() {
return isolate()->builtins()->KeyedLoadIC_String();
}
=======================================
--- /branches/bleeding_edge/src/ic/mips/ic-mips.cc Thu Sep 18 13:28:32 2014
UTC
+++ /branches/bleeding_edge/src/ic/mips/ic-mips.cc Mon Sep 22 13:23:27 2014
UTC
@@ -372,32 +372,6 @@
__ Addu(scratch, backing_store, scratch);
return MemOperand(scratch);
}
-
-
-void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
- // The return address is in ra.
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register key = LoadDescriptor::NameRegister();
- DCHECK(receiver.is(a1));
- DCHECK(key.is(a2));
-
- Label slow, notin;
- MemOperand mapped_location = GenerateMappedArgumentsLookup(
- masm, receiver, key, a0, a3, t0, ¬in, &slow);
- __ Ret(USE_DELAY_SLOT);
- __ lw(v0, mapped_location);
- __ bind(¬in);
- // The unmapped lookup expects that the parameter map is in a0.
- MemOperand unmapped_location =
- GenerateUnmappedArgumentsLookup(masm, key, a0, a3, &slow);
- __ lw(a0, unmapped_location);
- __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
- __ Branch(&slow, eq, a0, Operand(a3));
- __ Ret(USE_DELAY_SLOT);
- __ mov(v0, a0);
- __ bind(&slow);
- GenerateMiss(masm);
-}
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/ic/x64/ic-x64.cc Thu Sep 18 13:28:32 2014
UTC
+++ /branches/bleeding_edge/src/ic/x64/ic-x64.cc Mon Sep 22 13:23:27 2014
UTC
@@ -720,31 +720,6 @@
return FieldOperand(backing_store, scratch, times_pointer_size,
FixedArray::kHeaderSize);
}
-
-
-void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
- // The return address is on the stack.
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register key = LoadDescriptor::NameRegister();
- DCHECK(receiver.is(rdx));
- DCHECK(key.is(rcx));
-
- Label slow, notin;
- Operand mapped_location = GenerateMappedArgumentsLookup(
- masm, receiver, key, rbx, rax, rdi, ¬in, &slow);
- __ movp(rax, mapped_location);
- __ Ret();
- __ bind(¬in);
- // The unmapped lookup expects that the parameter map is in rbx.
- Operand unmapped_location =
- GenerateUnmappedArgumentsLookup(masm, key, rbx, rax, &slow);
- __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex);
- __ j(equal, &slow);
- __ movp(rax, unmapped_location);
- __ Ret();
- __ bind(&slow);
- GenerateMiss(masm);
-}
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.