| OLD | NEW | 
|     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 #include "src/v8.h" |     5 #include "src/v8.h" | 
|     6  |     6  | 
|     7 #if V8_TARGET_ARCH_X64 |     7 #if V8_TARGET_ARCH_X64 | 
|     8  |     8  | 
|     9 #include "src/code-factory.h" |     9 #include "src/code-factory.h" | 
|    10 #include "src/code-stubs.h" |    10 #include "src/code-stubs.h" | 
| (...skipping 1934 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1945   if (result_saved) { |  1945   if (result_saved) { | 
|  1946     __ Drop(1);  // literal index |  1946     __ Drop(1);  // literal index | 
|  1947     context()->PlugTOS(); |  1947     context()->PlugTOS(); | 
|  1948   } else { |  1948   } else { | 
|  1949     context()->Plug(rax); |  1949     context()->Plug(rax); | 
|  1950   } |  1950   } | 
|  1951 } |  1951 } | 
|  1952  |  1952  | 
|  1953  |  1953  | 
|  1954 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |  1954 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 
|  1955   DCHECK(expr->target()->IsValidReferenceExpression()); |  1955   DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); | 
|  1956  |  1956  | 
|  1957   Comment cmnt(masm_, "[ Assignment"); |  1957   Comment cmnt(masm_, "[ Assignment"); | 
|  1958   SetExpressionPosition(expr, INSERT_BREAK); |  1958   SetExpressionPosition(expr, INSERT_BREAK); | 
|  1959  |  1959  | 
|  1960   Property* property = expr->target()->AsProperty(); |  1960   Property* property = expr->target()->AsProperty(); | 
|  1961   LhsKind assign_type = Property::GetAssignType(property); |  1961   LhsKind assign_type = Property::GetAssignType(property); | 
|  1962  |  1962  | 
|  1963   // Evaluate LHS expression. |  1963   // Evaluate LHS expression. | 
|  1964   switch (assign_type) { |  1964   switch (assign_type) { | 
|  1965     case VARIABLE: |  1965     case VARIABLE: | 
| (...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2571       CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); |  2571       CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); | 
|  2572   JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code. |  2572   JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code. | 
|  2573   CallIC(code, expr->BinaryOperationFeedbackId()); |  2573   CallIC(code, expr->BinaryOperationFeedbackId()); | 
|  2574   patch_site.EmitPatchInfo(); |  2574   patch_site.EmitPatchInfo(); | 
|  2575   context()->Plug(rax); |  2575   context()->Plug(rax); | 
|  2576 } |  2576 } | 
|  2577  |  2577  | 
|  2578  |  2578  | 
|  2579 void FullCodeGenerator::EmitAssignment(Expression* expr, |  2579 void FullCodeGenerator::EmitAssignment(Expression* expr, | 
|  2580                                        FeedbackVectorICSlot slot) { |  2580                                        FeedbackVectorICSlot slot) { | 
|  2581   DCHECK(expr->IsValidReferenceExpression()); |  2581   DCHECK(expr->IsValidReferenceExpressionOrThis()); | 
|  2582  |  2582  | 
|  2583   Property* prop = expr->AsProperty(); |  2583   Property* prop = expr->AsProperty(); | 
|  2584   LhsKind assign_type = Property::GetAssignType(prop); |  2584   LhsKind assign_type = Property::GetAssignType(prop); | 
|  2585  |  2585  | 
|  2586   switch (assign_type) { |  2586   switch (assign_type) { | 
|  2587     case VARIABLE: { |  2587     case VARIABLE: { | 
|  2588       Variable* var = expr->AsVariableProxy()->var(); |  2588       Variable* var = expr->AsVariableProxy()->var(); | 
|  2589       EffectContext context(this); |  2589       EffectContext context(this); | 
|  2590       EmitVariableAssignment(var, Token::ASSIGN, slot); |  2590       EmitVariableAssignment(var, Token::ASSIGN, slot); | 
|  2591       break; |  2591       break; | 
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2713     Label const_error; |  2713     Label const_error; | 
|  2714     MemOperand location = VarOperand(var, rcx); |  2714     MemOperand location = VarOperand(var, rcx); | 
|  2715     __ movp(rdx, location); |  2715     __ movp(rdx, location); | 
|  2716     __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); |  2716     __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); | 
|  2717     __ j(not_equal, &const_error, Label::kNear); |  2717     __ j(not_equal, &const_error, Label::kNear); | 
|  2718     __ Push(var->name()); |  2718     __ Push(var->name()); | 
|  2719     __ CallRuntime(Runtime::kThrowReferenceError, 1); |  2719     __ CallRuntime(Runtime::kThrowReferenceError, 1); | 
|  2720     __ bind(&const_error); |  2720     __ bind(&const_error); | 
|  2721     __ CallRuntime(Runtime::kThrowConstAssignError, 0); |  2721     __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 
|  2722  |  2722  | 
 |  2723   } else if (var->is_this() && op == Token::INIT_CONST) { | 
 |  2724     // Initializing assignment to const {this} needs a write barrier. | 
 |  2725     DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 
 |  2726     Label uninitialized_this; | 
 |  2727     MemOperand location = VarOperand(var, rcx); | 
 |  2728     __ movp(rdx, location); | 
 |  2729     __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); | 
 |  2730     __ j(equal, &uninitialized_this); | 
 |  2731     __ Push(var->name()); | 
 |  2732     __ CallRuntime(Runtime::kThrowReferenceError, 1); | 
 |  2733     __ bind(&uninitialized_this); | 
 |  2734     EmitStoreToStackLocalOrContextSlot(var, location); | 
 |  2735  | 
|  2723   } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |  2736   } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 
|  2724     if (var->IsLookupSlot()) { |  2737     if (var->IsLookupSlot()) { | 
|  2725       // Assignment to var. |  2738       // Assignment to var. | 
|  2726       __ Push(rax);  // Value. |  2739       __ Push(rax);  // Value. | 
|  2727       __ Push(rsi);  // Context. |  2740       __ Push(rsi);  // Context. | 
|  2728       __ Push(var->name()); |  2741       __ Push(var->name()); | 
|  2729       __ Push(Smi::FromInt(language_mode())); |  2742       __ Push(Smi::FromInt(language_mode())); | 
|  2730       __ CallRuntime(Runtime::kStoreLookupSlot, 4); |  2743       __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 
|  2731     } else { |  2744     } else { | 
|  2732       // Assignment to var or initializing assignment to let/const in harmony |  2745       // Assignment to var or initializing assignment to let/const in harmony | 
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3054   __ Push(Smi::FromInt(language_mode())); |  3067   __ Push(Smi::FromInt(language_mode())); | 
|  3055  |  3068  | 
|  3056   // Push the start position of the scope the calls resides in. |  3069   // Push the start position of the scope the calls resides in. | 
|  3057   __ Push(Smi::FromInt(scope()->start_position())); |  3070   __ Push(Smi::FromInt(scope()->start_position())); | 
|  3058  |  3071  | 
|  3059   // Do the runtime call. |  3072   // Do the runtime call. | 
|  3060   __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |  3073   __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 
|  3061 } |  3074 } | 
|  3062  |  3075  | 
|  3063  |  3076  | 
|  3064 void FullCodeGenerator::EmitInitializeThisAfterSuper( |  | 
|  3065     SuperCallReference* super_ref, FeedbackVectorICSlot slot) { |  | 
|  3066   Variable* this_var = super_ref->this_var()->var(); |  | 
|  3067   GetVar(rcx, this_var); |  | 
|  3068   __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex); |  | 
|  3069   Label uninitialized_this; |  | 
|  3070   __ j(equal, &uninitialized_this); |  | 
|  3071   __ Push(this_var->name()); |  | 
|  3072   __ CallRuntime(Runtime::kThrowReferenceError, 1); |  | 
|  3073   __ bind(&uninitialized_this); |  | 
|  3074  |  | 
|  3075   EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |  | 
|  3076 } |  | 
|  3077  |  | 
|  3078  |  | 
|  3079 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |  3077 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 
|  3080 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |  3078 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 
|  3081   VariableProxy* callee = expr->expression()->AsVariableProxy(); |  3079   VariableProxy* callee = expr->expression()->AsVariableProxy(); | 
|  3082   if (callee->var()->IsLookupSlot()) { |  3080   if (callee->var()->IsLookupSlot()) { | 
|  3083     Label slow, done; |  3081     Label slow, done; | 
|  3084     SetExpressionPosition(callee); |  3082     SetExpressionPosition(callee); | 
|  3085     // Generate code for loading from variables potentially shadowed by |  3083     // Generate code for loading from variables potentially shadowed by | 
|  3086     // eval-introduced variables. |  3084     // eval-introduced variables. | 
|  3087     EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |  3085     EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 
|  3088     __ bind(&slow); |  3086     __ bind(&slow); | 
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3283   } |  3281   } | 
|  3284  |  3282  | 
|  3285   __ Move(rbx, FeedbackVector()); |  3283   __ Move(rbx, FeedbackVector()); | 
|  3286   __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot())); |  3284   __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot())); | 
|  3287  |  3285  | 
|  3288   CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |  3286   CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 
|  3289   __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |  3287   __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 
|  3290  |  3288  | 
|  3291   RecordJSReturnSite(expr); |  3289   RecordJSReturnSite(expr); | 
|  3292  |  3290  | 
|  3293   EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot()); |  | 
|  3294   context()->Plug(rax); |  3291   context()->Plug(rax); | 
|  3295 } |  3292 } | 
|  3296  |  3293  | 
|  3297  |  3294  | 
|  3298 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |  3295 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 
|  3299   ZoneList<Expression*>* args = expr->arguments(); |  3296   ZoneList<Expression*>* args = expr->arguments(); | 
|  3300   DCHECK(args->length() == 1); |  3297   DCHECK(args->length() == 1); | 
|  3301  |  3298  | 
|  3302   VisitForAccumulatorValue(args->at(0)); |  3299   VisitForAccumulatorValue(args->at(0)); | 
|  3303  |  3300  | 
| (...skipping 1381 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4685  |  4682  | 
|  4686   // Push NewTarget |  4683   // Push NewTarget | 
|  4687   DCHECK(args->at(2)->IsVariableProxy()); |  4684   DCHECK(args->at(2)->IsVariableProxy()); | 
|  4688   VisitForStackValue(args->at(2)); |  4685   VisitForStackValue(args->at(2)); | 
|  4689  |  4686  | 
|  4690   EmitCallJSRuntimeFunction(call); |  4687   EmitCallJSRuntimeFunction(call); | 
|  4691  |  4688  | 
|  4692   // Restore context register. |  4689   // Restore context register. | 
|  4693   __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  4690   __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  4694   context()->DropAndPlug(1, rax); |  4691   context()->DropAndPlug(1, rax); | 
|  4695  |  | 
|  4696   // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |  | 
|  4697   EmitInitializeThisAfterSuper(super_call_ref); |  | 
|  4698 } |  4692 } | 
|  4699  |  4693  | 
|  4700  |  4694  | 
|  4701 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |  4695 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 
|  4702   // Push the builtins object as receiver. |  4696   // Push the builtins object as receiver. | 
|  4703   __ movp(rax, GlobalObjectOperand()); |  4697   __ movp(rax, GlobalObjectOperand()); | 
|  4704   __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); |  4698   __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); | 
|  4705  |  4699  | 
|  4706   // Load the function from the receiver. |  4700   // Load the function from the receiver. | 
|  4707   __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |  4701   __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4887       break; |  4881       break; | 
|  4888     } |  4882     } | 
|  4889  |  4883  | 
|  4890     default: |  4884     default: | 
|  4891       UNREACHABLE(); |  4885       UNREACHABLE(); | 
|  4892   } |  4886   } | 
|  4893 } |  4887 } | 
|  4894  |  4888  | 
|  4895  |  4889  | 
|  4896 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |  4890 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 
|  4897   DCHECK(expr->expression()->IsValidReferenceExpression()); |  4891   DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); | 
|  4898  |  4892  | 
|  4899   Comment cmnt(masm_, "[ CountOperation"); |  4893   Comment cmnt(masm_, "[ CountOperation"); | 
|  4900  |  4894  | 
|  4901   Property* prop = expr->expression()->AsProperty(); |  4895   Property* prop = expr->expression()->AsProperty(); | 
|  4902   LhsKind assign_type = Property::GetAssignType(prop); |  4896   LhsKind assign_type = Property::GetAssignType(prop); | 
|  4903  |  4897  | 
|  4904   // Evaluate expression and get value. |  4898   // Evaluate expression and get value. | 
|  4905   if (assign_type == VARIABLE) { |  4899   if (assign_type == VARIABLE) { | 
|  4906     DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |  4900     DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 
|  4907     AccumulatorValueContext context(this); |  4901     AccumulatorValueContext context(this); | 
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5517             Assembler::target_address_at(call_target_address, |  5511             Assembler::target_address_at(call_target_address, | 
|  5518                                          unoptimized_code)); |  5512                                          unoptimized_code)); | 
|  5519   return OSR_AFTER_STACK_CHECK; |  5513   return OSR_AFTER_STACK_CHECK; | 
|  5520 } |  5514 } | 
|  5521  |  5515  | 
|  5522  |  5516  | 
|  5523 }  // namespace internal |  5517 }  // namespace internal | 
|  5524 }  // namespace v8 |  5518 }  // namespace v8 | 
|  5525  |  5519  | 
|  5526 #endif  // V8_TARGET_ARCH_X64 |  5520 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW |