| 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 |