Upstream version 10.39.233.0
[platform/framework/web/crosswalk.git] / src / v8 / src / deoptimizer.cc
index dd274ed..14b1bab 100644 (file)
@@ -1772,7 +1772,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
   }
 
   // Copy the double registers from the input into the output frame.
-  CopyDoubleRegisters(output_frame);
+  CopySIMD128Registers(output_frame);
 
   // Fill registers containing handler and number of parameters.
   SetPlatformCompiledStubRegisters(output_frame, &descriptor);
@@ -1961,6 +1961,61 @@ 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++) {
+    SIMD128MaterializationDescriptor<Address> d = deferred_float32x4s_[i];
+    float32x4_value_t x4 = d.value().f4;
+    Handle<Object> float32x4 = isolate_->factory()->NewFloat32x4(x4);
+    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),
+             x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+             d.destination());
+    }
+    Memory::Object_at(d.destination()) = *float32x4;
+  }
+
+  // Materialize all float64x2 before looking at arguments because when the
+  // output frames are used to materialize arguments objects later on they need
+  // to already contain valid float64x2 values.
+  for (int i = 0; i < deferred_float64x2s_.length(); i++) {
+    SIMD128MaterializationDescriptor<Address> d = deferred_float64x2s_[i];
+    float64x2_value_t x2 = d.value().d2;
+    Handle<Object> float64x2 = isolate_->factory()->NewFloat64x2(x2);
+    if (trace_scope_ != NULL) {
+      PrintF(trace_scope_->file(),
+             "Materialized a new float64x2 %p "
+             "[float64x2(%e, %e)] in slot %p\n",
+             reinterpret_cast<void*>(*float64x2),
+             x2.storage[0], x2.storage[1],
+             d.destination());
+    }
+    Memory::Object_at(d.destination()) = *float64x2;
+  }
+
+  // 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++) {
+    SIMD128MaterializationDescriptor<Address> d = deferred_int32x4s_[i];
+    int32x4_value_t x4 = d.value().i4;
+    Handle<Object> int32x4 = isolate_->factory()->NewInt32x4(x4);
+    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),
+             x4.storage[0], x4.storage[1], x4.storage[2], x4.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 =
@@ -1980,6 +2035,69 @@ 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++) {
+    SIMD128MaterializationDescriptor<int> d =
+        deferred_objects_float32x4_values_[i];
+    float32x4_value_t x4 = d.value().f4;
+    Handle<Object> float32x4 = isolate_->factory()->NewFloat32x4(x4);
+    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),
+             x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+             d.destination());
+    }
+    DCHECK(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 float64x2 values required for arguments/captured objects.
+  for (int i = 0; i < deferred_objects_float64x2_values_.length(); i++) {
+    SIMD128MaterializationDescriptor<int> d =
+        deferred_objects_float64x2_values_[i];
+    float64x2_value_t x2 = d.value().d2;
+    Handle<Object> float64x2 = isolate_->factory()->NewFloat64x2(x2);
+    if (trace_scope_ != NULL) {
+      PrintF(trace_scope_->file(),
+             "Materialized a new float64x2 %p "
+             "[float64x2(%e, %e)] for object at %d\n",
+             reinterpret_cast<void*>(*float64x2),
+             x2.storage[0], x2.storage[1],
+             d.destination());
+    }
+    DCHECK(values.at(d.destination())->IsTheHole());
+    values.Set(d.destination(), float64x2);
+  }
+
+  // Play it safe and clear all object float64x2 values before we continue.
+  deferred_objects_float64x2_values_.Clear();
+
+  // Materialize all int32x4 values required for arguments/captured objects.
+  for (int i = 0; i < deferred_objects_int32x4_values_.length(); i++) {
+    SIMD128MaterializationDescriptor<int> d =
+        deferred_objects_int32x4_values_[i];
+    int32x4_value_t x4 = d.value().i4;
+    Handle<Object> int32x4 = isolate_->factory()->NewInt32x4(x4);
+    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),
+             x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+             d.destination());
+    }
+    DCHECK(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());
@@ -2109,10 +2227,16 @@ void Deoptimizer::DoTranslateObjectAndSkip(TranslationIterator* iterator) {
     case Translation::INT32_REGISTER:
     case Translation::UINT32_REGISTER:
     case Translation::DOUBLE_REGISTER:
+    case Translation::FLOAT32x4_REGISTER:
+    case Translation::FLOAT64x2_REGISTER:
+    case Translation::INT32x4_REGISTER:
     case Translation::STACK_SLOT:
     case Translation::INT32_STACK_SLOT:
     case Translation::UINT32_STACK_SLOT:
     case Translation::DOUBLE_STACK_SLOT:
+    case Translation::FLOAT32x4_STACK_SLOT:
+    case Translation::FLOAT64x2_STACK_SLOT:
+    case Translation::INT32x4_STACK_SLOT:
     case Translation::LITERAL: {
       // The value is not part of any materialized object, so we can ignore it.
       iterator->Skip(Translation::NumberOfOperandsFor(opcode));
@@ -2262,6 +2386,49 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
       return;
     }
 
+    case Translation::FLOAT32x4_REGISTER:
+    case Translation::FLOAT64x2_REGISTER:
+    case Translation::INT32x4_REGISTER: {
+      int input_reg = iterator->Next();
+      simd128_value_t value = input_->GetSIMD128Register(input_reg);
+      if (trace_scope_ != NULL) {
+        if (opcode == Translation::FLOAT32x4_REGISTER) {
+          float32x4_value_t x4 = value.f4;
+          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",
+                 x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+                 SIMD128Register::AllocationIndexToString(input_reg));
+        } else if (opcode == Translation::FLOAT64x2_REGISTER) {
+          float64x2_value_t x2 = value.d2;
+          PrintF(trace_scope_->file(),
+                 "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+                 reinterpret_cast<intptr_t>(object_slot),
+                 field_index);
+          PrintF(trace_scope_->file(),
+                 "float64x2(%e, %e) ; %s\n",
+                 x2.storage[0], x2.storage[1],
+                 SIMD128Register::AllocationIndexToString(input_reg));
+        } else {
+          DCHECK(opcode == Translation::INT32x4_REGISTER);
+          int32x4_value_t x4 = value.i4;
+          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",
+                 x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+                 SIMD128Register::AllocationIndexToString(input_reg));
+        }
+      }
+      AddObjectSIMD128Value(value, opcode);
+      return;
+    }
+
     case Translation::STACK_SLOT: {
       int input_slot_index = iterator->Next();
       unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
@@ -2349,6 +2516,50 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
       return;
     }
 
