| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |