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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 CpuFeatures::Scope scope(SSE2); | 70 CpuFeatures::Scope scope(SSE2); |
71 return GeneratePrologue() && | 71 return GeneratePrologue() && |
72 GenerateBody() && | 72 GenerateBody() && |
73 GenerateDeferredCode() && | 73 GenerateDeferredCode() && |
74 GenerateSafepointTable(); | 74 GenerateSafepointTable(); |
75 } | 75 } |
76 | 76 |
77 | 77 |
78 void LCodeGen::FinishCode(Handle<Code> code) { | 78 void LCodeGen::FinishCode(Handle<Code> code) { |
79 ASSERT(is_done()); | 79 ASSERT(is_done()); |
80 code->set_stack_slots(StackSlotCount()); | 80 code->set_stack_slots(GetStackSlotCount()); |
81 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); | 81 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); |
82 PopulateDeoptimizationData(code); | 82 PopulateDeoptimizationData(code); |
83 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); | 83 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); |
84 } | 84 } |
85 | 85 |
86 | 86 |
87 void LCodeGen::Abort(const char* format, ...) { | 87 void LCodeGen::Abort(const char* format, ...) { |
88 if (FLAG_trace_bailout) { | 88 if (FLAG_trace_bailout) { |
89 SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); | 89 SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); |
90 PrintF("Aborting LCodeGen in @\"%s\": ", *name); | 90 PrintF("Aborting LCodeGen in @\"%s\": ", *name); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 __ int3(); | 125 __ int3(); |
126 } | 126 } |
127 #endif | 127 #endif |
128 | 128 |
129 __ push(ebp); // Caller's frame pointer. | 129 __ push(ebp); // Caller's frame pointer. |
130 __ mov(ebp, esp); | 130 __ mov(ebp, esp); |
131 __ push(esi); // Callee's context. | 131 __ push(esi); // Callee's context. |
132 __ push(edi); // Callee's JS function. | 132 __ push(edi); // Callee's JS function. |
133 | 133 |
134 // Reserve space for the stack slots needed by the code. | 134 // Reserve space for the stack slots needed by the code. |
135 int slots = StackSlotCount(); | 135 int slots = GetStackSlotCount(); |
136 if (slots > 0) { | 136 if (slots > 0) { |
137 if (FLAG_debug_code) { | 137 if (FLAG_debug_code) { |
138 __ mov(Operand(eax), Immediate(slots)); | 138 __ mov(Operand(eax), Immediate(slots)); |
139 Label loop; | 139 Label loop; |
140 __ bind(&loop); | 140 __ bind(&loop); |
141 __ push(Immediate(kSlotsZapValue)); | 141 __ push(Immediate(kSlotsZapValue)); |
142 __ dec(eax); | 142 __ dec(eax); |
143 __ j(not_zero, &loop); | 143 __ j(not_zero, &loop); |
144 } else { | 144 } else { |
145 __ sub(Operand(esp), Immediate(slots * kPointerSize)); | 145 __ sub(Operand(esp), Immediate(slots * kPointerSize)); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 | 247 |
248 // Deferred code is the last part of the instruction sequence. Mark | 248 // Deferred code is the last part of the instruction sequence. Mark |
249 // the generated code as done unless we bailed out. | 249 // the generated code as done unless we bailed out. |
250 if (!is_aborted()) status_ = DONE; | 250 if (!is_aborted()) status_ = DONE; |
251 return !is_aborted(); | 251 return !is_aborted(); |
252 } | 252 } |
253 | 253 |
254 | 254 |
255 bool LCodeGen::GenerateSafepointTable() { | 255 bool LCodeGen::GenerateSafepointTable() { |
256 ASSERT(is_done()); | 256 ASSERT(is_done()); |
257 safepoints_.Emit(masm(), StackSlotCount()); | 257 safepoints_.Emit(masm(), GetStackSlotCount()); |
258 return !is_aborted(); | 258 return !is_aborted(); |
259 } | 259 } |
260 | 260 |
261 | 261 |
262 Register LCodeGen::ToRegister(int index) const { | 262 Register LCodeGen::ToRegister(int index) const { |
263 return Register::FromAllocationIndex(index); | 263 return Register::FromAllocationIndex(index); |
264 } | 264 } |
265 | 265 |
266 | 266 |
267 XMMRegister LCodeGen::ToDoubleRegister(int index) const { | 267 XMMRegister LCodeGen::ToDoubleRegister(int index) const { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 } else if (op->IsStackSlot()) { | 379 } else if (op->IsStackSlot()) { |
380 if (is_tagged) { | 380 if (is_tagged) { |
381 translation->StoreStackSlot(op->index()); | 381 translation->StoreStackSlot(op->index()); |
382 } else { | 382 } else { |
383 translation->StoreInt32StackSlot(op->index()); | 383 translation->StoreInt32StackSlot(op->index()); |
384 } | 384 } |
385 } else if (op->IsDoubleStackSlot()) { | 385 } else if (op->IsDoubleStackSlot()) { |
386 translation->StoreDoubleStackSlot(op->index()); | 386 translation->StoreDoubleStackSlot(op->index()); |
387 } else if (op->IsArgument()) { | 387 } else if (op->IsArgument()) { |
388 ASSERT(is_tagged); | 388 ASSERT(is_tagged); |
389 int src_index = StackSlotCount() + op->index(); | 389 int src_index = GetStackSlotCount() + op->index(); |
390 translation->StoreStackSlot(src_index); | 390 translation->StoreStackSlot(src_index); |
391 } else if (op->IsRegister()) { | 391 } else if (op->IsRegister()) { |
392 Register reg = ToRegister(op); | 392 Register reg = ToRegister(op); |
393 if (is_tagged) { | 393 if (is_tagged) { |
394 translation->StoreRegister(reg); | 394 translation->StoreRegister(reg); |
395 } else { | 395 } else { |
396 translation->StoreInt32Register(reg); | 396 translation->StoreInt32Register(reg); |
397 } | 397 } |
398 } else if (op->IsDoubleRegister()) { | 398 } else if (op->IsDoubleRegister()) { |
399 XMMRegister reg = ToDoubleRegister(op); | 399 XMMRegister reg = ToDoubleRegister(op); |
(...skipping 1650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2050 // Preserve the return value on the stack and rely on the runtime call | 2050 // Preserve the return value on the stack and rely on the runtime call |
2051 // to return the value in the same register. We're leaving the code | 2051 // to return the value in the same register. We're leaving the code |
2052 // managed by the register allocator and tearing down the frame, it's | 2052 // managed by the register allocator and tearing down the frame, it's |
2053 // safe to write to the context register. | 2053 // safe to write to the context register. |
2054 __ push(eax); | 2054 __ push(eax); |
2055 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2055 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2056 __ CallRuntime(Runtime::kTraceExit, 1); | 2056 __ CallRuntime(Runtime::kTraceExit, 1); |
2057 } | 2057 } |
2058 __ mov(esp, ebp); | 2058 __ mov(esp, ebp); |
2059 __ pop(ebp); | 2059 __ pop(ebp); |
2060 __ Ret((ParameterCount() + 1) * kPointerSize, ecx); | 2060 __ Ret((GetParameterCount() + 1) * kPointerSize, ecx); |
2061 } | 2061 } |
2062 | 2062 |
2063 | 2063 |
2064 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { | 2064 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { |
2065 Register result = ToRegister(instr->result()); | 2065 Register result = ToRegister(instr->result()); |
2066 __ mov(result, Operand::Cell(instr->hydrogen()->cell())); | 2066 __ mov(result, Operand::Cell(instr->hydrogen()->cell())); |
2067 if (instr->hydrogen()->check_hole_value()) { | 2067 if (instr->hydrogen()->check_hole_value()) { |
2068 __ cmp(result, factory()->the_hole_value()); | 2068 __ cmp(result, factory()->the_hole_value()); |
2069 DeoptimizeIf(equal, instr->environment()); | 2069 DeoptimizeIf(equal, instr->environment()); |
2070 } | 2070 } |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2486 // Invoke the function. | 2486 // Invoke the function. |
2487 __ bind(&invoke); | 2487 __ bind(&invoke); |
2488 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); | 2488 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); |
2489 LPointerMap* pointers = instr->pointer_map(); | 2489 LPointerMap* pointers = instr->pointer_map(); |
2490 LEnvironment* env = instr->deoptimization_environment(); | 2490 LEnvironment* env = instr->deoptimization_environment(); |
2491 RecordPosition(pointers->position()); | 2491 RecordPosition(pointers->position()); |
2492 RegisterEnvironmentForDeoptimization(env); | 2492 RegisterEnvironmentForDeoptimization(env); |
2493 SafepointGenerator safepoint_generator(this, | 2493 SafepointGenerator safepoint_generator(this, |
2494 pointers, | 2494 pointers, |
2495 env->deoptimization_index()); | 2495 env->deoptimization_index()); |
2496 v8::internal::ParameterCount actual(eax); | 2496 ParameterCount actual(eax); |
2497 __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator); | 2497 __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator); |
2498 } | 2498 } |
2499 | 2499 |
2500 | 2500 |
2501 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 2501 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
2502 LOperand* argument = instr->InputAt(0); | 2502 LOperand* argument = instr->InputAt(0); |
2503 if (argument->IsConstantOperand()) { | 2503 if (argument->IsConstantOperand()) { |
2504 __ push(ToImmediate(argument)); | 2504 __ push(ToImmediate(argument)); |
2505 } else { | 2505 } else { |
2506 __ push(ToOperand(argument)); | 2506 __ push(ToOperand(argument)); |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2898 case kMathLog: | 2898 case kMathLog: |
2899 DoMathLog(instr); | 2899 DoMathLog(instr); |
2900 break; | 2900 break; |
2901 | 2901 |
2902 default: | 2902 default: |
2903 UNREACHABLE(); | 2903 UNREACHABLE(); |
2904 } | 2904 } |
2905 } | 2905 } |
2906 | 2906 |
2907 | 2907 |
| 2908 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
| 2909 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2910 ASSERT(ToRegister(instr->function()).is(edi)); |
| 2911 ASSERT(instr->HasPointerMap()); |
| 2912 ASSERT(instr->HasDeoptimizationEnvironment()); |
| 2913 LPointerMap* pointers = instr->pointer_map(); |
| 2914 LEnvironment* env = instr->deoptimization_environment(); |
| 2915 RecordPosition(pointers->position()); |
| 2916 RegisterEnvironmentForDeoptimization(env); |
| 2917 SafepointGenerator generator(this, pointers, env->deoptimization_index()); |
| 2918 ParameterCount count(instr->arity()); |
| 2919 __ InvokeFunction(edi, count, CALL_FUNCTION, &generator); |
| 2920 } |
| 2921 |
| 2922 |
2908 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 2923 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
2909 ASSERT(ToRegister(instr->context()).is(esi)); | 2924 ASSERT(ToRegister(instr->context()).is(esi)); |
2910 ASSERT(ToRegister(instr->key()).is(ecx)); | 2925 ASSERT(ToRegister(instr->key()).is(ecx)); |
2911 ASSERT(ToRegister(instr->result()).is(eax)); | 2926 ASSERT(ToRegister(instr->result()).is(eax)); |
2912 | 2927 |
2913 int arity = instr->arity(); | 2928 int arity = instr->arity(); |
2914 Handle<Code> ic = isolate()->stub_cache()-> | 2929 Handle<Code> ic = isolate()->stub_cache()-> |
2915 ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); | 2930 ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); |
2916 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 2931 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); |
2917 } | 2932 } |
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4177 ASSERT(osr_pc_offset_ == -1); | 4192 ASSERT(osr_pc_offset_ == -1); |
4178 osr_pc_offset_ = masm()->pc_offset(); | 4193 osr_pc_offset_ = masm()->pc_offset(); |
4179 } | 4194 } |
4180 | 4195 |
4181 | 4196 |
4182 #undef __ | 4197 #undef __ |
4183 | 4198 |
4184 } } // namespace v8::internal | 4199 } } // namespace v8::internal |
4185 | 4200 |
4186 #endif // V8_TARGET_ARCH_IA32 | 4201 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |