| 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);
|
|
|