| Index: src/ia32/deoptimizer-ia32.cc
|
| diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
|
| index a4f7ee8f720ab6fe55938d32de3aa9bd50ffcdfb..13a70afe521fb048be0eda28ec6224ec57a4ccfe 100644
|
| --- a/src/ia32/deoptimizer-ia32.cc
|
| +++ b/src/ia32/deoptimizer-ia32.cc
|
| @@ -258,192 +258,6 @@ Deoptimizer::InterruptPatchState Deoptimizer::GetInterruptPatchState(
|
| #endif // DEBUG
|
|
|
|
|
| -static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) {
|
| - ByteArray* translations = data->TranslationByteArray();
|
| - int length = data->DeoptCount();
|
| - for (int i = 0; i < length; i++) {
|
| - if (data->AstId(i) == ast_id) {
|
| - TranslationIterator it(translations, data->TranslationIndex(i)->value());
|
| - int value = it.Next();
|
| - ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value));
|
| - // Read the number of frames.
|
| - value = it.Next();
|
| - if (value == 1) return i;
|
| - }
|
| - }
|
| - UNREACHABLE();
|
| - return -1;
|
| -}
|
| -
|
| -
|
| -void Deoptimizer::DoComputeOsrOutputFrame() {
|
| - DeoptimizationInputData* data = DeoptimizationInputData::cast(
|
| - compiled_code_->deoptimization_data());
|
| - unsigned ast_id = data->OsrAstId()->value();
|
| - // TODO(kasperl): This should not be the bailout_id_. It should be
|
| - // the ast id. Confusing.
|
| - ASSERT(bailout_id_ == ast_id);
|
| -
|
| - int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
|
| - unsigned translation_index = data->TranslationIndex(bailout_id)->value();
|
| - ByteArray* translations = data->TranslationByteArray();
|
| -
|
| - TranslationIterator iterator(translations, translation_index);
|
| - Translation::Opcode opcode =
|
| - static_cast<Translation::Opcode>(iterator.Next());
|
| - ASSERT(Translation::BEGIN == opcode);
|
| - USE(opcode);
|
| - int count = iterator.Next();
|
| - iterator.Next(); // Drop JS frames count.
|
| - ASSERT(count == 1);
|
| - USE(count);
|
| -
|
| - opcode = static_cast<Translation::Opcode>(iterator.Next());
|
| - USE(opcode);
|
| - ASSERT(Translation::JS_FRAME == opcode);
|
| - unsigned node_id = iterator.Next();
|
| - USE(node_id);
|
| - ASSERT(node_id == ast_id);
|
| - int closure_id = iterator.Next();
|
| - USE(closure_id);
|
| - ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
|
| - unsigned height = iterator.Next();
|
| - unsigned height_in_bytes = height * kPointerSize;
|
| - USE(height_in_bytes);
|
| -
|
| - unsigned fixed_size = ComputeFixedSize(function_);
|
| - unsigned input_frame_size = input_->GetFrameSize();
|
| - ASSERT(fixed_size + height_in_bytes == input_frame_size);
|
| -
|
| - unsigned stack_slot_size = compiled_code_->stack_slots() * kPointerSize;
|
| - unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
|
| - unsigned outgoing_size = outgoing_height * kPointerSize;
|
| - unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
|
| - ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call.
|
| -
|
| - if (FLAG_trace_osr) {
|
| - PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ",
|
| - reinterpret_cast<intptr_t>(function_));
|
| - PrintFunctionName();
|
| - PrintF(" => node=%u, frame=%d->%d, ebp:esp=0x%08x:0x%08x]\n",
|
| - ast_id,
|
| - input_frame_size,
|
| - output_frame_size,
|
| - input_->GetRegister(ebp.code()),
|
| - input_->GetRegister(esp.code()));
|
| - }
|
| -
|
| - // There's only one output frame in the OSR case.
|
| - output_count_ = 1;
|
| - output_ = new FrameDescription*[1];
|
| - output_[0] = new(output_frame_size) FrameDescription(
|
| - output_frame_size, function_);
|
| - output_[0]->SetFrameType(StackFrame::JAVA_SCRIPT);
|
| -
|
| - // Clear the incoming parameters in the optimized frame to avoid
|
| - // confusing the garbage collector.
|
| - unsigned output_offset = output_frame_size - kPointerSize;
|
| - int parameter_count = function_->shared()->formal_parameter_count() + 1;
|
| - for (int i = 0; i < parameter_count; ++i) {
|
| - output_[0]->SetFrameSlot(output_offset, 0);
|
| - output_offset -= kPointerSize;
|
| - }
|
| -
|
| - // Translate the incoming parameters. This may overwrite some of the
|
| - // incoming argument slots we've just cleared.
|
| - int input_offset = input_frame_size - kPointerSize;
|
| - bool ok = true;
|
| - int limit = input_offset - (parameter_count * kPointerSize);
|
| - while (ok && input_offset > limit) {
|
| - ok = DoOsrTranslateCommand(&iterator, &input_offset);
|
| - }
|
| -
|
| - // There are no translation commands for the caller's pc and fp, the
|
| - // context, and the function. Set them up explicitly.
|
| - for (int i = StandardFrameConstants::kCallerPCOffset;
|
| - ok && i >= StandardFrameConstants::kMarkerOffset;
|
| - i -= kPointerSize) {
|
| - uint32_t input_value = input_->GetFrameSlot(input_offset);
|
| - if (FLAG_trace_osr) {
|
| - const char* name = "UNKNOWN";
|
| - switch (i) {
|
| - case StandardFrameConstants::kCallerPCOffset:
|
| - name = "caller's pc";
|
| - break;
|
| - case StandardFrameConstants::kCallerFPOffset:
|
| - name = "fp";
|
| - break;
|
| - case StandardFrameConstants::kContextOffset:
|
| - name = "context";
|
| - break;
|
| - case StandardFrameConstants::kMarkerOffset:
|
| - name = "function";
|
| - break;
|
| - }
|
| - PrintF(" [sp + %d] <- 0x%08x ; [sp + %d] (fixed part - %s)\n",
|
| - output_offset,
|
| - input_value,
|
| - input_offset,
|
| - name);
|
| - }
|
| - output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset));
|
| - input_offset -= kPointerSize;
|
| - output_offset -= kPointerSize;
|
| - }
|
| -
|
| - // All OSR stack frames are dynamically aligned to an 8-byte boundary.
|
| - int frame_pointer = input_->GetRegister(ebp.code());
|
| - if ((frame_pointer & kPointerSize) != 0) {
|
| - frame_pointer -= kPointerSize;
|
| - has_alignment_padding_ = 1;
|
| - }
|
| -
|
| - int32_t alignment_state = (has_alignment_padding_ == 1) ?
|
| - kAlignmentPaddingPushed :
|
| - kNoAlignmentPadding;
|
| - if (FLAG_trace_osr) {
|
| - PrintF(" [sp + %d] <- 0x%08x ; (alignment state)\n",
|
| - output_offset,
|
| - alignment_state);
|
| - }
|
| - output_[0]->SetFrameSlot(output_offset, alignment_state);
|
| - output_offset -= kPointerSize;
|
| -
|
| - // Translate the rest of the frame.
|
| - while (ok && input_offset >= 0) {
|
| - ok = DoOsrTranslateCommand(&iterator, &input_offset);
|
| - }
|
| -
|
| - // If translation of any command failed, continue using the input frame.
|
| - if (!ok) {
|
| - delete output_[0];
|
| - output_[0] = input_;
|
| - output_[0]->SetPc(reinterpret_cast<uint32_t>(from_));
|
| - } else {
|
| - // Set up the frame pointer and the context pointer.
|
| - output_[0]->SetRegister(ebp.code(), frame_pointer);
|
| - output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code()));
|
| -
|
| - unsigned pc_offset = data->OsrPcOffset()->value();
|
| - uint32_t pc = reinterpret_cast<uint32_t>(
|
| - compiled_code_->entry() + pc_offset);
|
| - output_[0]->SetPc(pc);
|
| - }
|
| - Code* continuation =
|
| - function_->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
|
| - output_[0]->SetContinuation(
|
| - reinterpret_cast<uint32_t>(continuation->entry()));
|
| -
|
| - if (FLAG_trace_osr) {
|
| - PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
|
| - ok ? "finished" : "aborted",
|
| - reinterpret_cast<intptr_t>(function_));
|
| - PrintFunctionName();
|
| - PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
|
| - }
|
| -}
|
| -
|
| -
|
| void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
|
| // Set the register values. The values are not important as there are no
|
| // callee saved registers in JavaScript frames, so all registers are
|
| @@ -611,27 +425,17 @@ void Deoptimizer::EntryGenerator::Generate() {
|
| }
|
| __ pop(eax);
|
|
|
| - if (type() != OSR) {
|
| - // If frame was dynamically aligned, pop padding.
|
| - Label no_padding;
|
| - __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
|
| - Immediate(0));
|
| - __ j(equal, &no_padding);
|
| - __ pop(ecx);
|
| - if (FLAG_debug_code) {
|
| - __ cmp(ecx, Immediate(kAlignmentZapValue));
|
| - __ Assert(equal, kAlignmentMarkerExpected);
|
| - }
|
| - __ bind(&no_padding);
|
| - } else {
|
| - // If frame needs dynamic alignment push padding.
|
| - Label no_padding;
|
| - __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
|
| - Immediate(0));
|
| - __ j(equal, &no_padding);
|
| - __ push(Immediate(kAlignmentZapValue));
|
| - __ bind(&no_padding);
|
| + // If frame was dynamically aligned, pop padding.
|
| + Label no_padding;
|
| + __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
|
| + Immediate(0));
|
| + __ j(equal, &no_padding);
|
| + __ pop(ecx);
|
| + if (FLAG_debug_code) {
|
| + __ cmp(ecx, Immediate(kAlignmentZapValue));
|
| + __ Assert(equal, kAlignmentMarkerExpected);
|
| }
|
| + __ bind(&no_padding);
|
|
|
| // Replace the current frame with the output frames.
|
| Label outer_push_loop, inner_push_loop,
|
| @@ -658,7 +462,7 @@ void Deoptimizer::EntryGenerator::Generate() {
|
| __ cmp(eax, edx);
|
| __ j(below, &outer_push_loop);
|
|
|
| - // In case of OSR or a failed STUB, we have to restore the XMM registers.
|
| + // In case of a failed STUB, we have to restore the XMM registers.
|
| if (CpuFeatures::IsSupported(SSE2)) {
|
| CpuFeatureScope scope(masm(), SSE2);
|
| for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
|
| @@ -669,9 +473,7 @@ void Deoptimizer::EntryGenerator::Generate() {
|
| }
|
|
|
| // Push state, pc, and continuation from the last output frame.
|
| - if (type() != OSR) {
|
| - __ push(Operand(ebx, FrameDescription::state_offset()));
|
| - }
|
| + __ push(Operand(ebx, FrameDescription::state_offset()));
|
| __ push(Operand(ebx, FrameDescription::pc_offset()));
|
| __ push(Operand(ebx, FrameDescription::continuation_offset()));
|
|
|
|
|