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

Side by Side Diff: src/full-codegen/ia32/full-codegen-ia32.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/full-codegen.cc ('k') | src/full-codegen/mips/full-codegen-mips.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_IA32 5 #if V8_TARGET_ARCH_IA32
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 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 416
417 SetReturnPosition(literal()); 417 SetReturnPosition(literal());
418 __ leave(); 418 __ leave();
419 419
420 int arg_count = info_->scope()->num_parameters() + 1; 420 int arg_count = info_->scope()->num_parameters() + 1;
421 int arguments_bytes = arg_count * kPointerSize; 421 int arguments_bytes = arg_count * kPointerSize;
422 __ Ret(arguments_bytes, ecx); 422 __ Ret(arguments_bytes, ecx);
423 } 423 }
424 } 424 }
425 425
426 void FullCodeGenerator::RestoreContext() {
427 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
428 }
426 429
427 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 430 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
428 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 431 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
429 MemOperand operand = codegen()->VarOperand(var, result_register()); 432 MemOperand operand = codegen()->VarOperand(var, result_register());
430 // Memory operands can be pushed directly. 433 // Memory operands can be pushed directly.
431 codegen()->PushOperand(operand); 434 codegen()->PushOperand(operand);
432 } 435 }
433 436
434 437
435 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 438 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 __ push(Immediate(constant_properties)); 1343 __ push(Immediate(constant_properties));
1341 __ push(Immediate(Smi::FromInt(flags))); 1344 __ push(Immediate(Smi::FromInt(flags)));
1342 __ CallRuntime(Runtime::kCreateObjectLiteral); 1345 __ CallRuntime(Runtime::kCreateObjectLiteral);
1343 } else { 1346 } else {
1344 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1347 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1345 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); 1348 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index())));
1346 __ mov(ecx, Immediate(constant_properties)); 1349 __ mov(ecx, Immediate(constant_properties));
1347 __ mov(edx, Immediate(Smi::FromInt(flags))); 1350 __ mov(edx, Immediate(Smi::FromInt(flags)));
1348 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1351 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1349 __ CallStub(&stub); 1352 __ CallStub(&stub);
1350 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1353 RestoreContext();
1351 } 1354 }
1352 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1355 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1353 1356
1354 // If result_saved is true the result is on top of the stack. If 1357 // If result_saved is true the result is on top of the stack. If
1355 // result_saved is false the result is in eax. 1358 // result_saved is false the result is in eax.
1356 bool result_saved = false; 1359 bool result_saved = false;
1357 1360
1358 AccessorTable accessor_table(zone()); 1361 AccessorTable accessor_table(zone());
1359 int property_index = 0; 1362 int property_index = 0;
1360 for (; property_index < expr->properties()->length(); property_index++) { 1363 for (; property_index < expr->properties()->length(); property_index++) {
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 Immediate(Smi::FromInt(continuation.pos()))); 1778 Immediate(Smi::FromInt(continuation.pos())));
1776 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); 1779 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi);
1777 __ mov(ecx, esi); 1780 __ mov(ecx, esi);
1778 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, 1781 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx,
1779 kDontSaveFPRegs); 1782 kDontSaveFPRegs);
1780 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); 1783 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset));
1781 __ cmp(esp, ebx); 1784 __ cmp(esp, ebx);
1782 __ j(equal, &post_runtime); 1785 __ j(equal, &post_runtime);
1783 __ push(eax); // generator object 1786 __ push(eax); // generator object
1784 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1787 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1785 __ mov(context_register(), 1788 RestoreContext();
1786 Operand(ebp, StandardFrameConstants::kContextOffset));
1787 __ bind(&post_runtime); 1789 __ bind(&post_runtime);
1788 PopOperand(result_register()); 1790 PopOperand(result_register());
1789 EmitReturnSequence(); 1791 EmitReturnSequence();
1790 1792
1791 __ bind(&resume); 1793 __ bind(&resume);
1792 context()->Plug(result_register()); 1794 context()->Plug(result_register());
1793 } 1795 }
1794 1796
1795 void FullCodeGenerator::PushOperand(MemOperand operand) { 1797 void FullCodeGenerator::PushOperand(MemOperand operand) {
1796 OperandStackDepthIncrement(1); 1798 OperandStackDepthIncrement(1);
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after
2417 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2419 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2418 .code(); 2420 .code();
2419 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); 2421 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
2420 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2422 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2421 // Don't assign a type feedback id to the IC, since type feedback is provided 2423 // Don't assign a type feedback id to the IC, since type feedback is provided
2422 // by the vector above. 2424 // by the vector above.
2423 CallIC(ic); 2425 CallIC(ic);
2424 OperandStackDepthDecrement(arg_count + 1); 2426 OperandStackDepthDecrement(arg_count + 1);
2425 2427
2426 RecordJSReturnSite(expr); 2428 RecordJSReturnSite(expr);
2427 2429 RestoreContext();
2428 // Restore context register.
2429 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2430
2431 context()->DropAndPlug(1, eax); 2430 context()->DropAndPlug(1, eax);
2432 } 2431 }
2433 2432
2434 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { 2433 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2435 int arg_count = expr->arguments()->length(); 2434 int arg_count = expr->arguments()->length();
2436 // Push copy of the first argument or undefined if it doesn't exist. 2435 // Push copy of the first argument or undefined if it doesn't exist.
2437 if (arg_count > 0) { 2436 if (arg_count > 0) {
2438 __ push(Operand(esp, arg_count * kPointerSize)); 2437 __ push(Operand(esp, arg_count * kPointerSize));
2439 } else { 2438 } else {
2440 __ push(Immediate(isolate()->factory()->undefined_value())); 2439 __ push(Immediate(isolate()->factory()->undefined_value()));
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2522 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2521 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2523 2522
2524 SetCallPosition(expr); 2523 SetCallPosition(expr);
2525 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2524 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2526 __ Set(eax, arg_count); 2525 __ Set(eax, arg_count);
2527 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2526 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2528 expr->tail_call_mode()), 2527 expr->tail_call_mode()),
2529 RelocInfo::CODE_TARGET); 2528 RelocInfo::CODE_TARGET);
2530 OperandStackDepthDecrement(arg_count + 1); 2529 OperandStackDepthDecrement(arg_count + 1);
2531 RecordJSReturnSite(expr); 2530 RecordJSReturnSite(expr);
2532 // Restore context register. 2531 RestoreContext();
2533 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2534 context()->DropAndPlug(1, eax); 2532 context()->DropAndPlug(1, eax);
2535 } 2533 }
2536 2534
2537 2535
2538 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2536 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2539 Comment cmnt(masm_, "[ CallNew"); 2537 Comment cmnt(masm_, "[ CallNew");
2540 // According to ECMA-262, section 11.2.2, page 44, the function 2538 // According to ECMA-262, section 11.2.2, page 44, the function
2541 // expression in new calls must be evaluated before the 2539 // expression in new calls must be evaluated before the
2542 // arguments. 2540 // arguments.
2543 2541
(...skipping 19 matching lines...) Expand all
2563 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2561 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2564 2562
2565 // Record call targets in unoptimized code. 2563 // Record call targets in unoptimized code.
2566 __ EmitLoadTypeFeedbackVector(ebx); 2564 __ EmitLoadTypeFeedbackVector(ebx);
2567 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2565 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot())));
2568 2566
2569 CallConstructStub stub(isolate()); 2567 CallConstructStub stub(isolate());
2570 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); 2568 __ call(stub.GetCode(), RelocInfo::CODE_TARGET);
2571 OperandStackDepthDecrement(arg_count + 1); 2569 OperandStackDepthDecrement(arg_count + 1);
2572 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2570 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2573 // Restore context register. 2571 RestoreContext();
2574 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2575 context()->Plug(eax); 2572 context()->Plug(eax);
2576 } 2573 }
2577 2574
2578 2575
2579 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2576 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2580 SuperCallReference* super_call_ref = 2577 SuperCallReference* super_call_ref =
2581 expr->expression()->AsSuperCallReference(); 2578 expr->expression()->AsSuperCallReference();
2582 DCHECK_NOT_NULL(super_call_ref); 2579 DCHECK_NOT_NULL(super_call_ref);
2583 2580
2584 // Push the super constructor target on the stack (may be null, 2581 // Push the super constructor target on the stack (may be null,
(...skipping 20 matching lines...) Expand all
2605 __ mov(edx, result_register()); 2602 __ mov(edx, result_register());
2606 2603
2607 // Load function and argument count into edi and eax. 2604 // Load function and argument count into edi and eax.
2608 __ Move(eax, Immediate(arg_count)); 2605 __ Move(eax, Immediate(arg_count));
2609 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2606 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2610 2607
2611 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2608 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2612 OperandStackDepthDecrement(arg_count + 1); 2609 OperandStackDepthDecrement(arg_count + 1);
2613 2610
2614 RecordJSReturnSite(expr); 2611 RecordJSReturnSite(expr);
2615 2612 RestoreContext();
2616 // Restore context register.
2617 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2618 context()->Plug(eax); 2613 context()->Plug(eax);
2619 } 2614 }
2620 2615
2621 2616
2622 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2617 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2623 ZoneList<Expression*>* args = expr->arguments(); 2618 ZoneList<Expression*>* args = expr->arguments();
2624 DCHECK(args->length() == 1); 2619 DCHECK(args->length() == 1);
2625 2620
2626 VisitForAccumulatorValue(args->at(0)); 2621 VisitForAccumulatorValue(args->at(0));
2627 2622
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
3008 VisitForStackValue(arg); 3003 VisitForStackValue(arg);
3009 } 3004 }
3010 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3005 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3011 // Move target to edi. 3006 // Move target to edi.
3012 int const argc = args->length() - 2; 3007 int const argc = args->length() - 2;
3013 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize)); 3008 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize));
3014 // Call the target. 3009 // Call the target.
3015 __ mov(eax, Immediate(argc)); 3010 __ mov(eax, Immediate(argc));
3016 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3011 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3017 OperandStackDepthDecrement(argc + 1); 3012 OperandStackDepthDecrement(argc + 1);
3018 // Restore context register. 3013 RestoreContext();
3019 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3020 // Discard the function left on TOS. 3014 // Discard the function left on TOS.
3021 context()->DropAndPlug(1, eax); 3015 context()->DropAndPlug(1, eax);
3022 } 3016 }
3023 3017
3024 3018
3025 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3019 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3026 ZoneList<Expression*>* args = expr->arguments(); 3020 ZoneList<Expression*>* args = expr->arguments();
3027 DCHECK(args->length() == 1); 3021 DCHECK(args->length() == 1);
3028 3022
3029 VisitForAccumulatorValue(args->at(0)); 3023 VisitForAccumulatorValue(args->at(0));
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
3129 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3123 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3130 ZoneList<Expression*>* args = expr->arguments(); 3124 ZoneList<Expression*>* args = expr->arguments();
3131 int arg_count = args->length(); 3125 int arg_count = args->length();
3132 3126
3133 SetCallPosition(expr); 3127 SetCallPosition(expr);
3134 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 3128 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
3135 __ Set(eax, arg_count); 3129 __ Set(eax, arg_count);
3136 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3130 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3137 RelocInfo::CODE_TARGET); 3131 RelocInfo::CODE_TARGET);
3138 OperandStackDepthDecrement(arg_count + 1); 3132 OperandStackDepthDecrement(arg_count + 1);
3139 3133 RestoreContext();
3140 // Restore context register.
3141 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3142 } 3134 }
3143 3135
3144 3136
3145 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3137 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3146 switch (expr->op()) { 3138 switch (expr->op()) {
3147 case Token::DELETE: { 3139 case Token::DELETE: {
3148 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3140 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3149 Property* property = expr->expression()->AsProperty(); 3141 Property* property = expr->expression()->AsProperty();
3150 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3142 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3151 3143
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
3605 Label* fall_through = NULL; 3597 Label* fall_through = NULL;
3606 context()->PrepareTest(&materialize_true, &materialize_false, 3598 context()->PrepareTest(&materialize_true, &materialize_false,
3607 &if_true, &if_false, &fall_through); 3599 &if_true, &if_false, &fall_through);
3608 3600
3609 Token::Value op = expr->op(); 3601 Token::Value op = expr->op();
3610 VisitForStackValue(expr->left()); 3602 VisitForStackValue(expr->left());
3611 switch (op) { 3603 switch (op) {
3612 case Token::IN: 3604 case Token::IN:
3613 VisitForStackValue(expr->right()); 3605 VisitForStackValue(expr->right());
3614 SetExpressionPosition(expr); 3606 SetExpressionPosition(expr);
3615 CallRuntimeWithOperands(Runtime::kHasProperty); 3607 EmitHasProperty();
3616 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3608 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3617 __ cmp(eax, isolate()->factory()->true_value()); 3609 __ cmp(eax, isolate()->factory()->true_value());
3618 Split(equal, if_true, if_false, fall_through); 3610 Split(equal, if_true, if_false, fall_through);
3619 break; 3611 break;
3620 3612
3621 case Token::INSTANCEOF: { 3613 case Token::INSTANCEOF: {
3622 VisitForAccumulatorValue(expr->right()); 3614 VisitForAccumulatorValue(expr->right());
3623 SetExpressionPosition(expr); 3615 SetExpressionPosition(expr);
3624 PopOperand(edx); 3616 PopOperand(edx);
3625 InstanceOfStub stub(isolate()); 3617 InstanceOfStub stub(isolate());
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
3871 isolate->builtins()->OnStackReplacement()->entry(), 3863 isolate->builtins()->OnStackReplacement()->entry(),
3872 Assembler::target_address_at(call_target_address, unoptimized_code)); 3864 Assembler::target_address_at(call_target_address, unoptimized_code));
3873 return ON_STACK_REPLACEMENT; 3865 return ON_STACK_REPLACEMENT;
3874 } 3866 }
3875 3867
3876 3868
3877 } // namespace internal 3869 } // namespace internal
3878 } // namespace v8 3870 } // namespace v8
3879 3871
3880 #endif // V8_TARGET_ARCH_IA32 3872 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen/full-codegen.cc ('k') | src/full-codegen/mips/full-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698