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

Side by Side Diff: src/arm64/lithium-codegen-arm64.cc

Issue 1038363002: Reland r21101: "ARM64: use jssp for stack slots" (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase. 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/arm64/lithium-codegen-arm64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/arm64/lithium-codegen-arm64.h" 7 #include "src/arm64/lithium-codegen-arm64.h"
8 #include "src/arm64/lithium-gap-resolver-arm64.h" 8 #include "src/arm64/lithium-gap-resolver-arm64.h"
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 CallICState::CallType call_type = 428 CallICState::CallType call_type =
429 (flags & CALL_AS_METHOD) ? CallICState::METHOD : CallICState::FUNCTION; 429 (flags & CALL_AS_METHOD) ? CallICState::METHOD : CallICState::FUNCTION;
430 430
431 Handle<Code> ic = 431 Handle<Code> ic =
432 CodeFactory::CallICInOptimizedCode(isolate(), arity, call_type).code(); 432 CodeFactory::CallICInOptimizedCode(isolate(), arity, call_type).code();
433 CallCode(ic, RelocInfo::CODE_TARGET, instr); 433 CallCode(ic, RelocInfo::CODE_TARGET, instr);
434 } else { 434 } else {
435 CallFunctionStub stub(isolate(), arity, flags); 435 CallFunctionStub stub(isolate(), arity, flags);
436 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 436 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
437 } 437 }
438 RecordPushedArgumentsDelta(instr->hydrogen()->argument_delta());
438 } 439 }
439 440
440 441
441 void LCodeGen::DoCallNew(LCallNew* instr) { 442 void LCodeGen::DoCallNew(LCallNew* instr) {
442 DCHECK(ToRegister(instr->context()).is(cp)); 443 DCHECK(ToRegister(instr->context()).is(cp));
443 DCHECK(instr->IsMarkedAsCall()); 444 DCHECK(instr->IsMarkedAsCall());
444 DCHECK(ToRegister(instr->constructor()).is(x1)); 445 DCHECK(ToRegister(instr->constructor()).is(x1));
445 446
446 __ Mov(x0, instr->arity()); 447 __ Mov(x0, instr->arity());
447 // No cell in x2 for construct type feedback in optimized code. 448 // No cell in x2 for construct type feedback in optimized code.
448 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); 449 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
449 450
450 CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS); 451 CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
451 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 452 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
453 RecordPushedArgumentsDelta(instr->hydrogen()->argument_delta());
452 454
453 DCHECK(ToRegister(instr->result()).is(x0)); 455 DCHECK(ToRegister(instr->result()).is(x0));
454 } 456 }
455 457
456 458
457 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { 459 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
458 DCHECK(instr->IsMarkedAsCall()); 460 DCHECK(instr->IsMarkedAsCall());
459 DCHECK(ToRegister(instr->context()).is(cp)); 461 DCHECK(ToRegister(instr->context()).is(cp));
460 DCHECK(ToRegister(instr->constructor()).is(x1)); 462 DCHECK(ToRegister(instr->constructor()).is(x1));
461 463
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 __ Bind(&packed_case); 499 __ Bind(&packed_case);
498 } 500 }
499 501
500 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); 502 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode);
501 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 503 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
502 __ Bind(&done); 504 __ Bind(&done);
503 } else { 505 } else {
504 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); 506 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
505 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 507 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
506 } 508 }
509 RecordPushedArgumentsDelta(instr->hydrogen()->argument_delta());
507 510
508 DCHECK(ToRegister(instr->result()).is(x0)); 511 DCHECK(ToRegister(instr->result()).is(x0));
509 } 512 }
510 513
511 514
512 void LCodeGen::CallRuntime(const Runtime::Function* function, 515 void LCodeGen::CallRuntime(const Runtime::Function* function,
513 int num_arguments, 516 int num_arguments,
514 LInstruction* instr, 517 LInstruction* instr,
515 SaveFPRegsMode save_doubles) { 518 SaveFPRegsMode save_doubles) {
516 DCHECK(instr != NULL); 519 DCHECK(instr != NULL);
517 520
518 __ CallRuntime(function, num_arguments, save_doubles); 521 __ CallRuntime(function, num_arguments, save_doubles);
519 522
520 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 523 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
521 } 524 }
522 525
523 526
524 void LCodeGen::LoadContextFromDeferred(LOperand* context) { 527 void LCodeGen::LoadContextFromDeferred(LOperand* context) {
525 if (context->IsRegister()) { 528 if (context->IsRegister()) {
526 __ Mov(cp, ToRegister(context)); 529 __ Mov(cp, ToRegister(context));
527 } else if (context->IsStackSlot()) { 530 } else if (context->IsStackSlot()) {
528 __ Ldr(cp, ToMemOperand(context)); 531 __ Ldr(cp, ToMemOperand(context, kMustUseFramePointer));
529 } else if (context->IsConstantOperand()) { 532 } else if (context->IsConstantOperand()) {
530 HConstant* constant = 533 HConstant* constant =
531 chunk_->LookupConstant(LConstantOperand::cast(context)); 534 chunk_->LookupConstant(LConstantOperand::cast(context));
532 __ LoadHeapObject(cp, 535 __ LoadHeapObject(cp,
533 Handle<HeapObject>::cast(constant->handle(isolate()))); 536 Handle<HeapObject>::cast(constant->handle(isolate())));
534 } else { 537 } else {
535 UNREACHABLE(); 538 UNREACHABLE();
536 } 539 }
537 } 540 }
538 541
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 return Operand(0); 1277 return Operand(0);
1275 } 1278 }
1276 1279
1277 1280
1278 static int64_t ArgumentsOffsetWithoutFrame(int index) { 1281 static int64_t ArgumentsOffsetWithoutFrame(int index) {
1279 DCHECK(index < 0); 1282 DCHECK(index < 0);
1280 return -(index + 1) * kPointerSize; 1283 return -(index + 1) * kPointerSize;
1281 } 1284 }
1282 1285
1283 1286
1284 MemOperand LCodeGen::ToMemOperand(LOperand* op) const { 1287 MemOperand LCodeGen::ToMemOperand(LOperand* op, StackMode stack_mode) const {
1285 DCHECK(op != NULL); 1288 DCHECK(op != NULL);
1286 DCHECK(!op->IsRegister()); 1289 DCHECK(!op->IsRegister());
1287 DCHECK(!op->IsDoubleRegister()); 1290 DCHECK(!op->IsDoubleRegister());
1288 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 1291 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
1289 if (NeedsEagerFrame()) { 1292 if (NeedsEagerFrame()) {
1290 return MemOperand(fp, StackSlotOffset(op->index())); 1293 int fp_offset = StackSlotOffset(op->index());
1294 // Loads and stores have a bigger reach in positive offset than negative.
1295 // We try to access using jssp (positive offset) first, then fall back to
1296 // fp (negative offset) if that fails.
1297 //
1298 // We can reference a stack slot from jssp only if we know how much we've
1299 // put on the stack. We don't know this in the following cases:
1300 // - stack_mode != kCanUseStackPointer: this is the case when deferred
1301 // code has saved the registers.
1302 // - saves_caller_doubles(): some double registers have been pushed, jssp
1303 // references the end of the double registers and not the end of the stack
1304 // slots.
1305 // In both of the cases above, we _could_ add the tracking information
1306 // required so that we can use jssp here, but in practice it isn't worth it.
1307 if ((stack_mode == kCanUseStackPointer) &&
1308 !info()->saves_caller_doubles()) {
1309 int jssp_offset_to_fp =
1310 StandardFrameConstants::kFixedFrameSizeFromFp +
1311 (pushed_arguments_ + GetStackSlotCount()) * kPointerSize;
1312 int jssp_offset = fp_offset + jssp_offset_to_fp;
1313 if (masm()->IsImmLSScaled(jssp_offset, LSDoubleWord)) {
1314 return MemOperand(masm()->StackPointer(), jssp_offset);
1315 }
1316 }
1317 return MemOperand(fp, fp_offset);
1291 } else { 1318 } else {
1292 // Retrieve parameter without eager stack-frame relative to the 1319 // Retrieve parameter without eager stack-frame relative to the
1293 // stack-pointer. 1320 // stack-pointer.
1294 return MemOperand(masm()->StackPointer(), 1321 return MemOperand(masm()->StackPointer(),
1295 ArgumentsOffsetWithoutFrame(op->index())); 1322 ArgumentsOffsetWithoutFrame(op->index()));
1296 } 1323 }
1297 } 1324 }
1298 1325
1299 1326
1300 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { 1327 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after
2078 __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None()); 2105 __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None());
2079 } else { 2106 } else {
2080 DCHECK(instr->target()->IsRegister()); 2107 DCHECK(instr->target()->IsRegister());
2081 Register target = ToRegister(instr->target()); 2108 Register target = ToRegister(instr->target());
2082 generator.BeforeCall(__ CallSize(target)); 2109 generator.BeforeCall(__ CallSize(target));
2083 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); 2110 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
2084 __ Call(target); 2111 __ Call(target);
2085 } 2112 }
2086 generator.AfterCall(); 2113 generator.AfterCall();
2087 } 2114 }
2115
2116 RecordPushedArgumentsDelta(instr->hydrogen()->argument_delta());
2088 } 2117 }
2089 2118
2090 2119
2091 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { 2120 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
2092 DCHECK(instr->IsMarkedAsCall()); 2121 DCHECK(instr->IsMarkedAsCall());
2093 DCHECK(ToRegister(instr->function()).is(x1)); 2122 DCHECK(ToRegister(instr->function()).is(x1));
2094 2123
2095 if (instr->hydrogen()->pass_argument_count()) { 2124 if (instr->hydrogen()->pass_argument_count()) {
2096 __ Mov(x0, Operand(instr->arity())); 2125 __ Mov(x0, Operand(instr->arity()));
2097 } 2126 }
2098 2127
2099 // Change context. 2128 // Change context.
2100 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset)); 2129 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset));
2101 2130
2102 // Load the code entry address 2131 // Load the code entry address
2103 __ Ldr(x10, FieldMemOperand(x1, JSFunction::kCodeEntryOffset)); 2132 __ Ldr(x10, FieldMemOperand(x1, JSFunction::kCodeEntryOffset));
2104 __ Call(x10); 2133 __ Call(x10);
2105 2134
2106 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 2135 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
2136 RecordPushedArgumentsDelta(instr->hydrogen()->argument_delta());
2107 } 2137 }
2108 2138
2109 2139
2110 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 2140 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
2111 CallRuntime(instr->function(), instr->arity(), instr); 2141 CallRuntime(instr->function(), instr->arity(), instr);
2142 RecordPushedArgumentsDelta(instr->hydrogen()->argument_delta());
2112 } 2143 }
2113 2144
2114 2145
2115 void LCodeGen::DoCallStub(LCallStub* instr) { 2146 void LCodeGen::DoCallStub(LCallStub* instr) {
2116 DCHECK(ToRegister(instr->context()).is(cp)); 2147 DCHECK(ToRegister(instr->context()).is(cp));
2117 DCHECK(ToRegister(instr->result()).is(x0)); 2148 DCHECK(ToRegister(instr->result()).is(x0));
2118 switch (instr->hydrogen()->major_key()) { 2149 switch (instr->hydrogen()->major_key()) {
2119 case CodeStub::RegExpExec: { 2150 case CodeStub::RegExpExec: {
2120 RegExpExecStub stub(isolate()); 2151 RegExpExecStub stub(isolate());
2121 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2152 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2122 break; 2153 break;
2123 } 2154 }
2124 case CodeStub::SubString: { 2155 case CodeStub::SubString: {
2125 SubStringStub stub(isolate()); 2156 SubStringStub stub(isolate());
2126 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2157 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2127 break; 2158 break;
2128 } 2159 }
2129 case CodeStub::StringCompare: { 2160 case CodeStub::StringCompare: {
2130 StringCompareStub stub(isolate()); 2161 StringCompareStub stub(isolate());
2131 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2162 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2132 break; 2163 break;
2133 } 2164 }
2134 default: 2165 default:
2135 UNREACHABLE(); 2166 UNREACHABLE();
2136 } 2167 }
2168 RecordPushedArgumentsDelta(instr->hydrogen()->argument_delta());
2137 } 2169 }
2138 2170
2139 2171
2140 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 2172 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
2141 GenerateOsrPrologue(); 2173 GenerateOsrPrologue();
2142 } 2174 }
2143 2175
2144 2176
2145 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 2177 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
2146 Register temp = ToRegister(instr->temp()); 2178 Register temp = ToRegister(instr->temp());
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 if (known_function.is_null()) { 3221 if (known_function.is_null()) {
3190 LPointerMap* pointers = instr->pointer_map(); 3222 LPointerMap* pointers = instr->pointer_map();
3191 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3223 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3192 ParameterCount count(instr->arity()); 3224 ParameterCount count(instr->arity());
3193 __ InvokeFunction(x1, count, CALL_FUNCTION, generator); 3225 __ InvokeFunction(x1, count, CALL_FUNCTION, generator);
3194 } else { 3226 } else {
3195 CallKnownFunction(known_function, 3227 CallKnownFunction(known_function,
3196 instr->hydrogen()->formal_parameter_count(), 3228 instr->hydrogen()->formal_parameter_count(),
3197 instr->arity(), instr); 3229 instr->arity(), instr);
3198 } 3230 }
3231 RecordPushedArgumentsDelta(instr->hydrogen()->argument_delta());
3199 } 3232 }
3200 3233
3201 3234
3202 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 3235 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
3203 Register temp1 = ToRegister(instr->temp1()); 3236 Register temp1 = ToRegister(instr->temp1());
3204 Register temp2 = ToRegister(instr->temp2()); 3237 Register temp2 = ToRegister(instr->temp2());
3205 3238
3206 // Get the frame pointer for the calling frame. 3239 // Get the frame pointer for the calling frame.
3207 __ Ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 3240 __ Ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3208 3241
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3302 } 3335 }
3303 3336
3304 3337
3305 void LCodeGen::DoLabel(LLabel* label) { 3338 void LCodeGen::DoLabel(LLabel* label) {
3306 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", 3339 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------",
3307 current_instruction_, 3340 current_instruction_,
3308 label->hydrogen_value()->id(), 3341 label->hydrogen_value()->id(),
3309 label->block_id(), 3342 label->block_id(),
3310 LabelType(label)); 3343 LabelType(label));
3311 3344
3345 // Inherit pushed_arguments_ from the predecessor's argument count.
3346 if (label->block()->HasPredecessor()) {
3347 pushed_arguments_ = label->block()->predecessors()->at(0)->argument_count();
3348 #ifdef DEBUG
3349 for (auto p : *label->block()->predecessors()) {
3350 DCHECK_EQ(p->argument_count(), pushed_arguments_);
3351 }
3352 #endif
3353 }
3354
3312 __ Bind(label->label()); 3355 __ Bind(label->label());
3313 current_block_ = label->block_id(); 3356 current_block_ = label->block_id();
3314 DoGap(label); 3357 DoGap(label);
3315 } 3358 }
3316 3359
3317 3360
3318 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 3361 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
3319 Register context = ToRegister(instr->context()); 3362 Register context = ToRegister(instr->context());
3320 Register result = ToRegister(instr->result()); 3363 Register result = ToRegister(instr->result());
3321 __ Ldr(result, ContextMemOperand(context, instr->slot_index())); 3364 __ Ldr(result, ContextMemOperand(context, instr->slot_index()));
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
4747 LOperand* arg = instr->argument(i); 4790 LOperand* arg = instr->argument(i);
4748 if (arg->IsDoubleRegister() || arg->IsDoubleStackSlot()) { 4791 if (arg->IsDoubleRegister() || arg->IsDoubleStackSlot()) {
4749 Abort(kDoPushArgumentNotImplementedForDoubleType); 4792 Abort(kDoPushArgumentNotImplementedForDoubleType);
4750 return; 4793 return;
4751 } 4794 }
4752 args.Queue(ToRegister(arg)); 4795 args.Queue(ToRegister(arg));
4753 } 4796 }
4754 4797
4755 // The preamble was done by LPreparePushArguments. 4798 // The preamble was done by LPreparePushArguments.
4756 args.PushQueued(MacroAssembler::PushPopQueue::SKIP_PREAMBLE); 4799 args.PushQueued(MacroAssembler::PushPopQueue::SKIP_PREAMBLE);
4800
4801 RecordPushedArgumentsDelta(instr->ArgumentCount());
4757 } 4802 }
4758 4803
4759 4804
4760 void LCodeGen::DoReturn(LReturn* instr) { 4805 void LCodeGen::DoReturn(LReturn* instr) {
4761 if (FLAG_trace && info()->IsOptimizing()) { 4806 if (FLAG_trace && info()->IsOptimizing()) {
4762 // Push the return value on the stack as the parameter. 4807 // Push the return value on the stack as the parameter.
4763 // Runtime::TraceExit returns its parameter in x0. We're leaving the code 4808 // Runtime::TraceExit returns its parameter in x0. We're leaving the code
4764 // managed by the register allocator and tearing down the frame, it's 4809 // managed by the register allocator and tearing down the frame, it's
4765 // safe to write to the context register. 4810 // safe to write to the context register.
4766 __ Push(x0); 4811 __ Push(x0);
(...skipping 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after
6049 Handle<ScopeInfo> scope_info = instr->scope_info(); 6094 Handle<ScopeInfo> scope_info = instr->scope_info();
6050 __ Push(scope_info); 6095 __ Push(scope_info);
6051 __ Push(ToRegister(instr->function())); 6096 __ Push(ToRegister(instr->function()));
6052 CallRuntime(Runtime::kPushBlockContext, 2, instr); 6097 CallRuntime(Runtime::kPushBlockContext, 2, instr);
6053 RecordSafepoint(Safepoint::kNoLazyDeopt); 6098 RecordSafepoint(Safepoint::kNoLazyDeopt);
6054 } 6099 }
6055 6100
6056 6101
6057 6102
6058 } } // namespace v8::internal 6103 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm64/lithium-codegen-arm64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698