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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 | 440 |
441 | 441 |
442 bool LCodeGen::GenerateDeferredCode() { | 442 bool LCodeGen::GenerateDeferredCode() { |
443 ASSERT(is_generating()); | 443 ASSERT(is_generating()); |
444 if (deferred_.length() > 0) { | 444 if (deferred_.length() > 0) { |
445 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 445 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
446 LDeferredCode* code = deferred_[i]; | 446 LDeferredCode* code = deferred_[i]; |
447 X87Stack copy(code->x87_stack()); | 447 X87Stack copy(code->x87_stack()); |
448 x87_stack_ = copy; | 448 x87_stack_ = copy; |
449 | 449 |
450 int pos = instructions_->at(code->instruction_index())->position(); | 450 HValue* value = |
451 RecordAndUpdatePosition(pos); | 451 instructions_->at(code->instruction_index())->hydrogen_value(); |
| 452 RecordAndWritePosition(value->position()); |
452 | 453 |
453 Comment(";;; <@%d,#%d> " | 454 Comment(";;; <@%d,#%d> " |
454 "-------------------- Deferred %s --------------------", | 455 "-------------------- Deferred %s --------------------", |
455 code->instruction_index(), | 456 code->instruction_index(), |
456 code->instr()->hydrogen_value()->id(), | 457 code->instr()->hydrogen_value()->id(), |
457 code->instr()->Mnemonic()); | 458 code->instr()->Mnemonic()); |
458 __ bind(code->entry()); | 459 __ bind(code->entry()); |
459 if (NeedsDeferredFrame()) { | 460 if (NeedsDeferredFrame()) { |
460 Comment(";;; Build frame"); | 461 Comment(";;; Build frame"); |
461 ASSERT(!frame_is_built_); | 462 ASSERT(!frame_is_built_); |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 UNREACHABLE(); | 929 UNREACHABLE(); |
929 } | 930 } |
930 } | 931 } |
931 | 932 |
932 | 933 |
933 void LCodeGen::CallCodeGeneric(Handle<Code> code, | 934 void LCodeGen::CallCodeGeneric(Handle<Code> code, |
934 RelocInfo::Mode mode, | 935 RelocInfo::Mode mode, |
935 LInstruction* instr, | 936 LInstruction* instr, |
936 SafepointMode safepoint_mode) { | 937 SafepointMode safepoint_mode) { |
937 ASSERT(instr != NULL); | 938 ASSERT(instr != NULL); |
938 LPointerMap* pointers = instr->pointer_map(); | |
939 RecordPosition(pointers->position()); | |
940 __ call(code, mode); | 939 __ call(code, mode); |
941 RecordSafepointWithLazyDeopt(instr, safepoint_mode); | 940 RecordSafepointWithLazyDeopt(instr, safepoint_mode); |
942 | 941 |
943 // Signal that we don't inline smi code before these stubs in the | 942 // Signal that we don't inline smi code before these stubs in the |
944 // optimizing code generator. | 943 // optimizing code generator. |
945 if (code->kind() == Code::BINARY_OP_IC || | 944 if (code->kind() == Code::BINARY_OP_IC || |
946 code->kind() == Code::COMPARE_IC) { | 945 code->kind() == Code::COMPARE_IC) { |
947 __ nop(); | 946 __ nop(); |
948 } | 947 } |
949 } | 948 } |
950 | 949 |
951 | 950 |
952 void LCodeGen::CallCode(Handle<Code> code, | 951 void LCodeGen::CallCode(Handle<Code> code, |
953 RelocInfo::Mode mode, | 952 RelocInfo::Mode mode, |
954 LInstruction* instr) { | 953 LInstruction* instr) { |
955 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); | 954 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); |
956 } | 955 } |
957 | 956 |
958 | 957 |
959 void LCodeGen::CallRuntime(const Runtime::Function* fun, | 958 void LCodeGen::CallRuntime(const Runtime::Function* fun, |
960 int argc, | 959 int argc, |
961 LInstruction* instr, | 960 LInstruction* instr, |
962 SaveFPRegsMode save_doubles) { | 961 SaveFPRegsMode save_doubles) { |
963 ASSERT(instr != NULL); | 962 ASSERT(instr != NULL); |
964 ASSERT(instr->HasPointerMap()); | 963 ASSERT(instr->HasPointerMap()); |
965 LPointerMap* pointers = instr->pointer_map(); | |
966 RecordPosition(pointers->position()); | |
967 | 964 |
968 __ CallRuntime(fun, argc, save_doubles); | 965 __ CallRuntime(fun, argc, save_doubles); |
969 | 966 |
970 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 967 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
971 | 968 |
972 ASSERT(info()->is_calling()); | 969 ASSERT(info()->is_calling()); |
973 } | 970 } |
974 | 971 |
975 | 972 |
976 void LCodeGen::LoadContextFromDeferred(LOperand* context) { | 973 void LCodeGen::LoadContextFromDeferred(LOperand* context) { |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1249 } | 1246 } |
1250 | 1247 |
1251 | 1248 |
1252 void LCodeGen::RecordSafepoint(LPointerMap* pointers, | 1249 void LCodeGen::RecordSafepoint(LPointerMap* pointers, |
1253 Safepoint::DeoptMode mode) { | 1250 Safepoint::DeoptMode mode) { |
1254 RecordSafepoint(pointers, Safepoint::kSimple, 0, mode); | 1251 RecordSafepoint(pointers, Safepoint::kSimple, 0, mode); |
1255 } | 1252 } |
1256 | 1253 |
1257 | 1254 |
1258 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode mode) { | 1255 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode mode) { |
1259 LPointerMap empty_pointers(RelocInfo::kNoPosition, zone()); | 1256 LPointerMap empty_pointers(zone()); |
1260 RecordSafepoint(&empty_pointers, mode); | 1257 RecordSafepoint(&empty_pointers, mode); |
1261 } | 1258 } |
1262 | 1259 |
1263 | 1260 |
1264 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, | 1261 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, |
1265 int arguments, | 1262 int arguments, |
1266 Safepoint::DeoptMode mode) { | 1263 Safepoint::DeoptMode mode) { |
1267 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, mode); | 1264 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, mode); |
1268 } | 1265 } |
1269 | 1266 |
1270 | 1267 |
1271 void LCodeGen::RecordPosition(int position) { | 1268 void LCodeGen::RecordAndWritePosition(int position) { |
1272 if (position == RelocInfo::kNoPosition) return; | 1269 if (position == RelocInfo::kNoPosition) return; |
1273 masm()->positions_recorder()->RecordPosition(position); | 1270 masm()->positions_recorder()->RecordPosition(position); |
| 1271 masm()->positions_recorder()->WriteRecordedPositions(); |
1274 } | 1272 } |
1275 | 1273 |
1276 | 1274 |
1277 void LCodeGen::RecordAndUpdatePosition(int position) { | |
1278 if (position >= 0 && position != old_position_) { | |
1279 masm()->positions_recorder()->RecordPosition(position); | |
1280 old_position_ = position; | |
1281 } | |
1282 } | |
1283 | |
1284 | |
1285 static const char* LabelType(LLabel* label) { | 1275 static const char* LabelType(LLabel* label) { |
1286 if (label->is_loop_header()) return " (loop header)"; | 1276 if (label->is_loop_header()) return " (loop header)"; |
1287 if (label->is_osr_entry()) return " (OSR entry)"; | 1277 if (label->is_osr_entry()) return " (OSR entry)"; |
1288 return ""; | 1278 return ""; |
1289 } | 1279 } |
1290 | 1280 |
1291 | 1281 |
1292 void LCodeGen::DoLabel(LLabel* label) { | 1282 void LCodeGen::DoLabel(LLabel* label) { |
1293 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", | 1283 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", |
1294 current_instruction_, | 1284 current_instruction_, |
(...skipping 2383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3678 __ j(zero, &invoke, Label::kNear); | 3668 __ j(zero, &invoke, Label::kNear); |
3679 __ bind(&loop); | 3669 __ bind(&loop); |
3680 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); | 3670 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); |
3681 __ dec(length); | 3671 __ dec(length); |
3682 __ j(not_zero, &loop); | 3672 __ j(not_zero, &loop); |
3683 | 3673 |
3684 // Invoke the function. | 3674 // Invoke the function. |
3685 __ bind(&invoke); | 3675 __ bind(&invoke); |
3686 ASSERT(instr->HasPointerMap()); | 3676 ASSERT(instr->HasPointerMap()); |
3687 LPointerMap* pointers = instr->pointer_map(); | 3677 LPointerMap* pointers = instr->pointer_map(); |
3688 RecordPosition(pointers->position()); | |
3689 SafepointGenerator safepoint_generator( | 3678 SafepointGenerator safepoint_generator( |
3690 this, pointers, Safepoint::kLazyDeopt); | 3679 this, pointers, Safepoint::kLazyDeopt); |
3691 ParameterCount actual(eax); | 3680 ParameterCount actual(eax); |
3692 __ InvokeFunction(function, actual, CALL_FUNCTION, | 3681 __ InvokeFunction(function, actual, CALL_FUNCTION, |
3693 safepoint_generator, CALL_AS_METHOD); | 3682 safepoint_generator, CALL_AS_METHOD); |
3694 } | 3683 } |
3695 | 3684 |
3696 | 3685 |
3697 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { | 3686 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { |
3698 __ int3(); | 3687 __ int3(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3763 int formal_parameter_count, | 3752 int formal_parameter_count, |
3764 int arity, | 3753 int arity, |
3765 LInstruction* instr, | 3754 LInstruction* instr, |
3766 CallKind call_kind, | 3755 CallKind call_kind, |
3767 EDIState edi_state) { | 3756 EDIState edi_state) { |
3768 bool dont_adapt_arguments = | 3757 bool dont_adapt_arguments = |
3769 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3758 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
3770 bool can_invoke_directly = | 3759 bool can_invoke_directly = |
3771 dont_adapt_arguments || formal_parameter_count == arity; | 3760 dont_adapt_arguments || formal_parameter_count == arity; |
3772 | 3761 |
3773 LPointerMap* pointers = instr->pointer_map(); | |
3774 RecordPosition(pointers->position()); | |
3775 | |
3776 if (can_invoke_directly) { | 3762 if (can_invoke_directly) { |
3777 if (edi_state == EDI_UNINITIALIZED) { | 3763 if (edi_state == EDI_UNINITIALIZED) { |
3778 __ LoadHeapObject(edi, function); | 3764 __ LoadHeapObject(edi, function); |
3779 } | 3765 } |
3780 | 3766 |
3781 // Change context. | 3767 // Change context. |
3782 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 3768 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
3783 | 3769 |
3784 // Set eax to arguments count if adaption is not needed. Assumes that eax | 3770 // Set eax to arguments count if adaption is not needed. Assumes that eax |
3785 // is available to write to at this point. | 3771 // is available to write to at this point. |
3786 if (dont_adapt_arguments) { | 3772 if (dont_adapt_arguments) { |
3787 __ mov(eax, arity); | 3773 __ mov(eax, arity); |
3788 } | 3774 } |
3789 | 3775 |
3790 // Invoke function directly. | 3776 // Invoke function directly. |
3791 __ SetCallKind(ecx, call_kind); | 3777 __ SetCallKind(ecx, call_kind); |
3792 if (function.is_identical_to(info()->closure())) { | 3778 if (function.is_identical_to(info()->closure())) { |
3793 __ CallSelf(); | 3779 __ CallSelf(); |
3794 } else { | 3780 } else { |
3795 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 3781 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
3796 } | 3782 } |
3797 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 3783 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
3798 } else { | 3784 } else { |
3799 // We need to adapt arguments. | 3785 // We need to adapt arguments. |
| 3786 LPointerMap* pointers = instr->pointer_map(); |
3800 SafepointGenerator generator( | 3787 SafepointGenerator generator( |
3801 this, pointers, Safepoint::kLazyDeopt); | 3788 this, pointers, Safepoint::kLazyDeopt); |
3802 ParameterCount count(arity); | 3789 ParameterCount count(arity); |
3803 ParameterCount expected(formal_parameter_count); | 3790 ParameterCount expected(formal_parameter_count); |
3804 __ InvokeFunction( | 3791 __ InvokeFunction( |
3805 function, expected, count, CALL_FUNCTION, generator, call_kind); | 3792 function, expected, count, CALL_FUNCTION, generator, call_kind); |
3806 } | 3793 } |
3807 } | 3794 } |
3808 | 3795 |
3809 | 3796 |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4259 | 4246 |
4260 | 4247 |
4261 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 4248 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
4262 ASSERT(ToRegister(instr->context()).is(esi)); | 4249 ASSERT(ToRegister(instr->context()).is(esi)); |
4263 ASSERT(ToRegister(instr->function()).is(edi)); | 4250 ASSERT(ToRegister(instr->function()).is(edi)); |
4264 ASSERT(instr->HasPointerMap()); | 4251 ASSERT(instr->HasPointerMap()); |
4265 | 4252 |
4266 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 4253 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
4267 if (known_function.is_null()) { | 4254 if (known_function.is_null()) { |
4268 LPointerMap* pointers = instr->pointer_map(); | 4255 LPointerMap* pointers = instr->pointer_map(); |
4269 RecordPosition(pointers->position()); | |
4270 SafepointGenerator generator( | 4256 SafepointGenerator generator( |
4271 this, pointers, Safepoint::kLazyDeopt); | 4257 this, pointers, Safepoint::kLazyDeopt); |
4272 ParameterCount count(instr->arity()); | 4258 ParameterCount count(instr->arity()); |
4273 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 4259 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); |
4274 } else { | 4260 } else { |
4275 CallKnownFunction(known_function, | 4261 CallKnownFunction(known_function, |
4276 instr->hydrogen()->formal_parameter_count(), | 4262 instr->hydrogen()->formal_parameter_count(), |
4277 instr->arity(), | 4263 instr->arity(), |
4278 instr, | 4264 instr, |
4279 CALL_AS_METHOD, | 4265 CALL_AS_METHOD, |
(...skipping 2114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6394 FixedArray::kHeaderSize - kPointerSize)); | 6380 FixedArray::kHeaderSize - kPointerSize)); |
6395 __ bind(&done); | 6381 __ bind(&done); |
6396 } | 6382 } |
6397 | 6383 |
6398 | 6384 |
6399 #undef __ | 6385 #undef __ |
6400 | 6386 |
6401 } } // namespace v8::internal | 6387 } } // namespace v8::internal |
6402 | 6388 |
6403 #endif // V8_TARGET_ARCH_IA32 | 6389 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |