Revision: 15635
Author: [email protected]
Date: Thu Jul 11 07:29:00 2013
Log: Turn ElementsTransitionAndStore stub into a HydrogenCodeStub.
[email protected], [email protected]
Review URL: https://codereview.chromium.org/18881004
http://code.google.com/p/v8/source/detail?r=15635
Modified:
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/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/flag-definitions.h
/branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/ic.h
/branches/bleeding_edge/src/mips/code-stubs-mips.cc
/branches/bleeding_edge/src/stub-cache.cc
/branches/bleeding_edge/src/x64/code-stubs-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Tue Jul 9 01:22:41
2013
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Thu Jul 11 07:29:00
2013
@@ -256,6 +256,17 @@
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
}
+
+
+void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { r0, r3, r1, r2 };
+ descriptor->register_param_count_ = 4;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ =
+ FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
+}
#define __ ACCESS_MASM(masm)
=======================================
--- /branches/bleeding_edge/src/code-stubs-hydrogen.cc Wed Jul 10 06:24:51
2013
+++ /branches/bleeding_edge/src/code-stubs-hydrogen.cc Thu Jul 11 07:29:00
2013
@@ -907,6 +907,77 @@
Handle<Code> StoreGlobalStub::GenerateCode() {
return DoGenerateCode(this);
}
+
+
+template<>
+HValue*
CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
+ ElementsTransitionAndStoreStub* stub = casted_stub();
+ ElementsKind from_kind = stub->from();
+ ElementsKind to_kind = stub->to();
+
+ HValue* value = GetParameter(0);
+ HValue* target_map = GetParameter(1);
+ HValue* key = GetParameter(2);
+ HValue* object = GetParameter(3);
+
+ if (FLAG_trace_elements_transitions) {
+ // Tracing elements transitions is the job of the runtime.
+ current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
+ set_current_block(NULL);
+ return value;
+ }
+
+ info()->MarkAsSavesCallerDoubles();
+
+ if (AllocationSite::GetMode(from_kind, to_kind) ==
TRACK_ALLOCATION_SITE) {
+ Add<HTrapAllocationMemento>(object);
+ }
+
+ // Check if we need to transition the array elements first
+ // (either SMI -> Double or Double -> Object).
+ if (DoesTransitionChangeElementsBufferFormat(from_kind, to_kind)) {
+ HInstruction* array_length = NULL;
+ if (stub->is_jsarray()) {
+ array_length = AddLoad(object, HObjectAccess::ForArrayLength());
+ } else {
+ array_length = AddLoadFixedArrayLength(AddLoadElements(object));
+ }
+ array_length->set_type(HType::Smi());
+
+ IfBuilder if_builder(this);
+
+ // Check if we have any elements.
+ if_builder.IfNot<HCompareNumericAndBranch>(array_length,
+ graph()->GetConstant0(),
+ Token::EQ);
+ if_builder.Then();
+
+ HInstruction* elements = AddLoadElements(object);
+
+ HInstruction* elements_length = AddLoadFixedArrayLength(elements);
+
+ BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
+ array_length, elements_length);
+
+ if_builder.End();
+ }
+
+ // Set transitioned map.
+ AddStore(object, HObjectAccess::ForMap(), target_map);
+
+ // Generate the actual store.
+ BuildUncheckedMonomorphicElementAccess(object, key, value, NULL,
+ stub->is_jsarray(), to_kind,
+ true, ALLOW_RETURN_HOLE,
+ stub->store_mode());
+
+ return value;
+}
+
+
+Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() {
+ return DoGenerateCode(this);
+}
} } // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/code-stubs.cc Mon Jul 8 03:02:16 2013
+++ /branches/bleeding_edge/src/code-stubs.cc Thu Jul 11 07:29:00 2013
@@ -809,44 +809,6 @@
return Contains(ToBooleanStub::SPEC_OBJECT)
|| Contains(ToBooleanStub::STRING);
}
-
-
-void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) {
- Label fail;
- AllocationSiteMode mode = AllocationSite::GetMode(from_, to_);
- ASSERT(!IsFastHoleyElementsKind(from_) || IsFastHoleyElementsKind(to_));
- if (!FLAG_trace_elements_transitions) {
- if (IsFastSmiOrObjectElementsKind(to_)) {
- if (IsFastSmiOrObjectElementsKind(from_)) {
- ElementsTransitionGenerator::
- GenerateMapChangeElementsTransition(masm, mode, &fail);
- } else if (IsFastDoubleElementsKind(from_)) {
- ASSERT(!IsFastSmiElementsKind(to_));
- ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode,
&fail);
- } else {
- UNREACHABLE();
- }
- KeyedStoreStubCompiler::GenerateStoreFastElement(masm,
- is_jsarray_,
- to_,
- store_mode_);
- } else if (IsFastSmiElementsKind(from_) &&
- IsFastDoubleElementsKind(to_)) {
- ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, &fail);
- KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm,
- is_jsarray_,
- store_mode_);
- } else if (IsFastDoubleElementsKind(from_)) {
- ASSERT(to_ == FAST_HOLEY_DOUBLE_ELEMENTS);
- ElementsTransitionGenerator::
- GenerateMapChangeElementsTransition(masm, mode, &fail);
- } else {
- UNREACHABLE();
- }
- }
- masm->bind(&fail);
- KeyedStoreIC::GenerateRuntimeSetProperty(masm, strict_mode_);
-}
void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) {
=======================================
--- /branches/bleeding_edge/src/code-stubs.h Mon Jul 8 03:02:16 2013
+++ /branches/bleeding_edge/src/code-stubs.h Thu Jul 11 07:29:00 2013
@@ -2210,41 +2210,47 @@
};
-class ElementsTransitionAndStoreStub : public PlatformCodeStub {
+class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
public:
ElementsTransitionAndStoreStub(ElementsKind from,
ElementsKind to,
bool is_jsarray,
- StrictModeFlag strict_mode,
KeyedAccessStoreMode store_mode)
: from_(from),
to_(to),
is_jsarray_(is_jsarray),
- strict_mode_(strict_mode),
- store_mode_(store_mode) {}
+ store_mode_(store_mode) {
+ ASSERT(!IsFastHoleyElementsKind(from) || IsFastHoleyElementsKind(to));
+ }
+
+ ElementsKind from() const { return from_; }
+ ElementsKind to() const { return to_; }
+ bool is_jsarray() const { return is_jsarray_; }
+ KeyedAccessStoreMode store_mode() const { return store_mode_; }
+
+ Handle<Code> GenerateCode();
+
+ void InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor);
private:
- class FromBits: public BitField<ElementsKind, 0, 8> {};
- class ToBits: public BitField<ElementsKind, 8, 8> {};
- class IsJSArrayBits: public BitField<bool, 16, 1> {};
- class StrictModeBits: public BitField<StrictModeFlag, 17, 1> {};
- class StoreModeBits: public BitField<KeyedAccessStoreMode, 18, 4> {};
+ class FromBits: public BitField<ElementsKind, 0, 8> {};
+ class ToBits: public BitField<ElementsKind, 8, 8> {};
+ class IsJSArrayBits: public BitField<bool, 16, 1> {};
+ class StoreModeBits: public BitField<KeyedAccessStoreMode, 17, 4> {};
Major MajorKey() { return ElementsTransitionAndStore; }
- int MinorKey() {
- return FromBits::encode(from_) |
- ToBits::encode(to_) |
- IsJSArrayBits::encode(is_jsarray_) |
- StrictModeBits::encode(strict_mode_) |
- StoreModeBits::encode(store_mode_);
+ int NotMissMinorKey() {
+ return FromBits::encode(from()) |
+ ToBits::encode(to()) |
+ IsJSArrayBits::encode(is_jsarray()) |
+ StoreModeBits::encode(store_mode());
}
-
- void Generate(MacroAssembler* masm);
ElementsKind from_;
ElementsKind to_;
bool is_jsarray_;
- StrictModeFlag strict_mode_;
KeyedAccessStoreMode store_mode_;
DISALLOW_COPY_AND_ASSIGN(ElementsTransitionAndStoreStub);
=======================================
--- /branches/bleeding_edge/src/elements-kind.h Thu Mar 28 06:30:16 2013
+++ /branches/bleeding_edge/src/elements-kind.h Thu Jul 11 07:29:00 2013
@@ -227,6 +227,15 @@
(elements_kind != TERMINAL_FAST_ELEMENTS_KIND &&
(!allow_only_packed || elements_kind != FAST_ELEMENTS));
}
+
+
+inline bool DoesTransitionChangeElementsBufferFormat(ElementsKind
from_kind,
+ ElementsKind to_kind)
{
+ return (IsFastSmiElementsKind(from_kind) &&
+ IsFastDoubleElementsKind(to_kind)) ||
+ (IsFastDoubleElementsKind(from_kind) &&
+ IsFastObjectElementsKind(to_kind));
+}
} } // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h Thu Jul 11 06:53:54 2013
+++ /branches/bleeding_edge/src/flag-definitions.h Thu Jul 11 07:29:00 2013
@@ -187,7 +187,7 @@
// Flags for experimental implementation features.
DEFINE_bool(packed_arrays, true, "optimizes arrays that have no holes")
DEFINE_bool(smi_only_arrays, true, "tracks arrays with only smi values")
-DEFINE_bool(compiled_transitions, true, "use optimizing compiler to "
+DEFINE_bool(compiled_transitions, false, "use optimizing compiler to "
"generate array elements transition stubs")
DEFINE_bool(compiled_keyed_stores, true, "use optimizing compiler to "
"generate keyed store stubs")
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Tue Jul 9 01:22:41
2013
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Jul 11 07:29:00
2013
@@ -260,6 +260,17 @@
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
}
+
+
+void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { eax, ebx, ecx, edx };
+ descriptor->register_param_count_ = 4;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ =
+ FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
+}
#define __ ACCESS_MASM(masm)
=======================================
--- /branches/bleeding_edge/src/ic.cc Thu Jul 11 04:54:43 2013
+++ /branches/bleeding_edge/src/ic.cc Thu Jul 11 07:29:00 2013
@@ -2474,6 +2474,24 @@
args.at<Object>(2),
MISS_FORCE_GENERIC);
}
+
+
+RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) {
+ SealHandleScope scope(isolate);
+ ASSERT(args.length() == 4);
+ KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
+ Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
+ Handle<Object> value = args.at<Object>(0);
+ Handle<Object> key = args.at<Object>(2);
+ Handle<Object> object = args.at<Object>(3);
+ StrictModeFlag strict_mode = Code::GetStrictMode(extra_ic_state);
+ return Runtime::SetObjectProperty(isolate,
+ object,
+ key,
+ value,
+ NONE,
+ strict_mode);
+}
void BinaryOpIC::patch(Code* code) {
=======================================
--- /branches/bleeding_edge/src/ic.h Tue Jul 9 01:22:41 2013
+++ /branches/bleeding_edge/src/ic.h Thu Jul 11 07:29:00 2013
@@ -858,6 +858,7 @@
DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure);
DECLARE_RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss);
DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure);
+DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss);
DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss);
DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss);
=======================================
--- /branches/bleeding_edge/src/mips/code-stubs-mips.cc Tue Jul 9 08:54:43
2013
+++ /branches/bleeding_edge/src/mips/code-stubs-mips.cc Thu Jul 11 07:29:00
2013
@@ -257,6 +257,17 @@
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
}
+
+
+void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { a0, a3, a1, a2 };
+ descriptor->register_param_count_ = 4;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ =
+ FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
+}
#define __ ACCESS_MASM(masm)
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Tue Jul 9 01:22:41 2013
+++ /branches/bleeding_edge/src/stub-cache.cc Thu Jul 11 07:29:00 2013
@@ -1997,7 +1997,6 @@
elements_kind,
transitioned_map->elements_kind(),
is_js_array,
- strict_mode(),
store_mode_).GetCode(isolate());
} else {
if (FLAG_compiled_keyed_stores &&
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Tue Jul 9 01:22:41
2013
+++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Thu Jul 11 07:29:00
2013
@@ -256,6 +256,17 @@
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
}
+
+
+void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { rax, rbx, rcx, rdx };
+ descriptor->register_param_count_ = 4;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ =
+ FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
+}
#define __ ACCESS_MASM(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/groups/opt_out.