OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 ast_id, | 260 ast_id, |
261 input_frame_size, | 261 input_frame_size, |
262 output_frame_size); | 262 output_frame_size); |
263 } | 263 } |
264 | 264 |
265 // There's only one output frame in the OSR case. | 265 // There's only one output frame in the OSR case. |
266 output_count_ = 1; | 266 output_count_ = 1; |
267 output_ = new FrameDescription*[1]; | 267 output_ = new FrameDescription*[1]; |
268 output_[0] = new(output_frame_size) FrameDescription( | 268 output_[0] = new(output_frame_size) FrameDescription( |
269 output_frame_size, function_); | 269 output_frame_size, function_); |
| 270 #ifdef DEBUG |
| 271 output_[0]->SetKind(Code::OPTIMIZED_FUNCTION); |
| 272 #endif |
270 | 273 |
271 // Clear the incoming parameters in the optimized frame to avoid | 274 // Clear the incoming parameters in the optimized frame to avoid |
272 // confusing the garbage collector. | 275 // confusing the garbage collector. |
273 unsigned output_offset = output_frame_size - kPointerSize; | 276 unsigned output_offset = output_frame_size - kPointerSize; |
274 int parameter_count = function_->shared()->formal_parameter_count() + 1; | 277 int parameter_count = function_->shared()->formal_parameter_count() + 1; |
275 for (int i = 0; i < parameter_count; ++i) { | 278 for (int i = 0; i < parameter_count; ++i) { |
276 output_[0]->SetFrameSlot(output_offset, 0); | 279 output_[0]->SetFrameSlot(output_offset, 0); |
277 output_offset -= kPointerSize; | 280 output_offset -= kPointerSize; |
278 } | 281 } |
279 | 282 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 | 378 |
376 // The 'fixed' part of the frame consists of the incoming parameters and | 379 // The 'fixed' part of the frame consists of the incoming parameters and |
377 // the part described by JavaScriptFrameConstants. | 380 // the part described by JavaScriptFrameConstants. |
378 unsigned fixed_frame_size = ComputeFixedSize(function); | 381 unsigned fixed_frame_size = ComputeFixedSize(function); |
379 unsigned input_frame_size = input_->GetFrameSize(); | 382 unsigned input_frame_size = input_->GetFrameSize(); |
380 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 383 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
381 | 384 |
382 // Allocate and store the output frame description. | 385 // Allocate and store the output frame description. |
383 FrameDescription* output_frame = | 386 FrameDescription* output_frame = |
384 new(output_frame_size) FrameDescription(output_frame_size, function); | 387 new(output_frame_size) FrameDescription(output_frame_size, function); |
| 388 #ifdef DEBUG |
| 389 output_frame->SetKind(Code::FUNCTION); |
| 390 #endif |
385 | 391 |
386 bool is_bottommost = (0 == frame_index); | 392 bool is_bottommost = (0 == frame_index); |
387 bool is_topmost = (output_count_ - 1 == frame_index); | 393 bool is_topmost = (output_count_ - 1 == frame_index); |
388 ASSERT(frame_index >= 0 && frame_index < output_count_); | 394 ASSERT(frame_index >= 0 && frame_index < output_count_); |
389 ASSERT(output_[frame_index] == NULL); | 395 ASSERT(output_[frame_index] == NULL); |
390 output_[frame_index] = output_frame; | 396 output_[frame_index] = output_frame; |
391 | 397 |
392 // The top address for the bottommost output frame can be computed from | 398 // The top address for the bottommost output frame can be computed from |
393 // the input frame pointer and the output frame's height. For all | 399 // the input frame pointer and the output frame's height. For all |
394 // subsequent output frames, it can be computed from the previous one's | 400 // subsequent output frames, it can be computed from the previous one's |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 if (is_topmost) { | 515 if (is_topmost) { |
510 output_frame->SetRegister(pc.code(), pc_value); | 516 output_frame->SetRegister(pc.code(), pc_value); |
511 } | 517 } |
512 | 518 |
513 FullCodeGenerator::State state = | 519 FullCodeGenerator::State state = |
514 FullCodeGenerator::StateField::decode(pc_and_state); | 520 FullCodeGenerator::StateField::decode(pc_and_state); |
515 output_frame->SetState(Smi::FromInt(state)); | 521 output_frame->SetState(Smi::FromInt(state)); |
516 | 522 |
517 | 523 |
518 // Set the continuation for the topmost frame. | 524 // Set the continuation for the topmost frame. |
519 if (is_topmost) { | 525 if (is_topmost && bailout_type_ != DEBUGGER) { |
520 Builtins* builtins = isolate_->builtins(); | 526 Builtins* builtins = isolate_->builtins(); |
521 Code* continuation = (bailout_type_ == EAGER) | 527 Code* continuation = (bailout_type_ == EAGER) |
522 ? builtins->builtin(Builtins::kNotifyDeoptimized) | 528 ? builtins->builtin(Builtins::kNotifyDeoptimized) |
523 : builtins->builtin(Builtins::kNotifyLazyDeoptimized); | 529 : builtins->builtin(Builtins::kNotifyLazyDeoptimized); |
524 output_frame->SetContinuation( | 530 output_frame->SetContinuation( |
525 reinterpret_cast<uint32_t>(continuation->entry())); | 531 reinterpret_cast<uint32_t>(continuation->entry())); |
526 } | 532 } |
527 | 533 |
528 if (output_count_ - 1 == frame_index) iterator->Done(); | 534 if (output_count_ - 1 == frame_index) iterator->Done(); |
529 } | 535 } |
530 | 536 |
531 | 537 |
| 538 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { |
| 539 // Set the register values. The values are not important as there are no |
| 540 // callee saved registers in JavaScript frames, so all registers are |
| 541 // spilled. Registers fp and sp are set to the correct values though. |
| 542 |
| 543 for (int i = 0; i < Register::kNumRegisters; i++) { |
| 544 input_->SetRegister(i, i * 4); |
| 545 } |
| 546 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); |
| 547 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); |
| 548 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) { |
| 549 input_->SetDoubleRegister(i, 0.0); |
| 550 } |
| 551 |
| 552 // Fill the frame content from the actual data on the frame. |
| 553 for (intptr_t i = 0; i < input_->GetFrameSize(); i += kPointerSize) { |
| 554 input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); |
| 555 } |
| 556 } |
| 557 |
| 558 |
532 #define __ masm()-> | 559 #define __ masm()-> |
533 | 560 |
534 | |
535 // This code tries to be close to ia32 code so that any changes can be | 561 // This code tries to be close to ia32 code so that any changes can be |
536 // easily ported. | 562 // easily ported. |
537 void Deoptimizer::EntryGenerator::Generate() { | 563 void Deoptimizer::EntryGenerator::Generate() { |
538 GeneratePrologue(); | 564 GeneratePrologue(); |
539 | 565 |
540 Isolate* isolate = masm()->isolate(); | 566 Isolate* isolate = masm()->isolate(); |
541 | 567 |
542 CpuFeatures::Scope scope(VFP3); | 568 CpuFeatures::Scope scope(VFP3); |
543 // Save all general purpose registers before messing with them. | 569 // Save all general purpose registers before messing with them. |
544 const int kNumberOfRegisters = Register::kNumRegisters; | 570 const int kNumberOfRegisters = Register::kNumRegisters; |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 __ push(ip); | 762 __ push(ip); |
737 __ b(&done); | 763 __ b(&done); |
738 ASSERT(masm()->pc_offset() - start == table_entry_size_); | 764 ASSERT(masm()->pc_offset() - start == table_entry_size_); |
739 } | 765 } |
740 __ bind(&done); | 766 __ bind(&done); |
741 } | 767 } |
742 | 768 |
743 #undef __ | 769 #undef __ |
744 | 770 |
745 } } // namespace v8::internal | 771 } } // namespace v8::internal |
OLD | NEW |