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/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 __ cmp(offset, i.InputRegister(1)); \ | 347 __ cmp(offset, i.InputRegister(1)); \ |
348 } else { \ | 348 } else { \ |
349 __ cmp(offset, i.InputImmediate(1)); \ | 349 __ cmp(offset, i.InputImmediate(1)); \ |
350 } \ | 350 } \ |
351 auto value = i.InputRegister(2); \ | 351 auto value = i.InputRegister(2); \ |
352 __ asm_instr(value, i.InputOffset(3), lo); \ | 352 __ asm_instr(value, i.InputOffset(3), lo); \ |
353 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | 353 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
354 } while (0) | 354 } while (0) |
355 | 355 |
356 | 356 |
357 void CodeGenerator::AssembleDeconstructActivationRecord() { | 357 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
358 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 358 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
359 int stack_slots = frame()->GetSpillSlotCount(); | 359 int stack_slots = frame()->GetSpillSlotCount(); |
360 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { | 360 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { |
361 __ LeaveFrame(StackFrame::MANUAL); | 361 __ LeaveFrame(StackFrame::MANUAL); |
362 } | 362 } |
| 363 if (stack_param_delta < 0) { |
| 364 int offset = -stack_param_delta * kPointerSize; |
| 365 __ add(sp, sp, Operand(offset)); |
| 366 } |
363 } | 367 } |
364 | 368 |
365 | 369 |
366 // Assembles an instruction after register allocation, producing machine code. | 370 // Assembles an instruction after register allocation, producing machine code. |
367 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 371 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
368 ArmOperandConverter i(this, instr); | 372 ArmOperandConverter i(this, instr); |
369 | 373 |
370 masm()->MaybeCheckConstPool(); | 374 masm()->MaybeCheckConstPool(); |
371 | 375 |
372 switch (ArchOpcodeField::decode(instr->opcode())) { | 376 switch (ArchOpcodeField::decode(instr->opcode())) { |
373 case kArchCallCodeObject: { | 377 case kArchCallCodeObject: { |
374 EnsureSpaceForLazyDeopt(); | 378 EnsureSpaceForLazyDeopt(); |
375 if (instr->InputAt(0)->IsImmediate()) { | 379 if (instr->InputAt(0)->IsImmediate()) { |
376 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 380 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), |
377 RelocInfo::CODE_TARGET); | 381 RelocInfo::CODE_TARGET); |
378 } else { | 382 } else { |
379 __ add(ip, i.InputRegister(0), | 383 __ add(ip, i.InputRegister(0), |
380 Operand(Code::kHeaderSize - kHeapObjectTag)); | 384 Operand(Code::kHeaderSize - kHeapObjectTag)); |
381 __ Call(ip); | 385 __ Call(ip); |
382 } | 386 } |
383 RecordCallPosition(instr); | 387 RecordCallPosition(instr); |
384 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 388 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
385 break; | 389 break; |
386 } | 390 } |
387 case kArchTailCallCodeObject: { | 391 case kArchTailCallCodeObject: { |
388 AssembleDeconstructActivationRecord(); | 392 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
| 393 AssembleDeconstructActivationRecord(stack_param_delta); |
389 if (instr->InputAt(0)->IsImmediate()) { | 394 if (instr->InputAt(0)->IsImmediate()) { |
390 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), | 395 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), |
391 RelocInfo::CODE_TARGET); | 396 RelocInfo::CODE_TARGET); |
392 } else { | 397 } else { |
393 __ add(ip, i.InputRegister(0), | 398 __ add(ip, i.InputRegister(0), |
394 Operand(Code::kHeaderSize - kHeapObjectTag)); | 399 Operand(Code::kHeaderSize - kHeapObjectTag)); |
395 __ Jump(ip); | 400 __ Jump(ip); |
396 } | 401 } |
397 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 402 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
398 break; | 403 break; |
(...skipping 14 matching lines...) Expand all Loading... |
413 break; | 418 break; |
414 } | 419 } |
415 case kArchTailCallJSFunction: { | 420 case kArchTailCallJSFunction: { |
416 Register func = i.InputRegister(0); | 421 Register func = i.InputRegister(0); |
417 if (FLAG_debug_code) { | 422 if (FLAG_debug_code) { |
418 // Check the function's context matches the context argument. | 423 // Check the function's context matches the context argument. |
419 __ ldr(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); | 424 __ ldr(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); |
420 __ cmp(cp, kScratchReg); | 425 __ cmp(cp, kScratchReg); |
421 __ Assert(eq, kWrongFunctionContext); | 426 __ Assert(eq, kWrongFunctionContext); |
422 } | 427 } |
423 AssembleDeconstructActivationRecord(); | 428 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
| 429 AssembleDeconstructActivationRecord(stack_param_delta); |
424 __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); | 430 __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
425 __ Jump(ip); | 431 __ Jump(ip); |
426 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 432 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
427 break; | 433 break; |
428 } | 434 } |
429 case kArchLazyBailout: { | 435 case kArchLazyBailout: { |
430 EnsureSpaceForLazyDeopt(); | 436 EnsureSpaceForLazyDeopt(); |
431 RecordCallPosition(instr); | 437 RecordCallPosition(instr); |
432 break; | 438 break; |
433 } | 439 } |
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 padding_size -= v8::internal::Assembler::kInstrSize; | 1333 padding_size -= v8::internal::Assembler::kInstrSize; |
1328 } | 1334 } |
1329 } | 1335 } |
1330 } | 1336 } |
1331 | 1337 |
1332 #undef __ | 1338 #undef __ |
1333 | 1339 |
1334 } // namespace compiler | 1340 } // namespace compiler |
1335 } // namespace internal | 1341 } // namespace internal |
1336 } // namespace v8 | 1342 } // namespace v8 |
OLD | NEW |