Chromium Code Reviews| Index: src/deoptimizer.cc |
| diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc |
| index 53b9b76377f3d9dc0d897ad322de4c487ab20150..37a737cd3c61e6d24160025ead3b207726f6855f 100644 |
| --- a/src/deoptimizer.cc |
| +++ b/src/deoptimizer.cc |
| @@ -559,8 +559,6 @@ bool Deoptimizer::TraceEnabledFor(BailoutType deopt_type, |
| return (frame_type == StackFrame::STUB) |
| ? FLAG_trace_stub_failures |
| : FLAG_trace_deopt; |
| - case OSR: |
| - return FLAG_trace_osr; |
| } |
| UNREACHABLE(); |
| return false; |
| @@ -573,7 +571,6 @@ const char* Deoptimizer::MessageFor(BailoutType type) { |
| case SOFT: return "soft"; |
| case LAZY: return "lazy"; |
| case DEBUGGER: return "debugger"; |
| - case OSR: return "OSR"; |
| } |
| UNREACHABLE(); |
| return NULL; |
| @@ -610,17 +607,23 @@ Deoptimizer::Deoptimizer(Isolate* isolate, |
| } |
| ASSERT(from != NULL); |
| if (function != NULL && function->IsOptimized()) { |
| - function->shared()->increment_deopt_count(); |
| if (bailout_type_ == Deoptimizer::SOFT) { |
| - isolate->counters()->soft_deopts_executed()->Increment(); |
| // Soft deopts shouldn't count against the overall re-optimization count |
| // that can eventually lead to disabling optimization for a function. |
| - int opt_count = function->shared()->opt_count(); |
| - if (opt_count > 0) opt_count--; |
| - function->shared()->set_opt_count(opt_count); |
| + isolate->counters()->soft_deopts_executed()->Increment(); |
| + } else { |
| + function->shared()->increment_deopt_count(); |
| } |
| } |
| compiled_code_ = FindOptimizedCode(function, optimized_code); |
| + |
| +#if DEBUG |
| + ASSERT(compiled_code_ != NULL); |
| + if (type == EAGER || type == SOFT || type == LAZY) { |
| + ASSERT(compiled_code_->kind() != Code::FUNCTION); |
| + } |
| +#endif |
| + |
| StackFrame::Type frame_type = function == NULL |
| ? StackFrame::STUB |
| : StackFrame::JAVA_SCRIPT; |
| @@ -647,15 +650,6 @@ Code* Deoptimizer::FindOptimizedCode(JSFunction* function, |
| ? static_cast<Code*>(isolate_->FindCodeObject(from_)) |
| : compiled_code; |
| } |
| - case Deoptimizer::OSR: { |
| - // The function has already been optimized and we're transitioning |
| - // from the unoptimized shared version to the optimized one in the |
| - // function. The return address (from_) points to unoptimized code. |
| - Code* compiled_code = function->code(); |
| - ASSERT(compiled_code->kind() == Code::OPTIMIZED_FUNCTION); |
| - ASSERT(!compiled_code->contains(from_)); |
| - return compiled_code; |
| - } |
| case Deoptimizer::DEBUGGER: |
| ASSERT(optimized_code->contains(from_)); |
| return optimized_code; |
| @@ -772,11 +766,6 @@ int Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) { |
| // We rely on this function not causing a GC. It is called from generated code |
| // without having a real stack frame in place. |
| void Deoptimizer::DoComputeOutputFrames() { |
| - if (bailout_type_ == OSR) { |
| - DoComputeOsrOutputFrame(); |
| - return; |
| - } |
| - |
| // Print some helpful diagnostic information. |
| int64_t start = OS::Ticks(); |
| if (FLAG_log_timer_events && |
| @@ -2237,190 +2226,6 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
| } |
| -bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator, |
| - int* input_offset) { |
| - disasm::NameConverter converter; |
| - FrameDescription* output = output_[0]; |
| - |
| - // The input values are all part of the unoptimized frame so they |
| - // are all tagged pointers. |
| - uintptr_t input_value = input_->GetFrameSlot(*input_offset); |
| - Object* input_object = reinterpret_cast<Object*>(input_value); |
| - |
| - Translation::Opcode opcode = |
| - static_cast<Translation::Opcode>(iterator->Next()); |
| - |
| - switch (opcode) { |
| - case Translation::BEGIN: |
| - case Translation::JS_FRAME: |
| - case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| - case Translation::CONSTRUCT_STUB_FRAME: |
| - case Translation::GETTER_STUB_FRAME: |
| - case Translation::SETTER_STUB_FRAME: |
| - case Translation::COMPILED_STUB_FRAME: |
| - UNREACHABLE(); // Malformed input. |
| - return false; |
| - |
| - case Translation::REGISTER: { |
| - int output_reg = iterator->Next(); |
| - if (FLAG_trace_osr) { |
| - PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", |
| - converter.NameOfCPURegister(output_reg), |
| - input_value, |
| - *input_offset); |
| - } |
| - output->SetRegister(output_reg, input_value); |
| - break; |
| - } |
| - |
| - case Translation::INT32_REGISTER: { |
| - int32_t int32_value = 0; |
| - if (!input_object->ToInt32(&int32_value)) return false; |
| - |
| - int output_reg = iterator->Next(); |
| - if (FLAG_trace_osr) { |
| - PrintF(" %s <- %d (int32) ; [sp + %d]\n", |
| - converter.NameOfCPURegister(output_reg), |
| - int32_value, |
| - *input_offset); |
| - } |
| - output->SetRegister(output_reg, int32_value); |
| - break; |
| - } |
| - |
| - case Translation::UINT32_REGISTER: { |
| - uint32_t uint32_value = 0; |
| - if (!input_object->ToUint32(&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; |
| - |
| - int output_reg = iterator->Next(); |
| - double double_value = input_object->Number(); |
| - if (FLAG_trace_osr) { |
| - PrintF(" %s <- %g (double) ; [sp + %d]\n", |
| - DoubleRegister::AllocationIndexToString(output_reg), |
| - double_value, |
| - *input_offset); |
| - } |
| - output->SetDoubleRegister(output_reg, double_value); |
| - break; |
| - } |
| - |
| - case Translation::STACK_SLOT: { |
| - int output_index = iterator->Next(); |
| - unsigned output_offset = |
| - output->GetOffsetFromSlotIndex(output_index); |
| - if (FLAG_trace_osr) { |
| - PrintF(" [sp + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", |
| - output_offset, |
| - input_value, |
| - *input_offset); |
| - reinterpret_cast<Object*>(input_value)->ShortPrint(); |
| - PrintF("\n"); |
| - } |
| - output->SetFrameSlot(output_offset, input_value); |
| - break; |
| - } |
| - |
| - case Translation::INT32_STACK_SLOT: { |
| - int32_t int32_value = 0; |
| - if (!input_object->ToInt32(&int32_value)) return false; |
| - |
| - int output_index = iterator->Next(); |
| - unsigned output_offset = |
| - output->GetOffsetFromSlotIndex(output_index); |
| - if (FLAG_trace_osr) { |
| - PrintF(" [sp + %d] <- %d (int32) ; [sp + %d]\n", |
| - output_offset, |
| - int32_value, |
| - *input_offset); |
| - } |
| - output->SetFrameSlot(output_offset, int32_value); |
| - break; |
| - } |
| - |
| - case Translation::UINT32_STACK_SLOT: { |
| - uint32_t uint32_value = 0; |
| - if (!input_object->ToUint32(&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; |
| - |
| - // Abort OSR if we don't have a number. |
| - if (!input_object->IsNumber()) return false; |
| - |
| - int output_index = iterator->Next(); |
| - unsigned output_offset = |
| - output->GetOffsetFromSlotIndex(output_index); |
| - double double_value = input_object->Number(); |
| - uint64_t int_value = BitCast<uint64_t, double>(double_value); |
| - int32_t lower = static_cast<int32_t>(int_value); |
| - int32_t upper = static_cast<int32_t>(int_value >> kBitsPerInt); |
| - if (FLAG_trace_osr) { |
| - PrintF(" [sp + %d] <- 0x%08x (upper bits of %g) ; [sp + %d]\n", |
| - output_offset + kUpperOffset, |
| - upper, |
| - double_value, |
| - *input_offset); |
| - PrintF(" [sp + %d] <- 0x%08x (lower bits of %g) ; [sp + %d]\n", |
| - output_offset + kLowerOffset, |
| - lower, |
| - double_value, |
| - *input_offset); |
| - } |
| - output->SetFrameSlot(output_offset + kLowerOffset, lower); |
| - output->SetFrameSlot(output_offset + kUpperOffset, upper); |
| - break; |
| - } |
| - |
| - case Translation::LITERAL: { |
| - // Just ignore non-materialized literals. |
| - iterator->Next(); |
| - break; |
| - } |
| - |
| - case Translation::ARGUMENTS_OBJECT: { |
| - // Optimized code assumes that the argument object has not been |
| - // materialized and so bypasses it when doing arguments access. |
| - // We should have bailed out before starting the frame |
| - // translation. |
| - UNREACHABLE(); |
| - return false; |
| - } |
| - } |
| - |
| - *input_offset -= kPointerSize; |
| - return true; |
| -} |
| - |
| - |
| void Deoptimizer::PatchInterruptCode(Code* unoptimized_code, |
| Code* interrupt_code, |
| Code* replacement_code) { |
| @@ -2519,16 +2324,21 @@ unsigned Deoptimizer::ComputeInputFrameSize() const { |
| // The fp-to-sp delta already takes the context and the function |
| // into account so we have to avoid double counting them (-2). |
| unsigned result = fixed_size + fp_to_sp_delta_ - (2 * kPointerSize); |
| + if (FLAG_trace_deopt) { |
| + PrintF("Deopt input frame size=%d (fixed_size=%d + fp_sp_delta=%d - %d)\n", |
|
Michael Starzinger
2013/07/31 14:55:50
nit: Can we remove this left-over debug code again
|
| + result, fixed_size, fp_to_sp_delta_, (2 * kPointerSize)); |
| + } |
| #ifdef DEBUG |
| - if (bailout_type_ == OSR) { |
| - // TODO(kasperl): It would be nice if we could verify that the |
| - // size matches with the stack height we can compute based on the |
| - // environment at the OSR entry. The code for that his built into |
| - // the DoComputeOsrOutputFrame function for now. |
| - } else if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { |
| + if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { |
| unsigned stack_slots = compiled_code_->stack_slots(); |
| unsigned outgoing_size = ComputeOutgoingArgumentSize(); |
| - ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); |
| + unsigned check = fixed_size + (stack_slots * kPointerSize) + outgoing_size; |
| + if (FLAG_trace_deopt) { |
| + PrintF("Deopt input frame size=%d (fixed_size=%d +" |
|
Michael Starzinger
2013/07/31 14:55:50
Likewise.
|
| + " stack_slots=%d * %d + %d)\n", |
| + check, fixed_size, stack_slots, kPointerSize, outgoing_size); |
| + } |
| + ASSERT(result == check); |
| } |
| #endif |
| return result; |