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