| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 // the frame (that is done in GeneratePrologue). | 83 // the frame (that is done in GeneratePrologue). |
| 84 FrameScope frame_scope(masm_, StackFrame::MANUAL); | 84 FrameScope frame_scope(masm_, StackFrame::MANUAL); |
| 85 | 85 |
| 86 support_aligned_spilled_doubles_ = info()->IsOptimizing(); | 86 support_aligned_spilled_doubles_ = info()->IsOptimizing(); |
| 87 | 87 |
| 88 dynamic_frame_alignment_ = info()->IsOptimizing() && | 88 dynamic_frame_alignment_ = info()->IsOptimizing() && |
| 89 ((chunk()->num_double_slots() > 2 && | 89 ((chunk()->num_double_slots() > 2 && |
| 90 !chunk()->graph()->is_recursive()) || | 90 !chunk()->graph()->is_recursive()) || |
| 91 !info()->osr_ast_id().IsNone()); | 91 !info()->osr_ast_id().IsNone()); |
| 92 | 92 |
| 93 handler_table_ = isolate()->factory()->NewFixedArray( |
| 94 info()->function() != NULL ? info()->function()->handler_count() : 0, |
| 95 TENURED); |
| 96 |
| 97 |
| 93 return GeneratePrologue() && | 98 return GeneratePrologue() && |
| 94 GenerateBody() && | 99 GenerateBody() && |
| 95 GenerateDeferredCode() && | 100 GenerateDeferredCode() && |
| 96 GenerateJumpTable() && | 101 GenerateJumpTable() && |
| 97 GenerateSafepointTable(); | 102 GenerateSafepointTable(); |
| 98 } | 103 } |
| 99 | 104 |
| 100 | 105 |
| 101 void LCodeGen::FinishCode(Handle<Code> code) { | 106 void LCodeGen::FinishCode(Handle<Code> code) { |
| 102 ASSERT(is_done()); | 107 ASSERT(is_done()); |
| 103 code->set_stack_slots(GetStackSlotCount()); | 108 code->set_stack_slots(GetStackSlotCount()); |
| 104 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); | 109 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); |
| 110 code->set_handler_table(*handler_table_); |
| 105 if (FLAG_weak_embedded_maps_in_optimized_code) { | 111 if (FLAG_weak_embedded_maps_in_optimized_code) { |
| 106 RegisterDependentCodeForEmbeddedMaps(code); | 112 RegisterDependentCodeForEmbeddedMaps(code); |
| 107 } | 113 } |
| 108 PopulateDeoptimizationData(code); | 114 PopulateDeoptimizationData(code); |
| 109 if (!info()->IsStub()) { | 115 if (!info()->IsStub()) { |
| 110 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); | 116 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); |
| 111 } | 117 } |
| 112 info()->CommitDependentMaps(code); | 118 info()->CommitDependentMaps(code); |
| 113 } | 119 } |
| 114 | 120 |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 int height = translation_size - environment->parameter_count(); | 629 int height = translation_size - environment->parameter_count(); |
| 624 | 630 |
| 625 WriteTranslation(environment->outer(), translation); | 631 WriteTranslation(environment->outer(), translation); |
| 626 bool has_closure_id = !info()->closure().is_null() && | 632 bool has_closure_id = !info()->closure().is_null() && |
| 627 !info()->closure().is_identical_to(environment->closure()); | 633 !info()->closure().is_identical_to(environment->closure()); |
| 628 int closure_id = has_closure_id | 634 int closure_id = has_closure_id |
| 629 ? DefineDeoptimizationLiteral(environment->closure()) | 635 ? DefineDeoptimizationLiteral(environment->closure()) |
| 630 : Translation::kSelfLiteralId; | 636 : Translation::kSelfLiteralId; |
| 631 switch (environment->frame_type()) { | 637 switch (environment->frame_type()) { |
| 632 case JS_FUNCTION: | 638 case JS_FUNCTION: |
| 633 translation->BeginJSFrame(environment->ast_id(), closure_id, height); | 639 translation->BeginJSFrame(environment->ast_id(), closure_id, height, |
| 640 environment->handler_count()); |
| 634 break; | 641 break; |
| 635 case JS_CONSTRUCT: | 642 case JS_CONSTRUCT: |
| 636 translation->BeginConstructStubFrame(closure_id, translation_size); | 643 translation->BeginConstructStubFrame(closure_id, translation_size); |
| 637 break; | 644 break; |
| 638 case JS_GETTER: | 645 case JS_GETTER: |
| 639 ASSERT(translation_size == 1); | 646 ASSERT(translation_size == 1); |
| 640 ASSERT(height == 0); | 647 ASSERT(height == 0); |
| 641 translation->BeginGetterStubFrame(closure_id); | 648 translation->BeginGetterStubFrame(closure_id); |
| 642 break; | 649 break; |
| 643 case JS_SETTER: | 650 case JS_SETTER: |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); | 1008 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); |
| 1002 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); | 1009 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); |
| 1003 | 1010 |
| 1004 // Populate the deoptimization entries. | 1011 // Populate the deoptimization entries. |
| 1005 for (int i = 0; i < length; i++) { | 1012 for (int i = 0; i < length; i++) { |
| 1006 LEnvironment* env = deoptimizations_[i]; | 1013 LEnvironment* env = deoptimizations_[i]; |
| 1007 data->SetAstId(i, env->ast_id()); | 1014 data->SetAstId(i, env->ast_id()); |
| 1008 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); | 1015 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); |
| 1009 data->SetArgumentsStackHeight(i, | 1016 data->SetArgumentsStackHeight(i, |
| 1010 Smi::FromInt(env->arguments_stack_height())); | 1017 Smi::FromInt(env->arguments_stack_height())); |
| 1018 // Write the total handler count to the deoptimization data, used to |
| 1019 // determine the stack sizes. |
| 1020 int handler_count = 0; |
| 1021 LEnvironment* current = env; |
| 1022 do { |
| 1023 handler_count += current->handler_count(); |
| 1024 current = current->outer(); |
| 1025 } while (current != NULL); |
| 1026 data->SetHandlerCount(i, Smi::FromInt(handler_count)); |
| 1027 |
| 1011 data->SetPc(i, Smi::FromInt(env->pc_offset())); | 1028 data->SetPc(i, Smi::FromInt(env->pc_offset())); |
| 1012 } | 1029 } |
| 1013 code->set_deoptimization_data(*data); | 1030 code->set_deoptimization_data(*data); |
| 1014 } | 1031 } |
| 1015 | 1032 |
| 1016 | 1033 |
| 1017 int LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { | 1034 int LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { |
| 1018 int result = deoptimization_literals_.length(); | 1035 int result = deoptimization_literals_.length(); |
| 1019 for (int i = 0; i < deoptimization_literals_.length(); ++i) { | 1036 for (int i = 0; i < deoptimization_literals_.length(); ++i) { |
| 1020 if (deoptimization_literals_[i].is_identical_to(literal)) return i; | 1037 if (deoptimization_literals_[i].is_identical_to(literal)) return i; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 if (move != NULL) DoParallelMove(move); | 1147 if (move != NULL) DoParallelMove(move); |
| 1131 } | 1148 } |
| 1132 } | 1149 } |
| 1133 | 1150 |
| 1134 | 1151 |
| 1135 void LCodeGen::DoInstructionGap(LInstructionGap* instr) { | 1152 void LCodeGen::DoInstructionGap(LInstructionGap* instr) { |
| 1136 DoGap(instr); | 1153 DoGap(instr); |
| 1137 } | 1154 } |
| 1138 | 1155 |
| 1139 | 1156 |
| 1157 void LCodeGen::DoEnterTry(LEnterTry* instr) { |
| 1158 Label try_entry, handler_entry; |
| 1159 __ jmp(&try_entry); |
| 1160 __ bind(&handler_entry); |
| 1161 handler_table_->set(instr->hydrogen()->index(), |
| 1162 Smi::FromInt(handler_entry.pos())); |
| 1163 // Save code object. |
| 1164 __ push(edi); |
| 1165 // Pass code object as argument. |
| 1166 __ push(edi); |
| 1167 // Call Runtime_CatchInOptimizedCode which patches the code with the call to |
| 1168 // the deopt stub and returns the offset to the address we must jump to. |
| 1169 __ CallRuntime(Runtime::kCatchInOptimizedCode, 1); |
| 1170 // Get actual offset. |
| 1171 __ SmiUntag(eax); |
| 1172 // Restore code object. |
| 1173 __ pop(edi); |
| 1174 // Compute the target PC adding the offset to the code object. |
| 1175 __ add(edi, eax); |
| 1176 // Jump to target PC. |
| 1177 __ jmp(edi); |
| 1178 __ Abort("Unreachable (the exception should have been caught)."); |
| 1179 __ bind(&try_entry); |
| 1180 __ PushTryHandler(StackHandler::OPTIMIZED_CATCH, instr->index()); |
| 1181 } |
| 1182 |
| 1183 |
| 1184 void LCodeGen::DoLeaveTry(LLeaveTry* instr) { |
| 1185 __ PopTryHandler(); |
| 1186 } |
| 1187 |
| 1188 |
| 1140 void LCodeGen::DoParameter(LParameter* instr) { | 1189 void LCodeGen::DoParameter(LParameter* instr) { |
| 1141 // Nothing to do. | 1190 // Nothing to do. |
| 1142 } | 1191 } |
| 1143 | 1192 |
| 1144 | 1193 |
| 1145 void LCodeGen::DoCallStub(LCallStub* instr) { | 1194 void LCodeGen::DoCallStub(LCallStub* instr) { |
| 1146 ASSERT(ToRegister(instr->context()).is(esi)); | 1195 ASSERT(ToRegister(instr->context()).is(esi)); |
| 1147 ASSERT(ToRegister(instr->result()).is(eax)); | 1196 ASSERT(ToRegister(instr->result()).is(eax)); |
| 1148 switch (instr->hydrogen()->major_key()) { | 1197 switch (instr->hydrogen()->major_key()) { |
| 1149 case CodeStub::RegExpConstructResult: { | 1198 case CodeStub::RegExpConstructResult: { |
| (...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1919 ASSERT(input->Equals(instr->result())); | 1968 ASSERT(input->Equals(instr->result())); |
| 1920 __ not_(ToRegister(input)); | 1969 __ not_(ToRegister(input)); |
| 1921 } | 1970 } |
| 1922 | 1971 |
| 1923 | 1972 |
| 1924 void LCodeGen::DoThrow(LThrow* instr) { | 1973 void LCodeGen::DoThrow(LThrow* instr) { |
| 1925 __ push(ToOperand(instr->value())); | 1974 __ push(ToOperand(instr->value())); |
| 1926 ASSERT(ToRegister(instr->context()).is(esi)); | 1975 ASSERT(ToRegister(instr->context()).is(esi)); |
| 1927 CallRuntime(Runtime::kThrow, 1, instr); | 1976 CallRuntime(Runtime::kThrow, 1, instr); |
| 1928 | 1977 |
| 1978 // Code after a throw now is reachable... |
| 1979 #if false |
| 1929 if (FLAG_debug_code) { | 1980 if (FLAG_debug_code) { |
| 1930 Comment("Unreachable code."); | 1981 Comment("Code after a throw should be unreachable."); |
| 1931 __ int3(); | 1982 __ int3(); |
| 1932 } | 1983 } |
| 1984 #endif |
| 1933 } | 1985 } |
| 1934 | 1986 |
| 1935 | 1987 |
| 1936 void LCodeGen::DoAddI(LAddI* instr) { | 1988 void LCodeGen::DoAddI(LAddI* instr) { |
| 1937 LOperand* left = instr->left(); | 1989 LOperand* left = instr->left(); |
| 1938 LOperand* right = instr->right(); | 1990 LOperand* right = instr->right(); |
| 1939 | 1991 |
| 1940 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { | 1992 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { |
| 1941 if (right->IsConstantOperand()) { | 1993 if (right->IsConstantOperand()) { |
| 1942 int32_t offset = ToInteger32(LConstantOperand::cast(right)); | 1994 int32_t offset = ToInteger32(LConstantOperand::cast(right)); |
| (...skipping 4617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6560 FixedArray::kHeaderSize - kPointerSize)); | 6612 FixedArray::kHeaderSize - kPointerSize)); |
| 6561 __ bind(&done); | 6613 __ bind(&done); |
| 6562 } | 6614 } |
| 6563 | 6615 |
| 6564 | 6616 |
| 6565 #undef __ | 6617 #undef __ |
| 6566 | 6618 |
| 6567 } } // namespace v8::internal | 6619 } } // namespace v8::internal |
| 6568 | 6620 |
| 6569 #endif // V8_TARGET_ARCH_IA32 | 6621 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |