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

Side by Side Diff: src/full-codegen/arm/full-codegen-arm.cc

Issue 1894953004: Add HasProperty code stub that tries simple lookups or jumps to runtime otherwise. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebasing Created 4 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/crankshaft/hydrogen.cc ('k') | src/full-codegen/arm64/full-codegen-arm64.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #if V8_TARGET_ARCH_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 PredictableCodeSizeScope predictable(masm_, -1); 461 PredictableCodeSizeScope predictable(masm_, -1);
462 __ LeaveFrame(StackFrame::JAVA_SCRIPT); 462 __ LeaveFrame(StackFrame::JAVA_SCRIPT);
463 { ConstantPoolUnavailableScope constant_pool_unavailable(masm_); 463 { ConstantPoolUnavailableScope constant_pool_unavailable(masm_);
464 __ add(sp, sp, Operand(sp_delta)); 464 __ add(sp, sp, Operand(sp_delta));
465 __ Jump(lr); 465 __ Jump(lr);
466 } 466 }
467 } 467 }
468 } 468 }
469 } 469 }
470 470
471 void FullCodeGenerator::RestoreContext() {
472 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
473 }
471 474
472 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 475 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
473 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 476 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
474 codegen()->GetVar(result_register(), var); 477 codegen()->GetVar(result_register(), var);
475 codegen()->PushOperand(result_register()); 478 codegen()->PushOperand(result_register());
476 } 479 }
477 480
478 481
479 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 482 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
480 } 483 }
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); 1414 __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
1412 __ mov(r1, Operand(constant_properties)); 1415 __ mov(r1, Operand(constant_properties));
1413 int flags = expr->ComputeFlags(); 1416 int flags = expr->ComputeFlags();
1414 __ mov(r0, Operand(Smi::FromInt(flags))); 1417 __ mov(r0, Operand(Smi::FromInt(flags)));
1415 if (MustCreateObjectLiteralWithRuntime(expr)) { 1418 if (MustCreateObjectLiteralWithRuntime(expr)) {
1416 __ Push(r3, r2, r1, r0); 1419 __ Push(r3, r2, r1, r0);
1417 __ CallRuntime(Runtime::kCreateObjectLiteral); 1420 __ CallRuntime(Runtime::kCreateObjectLiteral);
1418 } else { 1421 } else {
1419 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1422 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1420 __ CallStub(&stub); 1423 __ CallStub(&stub);
1421 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1424 RestoreContext();
1422 } 1425 }
1423 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1426 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1424 1427
1425 // If result_saved is true the result is on top of the stack. If 1428 // If result_saved is true the result is on top of the stack. If
1426 // result_saved is false the result is in r0. 1429 // result_saved is false the result is in r0.
1427 bool result_saved = false; 1430 bool result_saved = false;
1428 1431
1429 AccessorTable accessor_table(zone()); 1432 AccessorTable accessor_table(zone());
1430 int property_index = 0; 1433 int property_index = 0;
1431 for (; property_index < expr->properties()->length(); property_index++) { 1434 for (; property_index < expr->properties()->length(); property_index++) {
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); 1862 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset));
1860 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); 1863 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset));
1861 __ mov(r1, cp); 1864 __ mov(r1, cp);
1862 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, 1865 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2,
1863 kLRHasBeenSaved, kDontSaveFPRegs); 1866 kLRHasBeenSaved, kDontSaveFPRegs);
1864 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1867 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1865 __ cmp(sp, r1); 1868 __ cmp(sp, r1);
1866 __ b(eq, &post_runtime); 1869 __ b(eq, &post_runtime);
1867 __ push(r0); // generator object 1870 __ push(r0); // generator object
1868 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1871 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1869 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1872 RestoreContext();
1870 __ bind(&post_runtime); 1873 __ bind(&post_runtime);
1871 PopOperand(result_register()); 1874 PopOperand(result_register());
1872 EmitReturnSequence(); 1875 EmitReturnSequence();
1873 1876
1874 __ bind(&resume); 1877 __ bind(&resume);
1875 context()->Plug(result_register()); 1878 context()->Plug(result_register());
1876 } 1879 }
1877 1880
1878 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { 1881 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
1879 OperandStackDepthIncrement(2); 1882 OperandStackDepthIncrement(2);
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
2520 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2523 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2521 .code(); 2524 .code();
2522 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); 2525 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
2523 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2526 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2524 // Don't assign a type feedback id to the IC, since type feedback is provided 2527 // Don't assign a type feedback id to the IC, since type feedback is provided
2525 // by the vector above. 2528 // by the vector above.
2526 CallIC(ic); 2529 CallIC(ic);
2527 OperandStackDepthDecrement(arg_count + 1); 2530 OperandStackDepthDecrement(arg_count + 1);
2528 2531
2529 RecordJSReturnSite(expr); 2532 RecordJSReturnSite(expr);
2530 // Restore context register. 2533 RestoreContext();
2531 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2532 context()->DropAndPlug(1, r0); 2534 context()->DropAndPlug(1, r0);
2533 } 2535 }
2534 2536
2535 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { 2537 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2536 int arg_count = expr->arguments()->length(); 2538 int arg_count = expr->arguments()->length();
2537 // r4: copy of the first argument or undefined if it doesn't exist. 2539 // r4: copy of the first argument or undefined if it doesn't exist.
2538 if (arg_count > 0) { 2540 if (arg_count > 0) {
2539 __ ldr(r4, MemOperand(sp, arg_count * kPointerSize)); 2541 __ ldr(r4, MemOperand(sp, arg_count * kPointerSize));
2540 } else { 2542 } else {
2541 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); 2543 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 2630
2629 // Record source position for debugger. 2631 // Record source position for debugger.
2630 SetCallPosition(expr); 2632 SetCallPosition(expr);
2631 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2633 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2632 __ mov(r0, Operand(arg_count)); 2634 __ mov(r0, Operand(arg_count));
2633 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2635 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2634 expr->tail_call_mode()), 2636 expr->tail_call_mode()),
2635 RelocInfo::CODE_TARGET); 2637 RelocInfo::CODE_TARGET);
2636 OperandStackDepthDecrement(arg_count + 1); 2638 OperandStackDepthDecrement(arg_count + 1);
2637 RecordJSReturnSite(expr); 2639 RecordJSReturnSite(expr);
2638 // Restore context register. 2640 RestoreContext();
2639 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2640 context()->DropAndPlug(1, r0); 2641 context()->DropAndPlug(1, r0);
2641 } 2642 }
2642 2643
2643 2644
2644 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2645 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2645 Comment cmnt(masm_, "[ CallNew"); 2646 Comment cmnt(masm_, "[ CallNew");
2646 // According to ECMA-262, section 11.2.2, page 44, the function 2647 // According to ECMA-262, section 11.2.2, page 44, the function
2647 // expression in new calls must be evaluated before the 2648 // expression in new calls must be evaluated before the
2648 // arguments. 2649 // arguments.
2649 2650
(...skipping 19 matching lines...) Expand all
2669 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 2670 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2670 2671
2671 // Record call targets in unoptimized code. 2672 // Record call targets in unoptimized code.
2672 __ EmitLoadTypeFeedbackVector(r2); 2673 __ EmitLoadTypeFeedbackVector(r2);
2673 __ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2674 __ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
2674 2675
2675 CallConstructStub stub(isolate()); 2676 CallConstructStub stub(isolate());
2676 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2677 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2677 OperandStackDepthDecrement(arg_count + 1); 2678 OperandStackDepthDecrement(arg_count + 1);
2678 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2679 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2679 // Restore context register. 2680 RestoreContext();
2680 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2681 context()->Plug(r0); 2681 context()->Plug(r0);
2682 } 2682 }
2683 2683
2684 2684
2685 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2685 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2686 SuperCallReference* super_call_ref = 2686 SuperCallReference* super_call_ref =
2687 expr->expression()->AsSuperCallReference(); 2687 expr->expression()->AsSuperCallReference();
2688 DCHECK_NOT_NULL(super_call_ref); 2688 DCHECK_NOT_NULL(super_call_ref);
2689 2689
2690 // Push the super constructor target on the stack (may be null, 2690 // Push the super constructor target on the stack (may be null,
(...skipping 22 matching lines...) Expand all
2713 __ mov(r3, result_register()); 2713 __ mov(r3, result_register());
2714 2714
2715 // Load function and argument count into r1 and r0. 2715 // Load function and argument count into r1 and r0.
2716 __ mov(r0, Operand(arg_count)); 2716 __ mov(r0, Operand(arg_count));
2717 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 2717 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2718 2718
2719 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2719 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2720 OperandStackDepthDecrement(arg_count + 1); 2720 OperandStackDepthDecrement(arg_count + 1);
2721 2721
2722 RecordJSReturnSite(expr); 2722 RecordJSReturnSite(expr);
2723 2723 RestoreContext();
2724 // Restore context register.
2725 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2726 context()->Plug(r0); 2724 context()->Plug(r0);
2727 } 2725 }
2728 2726
2729 2727
2730 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2728 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2731 ZoneList<Expression*>* args = expr->arguments(); 2729 ZoneList<Expression*>* args = expr->arguments();
2732 DCHECK(args->length() == 1); 2730 DCHECK(args->length() == 1);
2733 2731
2734 VisitForAccumulatorValue(args->at(0)); 2732 VisitForAccumulatorValue(args->at(0));
2735 2733
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
3111 VisitForStackValue(arg); 3109 VisitForStackValue(arg);
3112 } 3110 }
3113 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3111 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3114 // Move target to r1. 3112 // Move target to r1.
3115 int const argc = args->length() - 2; 3113 int const argc = args->length() - 2;
3116 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize)); 3114 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
3117 // Call the target. 3115 // Call the target.
3118 __ mov(r0, Operand(argc)); 3116 __ mov(r0, Operand(argc));
3119 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3117 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3120 OperandStackDepthDecrement(argc + 1); 3118 OperandStackDepthDecrement(argc + 1);
3121 // Restore context register. 3119 RestoreContext();
3122 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3123 // Discard the function left on TOS. 3120 // Discard the function left on TOS.
3124 context()->DropAndPlug(1, r0); 3121 context()->DropAndPlug(1, r0);
3125 } 3122 }
3126 3123
3127 3124
3128 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3125 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3129 ZoneList<Expression*>* args = expr->arguments(); 3126 ZoneList<Expression*>* args = expr->arguments();
3130 VisitForAccumulatorValue(args->at(0)); 3127 VisitForAccumulatorValue(args->at(0));
3131 3128
3132 Label materialize_true, materialize_false; 3129 Label materialize_true, materialize_false;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
3229 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3226 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3230 ZoneList<Expression*>* args = expr->arguments(); 3227 ZoneList<Expression*>* args = expr->arguments();
3231 int arg_count = args->length(); 3228 int arg_count = args->length();
3232 3229
3233 SetCallPosition(expr); 3230 SetCallPosition(expr);
3234 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 3231 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
3235 __ mov(r0, Operand(arg_count)); 3232 __ mov(r0, Operand(arg_count));
3236 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3233 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3237 RelocInfo::CODE_TARGET); 3234 RelocInfo::CODE_TARGET);
3238 OperandStackDepthDecrement(arg_count + 1); 3235 OperandStackDepthDecrement(arg_count + 1);
3239 3236 RestoreContext();
3240 // Restore context register.
3241 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3242 } 3237 }
3243 3238
3244 3239
3245 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3240 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3246 switch (expr->op()) { 3241 switch (expr->op()) {
3247 case Token::DELETE: { 3242 case Token::DELETE: {
3248 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3243 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3249 Property* property = expr->expression()->AsProperty(); 3244 Property* property = expr->expression()->AsProperty();
3250 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3245 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3251 3246
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
3697 Label* fall_through = NULL; 3692 Label* fall_through = NULL;
3698 context()->PrepareTest(&materialize_true, &materialize_false, 3693 context()->PrepareTest(&materialize_true, &materialize_false,
3699 &if_true, &if_false, &fall_through); 3694 &if_true, &if_false, &fall_through);
3700 3695
3701 Token::Value op = expr->op(); 3696 Token::Value op = expr->op();
3702 VisitForStackValue(expr->left()); 3697 VisitForStackValue(expr->left());
3703 switch (op) { 3698 switch (op) {
3704 case Token::IN: 3699 case Token::IN:
3705 VisitForStackValue(expr->right()); 3700 VisitForStackValue(expr->right());
3706 SetExpressionPosition(expr); 3701 SetExpressionPosition(expr);
3707 CallRuntimeWithOperands(Runtime::kHasProperty); 3702 EmitHasProperty();
3708 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3703 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3709 __ CompareRoot(r0, Heap::kTrueValueRootIndex); 3704 __ CompareRoot(r0, Heap::kTrueValueRootIndex);
3710 Split(eq, if_true, if_false, fall_through); 3705 Split(eq, if_true, if_false, fall_through);
3711 break; 3706 break;
3712 3707
3713 case Token::INSTANCEOF: { 3708 case Token::INSTANCEOF: {
3714 VisitForAccumulatorValue(expr->right()); 3709 VisitForAccumulatorValue(expr->right());
3715 SetExpressionPosition(expr); 3710 SetExpressionPosition(expr);
3716 PopOperand(r1); 3711 PopOperand(r1);
3717 InstanceOfStub stub(isolate()); 3712 InstanceOfStub stub(isolate());
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
4030 DCHECK(interrupt_address == 4025 DCHECK(interrupt_address ==
4031 isolate->builtins()->OnStackReplacement()->entry()); 4026 isolate->builtins()->OnStackReplacement()->entry());
4032 return ON_STACK_REPLACEMENT; 4027 return ON_STACK_REPLACEMENT;
4033 } 4028 }
4034 4029
4035 4030
4036 } // namespace internal 4031 } // namespace internal
4037 } // namespace v8 4032 } // namespace v8
4038 4033
4039 #endif // V8_TARGET_ARCH_ARM 4034 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen.cc ('k') | src/full-codegen/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698