Commit aaddea11 authored by jarin's avatar jarin Committed by Commit bot

Materialize booleans in the turbofan deoptimizer.

BUG=
R=titzer@chromium.org

Review URL: https://codereview.chromium.org/1055453006

Cr-Commit-Position: refs/heads/master@{#28022}
parent d0db1c39
...@@ -528,10 +528,9 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation, ...@@ -528,10 +528,9 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
InstructionOperand* op, InstructionOperand* op,
MachineType type) { MachineType type) {
if (op->IsStackSlot()) { if (op->IsStackSlot()) {
// TODO(jarin) kMachBool and kRepBit should materialize true and false if (type == kMachBool || type == kRepBit) {
// rather than creating an int value. translation->StoreBoolStackSlot(StackSlotOperand::cast(op)->index());
if (type == kMachBool || type == kRepBit || type == kMachInt32 || } else if (type == kMachInt32 || type == kMachInt8 || type == kMachInt16) {
type == kMachInt8 || type == kMachInt16) {
translation->StoreInt32StackSlot(StackSlotOperand::cast(op)->index()); translation->StoreInt32StackSlot(StackSlotOperand::cast(op)->index());
} else if (type == kMachUint32 || type == kMachUint16 || } else if (type == kMachUint32 || type == kMachUint16 ||
type == kMachUint8) { type == kMachUint8) {
...@@ -547,10 +546,9 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation, ...@@ -547,10 +546,9 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
DoubleStackSlotOperand::cast(op)->index()); DoubleStackSlotOperand::cast(op)->index());
} else if (op->IsRegister()) { } else if (op->IsRegister()) {
InstructionOperandConverter converter(this, instr); InstructionOperandConverter converter(this, instr);
// TODO(jarin) kMachBool and kRepBit should materialize true and false if (type == kMachBool || type == kRepBit) {
// rather than creating an int value. translation->StoreBoolRegister(converter.ToRegister(op));
if (type == kMachBool || type == kRepBit || type == kMachInt32 || } else if (type == kMachInt32 || type == kMachInt8 || type == kMachInt16) {
type == kMachInt8 || type == kMachInt16) {
translation->StoreInt32Register(converter.ToRegister(op)); translation->StoreInt32Register(converter.ToRegister(op));
} else if (type == kMachUint32 || type == kMachUint16 || } else if (type == kMachUint32 || type == kMachUint16 ||
type == kMachUint8) { type == kMachUint8) {
......
...@@ -829,14 +829,17 @@ void Deoptimizer::DoComputeOutputFrames() { ...@@ -829,14 +829,17 @@ void Deoptimizer::DoComputeOutputFrames() {
case Translation::REGISTER: case Translation::REGISTER:
case Translation::INT32_REGISTER: case Translation::INT32_REGISTER:
case Translation::UINT32_REGISTER: case Translation::UINT32_REGISTER:
case Translation::BOOL_REGISTER:
case Translation::DOUBLE_REGISTER: case Translation::DOUBLE_REGISTER:
case Translation::STACK_SLOT: case Translation::STACK_SLOT:
case Translation::INT32_STACK_SLOT: case Translation::INT32_STACK_SLOT:
case Translation::UINT32_STACK_SLOT: case Translation::UINT32_STACK_SLOT:
case Translation::BOOL_STACK_SLOT:
case Translation::DOUBLE_STACK_SLOT: case Translation::DOUBLE_STACK_SLOT:
case Translation::LITERAL: case Translation::LITERAL:
case Translation::ARGUMENTS_OBJECT: case Translation::ARGUMENTS_OBJECT:
default: case Translation::DUPLICATED_OBJECT:
case Translation::CAPTURED_OBJECT:
FATAL("Unsupported translation"); FATAL("Unsupported translation");
break; break;
} }
...@@ -2101,10 +2104,12 @@ void Deoptimizer::DoTranslateObjectAndSkip(TranslationIterator* iterator) { ...@@ -2101,10 +2104,12 @@ void Deoptimizer::DoTranslateObjectAndSkip(TranslationIterator* iterator) {
case Translation::REGISTER: case Translation::REGISTER:
case Translation::INT32_REGISTER: case Translation::INT32_REGISTER:
case Translation::UINT32_REGISTER: case Translation::UINT32_REGISTER:
case Translation::BOOL_REGISTER:
case Translation::DOUBLE_REGISTER: case Translation::DOUBLE_REGISTER:
case Translation::STACK_SLOT: case Translation::STACK_SLOT:
case Translation::INT32_STACK_SLOT: case Translation::INT32_STACK_SLOT:
case Translation::UINT32_STACK_SLOT: case Translation::UINT32_STACK_SLOT:
case Translation::BOOL_STACK_SLOT:
case Translation::DOUBLE_STACK_SLOT: case Translation::DOUBLE_STACK_SLOT:
case Translation::LITERAL: { case Translation::LITERAL: {
// The value is not part of any materialized object, so we can ignore it. // The value is not part of any materialized object, so we can ignore it.
...@@ -2237,6 +2242,28 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, ...@@ -2237,6 +2242,28 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
return; return;
} }
case Translation::BOOL_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 (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(), "%" V8PRIuPTR " ; bool %s (%s)\n", value,
converter.NameOfCPURegister(input_reg), TraceValueType(is_smi));
}
if (value == 0) {
AddObjectTaggedValue(
reinterpret_cast<intptr_t>(isolate_->heap()->false_value()));
} else {
DCHECK_EQ(1, value);
AddObjectTaggedValue(
reinterpret_cast<intptr_t>(isolate_->heap()->true_value()));
}
return;
}
case Translation::DOUBLE_REGISTER: { case Translation::DOUBLE_REGISTER: {
int input_reg = iterator->Next(); int input_reg = iterator->Next();
double value = input_->GetDoubleRegister(input_reg); double value = input_->GetDoubleRegister(input_reg);
...@@ -2323,6 +2350,30 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, ...@@ -2323,6 +2350,30 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
return; return;
} }
case Translation::BOOL_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 (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(), "%" V8PRIuPTR " ; [sp + %d] (bool %s)\n",
value, input_offset, TraceValueType(is_smi));
}
if (value == 0) {
AddObjectTaggedValue(
reinterpret_cast<intptr_t>(isolate_->heap()->false_value()));
} else {
DCHECK_EQ(1, value);
AddObjectTaggedValue(
reinterpret_cast<intptr_t>(isolate_->heap()->true_value()));
}
return;
}
case Translation::DOUBLE_STACK_SLOT: { case Translation::DOUBLE_STACK_SLOT: {
int input_slot_index = iterator->Next(); int input_slot_index = iterator->Next();
unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
...@@ -2505,6 +2556,31 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, ...@@ -2505,6 +2556,31 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
return; return;
} }
case Translation::BOOL_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 (trace_scope_ != NULL) {
PrintF(trace_scope_->file(),
" 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR
" ; bool %s (%s)\n",
output_[frame_index]->GetTop() + output_offset, output_offset,
value, converter.NameOfCPURegister(input_reg),
TraceValueType(is_smi));
}
if (value == 0) {
output_[frame_index]->SetFrameSlot(
output_offset,
reinterpret_cast<intptr_t>(isolate_->heap()->false_value()));
} else {
DCHECK_EQ(1, value);
output_[frame_index]->SetFrameSlot(
output_offset,
reinterpret_cast<intptr_t>(isolate_->heap()->true_value()));
}
return;
}
case Translation::DOUBLE_REGISTER: { case Translation::DOUBLE_REGISTER: {
int input_reg = iterator->Next(); int input_reg = iterator->Next();
double value = input_->GetDoubleRegister(input_reg); double value = input_->GetDoubleRegister(input_reg);
...@@ -2605,6 +2681,32 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, ...@@ -2605,6 +2681,32 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
return; return;
} }
case Translation::BOOL_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 (trace_scope_ != NULL) {
PrintF(trace_scope_->file(), " 0x%08" V8PRIxPTR ": ",
output_[frame_index]->GetTop() + output_offset);
PrintF(trace_scope_->file(),
"[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n",
output_offset, value, input_offset, TraceValueType(is_smi));
}
if (value == 0) {
output_[frame_index]->SetFrameSlot(
output_offset,
reinterpret_cast<intptr_t>(isolate_->heap()->false_value()));
} else {
DCHECK_EQ(1, value);
output_[frame_index]->SetFrameSlot(
output_offset,
reinterpret_cast<intptr_t>(isolate_->heap()->true_value()));
}
return;
}
case Translation::DOUBLE_STACK_SLOT: { case Translation::DOUBLE_STACK_SLOT: {
int input_slot_index = iterator->Next(); int input_slot_index = iterator->Next();
unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
...@@ -3020,6 +3122,12 @@ void Translation::StoreUint32Register(Register reg) { ...@@ -3020,6 +3122,12 @@ void Translation::StoreUint32Register(Register reg) {
} }
void Translation::StoreBoolRegister(Register reg) {
buffer_->Add(BOOL_REGISTER, zone());
buffer_->Add(reg.code(), zone());
}
void Translation::StoreDoubleRegister(DoubleRegister reg) { void Translation::StoreDoubleRegister(DoubleRegister reg) {
buffer_->Add(DOUBLE_REGISTER, zone()); buffer_->Add(DOUBLE_REGISTER, zone());
buffer_->Add(DoubleRegister::ToAllocationIndex(reg), zone()); buffer_->Add(DoubleRegister::ToAllocationIndex(reg), zone());
...@@ -3044,6 +3152,12 @@ void Translation::StoreUint32StackSlot(int index) { ...@@ -3044,6 +3152,12 @@ void Translation::StoreUint32StackSlot(int index) {
} }
void Translation::StoreBoolStackSlot(int index) {
buffer_->Add(BOOL_STACK_SLOT, zone());
buffer_->Add(index, zone());
}
void Translation::StoreDoubleStackSlot(int index) { void Translation::StoreDoubleStackSlot(int index) {
buffer_->Add(DOUBLE_STACK_SLOT, zone()); buffer_->Add(DOUBLE_STACK_SLOT, zone());
buffer_->Add(index, zone()); buffer_->Add(index, zone());
...@@ -3076,10 +3190,12 @@ int Translation::NumberOfOperandsFor(Opcode opcode) { ...@@ -3076,10 +3190,12 @@ int Translation::NumberOfOperandsFor(Opcode opcode) {
case REGISTER: case REGISTER:
case INT32_REGISTER: case INT32_REGISTER:
case UINT32_REGISTER: case UINT32_REGISTER:
case BOOL_REGISTER:
case DOUBLE_REGISTER: case DOUBLE_REGISTER:
case STACK_SLOT: case STACK_SLOT:
case INT32_STACK_SLOT: case INT32_STACK_SLOT:
case UINT32_STACK_SLOT: case UINT32_STACK_SLOT:
case BOOL_STACK_SLOT:
case DOUBLE_STACK_SLOT: case DOUBLE_STACK_SLOT:
case LITERAL: case LITERAL:
case COMPILED_STUB_FRAME: case COMPILED_STUB_FRAME:
...@@ -3143,6 +3259,7 @@ SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument( ...@@ -3143,6 +3259,7 @@ SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument(
case Translation::REGISTER: case Translation::REGISTER:
case Translation::INT32_REGISTER: case Translation::INT32_REGISTER:
case Translation::UINT32_REGISTER: case Translation::UINT32_REGISTER:
case Translation::BOOL_REGISTER:
case Translation::DOUBLE_REGISTER: case Translation::DOUBLE_REGISTER:
// We are at safepoint which corresponds to call. All registers are // We are at safepoint which corresponds to call. All registers are
// saved by caller so there would be no live registers at this // saved by caller so there would be no live registers at this
...@@ -3167,6 +3284,12 @@ SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument( ...@@ -3167,6 +3284,12 @@ SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument(
return SlotRef(slot_addr, SlotRef::UINT32); return SlotRef(slot_addr, SlotRef::UINT32);
} }
case Translation::BOOL_STACK_SLOT: {
int slot_index = iterator->Next();
Address slot_addr = SlotAddress(frame, slot_index);
return SlotRef(slot_addr, SlotRef::BOOLBIT);
}
case Translation::DOUBLE_STACK_SLOT: { case Translation::DOUBLE_STACK_SLOT: {
int slot_index = iterator->Next(); int slot_index = iterator->Next();
Address slot_addr = SlotAddress(frame, slot_index); Address slot_addr = SlotAddress(frame, slot_index);
...@@ -3324,6 +3447,20 @@ Handle<Object> SlotRef::GetValue(Isolate* isolate) { ...@@ -3324,6 +3447,20 @@ Handle<Object> SlotRef::GetValue(Isolate* isolate) {
} }
} }
case BOOLBIT: {
#if V8_TARGET_BIG_ENDIAN && V8_HOST_ARCH_64_BIT
uint32_t value = Memory::uint32_at(addr_ + kIntSize);
#else
uint32_t value = Memory::uint32_at(addr_);
#endif
if (value == 0) {
return isolate->factory()->false_value();
} else {
DCHECK_EQ(1, value);
return isolate->factory()->true_value();
}
}
case DOUBLE: { case DOUBLE: {
double value = read_double_value(addr_); double value = read_double_value(addr_);
return isolate->factory()->NewNumber(value); return isolate->factory()->NewNumber(value);
...@@ -3396,6 +3533,7 @@ Handle<Object> SlotRefValueBuilder::GetNext(Isolate* isolate, int lvl) { ...@@ -3396,6 +3533,7 @@ Handle<Object> SlotRefValueBuilder::GetNext(Isolate* isolate, int lvl) {
case SlotRef::TAGGED: case SlotRef::TAGGED:
case SlotRef::INT32: case SlotRef::INT32:
case SlotRef::UINT32: case SlotRef::UINT32:
case SlotRef::BOOLBIT:
case SlotRef::DOUBLE: case SlotRef::DOUBLE:
case SlotRef::LITERAL: case SlotRef::LITERAL:
return slot.GetValue(isolate); return slot.GetValue(isolate);
......
...@@ -755,25 +755,27 @@ class TranslationIterator BASE_EMBEDDED { ...@@ -755,25 +755,27 @@ class TranslationIterator BASE_EMBEDDED {
}; };
#define TRANSLATION_OPCODE_LIST(V) \ #define TRANSLATION_OPCODE_LIST(V) \
V(BEGIN) \ V(BEGIN) \
V(JS_FRAME) \ V(JS_FRAME) \
V(CONSTRUCT_STUB_FRAME) \ V(CONSTRUCT_STUB_FRAME) \
V(GETTER_STUB_FRAME) \ V(GETTER_STUB_FRAME) \
V(SETTER_STUB_FRAME) \ V(SETTER_STUB_FRAME) \
V(ARGUMENTS_ADAPTOR_FRAME) \ V(ARGUMENTS_ADAPTOR_FRAME) \
V(COMPILED_STUB_FRAME) \ V(COMPILED_STUB_FRAME) \
V(DUPLICATED_OBJECT) \ V(DUPLICATED_OBJECT) \
V(ARGUMENTS_OBJECT) \ V(ARGUMENTS_OBJECT) \
V(CAPTURED_OBJECT) \ V(CAPTURED_OBJECT) \
V(REGISTER) \ V(REGISTER) \
V(INT32_REGISTER) \ V(INT32_REGISTER) \
V(UINT32_REGISTER) \ V(UINT32_REGISTER) \
V(DOUBLE_REGISTER) \ V(BOOL_REGISTER) \
V(STACK_SLOT) \ V(DOUBLE_REGISTER) \
V(INT32_STACK_SLOT) \ V(STACK_SLOT) \
V(UINT32_STACK_SLOT) \ V(INT32_STACK_SLOT) \
V(DOUBLE_STACK_SLOT) \ V(UINT32_STACK_SLOT) \
V(BOOL_STACK_SLOT) \
V(DOUBLE_STACK_SLOT) \
V(LITERAL) V(LITERAL)
...@@ -811,10 +813,12 @@ class Translation BASE_EMBEDDED { ...@@ -811,10 +813,12 @@ class Translation BASE_EMBEDDED {
void StoreRegister(Register reg); void StoreRegister(Register reg);
void StoreInt32Register(Register reg); void StoreInt32Register(Register reg);
void StoreUint32Register(Register reg); void StoreUint32Register(Register reg);
void StoreBoolRegister(Register reg);
void StoreDoubleRegister(DoubleRegister reg); void StoreDoubleRegister(DoubleRegister reg);
void StoreStackSlot(int index); void StoreStackSlot(int index);
void StoreInt32StackSlot(int index); void StoreInt32StackSlot(int index);
void StoreUint32StackSlot(int index); void StoreUint32StackSlot(int index);
void StoreBoolStackSlot(int index);
void StoreDoubleStackSlot(int index); void StoreDoubleStackSlot(int index);
void StoreLiteral(int literal_id); void StoreLiteral(int literal_id);
void StoreArgumentsObject(bool args_known, int args_index, int args_length); void StoreArgumentsObject(bool args_known, int args_index, int args_length);
...@@ -844,6 +848,7 @@ class SlotRef BASE_EMBEDDED { ...@@ -844,6 +848,7 @@ class SlotRef BASE_EMBEDDED {
TAGGED, TAGGED,
INT32, INT32,
UINT32, UINT32,
BOOLBIT,
DOUBLE, DOUBLE,
LITERAL, LITERAL,
DEFERRED_OBJECT, // Object captured by the escape analysis. DEFERRED_OBJECT, // Object captured by the escape analysis.
......
...@@ -11616,6 +11616,13 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint( ...@@ -11616,6 +11616,13 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(
break; break;
} }
case Translation::BOOL_REGISTER: {
int reg_code = iterator.Next();
os << "{input=" << converter.NameOfCPURegister(reg_code)
<< " (bool)}";
break;
}
case Translation::DOUBLE_REGISTER: { case Translation::DOUBLE_REGISTER: {
int reg_code = iterator.Next(); int reg_code = iterator.Next();
os << "{input=" << DoubleRegister::AllocationIndexToString(reg_code) os << "{input=" << DoubleRegister::AllocationIndexToString(reg_code)
...@@ -11641,6 +11648,12 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint( ...@@ -11641,6 +11648,12 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(
break; break;
} }
case Translation::BOOL_STACK_SLOT: {
int input_slot_index = iterator.Next();
os << "{input=" << input_slot_index << " (bool)}";
break;
}
case Translation::DOUBLE_STACK_SLOT: { case Translation::DOUBLE_STACK_SLOT: {
int input_slot_index = iterator.Next(); int input_slot_index = iterator.Next();
os << "{input=" << input_slot_index << "}"; os << "{input=" << input_slot_index << "}";
......
...@@ -62,10 +62,6 @@ ...@@ -62,10 +62,6 @@
# from the deoptimizer to do that. # from the deoptimizer to do that.
'arguments-indirect': [PASS, NO_VARIANTS], 'arguments-indirect': [PASS, NO_VARIANTS],
# TODO(jarin): deoptimizer materializes a number instead of a boolean.
'compiler/deopt-bool': [PASS, NO_VARIANTS],
'compiler/deopt-bool2': [PASS, NO_VARIANTS],
# TODO(verwaest): Some tests are over-restrictive about object layout. # TODO(verwaest): Some tests are over-restrictive about object layout.
'array-constructor-feedback': [PASS, NO_VARIANTS], 'array-constructor-feedback': [PASS, NO_VARIANTS],
'array-feedback': [PASS, NO_VARIANTS], 'array-feedback': [PASS, NO_VARIANTS],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment