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 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 __ JumpIfRoot(temp, Heap::kNativeContextMapRootIndex, &fast); | 1386 __ JumpIfRoot(temp, Heap::kNativeContextMapRootIndex, &fast); |
1387 // Check that extension is NULL. | 1387 // Check that extension is NULL. |
1388 __ Ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX)); | 1388 __ Ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX)); |
1389 __ Cbnz(temp, slow); | 1389 __ Cbnz(temp, slow); |
1390 // Load next context in chain. | 1390 // Load next context in chain. |
1391 __ Ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX)); | 1391 __ Ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX)); |
1392 __ B(&loop); | 1392 __ B(&loop); |
1393 __ Bind(&fast); | 1393 __ Bind(&fast); |
1394 } | 1394 } |
1395 | 1395 |
1396 __ Ldr(x0, GlobalObjectMemOperand()); | 1396 __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); |
1397 __ Mov(x2, Operand(var->name())); | 1397 __ Mov(LoadIC::NameRegister(), Operand(var->name())); |
1398 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL | 1398 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL |
1399 : CONTEXTUAL; | 1399 : CONTEXTUAL; |
1400 CallLoadIC(mode); | 1400 CallLoadIC(mode); |
1401 } | 1401 } |
1402 | 1402 |
1403 | 1403 |
1404 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1404 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1405 Label* slow) { | 1405 Label* slow) { |
1406 ASSERT(var->IsContextSlot()); | 1406 ASSERT(var->IsContextSlot()); |
1407 Register context = cp; | 1407 Register context = cp; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1466 // Record position before possible IC call. | 1466 // Record position before possible IC call. |
1467 SetSourcePosition(proxy->position()); | 1467 SetSourcePosition(proxy->position()); |
1468 Variable* var = proxy->var(); | 1468 Variable* var = proxy->var(); |
1469 | 1469 |
1470 // Three cases: global variables, lookup variables, and all other types of | 1470 // Three cases: global variables, lookup variables, and all other types of |
1471 // variables. | 1471 // variables. |
1472 switch (var->location()) { | 1472 switch (var->location()) { |
1473 case Variable::UNALLOCATED: { | 1473 case Variable::UNALLOCATED: { |
1474 Comment cmnt(masm_, "Global variable"); | 1474 Comment cmnt(masm_, "Global variable"); |
1475 // Use inline caching. Variable name is passed in x2 and the global | 1475 __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); |
1476 // object (receiver) in x0. | 1476 __ Mov(LoadIC::NameRegister(), Operand(var->name())); |
1477 __ Ldr(x0, GlobalObjectMemOperand()); | |
1478 __ Mov(x2, Operand(var->name())); | |
1479 CallLoadIC(CONTEXTUAL); | 1477 CallLoadIC(CONTEXTUAL); |
1480 context()->Plug(x0); | 1478 context()->Plug(x0); |
1481 break; | 1479 break; |
1482 } | 1480 } |
1483 | 1481 |
1484 case Variable::PARAMETER: | 1482 case Variable::PARAMETER: |
1485 case Variable::LOCAL: | 1483 case Variable::LOCAL: |
1486 case Variable::CONTEXT: { | 1484 case Variable::CONTEXT: { |
1487 Comment cmnt(masm_, var->IsContextSlot() | 1485 Comment cmnt(masm_, var->IsContextSlot() |
1488 ? "Context variable" | 1486 ? "Context variable" |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1942 case KEYED_PROPERTY: | 1940 case KEYED_PROPERTY: |
1943 EmitKeyedPropertyAssignment(expr); | 1941 EmitKeyedPropertyAssignment(expr); |
1944 break; | 1942 break; |
1945 } | 1943 } |
1946 } | 1944 } |
1947 | 1945 |
1948 | 1946 |
1949 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1947 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1950 SetSourcePosition(prop->position()); | 1948 SetSourcePosition(prop->position()); |
1951 Literal* key = prop->key()->AsLiteral(); | 1949 Literal* key = prop->key()->AsLiteral(); |
1952 __ Mov(x2, Operand(key->value())); | 1950 __ Mov(LoadIC::NameRegister(), Operand(key->value())); |
1953 // Call load IC. It has arguments receiver and property name x0 and x2. | 1951 // Call load IC. It has arguments receiver and property name x0 and x2. |
1954 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 1952 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
1955 } | 1953 } |
1956 | 1954 |
1957 | 1955 |
1958 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1956 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1959 SetSourcePosition(prop->position()); | 1957 SetSourcePosition(prop->position()); |
1960 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1958 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
1961 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1959 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
1962 CallIC(ic, prop->PropertyFeedbackId()); | 1960 CallIC(ic, prop->PropertyFeedbackId()); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2255 context()->Plug(x0); | 2253 context()->Plug(x0); |
2256 } | 2254 } |
2257 | 2255 |
2258 | 2256 |
2259 void FullCodeGenerator::VisitProperty(Property* expr) { | 2257 void FullCodeGenerator::VisitProperty(Property* expr) { |
2260 Comment cmnt(masm_, "[ Property"); | 2258 Comment cmnt(masm_, "[ Property"); |
2261 Expression* key = expr->key(); | 2259 Expression* key = expr->key(); |
2262 | 2260 |
2263 if (key->IsPropertyName()) { | 2261 if (key->IsPropertyName()) { |
2264 VisitForAccumulatorValue(expr->obj()); | 2262 VisitForAccumulatorValue(expr->obj()); |
| 2263 ASSERT(x0.is(LoadIC::ReceiverRegister())); |
2265 EmitNamedPropertyLoad(expr); | 2264 EmitNamedPropertyLoad(expr); |
2266 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2265 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2267 context()->Plug(x0); | 2266 context()->Plug(x0); |
2268 } else { | 2267 } else { |
2269 VisitForStackValue(expr->obj()); | 2268 VisitForStackValue(expr->obj()); |
2270 VisitForAccumulatorValue(expr->key()); | 2269 VisitForAccumulatorValue(expr->key()); |
2271 __ Pop(x1); | 2270 ASSERT(x0.is(KeyedLoadIC::NameRegister())); |
| 2271 __ Pop(KeyedLoadIC::ReceiverRegister()); |
2272 EmitKeyedPropertyLoad(expr); | 2272 EmitKeyedPropertyLoad(expr); |
2273 context()->Plug(x0); | 2273 context()->Plug(x0); |
2274 } | 2274 } |
2275 } | 2275 } |
2276 | 2276 |
2277 | 2277 |
2278 void FullCodeGenerator::CallIC(Handle<Code> code, | 2278 void FullCodeGenerator::CallIC(Handle<Code> code, |
2279 TypeFeedbackId ast_id) { | 2279 TypeFeedbackId ast_id) { |
2280 ic_total_count_++; | 2280 ic_total_count_++; |
2281 // All calls must have a predictable size in full-codegen code to ensure that | 2281 // All calls must have a predictable size in full-codegen code to ensure that |
(...skipping 15 matching lines...) Expand all Loading... |
2297 { StackValueContext context(this); | 2297 { StackValueContext context(this); |
2298 EmitVariableLoad(callee->AsVariableProxy()); | 2298 EmitVariableLoad(callee->AsVariableProxy()); |
2299 PrepareForBailout(callee, NO_REGISTERS); | 2299 PrepareForBailout(callee, NO_REGISTERS); |
2300 } | 2300 } |
2301 // Push undefined as receiver. This is patched in the method prologue if it | 2301 // Push undefined as receiver. This is patched in the method prologue if it |
2302 // is a sloppy mode method. | 2302 // is a sloppy mode method. |
2303 __ Push(isolate()->factory()->undefined_value()); | 2303 __ Push(isolate()->factory()->undefined_value()); |
2304 } else { | 2304 } else { |
2305 // Load the function from the receiver. | 2305 // Load the function from the receiver. |
2306 ASSERT(callee->IsProperty()); | 2306 ASSERT(callee->IsProperty()); |
2307 __ Peek(x0, 0); | 2307 __ Peek(LoadIC::ReceiverRegister(), 0); |
2308 EmitNamedPropertyLoad(callee->AsProperty()); | 2308 EmitNamedPropertyLoad(callee->AsProperty()); |
2309 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2309 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2310 // Push the target function under the receiver. | 2310 // Push the target function under the receiver. |
2311 __ Pop(x10); | 2311 __ Pop(x10); |
2312 __ Push(x0, x10); | 2312 __ Push(x0, x10); |
2313 } | 2313 } |
2314 | 2314 |
2315 EmitCall(expr, call_type); | 2315 EmitCall(expr, call_type); |
2316 } | 2316 } |
2317 | 2317 |
2318 | 2318 |
2319 // Code common for calls using the IC. | 2319 // Code common for calls using the IC. |
2320 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2320 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2321 Expression* key) { | 2321 Expression* key) { |
2322 // Load the key. | 2322 // Load the key. |
2323 VisitForAccumulatorValue(key); | 2323 VisitForAccumulatorValue(key); |
| 2324 ASSERT(x0.is(KeyedLoadIC::NameRegister())); |
2324 | 2325 |
2325 Expression* callee = expr->expression(); | 2326 Expression* callee = expr->expression(); |
2326 | 2327 |
2327 // Load the function from the receiver. | 2328 // Load the function from the receiver. |
2328 ASSERT(callee->IsProperty()); | 2329 ASSERT(callee->IsProperty()); |
2329 __ Peek(x1, 0); | 2330 __ Peek(KeyedLoadIC::ReceiverRegister(), 0); |
2330 EmitKeyedPropertyLoad(callee->AsProperty()); | 2331 EmitKeyedPropertyLoad(callee->AsProperty()); |
2331 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2332 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2332 | 2333 |
2333 // Push the target function under the receiver. | 2334 // Push the target function under the receiver. |
2334 __ Pop(x10); | 2335 __ Pop(x10); |
2335 __ Push(x0, x10); | 2336 __ Push(x0, x10); |
2336 | 2337 |
2337 EmitCall(expr, CallIC::METHOD); | 2338 EmitCall(expr, CallIC::METHOD); |
2338 } | 2339 } |
2339 | 2340 |
(...skipping 1399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3739 return; | 3740 return; |
3740 } | 3741 } |
3741 | 3742 |
3742 Comment cmnt(masm_, "[ CallRunTime"); | 3743 Comment cmnt(masm_, "[ CallRunTime"); |
3743 ZoneList<Expression*>* args = expr->arguments(); | 3744 ZoneList<Expression*>* args = expr->arguments(); |
3744 int arg_count = args->length(); | 3745 int arg_count = args->length(); |
3745 | 3746 |
3746 if (expr->is_jsruntime()) { | 3747 if (expr->is_jsruntime()) { |
3747 // Push the builtins object as the receiver. | 3748 // Push the builtins object as the receiver. |
3748 __ Ldr(x10, GlobalObjectMemOperand()); | 3749 __ Ldr(x10, GlobalObjectMemOperand()); |
3749 __ Ldr(x0, FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); | 3750 __ Ldr(LoadIC::ReceiverRegister(), |
3750 __ Push(x0); | 3751 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); |
| 3752 __ Push(LoadIC::ReceiverRegister()); |
3751 | 3753 |
3752 // Load the function from the receiver. | 3754 // Load the function from the receiver. |
3753 Handle<String> name = expr->name(); | 3755 Handle<String> name = expr->name(); |
3754 __ Mov(x2, Operand(name)); | 3756 __ Mov(LoadIC::NameRegister(), Operand(name)); |
3755 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 3757 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
3756 | 3758 |
3757 // Push the target function under the receiver. | 3759 // Push the target function under the receiver. |
3758 __ Pop(x10); | 3760 __ Pop(x10); |
3759 __ Push(x0, x10); | 3761 __ Push(x0, x10); |
3760 | 3762 |
3761 int arg_count = args->length(); | 3763 int arg_count = args->length(); |
3762 for (int i = 0; i < arg_count; i++) { | 3764 for (int i = 0; i < arg_count; i++) { |
3763 VisitForStackValue(args->at(i)); | 3765 VisitForStackValue(args->at(i)); |
3764 } | 3766 } |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3920 AccumulatorValueContext context(this); | 3922 AccumulatorValueContext context(this); |
3921 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 3923 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
3922 } else { | 3924 } else { |
3923 // Reserve space for result of postfix operation. | 3925 // Reserve space for result of postfix operation. |
3924 if (expr->is_postfix() && !context()->IsEffect()) { | 3926 if (expr->is_postfix() && !context()->IsEffect()) { |
3925 __ Push(xzr); | 3927 __ Push(xzr); |
3926 } | 3928 } |
3927 if (assign_type == NAMED_PROPERTY) { | 3929 if (assign_type == NAMED_PROPERTY) { |
3928 // Put the object both on the stack and in the accumulator. | 3930 // Put the object both on the stack and in the accumulator. |
3929 VisitForAccumulatorValue(prop->obj()); | 3931 VisitForAccumulatorValue(prop->obj()); |
3930 __ Push(x0); | 3932 ASSERT(x0.is(LoadIC::ReceiverRegister())); |
| 3933 __ Push(LoadIC::ReceiverRegister()); |
3931 EmitNamedPropertyLoad(prop); | 3934 EmitNamedPropertyLoad(prop); |
3932 } else { | 3935 } else { |
3933 // KEYED_PROPERTY | 3936 // KEYED_PROPERTY |
3934 VisitForStackValue(prop->obj()); | 3937 VisitForStackValue(prop->obj()); |
3935 VisitForAccumulatorValue(prop->key()); | 3938 VisitForAccumulatorValue(prop->key()); |
3936 __ Peek(x1, 0); | 3939 ASSERT(x0.is(KeyedLoadIC::NameRegister())); |
3937 __ Push(x0); | 3940 __ Peek(KeyedLoadIC::ReceiverRegister(), 0); |
| 3941 __ Push(KeyedLoadIC::NameRegister()); |
3938 EmitKeyedPropertyLoad(prop); | 3942 EmitKeyedPropertyLoad(prop); |
3939 } | 3943 } |
3940 } | 3944 } |
3941 | 3945 |
3942 // We need a second deoptimization point after loading the value | 3946 // We need a second deoptimization point after loading the value |
3943 // in case evaluating the property load my have a side effect. | 3947 // in case evaluating the property load my have a side effect. |
3944 if (assign_type == VARIABLE) { | 3948 if (assign_type == VARIABLE) { |
3945 PrepareForBailout(expr->expression(), TOS_REG); | 3949 PrepareForBailout(expr->expression(), TOS_REG); |
3946 } else { | 3950 } else { |
3947 PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 3951 PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4077 } | 4081 } |
4078 } | 4082 } |
4079 | 4083 |
4080 | 4084 |
4081 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4085 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
4082 ASSERT(!context()->IsEffect()); | 4086 ASSERT(!context()->IsEffect()); |
4083 ASSERT(!context()->IsTest()); | 4087 ASSERT(!context()->IsTest()); |
4084 VariableProxy* proxy = expr->AsVariableProxy(); | 4088 VariableProxy* proxy = expr->AsVariableProxy(); |
4085 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4089 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
4086 Comment cmnt(masm_, "Global variable"); | 4090 Comment cmnt(masm_, "Global variable"); |
4087 __ Ldr(x0, GlobalObjectMemOperand()); | 4091 __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); |
4088 __ Mov(x2, Operand(proxy->name())); | 4092 __ Mov(LoadIC::NameRegister(), Operand(proxy->name())); |
4089 // Use a regular load, not a contextual load, to avoid a reference | 4093 // Use a regular load, not a contextual load, to avoid a reference |
4090 // error. | 4094 // error. |
4091 CallLoadIC(NOT_CONTEXTUAL); | 4095 CallLoadIC(NOT_CONTEXTUAL); |
4092 PrepareForBailout(expr, TOS_REG); | 4096 PrepareForBailout(expr, TOS_REG); |
4093 context()->Plug(x0); | 4097 context()->Plug(x0); |
4094 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4098 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
4095 Label done, slow; | 4099 Label done, slow; |
4096 | 4100 |
4097 // Generate code for loading from variables potentially shadowed | 4101 // Generate code for loading from variables potentially shadowed |
4098 // by eval-introduced variables. | 4102 // by eval-introduced variables. |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4426 kLRHasBeenSaved, kDontSaveFPRegs); | 4430 kLRHasBeenSaved, kDontSaveFPRegs); |
4427 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); | 4431 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); |
4428 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4432 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4429 __ Pop(x0); // result | 4433 __ Pop(x0); // result |
4430 EmitReturnSequence(); | 4434 EmitReturnSequence(); |
4431 __ Bind(&l_resume); // received in x0 | 4435 __ Bind(&l_resume); // received in x0 |
4432 __ PopTryHandler(); | 4436 __ PopTryHandler(); |
4433 | 4437 |
4434 // receiver = iter; f = 'next'; arg = received; | 4438 // receiver = iter; f = 'next'; arg = received; |
4435 __ Bind(&l_next); | 4439 __ Bind(&l_next); |
| 4440 Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); |
| 4441 Register keyedload_name = KeyedLoadIC::NameRegister(); |
| 4442 ASSERT(keyedload_receiver.is(x1)); |
| 4443 ASSERT(keyedload_name.is(x0)); |
| 4444 |
4436 __ LoadRoot(x2, Heap::knext_stringRootIndex); // "next" | 4445 __ LoadRoot(x2, Heap::knext_stringRootIndex); // "next" |
4437 __ Peek(x3, 1 * kPointerSize); // iter | 4446 __ Peek(x3, 1 * kPointerSize); // iter |
4438 __ Push(x2, x3, x0); // "next", iter, received | 4447 __ Push(x2, x3, x0); // "next", iter, received |
4439 | 4448 |
4440 // result = receiver[f](arg); | 4449 // result = receiver[f](arg); |
4441 __ Bind(&l_call); | 4450 __ Bind(&l_call); |
4442 __ Peek(x1, 1 * kPointerSize); | 4451 __ Peek(keyedload_receiver, 1 * kPointerSize); |
4443 __ Peek(x0, 2 * kPointerSize); | 4452 __ Peek(keyedload_name, 2 * kPointerSize); |
4444 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 4453 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
4445 CallIC(ic, TypeFeedbackId::None()); | 4454 CallIC(ic, TypeFeedbackId::None()); |
4446 __ Mov(x1, x0); | 4455 __ Mov(x1, x0); |
4447 __ Poke(x1, 2 * kPointerSize); | 4456 __ Poke(x1, 2 * kPointerSize); |
4448 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 4457 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
4449 __ CallStub(&stub); | 4458 __ CallStub(&stub); |
4450 | 4459 |
4451 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4460 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4452 __ Drop(1); // The function is still on the stack; drop it. | 4461 __ Drop(1); // The function is still on the stack; drop it. |
4453 | 4462 |
4454 // if (!result.done) goto l_try; | 4463 // if (!result.done) goto l_try; |
4455 __ Bind(&l_loop); | 4464 __ Bind(&l_loop); |
4456 __ Push(x0); // save result | 4465 Register load_receiver = LoadIC::ReceiverRegister(); |
4457 __ LoadRoot(x2, Heap::kdone_stringRootIndex); // "done" | 4466 Register load_name = LoadIC::NameRegister(); |
4458 CallLoadIC(NOT_CONTEXTUAL); // result.done in x0 | 4467 ASSERT(load_receiver.is(x0)); |
| 4468 ASSERT(load_name.is(x2)); |
| 4469 __ Push(load_receiver); // save result |
| 4470 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
| 4471 CallLoadIC(NOT_CONTEXTUAL); // x0=result.done |
4459 // The ToBooleanStub argument (result.done) is in x0. | 4472 // The ToBooleanStub argument (result.done) is in x0. |
4460 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 4473 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
4461 CallIC(bool_ic); | 4474 CallIC(bool_ic); |
4462 __ Cbz(x0, &l_try); | 4475 __ Cbz(x0, &l_try); |
4463 | 4476 |
4464 // result.value | 4477 // result.value |
4465 __ Pop(x0); // result | 4478 __ Pop(load_receiver); // result |
4466 __ LoadRoot(x2, Heap::kvalue_stringRootIndex); // "value" | 4479 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" |
4467 CallLoadIC(NOT_CONTEXTUAL); // result.value in x0 | 4480 CallLoadIC(NOT_CONTEXTUAL); // x0=result.value |
4468 context()->DropAndPlug(2, x0); // drop iter and g | 4481 context()->DropAndPlug(2, x0); // drop iter and g |
4469 break; | 4482 break; |
4470 } | 4483 } |
4471 } | 4484 } |
4472 } | 4485 } |
4473 | 4486 |
4474 | 4487 |
4475 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 4488 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
4476 Expression *value, | 4489 Expression *value, |
4477 JSGeneratorObject::ResumeMode resume_mode) { | 4490 JSGeneratorObject::ResumeMode resume_mode) { |
4478 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); | 4491 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4886 return previous_; | 4899 return previous_; |
4887 } | 4900 } |
4888 | 4901 |
4889 | 4902 |
4890 #undef __ | 4903 #undef __ |
4891 | 4904 |
4892 | 4905 |
4893 } } // namespace v8::internal | 4906 } } // namespace v8::internal |
4894 | 4907 |
4895 #endif // V8_TARGET_ARCH_ARM64 | 4908 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |