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

Side by Side Diff: src/full-codegen/x87/full-codegen-x87.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, 8 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/full-codegen/x64/full-codegen-x64.cc ('k') | src/ia32/interface-descriptors-ia32.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_X87 5 #if V8_TARGET_ARCH_X87
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 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 413
414 SetReturnPosition(literal()); 414 SetReturnPosition(literal());
415 __ leave(); 415 __ leave();
416 416
417 int arg_count = info_->scope()->num_parameters() + 1; 417 int arg_count = info_->scope()->num_parameters() + 1;
418 int arguments_bytes = arg_count * kPointerSize; 418 int arguments_bytes = arg_count * kPointerSize;
419 __ Ret(arguments_bytes, ecx); 419 __ Ret(arguments_bytes, ecx);
420 } 420 }
421 } 421 }
422 422
423 void FullCodeGenerator::RestoreContext() {
424 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
425 }
423 426
424 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 427 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
425 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 428 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
426 MemOperand operand = codegen()->VarOperand(var, result_register()); 429 MemOperand operand = codegen()->VarOperand(var, result_register());
427 // Memory operands can be pushed directly. 430 // Memory operands can be pushed directly.
428 codegen()->PushOperand(operand); 431 codegen()->PushOperand(operand);
429 } 432 }
430 433
431 434
432 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 435 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
1332 __ push(Immediate(constant_properties)); 1335 __ push(Immediate(constant_properties));
1333 __ push(Immediate(Smi::FromInt(flags))); 1336 __ push(Immediate(Smi::FromInt(flags)));
1334 __ CallRuntime(Runtime::kCreateObjectLiteral); 1337 __ CallRuntime(Runtime::kCreateObjectLiteral);
1335 } else { 1338 } else {
1336 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1339 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1337 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); 1340 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index())));
1338 __ mov(ecx, Immediate(constant_properties)); 1341 __ mov(ecx, Immediate(constant_properties));
1339 __ mov(edx, Immediate(Smi::FromInt(flags))); 1342 __ mov(edx, Immediate(Smi::FromInt(flags)));
1340 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1343 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1341 __ CallStub(&stub); 1344 __ CallStub(&stub);
1342 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1345 RestoreContext();
1343 } 1346 }
1344 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1347 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1345 1348
1346 // If result_saved is true the result is on top of the stack. If 1349 // If result_saved is true the result is on top of the stack. If
1347 // result_saved is false the result is in eax. 1350 // result_saved is false the result is in eax.
1348 bool result_saved = false; 1351 bool result_saved = false;
1349 1352
1350 AccessorTable accessor_table(zone()); 1353 AccessorTable accessor_table(zone());
1351 int property_index = 0; 1354 int property_index = 0;
1352 for (; property_index < expr->properties()->length(); property_index++) { 1355 for (; property_index < expr->properties()->length(); property_index++) {
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 Immediate(Smi::FromInt(continuation.pos()))); 1770 Immediate(Smi::FromInt(continuation.pos())));
1768 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); 1771 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi);
1769 __ mov(ecx, esi); 1772 __ mov(ecx, esi);
1770 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, 1773 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx,
1771 kDontSaveFPRegs); 1774 kDontSaveFPRegs);
1772 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); 1775 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset));
1773 __ cmp(esp, ebx); 1776 __ cmp(esp, ebx);
1774 __ j(equal, &post_runtime); 1777 __ j(equal, &post_runtime);
1775 __ push(eax); // generator object 1778 __ push(eax); // generator object
1776 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1779 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1777 __ mov(context_register(), 1780 RestoreContext();
1778 Operand(ebp, StandardFrameConstants::kContextOffset));
1779 __ bind(&post_runtime); 1781 __ bind(&post_runtime);
1780 PopOperand(result_register()); 1782 PopOperand(result_register());
1781 EmitReturnSequence(); 1783 EmitReturnSequence();
1782 1784
1783 __ bind(&resume); 1785 __ bind(&resume);
1784 context()->Plug(result_register()); 1786 context()->Plug(result_register());
1785 } 1787 }
1786 1788
1787 void FullCodeGenerator::PushOperand(MemOperand operand) { 1789 void FullCodeGenerator::PushOperand(MemOperand operand) {
1788 OperandStackDepthIncrement(1); 1790 OperandStackDepthIncrement(1);
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after
2409 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2411 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2410 .code(); 2412 .code();
2411 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); 2413 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
2412 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2414 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2413 // Don't assign a type feedback id to the IC, since type feedback is provided 2415 // Don't assign a type feedback id to the IC, since type feedback is provided
2414 // by the vector above. 2416 // by the vector above.
2415 CallIC(ic); 2417 CallIC(ic);
2416 OperandStackDepthDecrement(arg_count + 1); 2418 OperandStackDepthDecrement(arg_count + 1);
2417 2419
2418 RecordJSReturnSite(expr); 2420 RecordJSReturnSite(expr);
2419 2421 RestoreContext();
2420 // Restore context register.
2421 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2422
2423 context()->DropAndPlug(1, eax); 2422 context()->DropAndPlug(1, eax);
2424 } 2423 }
2425 2424
2426 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { 2425 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2427 int arg_count = expr->arguments()->length(); 2426 int arg_count = expr->arguments()->length();
2428 // Push copy of the first argument or undefined if it doesn't exist. 2427 // Push copy of the first argument or undefined if it doesn't exist.
2429 if (arg_count > 0) { 2428 if (arg_count > 0) {
2430 __ push(Operand(esp, arg_count * kPointerSize)); 2429 __ push(Operand(esp, arg_count * kPointerSize));
2431 } else { 2430 } else {
2432 __ push(Immediate(isolate()->factory()->undefined_value())); 2431 __ push(Immediate(isolate()->factory()->undefined_value()));
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2514 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2513 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2515 2514
2516 SetCallPosition(expr); 2515 SetCallPosition(expr);
2517 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2516 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2518 __ Set(eax, arg_count); 2517 __ Set(eax, arg_count);
2519 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2518 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2520 expr->tail_call_mode()), 2519 expr->tail_call_mode()),
2521 RelocInfo::CODE_TARGET); 2520 RelocInfo::CODE_TARGET);
2522 OperandStackDepthDecrement(arg_count + 1); 2521 OperandStackDepthDecrement(arg_count + 1);
2523 RecordJSReturnSite(expr); 2522 RecordJSReturnSite(expr);
2524 // Restore context register. 2523 RestoreContext();
2525 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2526 context()->DropAndPlug(1, eax); 2524 context()->DropAndPlug(1, eax);
2527 } 2525 }
2528 2526
2529 2527
2530 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2528 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2531 Comment cmnt(masm_, "[ CallNew"); 2529 Comment cmnt(masm_, "[ CallNew");
2532 // According to ECMA-262, section 11.2.2, page 44, the function 2530 // According to ECMA-262, section 11.2.2, page 44, the function
2533 // expression in new calls must be evaluated before the 2531 // expression in new calls must be evaluated before the
2534 // arguments. 2532 // arguments.
2535 2533
(...skipping 19 matching lines...) Expand all
2555 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2553 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2556 2554
2557 // Record call targets in unoptimized code. 2555 // Record call targets in unoptimized code.
2558 __ EmitLoadTypeFeedbackVector(ebx); 2556 __ EmitLoadTypeFeedbackVector(ebx);
2559 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2557 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot())));
2560 2558
2561 CallConstructStub stub(isolate()); 2559 CallConstructStub stub(isolate());
2562 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); 2560 __ call(stub.GetCode(), RelocInfo::CODE_TARGET);
2563 OperandStackDepthDecrement(arg_count + 1); 2561 OperandStackDepthDecrement(arg_count + 1);
2564 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2562 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2565 // Restore context register. 2563 RestoreContext();
2566 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2567 context()->Plug(eax); 2564 context()->Plug(eax);
2568 } 2565 }
2569 2566
2570 2567
2571 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2568 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2572 SuperCallReference* super_call_ref = 2569 SuperCallReference* super_call_ref =
2573 expr->expression()->AsSuperCallReference(); 2570 expr->expression()->AsSuperCallReference();
2574 DCHECK_NOT_NULL(super_call_ref); 2571 DCHECK_NOT_NULL(super_call_ref);
2575 2572
2576 // Push the super constructor target on the stack (may be null, 2573 // Push the super constructor target on the stack (may be null,
(...skipping 20 matching lines...) Expand all
2597 __ mov(edx, result_register()); 2594 __ mov(edx, result_register());
2598 2595
2599 // Load function and argument count into edi and eax. 2596 // Load function and argument count into edi and eax.
2600 __ Move(eax, Immediate(arg_count)); 2597 __ Move(eax, Immediate(arg_count));
2601 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2598 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2602 2599
2603 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2600 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2604 OperandStackDepthDecrement(arg_count + 1); 2601 OperandStackDepthDecrement(arg_count + 1);
2605 2602
2606 RecordJSReturnSite(expr); 2603 RecordJSReturnSite(expr);
2607 2604 RestoreContext();
2608 // Restore context register.
2609 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2610 context()->Plug(eax); 2605 context()->Plug(eax);
2611 } 2606 }
2612 2607
2613 2608
2614 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2609 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2615 ZoneList<Expression*>* args = expr->arguments(); 2610 ZoneList<Expression*>* args = expr->arguments();
2616 DCHECK(args->length() == 1); 2611 DCHECK(args->length() == 1);
2617 2612
2618 VisitForAccumulatorValue(args->at(0)); 2613 VisitForAccumulatorValue(args->at(0));
2619 2614
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
3000 VisitForStackValue(arg); 2995 VisitForStackValue(arg);
3001 } 2996 }
3002 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 2997 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3003 // Move target to edi. 2998 // Move target to edi.
3004 int const argc = args->length() - 2; 2999 int const argc = args->length() - 2;
3005 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize)); 3000 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize));
3006 // Call the target. 3001 // Call the target.
3007 __ mov(eax, Immediate(argc)); 3002 __ mov(eax, Immediate(argc));
3008 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3003 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3009 OperandStackDepthDecrement(argc + 1); 3004 OperandStackDepthDecrement(argc + 1);
3010 // Restore context register. 3005 RestoreContext();
3011 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3012 // Discard the function left on TOS. 3006 // Discard the function left on TOS.
3013 context()->DropAndPlug(1, eax); 3007 context()->DropAndPlug(1, eax);
3014 } 3008 }
3015 3009
3016 3010
3017 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3011 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3018 ZoneList<Expression*>* args = expr->arguments(); 3012 ZoneList<Expression*>* args = expr->arguments();
3019 DCHECK(args->length() == 1); 3013 DCHECK(args->length() == 1);
3020 3014
3021 VisitForAccumulatorValue(args->at(0)); 3015 VisitForAccumulatorValue(args->at(0));
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
3121 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3115 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3122 ZoneList<Expression*>* args = expr->arguments(); 3116 ZoneList<Expression*>* args = expr->arguments();
3123 int arg_count = args->length(); 3117 int arg_count = args->length();
3124 3118
3125 SetCallPosition(expr); 3119 SetCallPosition(expr);
3126 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 3120 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
3127 __ Set(eax, arg_count); 3121 __ Set(eax, arg_count);
3128 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3122 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3129 RelocInfo::CODE_TARGET); 3123 RelocInfo::CODE_TARGET);
3130 OperandStackDepthDecrement(arg_count + 1); 3124 OperandStackDepthDecrement(arg_count + 1);
3131 3125 RestoreContext();
3132 // Restore context register.
3133 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3134 } 3126 }
3135 3127
3136 3128
3137 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3129 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3138 switch (expr->op()) { 3130 switch (expr->op()) {
3139 case Token::DELETE: { 3131 case Token::DELETE: {
3140 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3132 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3141 Property* property = expr->expression()->AsProperty(); 3133 Property* property = expr->expression()->AsProperty();
3142 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3134 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3143 3135
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
3597 Label* fall_through = NULL; 3589 Label* fall_through = NULL;
3598 context()->PrepareTest(&materialize_true, &materialize_false, 3590 context()->PrepareTest(&materialize_true, &materialize_false,
3599 &if_true, &if_false, &fall_through); 3591 &if_true, &if_false, &fall_through);
3600 3592
3601 Token::Value op = expr->op(); 3593 Token::Value op = expr->op();
3602 VisitForStackValue(expr->left()); 3594 VisitForStackValue(expr->left());
3603 switch (op) { 3595 switch (op) {
3604 case Token::IN: 3596 case Token::IN:
3605 VisitForStackValue(expr->right()); 3597 VisitForStackValue(expr->right());
3606 SetExpressionPosition(expr); 3598 SetExpressionPosition(expr);
3607 CallRuntimeWithOperands(Runtime::kHasProperty); 3599 EmitHasProperty();
3608 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3600 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3609 __ cmp(eax, isolate()->factory()->true_value()); 3601 __ cmp(eax, isolate()->factory()->true_value());
3610 Split(equal, if_true, if_false, fall_through); 3602 Split(equal, if_true, if_false, fall_through);
3611 break; 3603 break;
3612 3604
3613 case Token::INSTANCEOF: { 3605 case Token::INSTANCEOF: {
3614 VisitForAccumulatorValue(expr->right()); 3606 VisitForAccumulatorValue(expr->right());
3615 SetExpressionPosition(expr); 3607 SetExpressionPosition(expr);
3616 PopOperand(edx); 3608 PopOperand(edx);
3617 InstanceOfStub stub(isolate()); 3609 InstanceOfStub stub(isolate());
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
3863 isolate->builtins()->OnStackReplacement()->entry(), 3855 isolate->builtins()->OnStackReplacement()->entry(),
3864 Assembler::target_address_at(call_target_address, unoptimized_code)); 3856 Assembler::target_address_at(call_target_address, unoptimized_code));
3865 return ON_STACK_REPLACEMENT; 3857 return ON_STACK_REPLACEMENT;
3866 } 3858 }
3867 3859
3868 3860
3869 } // namespace internal 3861 } // namespace internal
3870 } // namespace v8 3862 } // namespace v8
3871 3863
3872 #endif // V8_TARGET_ARCH_X87 3864 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/full-codegen/x64/full-codegen-x64.cc ('k') | src/ia32/interface-descriptors-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698