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

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

Issue 1019393003: Revert "ARM64: use jssp for stack slots" (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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 after_push_argument_ = false;
439 } 438 }
440 439
441 440
442 void LCodeGen::DoCallNew(LCallNew* instr) { 441 void LCodeGen::DoCallNew(LCallNew* instr) {
443 DCHECK(ToRegister(instr->context()).is(cp)); 442 DCHECK(ToRegister(instr->context()).is(cp));
444 DCHECK(instr->IsMarkedAsCall()); 443 DCHECK(instr->IsMarkedAsCall());
445 DCHECK(ToRegister(instr->constructor()).is(x1)); 444 DCHECK(ToRegister(instr->constructor()).is(x1));
446 445
447 __ Mov(x0, instr->arity()); 446 __ Mov(x0, instr->arity());
448 // No cell in x2 for construct type feedback in optimized code. 447 // No cell in x2 for construct type feedback in optimized code.
449 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); 448 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
450 449
451 CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS); 450 CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
452 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 451 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
453 after_push_argument_ = false;
454 452
455 DCHECK(ToRegister(instr->result()).is(x0)); 453 DCHECK(ToRegister(instr->result()).is(x0));
456 } 454 }
457 455
458 456
459 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { 457 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
460 DCHECK(instr->IsMarkedAsCall()); 458 DCHECK(instr->IsMarkedAsCall());
461 DCHECK(ToRegister(instr->context()).is(cp)); 459 DCHECK(ToRegister(instr->context()).is(cp));
462 DCHECK(ToRegister(instr->constructor()).is(x1)); 460 DCHECK(ToRegister(instr->constructor()).is(x1));
463 461
(...skipping 27 matching lines...) Expand all
491 __ Bind(&packed_case); 489 __ Bind(&packed_case);
492 } 490 }
493 491
494 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); 492 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode);
495 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 493 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
496 __ Bind(&done); 494 __ Bind(&done);
497 } else { 495 } else {
498 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); 496 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
499 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 497 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
500 } 498 }
501 after_push_argument_ = false;
502 499
503 DCHECK(ToRegister(instr->result()).is(x0)); 500 DCHECK(ToRegister(instr->result()).is(x0));
504 } 501 }
505 502
506 503
507 void LCodeGen::CallRuntime(const Runtime::Function* function, 504 void LCodeGen::CallRuntime(const Runtime::Function* function,
508 int num_arguments, 505 int num_arguments,
509 LInstruction* instr, 506 LInstruction* instr,
510 SaveFPRegsMode save_doubles) { 507 SaveFPRegsMode save_doubles) {
511 DCHECK(instr != NULL); 508 DCHECK(instr != NULL);
512 509
513 __ CallRuntime(function, num_arguments, save_doubles); 510 __ CallRuntime(function, num_arguments, save_doubles);
514 511
515 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 512 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
516 } 513 }
517 514
518 515
519 void LCodeGen::LoadContextFromDeferred(LOperand* context) { 516 void LCodeGen::LoadContextFromDeferred(LOperand* context) {
520 if (context->IsRegister()) { 517 if (context->IsRegister()) {
521 __ Mov(cp, ToRegister(context)); 518 __ Mov(cp, ToRegister(context));
522 } else if (context->IsStackSlot()) { 519 } else if (context->IsStackSlot()) {
523 __ Ldr(cp, ToMemOperand(context, kMustUseFramePointer)); 520 __ Ldr(cp, ToMemOperand(context));
524 } else if (context->IsConstantOperand()) { 521 } else if (context->IsConstantOperand()) {
525 HConstant* constant = 522 HConstant* constant =
526 chunk_->LookupConstant(LConstantOperand::cast(context)); 523 chunk_->LookupConstant(LConstantOperand::cast(context));
527 __ LoadHeapObject(cp, 524 __ LoadHeapObject(cp,
528 Handle<HeapObject>::cast(constant->handle(isolate()))); 525 Handle<HeapObject>::cast(constant->handle(isolate())));
529 } else { 526 } else {
530 UNREACHABLE(); 527 UNREACHABLE();
531 } 528 }
532 } 529 }
533 530
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 return Operand(0); 1265 return Operand(0);
1269 } 1266 }
1270 1267
1271 1268
1272 static int64_t ArgumentsOffsetWithoutFrame(int index) { 1269 static int64_t ArgumentsOffsetWithoutFrame(int index) {
1273 DCHECK(index < 0); 1270 DCHECK(index < 0);
1274 return -(index + 1) * kPointerSize; 1271 return -(index + 1) * kPointerSize;
1275 } 1272 }
1276 1273
1277 1274
1278 MemOperand LCodeGen::ToMemOperand(LOperand* op, StackMode stack_mode) const { 1275 MemOperand LCodeGen::ToMemOperand(LOperand* op) const {
1279 DCHECK(op != NULL); 1276 DCHECK(op != NULL);
1280 DCHECK(!op->IsRegister()); 1277 DCHECK(!op->IsRegister());
1281 DCHECK(!op->IsDoubleRegister()); 1278 DCHECK(!op->IsDoubleRegister());
1282 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 1279 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
1283 if (NeedsEagerFrame()) { 1280 if (NeedsEagerFrame()) {
1284 int fp_offset = StackSlotOffset(op->index()); 1281 return MemOperand(fp, StackSlotOffset(op->index()));
1285 if (op->index() >= 0) {
1286 // Loads and stores have a bigger reach in positive offset than negative.
1287 // When the load or the store can't be done in one instruction via fp
1288 // (too big negative offset), we try to access via jssp (positive offset).
1289 // We can reference a stack slot from jssp only if jssp references the end
1290 // of the stack slots. It's not the case when:
1291 // - stack_mode != kCanUseStackPointer: this is the case when a deferred
1292 // code saved the registers.
1293 // - after_push_argument_: arguments has been pushed for a call.
1294 // - inlined_arguments_: inlined arguments have been pushed once. All the
1295 // remainder of the function cannot trust jssp any longer.
1296 // - saves_caller_doubles: some double registers have been pushed, jssp
1297 // references the end of the double registers and not the end of the
1298 // stack slots.
1299 // Also, if the offset from fp is small enough to make a load/store in
1300 // one instruction, we use a fp access.
1301 if ((stack_mode == kCanUseStackPointer) && !after_push_argument_ &&
1302 !inlined_arguments_ && !is_int9(fp_offset) &&
1303 !info()->saves_caller_doubles()) {
1304 int jssp_offset =
1305 (GetStackSlotCount() - op->index() - 1) * kPointerSize;
1306 return MemOperand(masm()->StackPointer(), jssp_offset);
1307 }
1308 }
1309 return MemOperand(fp, fp_offset);
1310 } else { 1282 } else {
1311 // Retrieve parameter without eager stack-frame relative to the 1283 // Retrieve parameter without eager stack-frame relative to the
1312 // stack-pointer. 1284 // stack-pointer.
1313 return MemOperand(masm()->StackPointer(), 1285 return MemOperand(masm()->StackPointer(),
1314 ArgumentsOffsetWithoutFrame(op->index())); 1286 ArgumentsOffsetWithoutFrame(op->index()));
1315 } 1287 }
1316 } 1288 }
1317 1289
1318 1290
1319 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { 1291 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1703 LPointerMap* pointers = instr->pointer_map(); 1675 LPointerMap* pointers = instr->pointer_map();
1704 SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt); 1676 SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt);
1705 // The number of arguments is stored in argc (receiver) which is x0, as 1677 // The number of arguments is stored in argc (receiver) which is x0, as
1706 // expected by InvokeFunction. 1678 // expected by InvokeFunction.
1707 ParameterCount actual(argc); 1679 ParameterCount actual(argc);
1708 __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator); 1680 __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
1709 } 1681 }
1710 1682
1711 1683
1712 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 1684 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
1713 // We push some arguments and they will be pop in an other block. We can't
1714 // trust that jssp references the end of the stack slots until the end of
1715 // the function.
1716 inlined_arguments_ = true;
1717 Register result = ToRegister(instr->result()); 1685 Register result = ToRegister(instr->result());
1718 1686
1719 if (instr->hydrogen()->from_inlined()) { 1687 if (instr->hydrogen()->from_inlined()) {
1720 // When we are inside an inlined function, the arguments are the last things 1688 // When we are inside an inlined function, the arguments are the last things
1721 // that have been pushed on the stack. Therefore the arguments array can be 1689 // that have been pushed on the stack. Therefore the arguments array can be
1722 // accessed directly from jssp. 1690 // accessed directly from jssp.
1723 // However in the normal case, it is accessed via fp but there are two words 1691 // However in the normal case, it is accessed via fp but there are two words
1724 // on the stack between fp and the arguments (the saved lr and fp) and the 1692 // on the stack between fp and the arguments (the saved lr and fp) and the
1725 // LAccessArgumentsAt implementation take that into account. 1693 // LAccessArgumentsAt implementation take that into account.
1726 // In the inlined case we need to subtract the size of 2 words to jssp to 1694 // In the inlined case we need to subtract the size of 2 words to jssp to
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
2123 __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None()); 2091 __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None());
2124 } else { 2092 } else {
2125 DCHECK(instr->target()->IsRegister()); 2093 DCHECK(instr->target()->IsRegister());
2126 Register target = ToRegister(instr->target()); 2094 Register target = ToRegister(instr->target());
2127 generator.BeforeCall(__ CallSize(target)); 2095 generator.BeforeCall(__ CallSize(target));
2128 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); 2096 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
2129 __ Call(target); 2097 __ Call(target);
2130 } 2098 }
2131 generator.AfterCall(); 2099 generator.AfterCall();
2132 } 2100 }
2133
2134 after_push_argument_ = false;
2135 } 2101 }
2136 2102
2137 2103
2138 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { 2104 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
2139 DCHECK(instr->IsMarkedAsCall()); 2105 DCHECK(instr->IsMarkedAsCall());
2140 DCHECK(ToRegister(instr->function()).is(x1)); 2106 DCHECK(ToRegister(instr->function()).is(x1));
2141 2107
2142 if (instr->hydrogen()->pass_argument_count()) { 2108 if (instr->hydrogen()->pass_argument_count()) {
2143 __ Mov(x0, Operand(instr->arity())); 2109 __ Mov(x0, Operand(instr->arity()));
2144 } 2110 }
2145 2111
2146 // Change context. 2112 // Change context.
2147 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset)); 2113 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset));
2148 2114
2149 // Load the code entry address 2115 // Load the code entry address
2150 __ Ldr(x10, FieldMemOperand(x1, JSFunction::kCodeEntryOffset)); 2116 __ Ldr(x10, FieldMemOperand(x1, JSFunction::kCodeEntryOffset));
2151 __ Call(x10); 2117 __ Call(x10);
2152 2118
2153 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 2119 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
2154 after_push_argument_ = false;
2155 } 2120 }
2156 2121
2157 2122
2158 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 2123 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
2159 CallRuntime(instr->function(), instr->arity(), instr); 2124 CallRuntime(instr->function(), instr->arity(), instr);
2160 after_push_argument_ = false;
2161 } 2125 }
2162 2126
2163 2127
2164 void LCodeGen::DoCallStub(LCallStub* instr) { 2128 void LCodeGen::DoCallStub(LCallStub* instr) {
2165 DCHECK(ToRegister(instr->context()).is(cp)); 2129 DCHECK(ToRegister(instr->context()).is(cp));
2166 DCHECK(ToRegister(instr->result()).is(x0)); 2130 DCHECK(ToRegister(instr->result()).is(x0));
2167 switch (instr->hydrogen()->major_key()) { 2131 switch (instr->hydrogen()->major_key()) {
2168 case CodeStub::RegExpExec: { 2132 case CodeStub::RegExpExec: {
2169 RegExpExecStub stub(isolate()); 2133 RegExpExecStub stub(isolate());
2170 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2134 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2171 break; 2135 break;
2172 } 2136 }
2173 case CodeStub::SubString: { 2137 case CodeStub::SubString: {
2174 SubStringStub stub(isolate()); 2138 SubStringStub stub(isolate());
2175 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2139 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2176 break; 2140 break;
2177 } 2141 }
2178 case CodeStub::StringCompare: { 2142 case CodeStub::StringCompare: {
2179 StringCompareStub stub(isolate()); 2143 StringCompareStub stub(isolate());
2180 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2144 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2181 break; 2145 break;
2182 } 2146 }
2183 default: 2147 default:
2184 UNREACHABLE(); 2148 UNREACHABLE();
2185 } 2149 }
2186 after_push_argument_ = false;
2187 } 2150 }
2188 2151
2189 2152
2190 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 2153 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
2191 GenerateOsrPrologue(); 2154 GenerateOsrPrologue();
2192 } 2155 }
2193 2156
2194 2157
2195 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 2158 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
2196 Register temp = ToRegister(instr->temp()); 2159 Register temp = ToRegister(instr->temp());
(...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after
3232 if (known_function.is_null()) { 3195 if (known_function.is_null()) {
3233 LPointerMap* pointers = instr->pointer_map(); 3196 LPointerMap* pointers = instr->pointer_map();
3234 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3197 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3235 ParameterCount count(instr->arity()); 3198 ParameterCount count(instr->arity());
3236 __ InvokeFunction(x1, count, CALL_FUNCTION, generator); 3199 __ InvokeFunction(x1, count, CALL_FUNCTION, generator);
3237 } else { 3200 } else {
3238 CallKnownFunction(known_function, 3201 CallKnownFunction(known_function,
3239 instr->hydrogen()->formal_parameter_count(), 3202 instr->hydrogen()->formal_parameter_count(),
3240 instr->arity(), instr); 3203 instr->arity(), instr);
3241 } 3204 }
3242 after_push_argument_ = false;
3243 } 3205 }
3244 3206
3245 3207
3246 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 3208 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
3247 Register temp1 = ToRegister(instr->temp1()); 3209 Register temp1 = ToRegister(instr->temp1());
3248 Register temp2 = ToRegister(instr->temp2()); 3210 Register temp2 = ToRegister(instr->temp2());
3249 3211
3250 // Get the frame pointer for the calling frame. 3212 // Get the frame pointer for the calling frame.
3251 __ Ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 3213 __ Ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3252 3214
(...skipping 1521 matching lines...) Expand 10 before | Expand all | Expand 10 after
4774 LOperand* arg = instr->argument(i); 4736 LOperand* arg = instr->argument(i);
4775 if (arg->IsDoubleRegister() || arg->IsDoubleStackSlot()) { 4737 if (arg->IsDoubleRegister() || arg->IsDoubleStackSlot()) {
4776 Abort(kDoPushArgumentNotImplementedForDoubleType); 4738 Abort(kDoPushArgumentNotImplementedForDoubleType);
4777 return; 4739 return;
4778 } 4740 }
4779 args.Queue(ToRegister(arg)); 4741 args.Queue(ToRegister(arg));
4780 } 4742 }
4781 4743
4782 // The preamble was done by LPreparePushArguments. 4744 // The preamble was done by LPreparePushArguments.
4783 args.PushQueued(MacroAssembler::PushPopQueue::SKIP_PREAMBLE); 4745 args.PushQueued(MacroAssembler::PushPopQueue::SKIP_PREAMBLE);
4784
4785 after_push_argument_ = true;
4786 } 4746 }
4787 4747
4788 4748
4789 void LCodeGen::DoReturn(LReturn* instr) { 4749 void LCodeGen::DoReturn(LReturn* instr) {
4790 if (FLAG_trace && info()->IsOptimizing()) { 4750 if (FLAG_trace && info()->IsOptimizing()) {
4791 // Push the return value on the stack as the parameter. 4751 // Push the return value on the stack as the parameter.
4792 // Runtime::TraceExit returns its parameter in x0. We're leaving the code 4752 // Runtime::TraceExit returns its parameter in x0. We're leaving the code
4793 // managed by the register allocator and tearing down the frame, it's 4753 // managed by the register allocator and tearing down the frame, it's
4794 // safe to write to the context register. 4754 // safe to write to the context register.
4795 __ Push(x0); 4755 __ Push(x0);
(...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after
6070 Handle<ScopeInfo> scope_info = instr->scope_info(); 6030 Handle<ScopeInfo> scope_info = instr->scope_info();
6071 __ Push(scope_info); 6031 __ Push(scope_info);
6072 __ Push(ToRegister(instr->function())); 6032 __ Push(ToRegister(instr->function()));
6073 CallRuntime(Runtime::kPushBlockContext, 2, instr); 6033 CallRuntime(Runtime::kPushBlockContext, 2, instr);
6074 RecordSafepoint(Safepoint::kNoLazyDeopt); 6034 RecordSafepoint(Safepoint::kNoLazyDeopt);
6075 } 6035 }
6076 6036
6077 6037
6078 6038
6079 } } // namespace v8::internal 6039 } } // 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