}
-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)
}
-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
}
+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) {
StubFailureTrampolineStub stub1(NOT_JS_FUNCTION_STUB_MODE);
StubFailureTrampolineStub stub2(JS_FUNCTION_STUB_MODE);
};
-class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
+class ElementsTransitionAndStoreStub : public PlatformCodeStub {
public:
ElementsTransitionAndStoreStub(ElementsKind from,
ElementsKind to,
bool is_jsarray,
+ StrictModeFlag strict_mode,
KeyedAccessStoreMode store_mode)
: from_(from),
to_(to),
is_jsarray_(is_jsarray),
- 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);
+ strict_mode_(strict_mode),
+ store_mode_(store_mode) {}
private:
- 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> {};
+ 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> {};
Major MajorKey() { return ElementsTransitionAndStore; }
- int NotMissMinorKey() {
- return FromBits::encode(from()) |
- ToBits::encode(to()) |
- IsJSArrayBits::encode(is_jsarray()) |
- StoreModeBits::encode(store_mode());
+ int MinorKey() {
+ return FromBits::encode(from_) |
+ ToBits::encode(to_) |
+ IsJSArrayBits::encode(is_jsarray_) |
+ StrictModeBits::encode(strict_mode_) |
+ 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);
}
-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
#endif // V8_ELEMENTS_KIND_H_
// 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, false, "use optimizing compiler to "
+DEFINE_bool(compiled_transitions, true, "use optimizing compiler to "
"generate array elements transition stubs")
DEFINE_bool(compiled_keyed_stores, true, "use optimizing compiler to "
"generate keyed store stubs")
}
-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)
}
-RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) {
- SealHandleScope scope(isolate);
- ASSERT(args.length() == 4);
- KeyedStoreIC ic(IC::EXTRA_CALL_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) {
set_target(code);
}
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);
}
-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)
elements_kind,
transitioned_map->elements_kind(),
is_js_array,
+ strict_mode(),
store_mode_).GetCode(isolate());
} else {
if (FLAG_compiled_keyed_stores &&
}
-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)