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/arm64/macro-assembler-arm64.h" | 7 #include "src/arm64/macro-assembler-arm64.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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 if (instr->InputAt(1)->IsRegister()) { \ | 336 if (instr->InputAt(1)->IsRegister()) { \ |
337 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ | 337 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ |
338 i.InputRegister##width(1)); \ | 338 i.InputRegister##width(1)); \ |
339 } else { \ | 339 } else { \ |
340 int64_t imm = i.InputOperand##width(1).immediate().value(); \ | 340 int64_t imm = i.InputOperand##width(1).immediate().value(); \ |
341 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \ | 341 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \ |
342 } \ | 342 } \ |
343 } while (0) | 343 } while (0) |
344 | 344 |
345 | 345 |
| 346 void CodeGenerator::AssembleDeconstructActivationRecord() { |
| 347 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 348 int stack_slots = frame()->GetSpillSlotCount(); |
| 349 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { |
| 350 __ Mov(jssp, fp); |
| 351 __ Pop(fp, lr); |
| 352 int pop_count = descriptor->IsJSFunctionCall() |
| 353 ? static_cast<int>(descriptor->JSParameterCount()) |
| 354 : 0; |
| 355 __ Drop(pop_count); |
| 356 } |
| 357 } |
| 358 |
| 359 |
346 // Assembles an instruction after register allocation, producing machine code. | 360 // Assembles an instruction after register allocation, producing machine code. |
347 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 361 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
348 Arm64OperandConverter i(this, instr); | 362 Arm64OperandConverter i(this, instr); |
349 InstructionCode opcode = instr->opcode(); | 363 InstructionCode opcode = instr->opcode(); |
350 switch (ArchOpcodeField::decode(opcode)) { | 364 switch (ArchOpcodeField::decode(opcode)) { |
351 case kArchCallCodeObject: { | 365 case kArchCallCodeObject: { |
352 EnsureSpaceForLazyDeopt(); | 366 EnsureSpaceForLazyDeopt(); |
353 if (instr->InputAt(0)->IsImmediate()) { | 367 if (instr->InputAt(0)->IsImmediate()) { |
354 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 368 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), |
355 RelocInfo::CODE_TARGET); | 369 RelocInfo::CODE_TARGET); |
356 } else { | 370 } else { |
357 Register target = i.InputRegister(0); | 371 Register target = i.InputRegister(0); |
358 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); | 372 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); |
359 __ Call(target); | 373 __ Call(target); |
360 } | 374 } |
361 RecordCallPosition(instr); | 375 RecordCallPosition(instr); |
362 break; | 376 break; |
363 } | 377 } |
| 378 case kArchTailCallCodeObject: { |
| 379 AssembleDeconstructActivationRecord(); |
| 380 if (instr->InputAt(0)->IsImmediate()) { |
| 381 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), |
| 382 RelocInfo::CODE_TARGET); |
| 383 } else { |
| 384 Register target = i.InputRegister(0); |
| 385 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); |
| 386 __ Jump(target); |
| 387 } |
| 388 break; |
| 389 } |
364 case kArchCallJSFunction: { | 390 case kArchCallJSFunction: { |
365 EnsureSpaceForLazyDeopt(); | 391 EnsureSpaceForLazyDeopt(); |
366 Register func = i.InputRegister(0); | 392 Register func = i.InputRegister(0); |
367 if (FLAG_debug_code) { | 393 if (FLAG_debug_code) { |
368 // Check the function's context matches the context argument. | 394 // Check the function's context matches the context argument. |
369 UseScratchRegisterScope scope(masm()); | 395 UseScratchRegisterScope scope(masm()); |
370 Register temp = scope.AcquireX(); | 396 Register temp = scope.AcquireX(); |
371 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); | 397 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); |
372 __ cmp(cp, temp); | 398 __ cmp(cp, temp); |
373 __ Assert(eq, kWrongFunctionContext); | 399 __ Assert(eq, kWrongFunctionContext); |
374 } | 400 } |
375 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); | 401 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
376 __ Call(x10); | 402 __ Call(x10); |
377 RecordCallPosition(instr); | 403 RecordCallPosition(instr); |
378 break; | 404 break; |
379 } | 405 } |
| 406 case kArchTailCallJSFunction: { |
| 407 Register func = i.InputRegister(0); |
| 408 if (FLAG_debug_code) { |
| 409 // Check the function's context matches the context argument. |
| 410 UseScratchRegisterScope scope(masm()); |
| 411 Register temp = scope.AcquireX(); |
| 412 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); |
| 413 __ cmp(cp, temp); |
| 414 __ Assert(eq, kWrongFunctionContext); |
| 415 } |
| 416 AssembleDeconstructActivationRecord(); |
| 417 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
| 418 __ Jump(x10); |
| 419 break; |
| 420 } |
380 case kArchJmp: | 421 case kArchJmp: |
381 AssembleArchJump(i.InputRpo(0)); | 422 AssembleArchJump(i.InputRpo(0)); |
382 break; | 423 break; |
383 case kArchTableSwitch: | 424 case kArchTableSwitch: |
384 AssembleArchTableSwitch(instr); | 425 AssembleArchTableSwitch(instr); |
385 break; | 426 break; |
386 case kArchLookupSwitch: | 427 case kArchLookupSwitch: |
387 AssembleArchLookupSwitch(instr); | 428 AssembleArchLookupSwitch(instr); |
388 break; | 429 break; |
389 case kArchNop: | 430 case kArchNop: |
(...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1277 } | 1318 } |
1278 } | 1319 } |
1279 MarkLazyDeoptSite(); | 1320 MarkLazyDeoptSite(); |
1280 } | 1321 } |
1281 | 1322 |
1282 #undef __ | 1323 #undef __ |
1283 | 1324 |
1284 } // namespace compiler | 1325 } // namespace compiler |
1285 } // namespace internal | 1326 } // namespace internal |
1286 } // namespace v8 | 1327 } // namespace v8 |
OLD | NEW |