+    case Translation::FLOAT32x4_STACK_SLOT:
+    case Translation::FLOAT64x2_STACK_SLOT:
+    case Translation::INT32x4_STACK_SLOT: {
+      int input_slot_index = iterator->Next();
+      unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
+      simd128_value_t value = input_->GetSIMD128FrameSlot(input_offset);
+      if (trace_scope_ != NULL) {
+        if (opcode == Translation::FLOAT32x4_STACK_SLOT) {
+          float32x4_value_t x4 = value.f4;
+          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",
+                 x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+                 input_offset);
+        } else if (opcode == Translation::FLOAT64x2_STACK_SLOT) {
+          float64x2_value_t x2 = value.d2;
+          PrintF(trace_scope_->file(),
+                 "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+                 reinterpret_cast<intptr_t>(object_slot),
+                 field_index);
+          PrintF(trace_scope_->file(),
+                 "float64x2(%e, %e) ; [sp + %d]\n",
+                 x2.storage[0], x2.storage[1],
+                 input_offset);
+        } else {
+          DCHECK(opcode == Translation::INT32x4_STACK_SLOT);
+          int32x4_value_t x4 = value.i4;
+          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",
+                 x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+                 input_offset);
+        }
+      }
+      AddObjectSIMD128Value(value, opcode);
+      return;
+    }
+
     case Translation::LITERAL: {
       Object* literal = ComputeLiteral(iterator->Next());
       if (trace_scope_ != NULL) {
@@ -2533,6 +2744,50 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
       return;
     }
 
+    case Translation::FLOAT32x4_REGISTER:
+    case Translation::FLOAT64x2_REGISTER:
+    case Translation::INT32x4_REGISTER: {
+      int input_reg = iterator->Next();
+      simd128_value_t value = input_->GetSIMD128Register(input_reg);
+      if (trace_scope_ != NULL) {
+        if (opcode == Translation::FLOAT32x4_REGISTER) {
+          float32x4_value_t x4 = value.f4;
+          PrintF(trace_scope_->file(),
+                 "    0x%08" V8PRIxPTR ":"
+                 " [top + %d] <- float32x4(%e, %e, %e, %e) ; %s\n",
+                 output_[frame_index]->GetTop() + output_offset,
+                 output_offset,
+                 x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+                 SIMD128Register::AllocationIndexToString(input_reg));
+        } else if (opcode == Translation::FLOAT64x2_REGISTER) {
+          float64x2_value_t x2 = value.d2;
+          PrintF(trace_scope_->file(),
+                 "    0x%08" V8PRIxPTR ":"
+                 " [top + %d] <- float64x2(%e, %e) ; %s\n",
+                 output_[frame_index]->GetTop() + output_offset,
+                 output_offset,
+                 x2.storage[0], x2.storage[1],
+                 SIMD128Register::AllocationIndexToString(input_reg));
+        } else {
+          DCHECK(opcode == Translation::INT32x4_REGISTER);
+          int32x4_value_t x4 = value.i4;
+          PrintF(trace_scope_->file(),
+                 "    0x%08" V8PRIxPTR ":"
+                 " [top + %d] <- int32x4(%u, %u, %u, %u) ; %s\n",
+                 output_[frame_index]->GetTop() + output_offset,
+                 output_offset,
+                 x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+                 SIMD128Register::AllocationIndexToString(input_reg));
+        }
+      }
+      // We save the untagged value on the side and store a GC-safe
+      // temporary placeholder in the frame.
+      AddSIMD128Value(output_[frame_index]->GetTop() + output_offset, value,
+                      opcode);
+      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);
@@ -2634,6 +2889,51 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
       return;
     }
 
