Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: src/compiler/arm/code-generator-arm.cc

Issue 1108563002: Detect simple tail calls (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixed index type Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler.cc ('k') | src/compiler/arm/instruction-selector-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 __ cmp(offset, i.InputRegister(1)); \ 292 __ cmp(offset, i.InputRegister(1)); \
293 } else { \ 293 } else { \
294 __ cmp(offset, i.InputImmediate(1)); \ 294 __ cmp(offset, i.InputImmediate(1)); \
295 } \ 295 } \
296 auto value = i.InputRegister(2); \ 296 auto value = i.InputRegister(2); \
297 __ asm_instr(value, i.InputOffset(3), lo); \ 297 __ asm_instr(value, i.InputOffset(3), lo); \
298 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ 298 DCHECK_EQ(LeaveCC, i.OutputSBit()); \
299 } while (0) 299 } while (0)
300 300
301 301
302 void CodeGenerator::AssembleDeconstructActivationRecord() {
303 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
304 int stack_slots = frame()->GetSpillSlotCount();
305 if (descriptor->IsJSFunctionCall() || stack_slots > 0) {
306 __ LeaveFrame(StackFrame::MANUAL);
307 int pop_count = descriptor->IsJSFunctionCall()
308 ? static_cast<int>(descriptor->JSParameterCount())
309 : 0;
310 __ Drop(pop_count);
311 }
312 }
313
314
302 // Assembles an instruction after register allocation, producing machine code. 315 // Assembles an instruction after register allocation, producing machine code.
303 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { 316 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
304 ArmOperandConverter i(this, instr); 317 ArmOperandConverter i(this, instr);
305 318
306 switch (ArchOpcodeField::decode(instr->opcode())) { 319 switch (ArchOpcodeField::decode(instr->opcode())) {
307 case kArchCallCodeObject: { 320 case kArchCallCodeObject: {
308 EnsureSpaceForLazyDeopt(); 321 EnsureSpaceForLazyDeopt();
309 if (instr->InputAt(0)->IsImmediate()) { 322 if (instr->InputAt(0)->IsImmediate()) {
310 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 323 __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
311 RelocInfo::CODE_TARGET); 324 RelocInfo::CODE_TARGET);
312 } else { 325 } else {
313 __ add(ip, i.InputRegister(0), 326 __ add(ip, i.InputRegister(0),
314 Operand(Code::kHeaderSize - kHeapObjectTag)); 327 Operand(Code::kHeaderSize - kHeapObjectTag));
315 __ Call(ip); 328 __ Call(ip);
316 } 329 }
317 RecordCallPosition(instr); 330 RecordCallPosition(instr);
318 DCHECK_EQ(LeaveCC, i.OutputSBit()); 331 DCHECK_EQ(LeaveCC, i.OutputSBit());
319 break; 332 break;
320 } 333 }
334 case kArchTailCallCodeObject: {
335 AssembleDeconstructActivationRecord();
336 if (instr->InputAt(0)->IsImmediate()) {
337 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
338 RelocInfo::CODE_TARGET);
339 } else {
340 __ add(ip, i.InputRegister(0),
341 Operand(Code::kHeaderSize - kHeapObjectTag));
342 __ Jump(ip);
343 }
344 DCHECK_EQ(LeaveCC, i.OutputSBit());
345 break;
346 }
321 case kArchCallJSFunction: { 347 case kArchCallJSFunction: {
322 EnsureSpaceForLazyDeopt(); 348 EnsureSpaceForLazyDeopt();
323 Register func = i.InputRegister(0); 349 Register func = i.InputRegister(0);
324 if (FLAG_debug_code) { 350 if (FLAG_debug_code) {
325 // Check the function's context matches the context argument. 351 // Check the function's context matches the context argument.
326 __ ldr(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); 352 __ ldr(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
327 __ cmp(cp, kScratchReg); 353 __ cmp(cp, kScratchReg);
328 __ Assert(eq, kWrongFunctionContext); 354 __ Assert(eq, kWrongFunctionContext);
329 } 355 }
330 __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 356 __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
331 __ Call(ip); 357 __ Call(ip);
332 RecordCallPosition(instr); 358 RecordCallPosition(instr);
333 DCHECK_EQ(LeaveCC, i.OutputSBit()); 359 DCHECK_EQ(LeaveCC, i.OutputSBit());
334 break; 360 break;
335 } 361 }
362 case kArchTailCallJSFunction: {
363 Register func = i.InputRegister(0);
364 if (FLAG_debug_code) {
365 // Check the function's context matches the context argument.
366 __ ldr(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
367 __ cmp(cp, kScratchReg);
368 __ Assert(eq, kWrongFunctionContext);
369 }
370 AssembleDeconstructActivationRecord();
371 __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
372 __ Jump(ip);
373 DCHECK_EQ(LeaveCC, i.OutputSBit());
374 break;
375 }
336 case kArchJmp: 376 case kArchJmp:
337 AssembleArchJump(i.InputRpo(0)); 377 AssembleArchJump(i.InputRpo(0));
338 DCHECK_EQ(LeaveCC, i.OutputSBit()); 378 DCHECK_EQ(LeaveCC, i.OutputSBit());
339 break; 379 break;
340 case kArchLookupSwitch: 380 case kArchLookupSwitch:
341 AssembleArchLookupSwitch(instr); 381 AssembleArchLookupSwitch(instr);
342 DCHECK_EQ(LeaveCC, i.OutputSBit()); 382 DCHECK_EQ(LeaveCC, i.OutputSBit());
343 break; 383 break;
344 case kArchTableSwitch: 384 case kArchTableSwitch:
345 AssembleArchTableSwitch(instr); 385 AssembleArchTableSwitch(instr);
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 } 1214 }
1175 } 1215 }
1176 MarkLazyDeoptSite(); 1216 MarkLazyDeoptSite();
1177 } 1217 }
1178 1218
1179 #undef __ 1219 #undef __
1180 1220
1181 } // namespace compiler 1221 } // namespace compiler
1182 } // namespace internal 1222 } // namespace internal
1183 } // namespace v8 1223 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler.cc ('k') | src/compiler/arm/instruction-selector-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698