| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 | 76 |
| 77 // Open a frame scope to indicate that there is a frame on the stack. The | 77 // Open a frame scope to indicate that there is a frame on the stack. The |
| 78 // MANUAL indicates that the scope shouldn't actually generate code to set up | 78 // MANUAL indicates that the scope shouldn't actually generate code to set up |
| 79 // the frame (that is done in GeneratePrologue). | 79 // the frame (that is done in GeneratePrologue). |
| 80 FrameScope frame_scope(masm_, StackFrame::MANUAL); | 80 FrameScope frame_scope(masm_, StackFrame::MANUAL); |
| 81 | 81 |
| 82 dynamic_frame_alignment_ = (chunk()->num_double_slots() > 2 && | 82 dynamic_frame_alignment_ = (chunk()->num_double_slots() > 2 && |
| 83 !chunk()->graph()->is_recursive()) || | 83 !chunk()->graph()->is_recursive()) || |
| 84 !info()->osr_ast_id().IsNone(); | 84 !info()->osr_ast_id().IsNone(); |
| 85 | 85 |
| 86 handler_table_ = isolate()->factory()->NewFixedArray( |
| 87 info()->function()->handler_count(), TENURED); |
| 88 |
| 89 |
| 86 return GeneratePrologue() && | 90 return GeneratePrologue() && |
| 87 GenerateBody() && | 91 GenerateBody() && |
| 88 GenerateDeferredCode() && | 92 GenerateDeferredCode() && |
| 89 GenerateSafepointTable(); | 93 GenerateSafepointTable(); |
| 90 } | 94 } |
| 91 | 95 |
| 92 | 96 |
| 93 void LCodeGen::FinishCode(Handle<Code> code) { | 97 void LCodeGen::FinishCode(Handle<Code> code) { |
| 94 ASSERT(is_done()); | 98 ASSERT(is_done()); |
| 95 code->set_stack_slots(GetStackSlotCount()); | 99 code->set_stack_slots(GetStackSlotCount()); |
| 96 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); | 100 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); |
| 101 code->set_handler_table(*handler_table_); |
| 97 PopulateDeoptimizationData(code); | 102 PopulateDeoptimizationData(code); |
| 98 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); | 103 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); |
| 99 } | 104 } |
| 100 | 105 |
| 101 | 106 |
| 102 void LCodeGen::Abort(const char* reason) { | 107 void LCodeGen::Abort(const char* reason) { |
| 103 info()->set_bailout_reason(reason); | 108 info()->set_bailout_reason(reason); |
| 104 status_ = ABORTED; | 109 status_ = ABORTED; |
| 105 } | 110 } |
| 106 | 111 |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 int translation_size = environment->values()->length(); | 416 int translation_size = environment->values()->length(); |
| 412 // The output frame height does not include the parameters. | 417 // The output frame height does not include the parameters. |
| 413 int height = translation_size - environment->parameter_count(); | 418 int height = translation_size - environment->parameter_count(); |
| 414 | 419 |
| 415 WriteTranslation(environment->outer(), translation); | 420 WriteTranslation(environment->outer(), translation); |
| 416 int closure_id = *info()->closure() != *environment->closure() | 421 int closure_id = *info()->closure() != *environment->closure() |
| 417 ? DefineDeoptimizationLiteral(environment->closure()) | 422 ? DefineDeoptimizationLiteral(environment->closure()) |
| 418 : Translation::kSelfLiteralId; | 423 : Translation::kSelfLiteralId; |
| 419 switch (environment->frame_type()) { | 424 switch (environment->frame_type()) { |
| 420 case JS_FUNCTION: | 425 case JS_FUNCTION: |
| 421 translation->BeginJSFrame(environment->ast_id(), closure_id, height); | 426 translation->BeginJSFrame(environment->ast_id(), closure_id, height, |
| 427 environment->handler_count()); |
| 422 break; | 428 break; |
| 423 case JS_CONSTRUCT: | 429 case JS_CONSTRUCT: |
| 424 translation->BeginConstructStubFrame(closure_id, translation_size); | 430 translation->BeginConstructStubFrame(closure_id, translation_size); |
| 425 break; | 431 break; |
| 426 case JS_GETTER: | 432 case JS_GETTER: |
| 427 ASSERT(translation_size == 1); | 433 ASSERT(translation_size == 1); |
| 428 ASSERT(height == 0); | 434 ASSERT(height == 0); |
| 429 translation->BeginGetterStubFrame(closure_id); | 435 translation->BeginGetterStubFrame(closure_id); |
| 430 break; | 436 break; |
| 431 case JS_SETTER: | 437 case JS_SETTER: |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); | 696 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); |
| 691 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); | 697 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); |
| 692 | 698 |
| 693 // Populate the deoptimization entries. | 699 // Populate the deoptimization entries. |
| 694 for (int i = 0; i < length; i++) { | 700 for (int i = 0; i < length; i++) { |
| 695 LEnvironment* env = deoptimizations_[i]; | 701 LEnvironment* env = deoptimizations_[i]; |
| 696 data->SetAstId(i, env->ast_id()); | 702 data->SetAstId(i, env->ast_id()); |
| 697 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); | 703 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); |
| 698 data->SetArgumentsStackHeight(i, | 704 data->SetArgumentsStackHeight(i, |
| 699 Smi::FromInt(env->arguments_stack_height())); | 705 Smi::FromInt(env->arguments_stack_height())); |
| 706 // Write the total handler count to the deoptimization data, used to |
| 707 // determine the stack sizes. |
| 708 int handler_count = 0; |
| 709 LEnvironment* current = env; |
| 710 do { |
| 711 handler_count += current->handler_count(); |
| 712 current = current->outer(); |
| 713 } while (current != NULL); |
| 714 data->SetHandlerCount(i, Smi::FromInt(handler_count)); |
| 715 |
| 700 data->SetPc(i, Smi::FromInt(env->pc_offset())); | 716 data->SetPc(i, Smi::FromInt(env->pc_offset())); |
| 701 } | 717 } |
| 702 code->set_deoptimization_data(*data); | 718 code->set_deoptimization_data(*data); |
| 703 } | 719 } |
| 704 | 720 |
| 705 | 721 |
| 706 int LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { | 722 int LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { |
| 707 int result = deoptimization_literals_.length(); | 723 int result = deoptimization_literals_.length(); |
| 708 for (int i = 0; i < deoptimization_literals_.length(); ++i) { | 724 for (int i = 0; i < deoptimization_literals_.length(); ++i) { |
| 709 if (deoptimization_literals_[i].is_identical_to(literal)) return i; | 725 if (deoptimization_literals_[i].is_identical_to(literal)) return i; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 if (move != NULL) DoParallelMove(move); | 828 if (move != NULL) DoParallelMove(move); |
| 813 } | 829 } |
| 814 } | 830 } |
| 815 | 831 |
| 816 | 832 |
| 817 void LCodeGen::DoInstructionGap(LInstructionGap* instr) { | 833 void LCodeGen::DoInstructionGap(LInstructionGap* instr) { |
| 818 DoGap(instr); | 834 DoGap(instr); |
| 819 } | 835 } |
| 820 | 836 |
| 821 | 837 |
| 838 void LCodeGen::DoEnterTry(LEnterTry* instr) { |
| 839 Label try_entry, handler_entry; |
| 840 __ jmp(&try_entry); |
| 841 __ bind(&handler_entry); |
| 842 handler_table_->set(instr->hydrogen()->index(), |
| 843 Smi::FromInt(handler_entry.pos())); |
| 844 // Save code object. |
| 845 __ push(edi); |
| 846 // Pass code object as argument. |
| 847 __ push(edi); |
| 848 // Call Runtime_CatchInOptimizedCode which patches the code with the call to |
| 849 // the deopt stub and returns the offset to the address we must jump to. |
| 850 __ CallRuntime(Runtime::kCatchInOptimizedCode, 1); |
| 851 // Get actual offset. |
| 852 __ SmiUntag(eax); |
| 853 // Restore code object. |
| 854 __ pop(edi); |
| 855 // Compute the target PC adding the offset to the code object. |
| 856 __ add(edi, eax); |
| 857 // Jump to target PC. |
| 858 __ jmp(edi); |
| 859 __ Abort("Unreachable (the exception should have been caught)."); |
| 860 __ bind(&try_entry); |
| 861 __ PushTryHandler(StackHandler::OPTIMIZED_CATCH, instr->index()); |
| 862 } |
| 863 |
| 864 |
| 865 void LCodeGen::DoLeaveTry(LLeaveTry* instr) { |
| 866 __ PopTryHandler(); |
| 867 } |
| 868 |
| 869 |
| 822 void LCodeGen::DoParameter(LParameter* instr) { | 870 void LCodeGen::DoParameter(LParameter* instr) { |
| 823 // Nothing to do. | 871 // Nothing to do. |
| 824 } | 872 } |
| 825 | 873 |
| 826 | 874 |
| 827 void LCodeGen::DoCallStub(LCallStub* instr) { | 875 void LCodeGen::DoCallStub(LCallStub* instr) { |
| 828 ASSERT(ToRegister(instr->context()).is(esi)); | 876 ASSERT(ToRegister(instr->context()).is(esi)); |
| 829 ASSERT(ToRegister(instr->result()).is(eax)); | 877 ASSERT(ToRegister(instr->result()).is(eax)); |
| 830 switch (instr->hydrogen()->major_key()) { | 878 switch (instr->hydrogen()->major_key()) { |
| 831 case CodeStub::RegExpConstructResult: { | 879 case CodeStub::RegExpConstructResult: { |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1481 ASSERT(input->Equals(instr->result())); | 1529 ASSERT(input->Equals(instr->result())); |
| 1482 __ not_(ToRegister(input)); | 1530 __ not_(ToRegister(input)); |
| 1483 } | 1531 } |
| 1484 | 1532 |
| 1485 | 1533 |
| 1486 void LCodeGen::DoThrow(LThrow* instr) { | 1534 void LCodeGen::DoThrow(LThrow* instr) { |
| 1487 __ push(ToOperand(instr->value())); | 1535 __ push(ToOperand(instr->value())); |
| 1488 ASSERT(ToRegister(instr->context()).is(esi)); | 1536 ASSERT(ToRegister(instr->context()).is(esi)); |
| 1489 CallRuntime(Runtime::kThrow, 1, instr); | 1537 CallRuntime(Runtime::kThrow, 1, instr); |
| 1490 | 1538 |
| 1539 // Code after a throw now is reachable... |
| 1540 #if false |
| 1491 if (FLAG_debug_code) { | 1541 if (FLAG_debug_code) { |
| 1492 Comment("Unreachable code."); | 1542 Comment("Code after a throw should be unreachable."); |
| 1493 __ int3(); | 1543 __ int3(); |
| 1494 } | 1544 } |
| 1545 #endif |
| 1495 } | 1546 } |
| 1496 | 1547 |
| 1497 | 1548 |
| 1498 void LCodeGen::DoAddI(LAddI* instr) { | 1549 void LCodeGen::DoAddI(LAddI* instr) { |
| 1499 LOperand* left = instr->InputAt(0); | 1550 LOperand* left = instr->InputAt(0); |
| 1500 LOperand* right = instr->InputAt(1); | 1551 LOperand* right = instr->InputAt(1); |
| 1501 ASSERT(left->Equals(instr->result())); | 1552 ASSERT(left->Equals(instr->result())); |
| 1502 | 1553 |
| 1503 if (right->IsConstantOperand()) { | 1554 if (right->IsConstantOperand()) { |
| 1504 __ add(ToOperand(left), ToInteger32Immediate(right)); | 1555 __ add(ToOperand(left), ToInteger32Immediate(right)); |
| (...skipping 4008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5513 FixedArray::kHeaderSize - kPointerSize)); | 5564 FixedArray::kHeaderSize - kPointerSize)); |
| 5514 __ bind(&done); | 5565 __ bind(&done); |
| 5515 } | 5566 } |
| 5516 | 5567 |
| 5517 | 5568 |
| 5518 #undef __ | 5569 #undef __ |
| 5519 | 5570 |
| 5520 } } // namespace v8::internal | 5571 } } // namespace v8::internal |
| 5521 | 5572 |
| 5522 #endif // V8_TARGET_ARCH_IA32 | 5573 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |