Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 10910161: Partial ia32 implementation of optimized try/catch (by Kevin Millikin) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed build. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698