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