Index: src/deoptimizer.cc |
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc |
index 077337fbd089ec37dabb097817b7251bcd85c178..a105c4e46756d17de2e36903be6f061068a55e55 100644 |
--- a/src/deoptimizer.cc |
+++ b/src/deoptimizer.cc |
@@ -1784,6 +1784,43 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
Memory::Object_at(d.destination()) = *num; |
} |
+ // Materialize all float32x4 before looking at arguments because when the |
+ // output frames are used to materialize arguments objects later on they need |
+ // to already contain valid float32x4 values. |
+ for (int i = 0; i < deferred_float32x4s_.length(); i++) { |
+ Float32x4MaterializationDescriptor<Address> d = deferred_float32x4s_[i]; |
+ Handle<Object> float32x4 = isolate_->factory()->NewFloat32x4(d.value()); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ "Materialized a new float32x4 %p " |
+ "[float32x4(%e, %e, %e, %e)] in slot %p\n", |
+ reinterpret_cast<void*>(*float32x4), |
+ d.value().storage[0], d.value().storage[1], |
+ d.value().storage[2], d.value().storage[3], |
+ d.destination()); |
+ } |
+ Memory::Object_at(d.destination()) = *float32x4; |
+ } |
+ |
+ // Materialize all int32x4 before looking at arguments because when the |
+ // output frames are used to materialize arguments objects later on they need |
+ // to already contain valid int32x4 values. |
+ for (int i = 0; i < deferred_int32x4s_.length(); i++) { |
+ Int32x4MaterializationDescriptor<Address> d = deferred_int32x4s_[i]; |
+ Handle<Object> int32x4 = isolate_->factory()->NewInt32x4(d.value()); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ "Materialized a new int32x4 %p " |
+ "[int32x4(%u, %u, %u, %u)] in slot %p\n", |
+ reinterpret_cast<void*>(*int32x4), |
+ d.value().storage[0], d.value().storage[1], |
+ d.value().storage[2], d.value().storage[3], |
+ d.destination()); |
+ } |
+ Memory::Object_at(d.destination()) = *int32x4; |
+ } |
+ |
+ |
// Materialize all heap numbers required for arguments/captured objects. |
for (int i = 0; i < deferred_objects_double_values_.length(); i++) { |
HeapNumberMaterializationDescriptor<int> d = |
@@ -1803,6 +1840,48 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
// Play it safe and clear all object double values before we continue. |
deferred_objects_double_values_.Clear(); |
+ // Materialize all float32x4 values required for arguments/captured objects. |
+ for (int i = 0; i < deferred_objects_float32x4_values_.length(); i++) { |
+ Float32x4MaterializationDescriptor<int> d = |
+ deferred_objects_float32x4_values_[i]; |
+ Handle<Object> float32x4 = isolate_->factory()->NewFloat32x4(d.value()); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ "Materialized a new float32x4 %p " |
+ "[float32x4(%e, %e, %e, %e)] for object at %d\n", |
+ reinterpret_cast<void*>(*float32x4), |
+ d.value().storage[0], d.value().storage[1], |
+ d.value().storage[2], d.value().storage[3], |
+ d.destination()); |
+ } |
+ ASSERT(values.at(d.destination())->IsTheHole()); |
+ values.Set(d.destination(), float32x4); |
+ } |
+ |
+ // Play it safe and clear all object float32x4 values before we continue. |
+ deferred_objects_float32x4_values_.Clear(); |
+ |
+ // Materialize all int32x4 values required for arguments/captured objects. |
+ for (int i = 0; i < deferred_objects_int32x4_values_.length(); i++) { |
+ Int32x4MaterializationDescriptor<int> d = |
+ deferred_objects_int32x4_values_[i]; |
+ Handle<Object> int32x4 = isolate_->factory()->NewInt32x4(d.value()); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ "Materialized a new int32x4 %p " |
+ "[int32x4(%u, %u, %u, %u)] for object at %d\n", |
+ reinterpret_cast<void*>(*int32x4), |
+ d.value().storage[0], d.value().storage[1], |
+ d.value().storage[2], d.value().storage[3], |
+ d.destination()); |
+ } |
+ ASSERT(values.at(d.destination())->IsTheHole()); |
+ values.Set(d.destination(), int32x4); |
+ } |
+ |
+ // Play it safe and clear all object int32x4 values before we continue. |
+ deferred_objects_int32x4_values_.Clear(); |
+ |
// Materialize arguments/captured objects. |
if (!deferred_objects_.is_empty()) { |
List<Handle<Object> > materialized_objects(deferred_objects_.length()); |
@@ -2014,6 +2093,40 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, |
return; |
} |
+ case Translation::FLOAT32x4_REGISTER: { |
+ int input_reg = iterator->Next(); |
+ float32x4_value_t value = input_->GetFloat32x4Register(input_reg); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
+ reinterpret_cast<intptr_t>(object_slot), |
+ field_index); |
+ PrintF(trace_scope_->file(), |
+ "float32x4(%e, %e, %e, %e) ; %s\n", value.storage[0], |
+ value.storage[1], value.storage[2], value.storage[3], |
+ Float32x4Register::AllocationIndexToString(input_reg)); |
+ } |
+ AddObjectFloat32x4Value(value); |
+ return; |
+ } |
+ |
+ case Translation::INT32x4_REGISTER: { |
+ int input_reg = iterator->Next(); |
+ int32x4_value_t value = input_->GetInt32x4Register(input_reg); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
+ reinterpret_cast<intptr_t>(object_slot), |
+ field_index); |
+ PrintF(trace_scope_->file(), |
+ "int32x4(%u, %u, %u, %u) ; %s\n", value.storage[0], |
+ value.storage[1], value.storage[2], value.storage[3], |
+ Int32x4Register::AllocationIndexToString(input_reg)); |
+ } |
+ AddObjectInt32x4Value(value); |
+ return; |
+ } |
+ |
case Translation::STACK_SLOT: { |
int input_slot_index = iterator->Next(); |
unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
@@ -2101,6 +2214,42 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, |
return; |
} |
+ case Translation::FLOAT32x4_STACK_SLOT: { |
+ int input_slot_index = iterator->Next(); |
+ unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
+ float32x4_value_t value = input_->GetFloat32x4FrameSlot(input_offset); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
+ reinterpret_cast<intptr_t>(object_slot), |
+ field_index); |
+ PrintF(trace_scope_->file(), |
+ "float32x4(%e, %e, %e, %e) ; [sp + %d]\n", |
+ value.storage[0], value.storage[1], value.storage[2], |
+ value.storage[3], input_offset); |
+ } |
+ AddObjectFloat32x4Value(value); |
+ return; |
+ } |
+ |
+ case Translation::INT32x4_STACK_SLOT: { |
+ int input_slot_index = iterator->Next(); |
+ unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
+ int32x4_value_t value = input_->GetInt32x4FrameSlot(input_offset); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
+ reinterpret_cast<intptr_t>(object_slot), |
+ field_index); |
+ PrintF(trace_scope_->file(), |
+ "int32x4(%u, %u, %u, %u) ; [sp + %d]\n", |
+ value.storage[0], value.storage[1], value.storage[2], |
+ value.storage[3], input_offset); |
+ } |
+ AddObjectInt32x4Value(value); |
+ return; |
+ } |
+ |
case Translation::LITERAL: { |
Object* literal = ComputeLiteral(iterator->Next()); |
if (trace_scope_ != NULL) { |
@@ -2283,6 +2432,46 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
return; |
} |
+ case Translation::FLOAT32x4_REGISTER: { |
+ int input_reg = iterator->Next(); |
+ float32x4_value_t value = input_->GetFloat32x4Register(input_reg); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ " 0x%08" V8PRIxPTR ":" |
+ " [top + %d] <- float32x4(%e, %e, %e, %e) ; %s\n", |
+ output_[frame_index]->GetTop() + output_offset, |
+ output_offset, |
+ value.storage[0], value.storage[1], |
+ value.storage[2], value.storage[3], |
+ Float32x4Register::AllocationIndexToString(input_reg)); |
+ } |
+ // We save the untagged value on the side and store a GC-safe |
+ // temporary placeholder in the frame. |
+ AddFloat32x4Value(output_[frame_index]->GetTop() + output_offset, value); |
+ output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
+ return; |
+ } |
+ |
+ case Translation::INT32x4_REGISTER: { |
+ int input_reg = iterator->Next(); |
+ int32x4_value_t value = input_->GetInt32x4Register(input_reg); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ " 0x%08" V8PRIxPTR ":" |
+ " [top + %d] <- int32x4(%u, %u, %u, %u) ; %s\n", |
+ output_[frame_index]->GetTop() + output_offset, |
+ output_offset, |
+ value.storage[0], value.storage[1], |
+ value.storage[2], value.storage[3], |
+ Int32x4Register::AllocationIndexToString(input_reg)); |
+ } |
+ // We save the untagged value on the side and store a GC-safe |
+ // temporary placeholder in the frame. |
+ AddInt32x4Value(output_[frame_index]->GetTop() + output_offset, value); |
+ output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
+ return; |
+ } |
+ |
case Translation::STACK_SLOT: { |
int input_slot_index = iterator->Next(); |
unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
@@ -2384,6 +2573,48 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
return; |
} |
+ case Translation::FLOAT32x4_STACK_SLOT: { |
+ int input_slot_index = iterator->Next(); |
+ unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
+ float32x4_value_t value = input_->GetFloat32x4FrameSlot(input_offset); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ " 0x%08" V8PRIxPTR ": " |
+ "[top + %d] <- float32x4(%e, %e, %e, %e) ; [sp + %d]\n", |
+ output_[frame_index]->GetTop() + output_offset, |
+ output_offset, |
+ value.storage[0], value.storage[1], |
+ value.storage[2], value.storage[3], |
+ input_offset); |
+ } |
+ // We save the untagged value on the side and store a GC-safe |
+ // temporary placeholder in the frame. |
+ AddFloat32x4Value(output_[frame_index]->GetTop() + output_offset, value); |
+ output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
+ return; |
+ } |
+ |
+ case Translation::INT32x4_STACK_SLOT: { |
+ int input_slot_index = iterator->Next(); |
+ unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
+ int32x4_value_t value = input_->GetInt32x4FrameSlot(input_offset); |
+ if (trace_scope_ != NULL) { |
+ PrintF(trace_scope_->file(), |
+ " 0x%08" V8PRIxPTR ": " |
+ "[top + %d] <- int32x4(%u, %u, %u, %u) ; [sp + %d]\n", |
+ output_[frame_index]->GetTop() + output_offset, |
+ output_offset, |
+ value.storage[0], value.storage[1], |
+ value.storage[2], value.storage[3], |
+ input_offset); |
+ } |
+ // We save the untagged value on the side and store a GC-safe |
+ // temporary placeholder in the frame. |
+ AddInt32x4Value(output_[frame_index]->GetTop() + output_offset, value); |
+ output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
+ return; |
+ } |
+ |
case Translation::LITERAL: { |
Object* literal = ComputeLiteral(iterator->Next()); |
if (trace_scope_ != NULL) { |
@@ -2532,6 +2763,22 @@ void Deoptimizer::AddObjectDoubleValue(double value) { |
} |
+void Deoptimizer::AddObjectFloat32x4Value(float32x4_value_t value) { |
+ deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value()); |
+ Float32x4MaterializationDescriptor<int> value_desc( |
+ deferred_objects_tagged_values_.length() - 1, value); |
+ deferred_objects_float32x4_values_.Add(value_desc); |
+} |
+ |
+ |
+void Deoptimizer::AddObjectInt32x4Value(int32x4_value_t value) { |
+ deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value()); |
+ Int32x4MaterializationDescriptor<int> value_desc( |
+ deferred_objects_tagged_values_.length() - 1, value); |
+ deferred_objects_int32x4_values_.Add(value_desc); |
+} |
+ |
+ |
void Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) { |
HeapNumberMaterializationDescriptor<Address> value_desc( |
reinterpret_cast<Address>(slot_address), value); |
@@ -2539,6 +2786,22 @@ void Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) { |
} |
+void Deoptimizer::AddFloat32x4Value(intptr_t slot_address, |
+ float32x4_value_t value) { |
+ Float32x4MaterializationDescriptor<Address> value_desc( |
+ reinterpret_cast<Address>(slot_address), value); |
+ deferred_float32x4s_.Add(value_desc); |
+} |
+ |
+ |
+void Deoptimizer::AddInt32x4Value(intptr_t slot_address, |
+ int32x4_value_t value) { |
+ Int32x4MaterializationDescriptor<Address> value_desc( |
+ reinterpret_cast<Address>(slot_address), value); |
+ deferred_int32x4s_.Add(value_desc); |
+} |
+ |
+ |
void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate, |
BailoutType type, |
int max_entry_id) { |
@@ -2779,6 +3042,18 @@ void Translation::StoreDoubleRegister(DoubleRegister reg) { |
} |
+void Translation::StoreFloat32x4Register(Float32x4Register reg) { |
+ buffer_->Add(FLOAT32x4_REGISTER, zone()); |
+ buffer_->Add(Float32x4Register::ToAllocationIndex(reg), zone()); |
+} |
+ |
+ |
+void Translation::StoreInt32x4Register(Int32x4Register reg) { |
+ buffer_->Add(INT32x4_REGISTER, zone()); |
+ buffer_->Add(Int32x4Register::ToAllocationIndex(reg), zone()); |
+} |
+ |
+ |
void Translation::StoreStackSlot(int index) { |
buffer_->Add(STACK_SLOT, zone()); |
buffer_->Add(index, zone()); |
@@ -2803,6 +3078,18 @@ void Translation::StoreDoubleStackSlot(int index) { |
} |
+void Translation::StoreFloat32x4StackSlot(int index) { |
+ buffer_->Add(FLOAT32x4_STACK_SLOT, zone()); |
+ buffer_->Add(index, zone()); |
+} |
+ |
+ |
+void Translation::StoreInt32x4StackSlot(int index) { |
+ buffer_->Add(INT32x4_STACK_SLOT, zone()); |
+ buffer_->Add(index, zone()); |
+} |
+ |
+ |
void Translation::StoreLiteral(int literal_id) { |
buffer_->Add(LITERAL, zone()); |
buffer_->Add(literal_id, zone()); |
@@ -2830,10 +3117,14 @@ int Translation::NumberOfOperandsFor(Opcode opcode) { |
case INT32_REGISTER: |
case UINT32_REGISTER: |
case DOUBLE_REGISTER: |
+ case FLOAT32x4_REGISTER: |
+ case INT32x4_REGISTER: |
case STACK_SLOT: |
case INT32_STACK_SLOT: |
case UINT32_STACK_SLOT: |
case DOUBLE_STACK_SLOT: |
+ case FLOAT32x4_STACK_SLOT: |
+ case INT32x4_STACK_SLOT: |
case LITERAL: |
case COMPILED_STUB_FRAME: |
return 1; |
@@ -2893,6 +3184,8 @@ SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator, |
case Translation::INT32_REGISTER: |
case Translation::UINT32_REGISTER: |
case Translation::DOUBLE_REGISTER: |
+ case Translation::FLOAT32x4_REGISTER: |
+ case Translation::INT32x4_REGISTER: |
// We are at safepoint which corresponds to call. All registers are |
// saved by caller so there would be no live registers at this |
// point. Thus these translation commands should not be used. |
@@ -2922,6 +3215,18 @@ SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator, |
return SlotRef(slot_addr, SlotRef::DOUBLE); |
} |
+ case Translation::FLOAT32x4_STACK_SLOT: { |
+ int slot_index = iterator->Next(); |
+ Address slot_addr = SlotAddress(frame, slot_index); |
+ return SlotRef(slot_addr, SlotRef::FLOAT32x4); |
+ } |
+ |
+ case Translation::INT32x4_STACK_SLOT: { |
+ int slot_index = iterator->Next(); |
+ Address slot_addr = SlotAddress(frame, slot_index); |
+ return SlotRef(slot_addr, SlotRef::INT32x4); |
+ } |
+ |
case Translation::LITERAL: { |
int literal_index = iterator->Next(); |
return SlotRef(data->GetIsolate(), |