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/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compiler/code-generator-impl.h" | 9 #include "src/compiler/code-generator-impl.h" |
10 #include "src/compiler/gap-resolver.h" | 10 #include "src/compiler/gap-resolver.h" |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 } \ | 385 } \ |
386 auto value = i.InputRegister(2); \ | 386 auto value = i.InputRegister(2); \ |
387 __ asm_instr(value, i.InputOffset(3), lo); \ | 387 __ asm_instr(value, i.InputOffset(3), lo); \ |
388 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | 388 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
389 } while (0) | 389 } while (0) |
390 | 390 |
391 void CodeGenerator::AssembleDeconstructFrame() { | 391 void CodeGenerator::AssembleDeconstructFrame() { |
392 __ LeaveFrame(StackFrame::MANUAL); | 392 __ LeaveFrame(StackFrame::MANUAL); |
393 } | 393 } |
394 | 394 |
395 void CodeGenerator::AssembleSetupStackPointer() {} | |
396 | |
397 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 395 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
398 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 396 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
399 if (sp_slot_delta > 0) { | 397 if (sp_slot_delta > 0) { |
400 __ add(sp, sp, Operand(sp_slot_delta * kPointerSize)); | 398 __ add(sp, sp, Operand(sp_slot_delta * kPointerSize)); |
401 } | 399 } |
402 frame_access_state()->SetFrameAccessToDefault(); | 400 frame_access_state()->SetFrameAccessToDefault(); |
403 } | 401 } |
404 | 402 |
405 | 403 |
406 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { | 404 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { | 1314 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { |
1317 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1315 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
1318 isolate(), deoptimization_id, bailout_type); | 1316 isolate(), deoptimization_id, bailout_type); |
1319 // TODO(turbofan): We should be able to generate better code by sharing the | 1317 // TODO(turbofan): We should be able to generate better code by sharing the |
1320 // actual final call site and just bl'ing to it here, similar to what we do | 1318 // actual final call site and just bl'ing to it here, similar to what we do |
1321 // in the lithium backend. | 1319 // in the lithium backend. |
1322 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1320 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
1323 __ CheckConstPool(false, false); | 1321 __ CheckConstPool(false, false); |
1324 } | 1322 } |
1325 | 1323 |
| 1324 void CodeGenerator::FinishFrame(Frame* frame) { |
| 1325 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1326 | 1326 |
1327 void CodeGenerator::AssemblePrologue() { | 1327 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); |
| 1328 if (saves_fp != 0) { |
| 1329 frame->AlignSavedCalleeRegisterSlots(); |
| 1330 } |
| 1331 |
| 1332 if (saves_fp != 0) { |
| 1333 // Save callee-saved FP registers. |
| 1334 STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32); |
| 1335 uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1; |
| 1336 uint32_t first = base::bits::CountTrailingZeros32(saves_fp); |
| 1337 DCHECK_EQ((last - first + 1), base::bits::CountPopulation32(saves_fp)); |
| 1338 frame->AllocateSavedCalleeRegisterSlots((last - first + 1) * |
| 1339 (kDoubleSize / kPointerSize)); |
| 1340 } |
| 1341 const RegList saves = FLAG_enable_embedded_constant_pool |
| 1342 ? (descriptor->CalleeSavedRegisters() & ~pp.bit()) |
| 1343 : descriptor->CalleeSavedRegisters(); |
| 1344 if (saves != 0) { |
| 1345 // Save callee-saved registers. |
| 1346 frame->AllocateSavedCalleeRegisterSlots( |
| 1347 base::bits::CountPopulation32(saves)); |
| 1348 } |
| 1349 } |
| 1350 |
| 1351 void CodeGenerator::AssembleConstructFrame() { |
1328 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1352 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1329 if (frame_access_state()->has_frame()) { | 1353 if (frame_access_state()->has_frame()) { |
1330 if (descriptor->IsCFunctionCall()) { | 1354 if (descriptor->IsCFunctionCall()) { |
1331 if (FLAG_enable_embedded_constant_pool) { | 1355 if (FLAG_enable_embedded_constant_pool) { |
1332 __ Push(lr, fp, pp); | 1356 __ Push(lr, fp, pp); |
1333 // Adjust FP to point to saved FP. | 1357 // Adjust FP to point to saved FP. |
1334 __ sub(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); | 1358 __ sub(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); |
1335 } else { | 1359 } else { |
1336 __ Push(lr, fp); | 1360 __ Push(lr, fp); |
1337 __ mov(fp, sp); | 1361 __ mov(fp, sp); |
1338 } | 1362 } |
1339 } else if (descriptor->IsJSFunctionCall()) { | 1363 } else if (descriptor->IsJSFunctionCall()) { |
1340 __ Prologue(this->info()->GeneratePreagedPrologue()); | 1364 __ Prologue(this->info()->GeneratePreagedPrologue()); |
1341 } else { | 1365 } else { |
1342 __ StubPrologue(info()->GetOutputStackFrameType()); | 1366 __ StubPrologue(info()->GetOutputStackFrameType()); |
1343 } | 1367 } |
1344 } | 1368 } |
1345 | 1369 |
1346 int stack_shrink_slots = frame()->GetSpillSlotCount(); | 1370 int shrink_slots = frame()->GetSpillSlotCount(); |
| 1371 |
1347 if (info()->is_osr()) { | 1372 if (info()->is_osr()) { |
1348 // TurboFan OSR-compiled functions cannot be entered directly. | 1373 // TurboFan OSR-compiled functions cannot be entered directly. |
1349 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1374 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
1350 | 1375 |
1351 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1376 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
1352 // frame is still on the stack. Optimized code uses OSR values directly from | 1377 // frame is still on the stack. Optimized code uses OSR values directly from |
1353 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1378 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
1354 // remaining stack slots. | 1379 // remaining stack slots. |
1355 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1380 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
1356 osr_pc_offset_ = __ pc_offset(); | 1381 osr_pc_offset_ = __ pc_offset(); |
1357 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); | 1382 shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); |
1358 } | 1383 } |
1359 | 1384 |
1360 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); | 1385 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); |
1361 if (saves_fp != 0) { | 1386 if (shrink_slots > 0) { |
1362 stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots(); | 1387 __ sub(sp, sp, Operand(shrink_slots * kPointerSize)); |
1363 } | |
1364 if (stack_shrink_slots > 0) { | |
1365 __ sub(sp, sp, Operand(stack_shrink_slots * kPointerSize)); | |
1366 } | 1388 } |
1367 | 1389 |
1368 if (saves_fp != 0) { | 1390 if (saves_fp != 0) { |
1369 // Save callee-saved FP registers. | 1391 // Save callee-saved FP registers. |
1370 STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32); | 1392 STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32); |
1371 uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1; | 1393 uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1; |
1372 uint32_t first = base::bits::CountTrailingZeros32(saves_fp); | 1394 uint32_t first = base::bits::CountTrailingZeros32(saves_fp); |
1373 DCHECK_EQ((last - first + 1), base::bits::CountPopulation32(saves_fp)); | 1395 DCHECK_EQ((last - first + 1), base::bits::CountPopulation32(saves_fp)); |
1374 __ vstm(db_w, sp, DwVfpRegister::from_code(first), | 1396 __ vstm(db_w, sp, DwVfpRegister::from_code(first), |
1375 DwVfpRegister::from_code(last)); | 1397 DwVfpRegister::from_code(last)); |
1376 frame()->AllocateSavedCalleeRegisterSlots((last - first + 1) * | |
1377 (kDoubleSize / kPointerSize)); | |
1378 } | 1398 } |
1379 const RegList saves = FLAG_enable_embedded_constant_pool | 1399 const RegList saves = FLAG_enable_embedded_constant_pool |
1380 ? (descriptor->CalleeSavedRegisters() & ~pp.bit()) | 1400 ? (descriptor->CalleeSavedRegisters() & ~pp.bit()) |
1381 : descriptor->CalleeSavedRegisters(); | 1401 : descriptor->CalleeSavedRegisters(); |
1382 if (saves != 0) { | 1402 if (saves != 0) { |
1383 // Save callee-saved registers. | 1403 // Save callee-saved registers. |
1384 __ stm(db_w, sp, saves); | 1404 __ stm(db_w, sp, saves); |
1385 frame()->AllocateSavedCalleeRegisterSlots( | |
1386 base::bits::CountPopulation32(saves)); | |
1387 } | 1405 } |
1388 } | 1406 } |
1389 | 1407 |
1390 | 1408 |
1391 void CodeGenerator::AssembleReturn() { | 1409 void CodeGenerator::AssembleReturn() { |
1392 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1410 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1393 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 1411 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
1394 | 1412 |
1395 // Restore registers. | 1413 // Restore registers. |
1396 const RegList saves = FLAG_enable_embedded_constant_pool | 1414 const RegList saves = FLAG_enable_embedded_constant_pool |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1635 padding_size -= v8::internal::Assembler::kInstrSize; | 1653 padding_size -= v8::internal::Assembler::kInstrSize; |
1636 } | 1654 } |
1637 } | 1655 } |
1638 } | 1656 } |
1639 | 1657 |
1640 #undef __ | 1658 #undef __ |
1641 | 1659 |
1642 } // namespace compiler | 1660 } // namespace compiler |
1643 } // namespace internal | 1661 } // namespace internal |
1644 } // namespace v8 | 1662 } // namespace v8 |
OLD | NEW |