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 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { | 1266 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { |
1269 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1267 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
1270 isolate(), deoptimization_id, bailout_type); | 1268 isolate(), deoptimization_id, bailout_type); |
1271 // TODO(turbofan): We should be able to generate better code by sharing the | 1269 // TODO(turbofan): We should be able to generate better code by sharing the |
1272 // actual final call site and just bl'ing to it here, similar to what we do | 1270 // actual final call site and just bl'ing to it here, similar to what we do |
1273 // in the lithium backend. | 1271 // in the lithium backend. |
1274 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1272 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
1275 __ CheckConstPool(false, false); | 1273 __ CheckConstPool(false, false); |
1276 } | 1274 } |
1277 | 1275 |
| 1276 void CodeGenerator::FinishFrame(Frame* frame) { |
| 1277 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1278 int stack_shrink_slots = frame->GetSpillSlotCount(); |
| 1279 if (info()->is_osr()) { |
| 1280 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); |
| 1281 } |
| 1282 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); |
| 1283 if (saves_fp != 0) { |
| 1284 stack_shrink_slots += frame->AlignSavedCalleeRegisterSlots(); |
| 1285 } |
1278 | 1286 |
1279 void CodeGenerator::AssemblePrologue() { | 1287 if (saves_fp != 0) { |
| 1288 // Save callee-saved FP registers. |
| 1289 STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32); |
| 1290 uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1; |
| 1291 uint32_t first = base::bits::CountTrailingZeros32(saves_fp); |
| 1292 DCHECK_EQ((last - first + 1), base::bits::CountPopulation32(saves_fp)); |
| 1293 frame->AllocateSavedCalleeRegisterSlots((last - first + 1) * |
| 1294 (kDoubleSize / kPointerSize)); |
| 1295 } |
| 1296 const RegList saves = FLAG_enable_embedded_constant_pool |
| 1297 ? (descriptor->CalleeSavedRegisters() & ~pp.bit()) |
| 1298 : descriptor->CalleeSavedRegisters(); |
| 1299 if (saves != 0) { |
| 1300 // Save callee-saved registers. |
| 1301 frame->AllocateSavedCalleeRegisterSlots( |
| 1302 base::bits::CountPopulation32(saves)); |
| 1303 } |
| 1304 frame->set_stack_shrink_slots(stack_shrink_slots); |
| 1305 } |
| 1306 |
| 1307 void CodeGenerator::AssembleConstructFrame() { |
1280 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1308 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1281 if (frame_access_state()->has_frame()) { | 1309 if (frame_access_state()->has_frame()) { |
1282 if (descriptor->IsCFunctionCall()) { | 1310 if (descriptor->IsCFunctionCall()) { |
1283 if (FLAG_enable_embedded_constant_pool) { | 1311 if (FLAG_enable_embedded_constant_pool) { |
1284 __ Push(lr, fp, pp); | 1312 __ Push(lr, fp, pp); |
1285 // Adjust FP to point to saved FP. | 1313 // Adjust FP to point to saved FP. |
1286 __ sub(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); | 1314 __ sub(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); |
1287 } else { | 1315 } else { |
1288 __ Push(lr, fp); | 1316 __ Push(lr, fp); |
1289 __ mov(fp, sp); | 1317 __ mov(fp, sp); |
1290 } | 1318 } |
1291 } else if (descriptor->IsJSFunctionCall()) { | 1319 } else if (descriptor->IsJSFunctionCall()) { |
1292 __ Prologue(this->info()->GeneratePreagedPrologue()); | 1320 __ Prologue(this->info()->GeneratePreagedPrologue()); |
1293 } else { | 1321 } else { |
1294 __ StubPrologue(info()->GetOutputStackFrameType()); | 1322 __ StubPrologue(info()->GetOutputStackFrameType()); |
1295 } | 1323 } |
1296 } | 1324 } |
1297 | 1325 |
1298 int stack_shrink_slots = frame()->GetSpillSlotCount(); | |
1299 if (info()->is_osr()) { | 1326 if (info()->is_osr()) { |
1300 // TurboFan OSR-compiled functions cannot be entered directly. | 1327 // TurboFan OSR-compiled functions cannot be entered directly. |
1301 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1328 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
1302 | 1329 |
1303 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1330 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
1304 // frame is still on the stack. Optimized code uses OSR values directly from | 1331 // frame is still on the stack. Optimized code uses OSR values directly from |
1305 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1332 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
1306 // remaining stack slots. | 1333 // remaining stack slots. |
1307 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1334 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
1308 osr_pc_offset_ = __ pc_offset(); | 1335 osr_pc_offset_ = __ pc_offset(); |
1309 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); | |
1310 } | 1336 } |
1311 | 1337 |
1312 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); | 1338 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); |
1313 if (saves_fp != 0) { | 1339 if (frame()->stack_shrink_slots() > 0) { |
1314 stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots(); | 1340 __ sub(sp, sp, Operand(frame()->stack_shrink_slots() * kPointerSize)); |
1315 } | |
1316 if (stack_shrink_slots > 0) { | |
1317 __ sub(sp, sp, Operand(stack_shrink_slots * kPointerSize)); | |
1318 } | 1341 } |
1319 | 1342 |
1320 if (saves_fp != 0) { | 1343 if (saves_fp != 0) { |
1321 // Save callee-saved FP registers. | 1344 // Save callee-saved FP registers. |
1322 STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32); | 1345 STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32); |
1323 uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1; | 1346 uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1; |
1324 uint32_t first = base::bits::CountTrailingZeros32(saves_fp); | 1347 uint32_t first = base::bits::CountTrailingZeros32(saves_fp); |
1325 DCHECK_EQ((last - first + 1), base::bits::CountPopulation32(saves_fp)); | 1348 DCHECK_EQ((last - first + 1), base::bits::CountPopulation32(saves_fp)); |
1326 __ vstm(db_w, sp, DwVfpRegister::from_code(first), | 1349 __ vstm(db_w, sp, DwVfpRegister::from_code(first), |
1327 DwVfpRegister::from_code(last)); | 1350 DwVfpRegister::from_code(last)); |
1328 frame()->AllocateSavedCalleeRegisterSlots((last - first + 1) * | |
1329 (kDoubleSize / kPointerSize)); | |
1330 } | 1351 } |
1331 const RegList saves = FLAG_enable_embedded_constant_pool | 1352 const RegList saves = FLAG_enable_embedded_constant_pool |
1332 ? (descriptor->CalleeSavedRegisters() & ~pp.bit()) | 1353 ? (descriptor->CalleeSavedRegisters() & ~pp.bit()) |
1333 : descriptor->CalleeSavedRegisters(); | 1354 : descriptor->CalleeSavedRegisters(); |
1334 if (saves != 0) { | 1355 if (saves != 0) { |
1335 // Save callee-saved registers. | 1356 // Save callee-saved registers. |
1336 __ stm(db_w, sp, saves); | 1357 __ stm(db_w, sp, saves); |
1337 frame()->AllocateSavedCalleeRegisterSlots( | |
1338 base::bits::CountPopulation32(saves)); | |
1339 } | 1358 } |
1340 } | 1359 } |
1341 | 1360 |
1342 | 1361 |
1343 void CodeGenerator::AssembleReturn() { | 1362 void CodeGenerator::AssembleReturn() { |
1344 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1363 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1345 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 1364 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
1346 | 1365 |
1347 // Restore registers. | 1366 // Restore registers. |
1348 const RegList saves = FLAG_enable_embedded_constant_pool | 1367 const RegList saves = FLAG_enable_embedded_constant_pool |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 padding_size -= v8::internal::Assembler::kInstrSize; | 1602 padding_size -= v8::internal::Assembler::kInstrSize; |
1584 } | 1603 } |
1585 } | 1604 } |
1586 } | 1605 } |
1587 | 1606 |
1588 #undef __ | 1607 #undef __ |
1589 | 1608 |
1590 } // namespace compiler | 1609 } // namespace compiler |
1591 } // namespace internal | 1610 } // namespace internal |
1592 } // namespace v8 | 1611 } // namespace v8 |
OLD | NEW |