Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Unified Diff: src/deoptimizer.cc

Issue 10778029: Allow uint32 value on optimized frames if they are consumed by safe operations. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: arm and x64 ports Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/deoptimizer.cc
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 6daa249b41ce82030281a7bdc196d7382f35b01d..d25a6377c4633a0c83482a20aa3a5a2424481cb8 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -756,6 +756,34 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
return;
}
+ case Translation::UINT32_REGISTER: {
+ int input_reg = iterator->Next();
+ uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg));
+ bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
+ if (FLAG_trace_deopt) {
+ PrintF(
+ " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR
+ " ; uint %s (%s)\n",
+ output_[frame_index]->GetTop() + output_offset,
+ output_offset,
+ value,
+ converter.NameOfCPURegister(input_reg),
+ is_smi ? "smi" : "heap number");
+ }
+ if (is_smi) {
+ intptr_t tagged_value =
+ reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
+ output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
+ } else {
+ // We save the untagged value on the side and store a GC-safe
+ // temporary placeholder in the frame.
+ AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
+ static_cast<double>(static_cast<uint32_t>(value)));
+ output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
+ }
+ return;
+ }
+
case Translation::DOUBLE_REGISTER: {
int input_reg = iterator->Next();
double value = input_->GetDoubleRegister(input_reg);
@@ -821,6 +849,36 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
return;
}
+ case Translation::UINT32_STACK_SLOT: {
+ int input_slot_index = iterator->Next();
+ unsigned input_offset =
+ input_->GetOffsetFromSlotIndex(input_slot_index);
+ uintptr_t value =
+ static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
+ bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": ",
+ output_[frame_index]->GetTop() + output_offset);
+ PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n",
+ output_offset,
+ value,
+ input_offset,
+ is_smi ? "smi" : "heap number");
+ }
+ if (is_smi) {
+ intptr_t tagged_value =
+ reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
+ output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
+ } else {
+ // We save the untagged value on the side and store a GC-safe
+ // temporary placeholder in the frame.
+ AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
+ static_cast<double>(static_cast<uint32_t>(value)));
+ output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
+ }
+ return;
+ }
+
case Translation::DOUBLE_STACK_SLOT: {
int input_slot_index = iterator->Next();
unsigned input_offset =
@@ -873,6 +931,56 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
}
+static bool ObjectToInt32(Object* obj, int32_t* value) {
+ if (obj->IsSmi()) {
+ *value = Smi::cast(obj)->value();
+ return true;
+ }
+
+ if (obj->IsHeapNumber()) {
+ double num = HeapNumber::cast(obj)->value();
+ if (FastD2I(FastI2D(num)) != num) {
+ if (FLAG_trace_osr) {
+ PrintF("**** %g could not be converted to int32 ****\n",
+ HeapNumber::cast(obj)->value());
+ }
+ return false;
+ }
+
+ *value = FastD2I(num);
+ return true;
+ }
+
+ return false;
+}
+
+
+static bool ObjectToUint32(Object* obj, uint32_t* value) {
+ if (obj->IsSmi()) {
+ if (Smi::cast(obj)->value() < 0) return false;
+
+ *value = static_cast<uint32_t>(Smi::cast(obj)->value());
+ return true;
+ }
+
+ if (obj->IsHeapNumber()) {
+ double num = HeapNumber::cast(obj)->value();
+ if ((num < 0) || (FastD2UI(FastUI2D(num)) != num)) {
+ if (FLAG_trace_osr) {
+ PrintF("**** %g could not be converted to uint32 ****\n",
+ HeapNumber::cast(obj)->value());
+ }
+ return false;
+ }
+
+ *value = FastD2UI(num);
+ return true;
+ }
+
+ return false;
+}
+
+
bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
int* input_offset) {
disasm::NameConverter converter;
@@ -912,22 +1020,10 @@ bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
}
case Translation::INT32_REGISTER: {
- // Abort OSR if we don't have a number.
- if (!input_object->IsNumber()) return false;
+ int32_t int32_value = 0;
+ if (!ObjectToInt32(input_object, &int32_value)) return false;
int output_reg = iterator->Next();
- int int32_value = input_object->IsSmi()
- ? Smi::cast(input_object)->value()
- : FastD2I(input_object->Number());
- // Abort the translation if the conversion lost information.
- if (!input_object->IsSmi() &&
- FastI2D(int32_value) != input_object->Number()) {
- if (FLAG_trace_osr) {
- PrintF("**** %g could not be converted to int32 ****\n",
- input_object->Number());
- }
- return false;
- }
if (FLAG_trace_osr) {
PrintF(" %s <- %d (int32) ; [sp + %d]\n",
converter.NameOfCPURegister(output_reg),
@@ -938,6 +1034,21 @@ bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
break;
}
+ case Translation::UINT32_REGISTER: {
+ uint32_t uint32_value = 0;
+ if (!ObjectToUint32(input_object, &uint32_value)) return false;
+
+ int output_reg = iterator->Next();
+ if (FLAG_trace_osr) {
+ PrintF(" %s <- %u (uint32) ; [sp + %d]\n",
+ converter.NameOfCPURegister(output_reg),
+ uint32_value,
+ *input_offset);
+ }
+ output->SetRegister(output_reg, static_cast<int32_t>(uint32_value));
+ }
+
+
case Translation::DOUBLE_REGISTER: {
// Abort OSR if we don't have a number.
if (!input_object->IsNumber()) return false;
@@ -971,24 +1082,12 @@ bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
}
case Translation::INT32_STACK_SLOT: {
- // Abort OSR if we don't have a number.
- if (!input_object->IsNumber()) return false;
+ int32_t int32_value = 0;
+ if (!ObjectToInt32(input_object, &int32_value)) return false;
int output_index = iterator->Next();
unsigned output_offset =
output->GetOffsetFromSlotIndex(output_index);
- int int32_value = input_object->IsSmi()
- ? Smi::cast(input_object)->value()
- : DoubleToInt32(input_object->Number());
- // Abort the translation if the conversion lost information.
- if (!input_object->IsSmi() &&
- FastI2D(int32_value) != input_object->Number()) {
- if (FLAG_trace_osr) {
- PrintF("**** %g could not be converted to int32 ****\n",
- input_object->Number());
- }
- return false;
- }
if (FLAG_trace_osr) {
PrintF(" [sp + %d] <- %d (int32) ; [sp + %d]\n",
output_offset,
@@ -999,6 +1098,23 @@ bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
break;
}
+ case Translation::UINT32_STACK_SLOT: {
+ uint32_t uint32_value = 0;
+ if (!ObjectToUint32(input_object, &uint32_value)) return false;
+
+ int output_index = iterator->Next();
+ unsigned output_offset =
+ output->GetOffsetFromSlotIndex(output_index);
+ if (FLAG_trace_osr) {
+ PrintF(" [sp + %d] <- %u (uint32) ; [sp + %d]\n",
+ output_offset,
+ uint32_value,
+ *input_offset);
+ }
+ output->SetFrameSlot(output_offset, static_cast<int32_t>(uint32_value));
+ break;
+ }
+
case Translation::DOUBLE_STACK_SLOT: {
static const int kLowerOffset = 0 * kPointerSize;
static const int kUpperOffset = 1 * kPointerSize;
@@ -1379,6 +1495,12 @@ void Translation::StoreInt32Register(Register reg) {
}
+void Translation::StoreUint32Register(Register reg) {
+ buffer_->Add(UINT32_REGISTER, zone());
+ buffer_->Add(reg.code(), zone());
+}
+
+
void Translation::StoreDoubleRegister(DoubleRegister reg) {
buffer_->Add(DOUBLE_REGISTER, zone());
buffer_->Add(DoubleRegister::ToAllocationIndex(reg), zone());
@@ -1397,6 +1519,12 @@ void Translation::StoreInt32StackSlot(int index) {
}
+void Translation::StoreUint32StackSlot(int index) {
+ buffer_->Add(UINT32_STACK_SLOT, zone());
+ buffer_->Add(index, zone());
+}
+
+
void Translation::StoreDoubleStackSlot(int index) {
buffer_->Add(DOUBLE_STACK_SLOT, zone());
buffer_->Add(index, zone());
@@ -1426,9 +1554,11 @@ int Translation::NumberOfOperandsFor(Opcode opcode) {
return 0;
case REGISTER:
case INT32_REGISTER:
+ case UINT32_REGISTER:
case DOUBLE_REGISTER:
case STACK_SLOT:
case INT32_STACK_SLOT:
+ case UINT32_STACK_SLOT:
case DOUBLE_STACK_SLOT:
case LITERAL:
return 1;
@@ -1460,12 +1590,16 @@ const char* Translation::StringFor(Opcode opcode) {
return "REGISTER";
case INT32_REGISTER:
return "INT32_REGISTER";
+ case UINT32_REGISTER:
+ return "UINT32_REGISTER";
case DOUBLE_REGISTER:
return "DOUBLE_REGISTER";
case STACK_SLOT:
return "STACK_SLOT";
case INT32_STACK_SLOT:
return "INT32_STACK_SLOT";
+ case UINT32_STACK_SLOT:
+ return "UINT32_STACK_SLOT";
case DOUBLE_STACK_SLOT:
return "DOUBLE_STACK_SLOT";
case LITERAL:
@@ -1521,6 +1655,7 @@ SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator,
case Translation::REGISTER:
case Translation::INT32_REGISTER:
+ case Translation::UINT32_REGISTER:
case Translation::DOUBLE_REGISTER:
case Translation::DUPLICATE:
// We are at safepoint which corresponds to call. All registers are
@@ -1540,6 +1675,12 @@ SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator,
return SlotRef(slot_addr, SlotRef::INT32);
}
+ case Translation::UINT32_STACK_SLOT: {
+ int slot_index = iterator->Next();
+ Address slot_addr = SlotAddress(frame, slot_index);
+ return SlotRef(slot_addr, SlotRef::UINT32);
+ }
+
case Translation::DOUBLE_STACK_SLOT: {
int slot_index = iterator->Next();
Address slot_addr = SlotAddress(frame, slot_index);

Powered by Google App Engine
This is Rietveld 408576698