OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/compiler/osr.h" |
10 #include "src/ppc/macro-assembler-ppc.h" | 11 #include "src/ppc/macro-assembler-ppc.h" |
11 #include "src/scopes.h" | 12 #include "src/scopes.h" |
12 | 13 |
13 namespace v8 { | 14 namespace v8 { |
14 namespace internal { | 15 namespace internal { |
15 namespace compiler { | 16 namespace compiler { |
16 | 17 |
17 #define __ masm()-> | 18 #define __ masm()-> |
18 | 19 |
19 | 20 |
(...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1297 void CodeGenerator::AssembleDeoptimizerCall( | 1298 void CodeGenerator::AssembleDeoptimizerCall( |
1298 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { | 1299 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { |
1299 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1300 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
1300 isolate(), deoptimization_id, bailout_type); | 1301 isolate(), deoptimization_id, bailout_type); |
1301 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1302 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
1302 } | 1303 } |
1303 | 1304 |
1304 | 1305 |
1305 void CodeGenerator::AssemblePrologue() { | 1306 void CodeGenerator::AssemblePrologue() { |
1306 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1307 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1307 int stack_slots = frame()->GetSpillSlotCount(); | 1308 |
1308 if (descriptor->kind() == CallDescriptor::kCallAddress) { | 1309 if (descriptor->kind() == CallDescriptor::kCallAddress) { |
1309 __ function_descriptor(); | 1310 __ function_descriptor(); |
1310 RegList frame_saves = 0; | |
1311 __ mflr(r0); | 1311 __ mflr(r0); |
1312 if (FLAG_enable_embedded_constant_pool) { | 1312 if (FLAG_enable_embedded_constant_pool) { |
1313 __ Push(r0, fp, kConstantPoolRegister); | 1313 __ Push(r0, fp, kConstantPoolRegister); |
1314 // Adjust FP to point to saved FP. | 1314 // Adjust FP to point to saved FP. |
1315 __ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); | 1315 __ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); |
1316 frame_saves |= kConstantPoolRegister.bit(); | |
1317 } else { | 1316 } else { |
1318 __ Push(r0, fp); | 1317 __ Push(r0, fp); |
1319 __ mr(fp, sp); | 1318 __ mr(fp, sp); |
1320 } | 1319 } |
1321 | |
1322 // Save callee-saved registers. | |
1323 const RegList saves = descriptor->CalleeSavedRegisters() & ~frame_saves; | |
1324 __ MultiPush(saves); | |
1325 // register save area does not include the fp. | |
1326 DCHECK(kNumCalleeSaved - 1 == | |
1327 base::bits::CountPopulation32(saves | frame_saves)); | |
1328 int register_save_area_size = (kNumCalleeSaved - 1) * kPointerSize; | |
1329 | |
1330 // Save callee-saved Double registers. | |
1331 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); | |
1332 __ MultiPushDoubles(double_saves); | |
1333 DCHECK(kNumCalleeSavedDoubles == | |
1334 base::bits::CountPopulation32(double_saves)); | |
1335 register_save_area_size += kNumCalleeSavedDoubles * kDoubleSize; | |
1336 | |
1337 frame()->SetRegisterSaveAreaSize(register_save_area_size); | |
1338 } else if (descriptor->IsJSFunctionCall()) { | 1320 } else if (descriptor->IsJSFunctionCall()) { |
1339 CompilationInfo* info = this->info(); | 1321 CompilationInfo* info = this->info(); |
1340 __ Prologue(info->IsCodePreAgingActive()); | 1322 __ Prologue(info->IsCodePreAgingActive()); |
1341 frame()->SetRegisterSaveAreaSize( | |
1342 StandardFrameConstants::kFixedFrameSizeFromFp); | |
1343 } else if (needs_frame_) { | 1323 } else if (needs_frame_) { |
1344 __ StubPrologue(); | 1324 __ StubPrologue(); |
1345 frame()->SetRegisterSaveAreaSize( | |
1346 StandardFrameConstants::kFixedFrameSizeFromFp); | |
1347 } else { | 1325 } else { |
1348 frame()->SetPCOnStack(false); | 1326 frame()->SetElidedFrameSizeInSlots(0); |
1349 } | 1327 } |
1350 | 1328 |
| 1329 int stack_shrink_slots = frame()->GetSpillSlotCount(); |
1351 if (info()->is_osr()) { | 1330 if (info()->is_osr()) { |
1352 // TurboFan OSR-compiled functions cannot be entered directly. | 1331 // TurboFan OSR-compiled functions cannot be entered directly. |
1353 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1332 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
1354 | 1333 |
1355 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1334 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
1356 // frame is still on the stack. Optimized code uses OSR values directly from | 1335 // frame is still on the stack. Optimized code uses OSR values directly from |
1357 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1336 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
1358 // remaining stack slots. | 1337 // remaining stack slots. |
1359 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1338 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
1360 osr_pc_offset_ = __ pc_offset(); | 1339 osr_pc_offset_ = __ pc_offset(); |
1361 // TODO(titzer): cannot address target function == local #-1 | 1340 // TODO(titzer): cannot address target function == local #-1 |
1362 __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1341 __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
1363 DCHECK(stack_slots >= frame()->GetOsrStackSlotCount()); | 1342 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); |
1364 stack_slots -= frame()->GetOsrStackSlotCount(); | |
1365 } | 1343 } |
1366 | 1344 |
1367 if (stack_slots > 0) { | 1345 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); |
1368 __ Add(sp, sp, -stack_slots * kPointerSize, r0); | 1346 if (double_saves != 0) { |
| 1347 stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots(); |
| 1348 } |
| 1349 if (stack_shrink_slots > 0) { |
| 1350 __ Add(sp, sp, -stack_shrink_slots * kPointerSize, r0); |
| 1351 } |
| 1352 |
| 1353 // Save callee-saved Double registers. |
| 1354 if (double_saves != 0) { |
| 1355 __ MultiPushDoubles(double_saves); |
| 1356 DCHECK(kNumCalleeSavedDoubles == |
| 1357 base::bits::CountPopulation32(double_saves)); |
| 1358 frame()->AllocateSavedCalleeRegisterSlots(kNumCalleeSavedDoubles * |
| 1359 (kDoubleSize / kPointerSize)); |
| 1360 } |
| 1361 |
| 1362 // Save callee-saved registers. |
| 1363 const RegList saves = |
| 1364 FLAG_enable_embedded_constant_pool |
| 1365 ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit() |
| 1366 : descriptor->CalleeSavedRegisters(); |
| 1367 if (saves != 0) { |
| 1368 __ MultiPush(saves); |
| 1369 // register save area does not include the fp or constant pool pointer. |
| 1370 const int num_saves = |
| 1371 kNumCalleeSaved - 1 - (FLAG_enable_embedded_constant_pool ? 1 : 0); |
| 1372 DCHECK(num_saves == base::bits::CountPopulation32(saves)); |
| 1373 frame()->AllocateSavedCalleeRegisterSlots(num_saves); |
1369 } | 1374 } |
1370 } | 1375 } |
1371 | 1376 |
1372 | 1377 |
1373 void CodeGenerator::AssembleReturn() { | 1378 void CodeGenerator::AssembleReturn() { |
1374 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1379 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1375 int stack_slots = frame()->GetSpillSlotCount(); | |
1376 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 1380 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
| 1381 |
| 1382 // Restore registers. |
| 1383 const RegList saves = |
| 1384 FLAG_enable_embedded_constant_pool |
| 1385 ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit() |
| 1386 : descriptor->CalleeSavedRegisters(); |
| 1387 if (saves != 0) { |
| 1388 __ MultiPop(saves); |
| 1389 } |
| 1390 |
| 1391 // Restore double registers. |
| 1392 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); |
| 1393 if (double_saves != 0) { |
| 1394 __ MultiPopDoubles(double_saves); |
| 1395 } |
| 1396 |
1377 if (descriptor->kind() == CallDescriptor::kCallAddress) { | 1397 if (descriptor->kind() == CallDescriptor::kCallAddress) { |
1378 if (frame()->GetRegisterSaveAreaSize() > 0) { | |
1379 // Remove this frame's spill slots first. | |
1380 if (stack_slots > 0) { | |
1381 __ Add(sp, sp, stack_slots * kPointerSize, r0); | |
1382 } | |
1383 // Restore double registers. | |
1384 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); | |
1385 __ MultiPopDoubles(double_saves); | |
1386 | |
1387 // Restore registers. | |
1388 RegList frame_saves = 0; | |
1389 if (FLAG_enable_embedded_constant_pool) { | |
1390 frame_saves |= kConstantPoolRegister.bit(); | |
1391 } | |
1392 const RegList saves = descriptor->CalleeSavedRegisters() & ~frame_saves; | |
1393 __ MultiPop(saves); | |
1394 } | |
1395 __ LeaveFrame(StackFrame::MANUAL, pop_count * kPointerSize); | 1398 __ LeaveFrame(StackFrame::MANUAL, pop_count * kPointerSize); |
1396 } else if (descriptor->IsJSFunctionCall() || needs_frame_) { | 1399 } else if (descriptor->IsJSFunctionCall() || needs_frame_) { |
1397 // Canonicalize JSFunction return sites for now. | 1400 // Canonicalize JSFunction return sites for now. |
1398 if (return_label_.is_bound()) { | 1401 if (return_label_.is_bound()) { |
1399 __ b(&return_label_); | 1402 __ b(&return_label_); |
1400 return; | 1403 return; |
1401 } else { | 1404 } else { |
1402 __ bind(&return_label_); | 1405 __ bind(&return_label_); |
1403 __ LeaveFrame(StackFrame::MANUAL, pop_count * kPointerSize); | 1406 __ LeaveFrame(StackFrame::MANUAL, pop_count * kPointerSize); |
1404 } | 1407 } |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1609 padding_size -= v8::internal::Assembler::kInstrSize; | 1612 padding_size -= v8::internal::Assembler::kInstrSize; |
1610 } | 1613 } |
1611 } | 1614 } |
1612 } | 1615 } |
1613 | 1616 |
1614 #undef __ | 1617 #undef __ |
1615 | 1618 |
1616 } // namespace compiler | 1619 } // namespace compiler |
1617 } // namespace internal | 1620 } // namespace internal |
1618 } // namespace v8 | 1621 } // namespace v8 |
OLD | NEW |