+    case Translation::FLOAT32x4_STACK_SLOT:
+    case Translation::FLOAT64x2_STACK_SLOT:
+    case Translation::INT32x4_STACK_SLOT: {
+      int input_slot_index = iterator->Next();
+      unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
+      simd128_value_t value = input_->GetSIMD128FrameSlot(input_offset);
+      if (trace_scope_ != NULL) {
+        if (opcode == Translation::FLOAT32x4_STACK_SLOT) {
+          float32x4_value_t x4 = value.f4;
+          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,
+                 x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+                 input_offset);
+        } else if (opcode == Translation::FLOAT64x2_STACK_SLOT) {
+          float64x2_value_t x2 = value.d2;
+          PrintF(trace_scope_->file(),
+                 "    0x%08" V8PRIxPTR ": "
+                 "[top + %d] <- float64x2(%e, %e) ; [sp + %d]\n",
+                 output_[frame_index]->GetTop() + output_offset,
+                 output_offset,
+                 x2.storage[0], x2.storage[1],
+                 input_offset);
+        } else {
+          DCHECK(opcode == Translation::INT32x4_STACK_SLOT);
+          int32x4_value_t x4 = value.i4;
+          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,
+                 x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+                 input_offset);
+        }
+      }
+      // We save the untagged value on the side and store a GC-safe
+      // temporary placeholder in the frame.
+      AddSIMD128Value(output_[frame_index]->GetTop() + output_offset, value,
+                      opcode);
+      output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
+      return;
+    }
+
     case Translation::LITERAL: {
       Object* literal = ComputeLiteral(iterator->Next());
       if (trace_scope_ != NULL) {
@@ -2780,6 +3080,27 @@ void Deoptimizer::AddObjectDoubleValue(double value) {
 }
 
 
+void Deoptimizer::AddObjectSIMD128Value(simd128_value_t value,
+                                        int translation_opcode) {
+  deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value());
+  SIMD128MaterializationDescriptor<int> value_desc(
+      deferred_objects_tagged_values_.length() - 1, value);
+  Translation::Opcode opcode =
+      static_cast<Translation::Opcode>(translation_opcode);
+  if (opcode == Translation::FLOAT32x4_REGISTER ||
+      opcode == Translation::FLOAT32x4_STACK_SLOT) {
+    deferred_objects_float32x4_values_.Add(value_desc);
+  } else if (opcode == Translation::FLOAT64x2_REGISTER ||
+             opcode == Translation::FLOAT64x2_STACK_SLOT) {
+    deferred_objects_float64x2_values_.Add(value_desc);
+  } else {
+    DCHECK(opcode == Translation::INT32x4_REGISTER ||
+           opcode == Translation::INT32x4_STACK_SLOT);
+    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);
@@ -2787,6 +3108,27 @@ void Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) {
 }
 
 
+void Deoptimizer::AddSIMD128Value(intptr_t slot_address,
+                                  simd128_value_t value,
+                                  int translation_opcode) {
+  SIMD128MaterializationDescriptor<Address> value_desc(
+      reinterpret_cast<Address>(slot_address), value);
+  Translation::Opcode opcode =
+      static_cast<Translation::Opcode>(translation_opcode);
+  if (opcode == Translation::FLOAT32x4_REGISTER ||
+      opcode == Translation::FLOAT32x4_STACK_SLOT) {
+    deferred_float32x4s_.Add(value_desc);
+  } else if (opcode == Translation::FLOAT64x2_REGISTER ||
+             opcode == Translation::FLOAT64x2_STACK_SLOT) {
+    deferred_float64x2s_.Add(value_desc);
+  } else {
+    DCHECK(opcode == Translation::INT32x4_REGISTER ||
+           opcode == Translation::INT32x4_STACK_SLOT);
+    deferred_int32x4s_.Add(value_desc);
+  }
+}
+
+
 void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
                                                    BailoutType type,
                                                    int max_entry_id) {
@@ -3030,6 +3372,12 @@ void Translation::StoreDoubleRegister(DoubleRegister reg) {
 }
 
 
+void Translation::StoreSIMD128Register(SIMD128Register reg, Opcode opcode) {
+  buffer_->Add(opcode, zone());
+  buffer_->Add(SIMD128Register::ToAllocationIndex(reg), zone());
+}
+
+
 void Translation::StoreStackSlot(int index) {
   buffer_->Add(STACK_SLOT, zone());
   buffer_->Add(index, zone());
@@ -3054,6 +3402,12 @@ void Translation::StoreDoubleStackSlot(int index) {
 }
 
 
+void Translation::StoreSIMD128StackSlot(int index, Opcode opcode) {
+  buffer_->Add(opcode, zone());
+  buffer_->Add(index, zone());
+}
+
+
 void Translation::StoreLiteral(int literal_id) {
   buffer_->Add(LITERAL, zone());
   buffer_->Add(literal_id, zone());
@@ -3081,10 +3435,16 @@ int Translation::NumberOfOperandsFor(Opcode opcode) {
     case INT32_REGISTER:
     case UINT32_REGISTER:
     case DOUBLE_REGISTER:
+    case FLOAT32x4_REGISTER:
+    case FLOAT64x2_REGISTER:
+    case INT32x4_REGISTER:
     case STACK_SLOT:
     case INT32_STACK_SLOT:
     case UINT32_STACK_SLOT:
     case DOUBLE_STACK_SLOT:
+    case FLOAT32x4_STACK_SLOT:
+    case FLOAT64x2_STACK_SLOT:
+    case INT32x4_STACK_SLOT:
     case LITERAL:
     case COMPILED_STUB_FRAME:
       return 1;
@@ -3148,6 +3508,9 @@ SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument(
     case Translation::INT32_REGISTER:
     case Translation::UINT32_REGISTER:
     case Translation::DOUBLE_REGISTER:
+    case Translation::FLOAT32x4_REGISTER:
+    case Translation::FLOAT64x2_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.
@@ -3177,6 +3540,24 @@ SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument(
       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::FLOAT64x2_STACK_SLOT: {
+      int slot_index = iterator->Next();
+      Address slot_addr = SlotAddress(frame, slot_index);
+      return SlotRef(slot_addr, SlotRef::FLOAT64x2);
+    }
+
+    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(),
@@ -3326,6 +3707,15 @@ Handle<Object> SlotRef::GetValue(Isolate* isolate) {
       return isolate->factory()->NewNumber(value);
     }
 
+    case FLOAT32x4:
+      return isolate->factory()->NewFloat32x4(read_simd128_value(addr_).f4);
+
+    case FLOAT64x2:
+      return isolate->factory()->NewFloat64x2(read_simd128_value(addr_).d2);
+
+    case INT32x4:
+      return isolate->factory()->NewInt32x4(read_simd128_value(addr_).i4);
+
     case LITERAL:
       return literal_;