| 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 | 
| 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 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1327   } | 1327   } | 
| 1328 } | 1328 } | 
| 1329 | 1329 | 
| 1330 | 1330 | 
| 1331 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, | 1331 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, | 
| 1332                                                TypeofMode typeof_mode) { | 1332                                                TypeofMode typeof_mode) { | 
| 1333   Variable* var = proxy->var(); | 1333   Variable* var = proxy->var(); | 
| 1334   DCHECK(var->IsUnallocatedOrGlobalSlot() || | 1334   DCHECK(var->IsUnallocatedOrGlobalSlot() || | 
| 1335          (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); | 1335          (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); | 
| 1336   __ Move(LoadDescriptor::NameRegister(), var->name()); | 1336   __ Move(LoadDescriptor::NameRegister(), var->name()); | 
| 1337   __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1337   __ LoadGlobalObject(LoadDescriptor::ReceiverRegister()); | 
| 1338   __ Move(LoadDescriptor::SlotRegister(), | 1338   __ Move(LoadDescriptor::SlotRegister(), | 
| 1339           SmiFromSlot(proxy->VariableFeedbackSlot())); | 1339           SmiFromSlot(proxy->VariableFeedbackSlot())); | 
| 1340   CallLoadIC(typeof_mode); | 1340   CallLoadIC(typeof_mode); | 
| 1341 } | 1341 } | 
| 1342 | 1342 | 
| 1343 | 1343 | 
| 1344 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, | 1344 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, | 
| 1345                                          TypeofMode typeof_mode) { | 1345                                          TypeofMode typeof_mode) { | 
| 1346   // Record position before possible IC call. | 1346   // Record position before possible IC call. | 
| 1347   SetExpressionPosition(proxy); | 1347   SetExpressionPosition(proxy); | 
| (...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2113   Label allocate, done_allocate; | 2113   Label allocate, done_allocate; | 
| 2114 | 2114 | 
| 2115   __ Allocate(JSIteratorResult::kSize, rax, rcx, rdx, &allocate, TAG_OBJECT); | 2115   __ Allocate(JSIteratorResult::kSize, rax, rcx, rdx, &allocate, TAG_OBJECT); | 
| 2116   __ jmp(&done_allocate, Label::kNear); | 2116   __ jmp(&done_allocate, Label::kNear); | 
| 2117 | 2117 | 
| 2118   __ bind(&allocate); | 2118   __ bind(&allocate); | 
| 2119   __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 2119   __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 
| 2120   __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 2120   __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 
| 2121 | 2121 | 
| 2122   __ bind(&done_allocate); | 2122   __ bind(&done_allocate); | 
| 2123   __ movp(rbx, GlobalObjectOperand()); | 2123   __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, rbx); | 
| 2124   __ movp(rbx, FieldOperand(rbx, JSGlobalObject::kNativeContextOffset)); |  | 
| 2125   __ movp(rbx, ContextOperand(rbx, Context::ITERATOR_RESULT_MAP_INDEX)); |  | 
| 2126   __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); | 2124   __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); | 
| 2127   __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); | 2125   __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); | 
| 2128   __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); | 2126   __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); | 
| 2129   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); | 2127   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); | 
| 2130   __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset)); | 2128   __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset)); | 
| 2131   __ LoadRoot(FieldOperand(rax, JSIteratorResult::kDoneOffset), | 2129   __ LoadRoot(FieldOperand(rax, JSIteratorResult::kDoneOffset), | 
| 2132               done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); | 2130               done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); | 
| 2133   STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 2131   STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 
| 2134 } | 2132 } | 
| 2135 | 2133 | 
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2403         rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); | 2401         rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); | 
| 2404   } | 2402   } | 
| 2405 } | 2403 } | 
| 2406 | 2404 | 
| 2407 | 2405 | 
| 2408 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2406 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 
| 2409                                                FeedbackVectorSlot slot) { | 2407                                                FeedbackVectorSlot slot) { | 
| 2410   if (var->IsUnallocated()) { | 2408   if (var->IsUnallocated()) { | 
| 2411     // Global var, const, or let. | 2409     // Global var, const, or let. | 
| 2412     __ Move(StoreDescriptor::NameRegister(), var->name()); | 2410     __ Move(StoreDescriptor::NameRegister(), var->name()); | 
| 2413     __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2411     __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); | 
| 2414     EmitLoadStoreICSlot(slot); | 2412     EmitLoadStoreICSlot(slot); | 
| 2415     CallStoreIC(); | 2413     CallStoreIC(); | 
| 2416 | 2414 | 
| 2417   } else if (var->mode() == LET && op != Token::INIT) { | 2415   } else if (var->mode() == LET && op != Token::INIT) { | 
| 2418     // Non-initializing assignment to let variable needs a write barrier. | 2416     // Non-initializing assignment to let variable needs a write barrier. | 
| 2419     DCHECK(!var->IsLookupSlot()); | 2417     DCHECK(!var->IsLookupSlot()); | 
| 2420     DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2418     DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 
| 2421     Label assign; | 2419     Label assign; | 
| 2422     MemOperand location = VarOperand(var, rcx); | 2420     MemOperand location = VarOperand(var, rcx); | 
| 2423     __ movp(rdx, location); | 2421     __ movp(rdx, location); | 
| (...skipping 1623 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4047 | 4045 | 
| 4048 void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) { | 4046 void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) { | 
| 4049   ZoneList<Expression*>* args = expr->arguments(); | 4047   ZoneList<Expression*>* args = expr->arguments(); | 
| 4050   DCHECK_EQ(2, args->length()); | 4048   DCHECK_EQ(2, args->length()); | 
| 4051   VisitForStackValue(args->at(0)); | 4049   VisitForStackValue(args->at(0)); | 
| 4052   VisitForStackValue(args->at(1)); | 4050   VisitForStackValue(args->at(1)); | 
| 4053 | 4051 | 
| 4054   Label runtime, done; | 4052   Label runtime, done; | 
| 4055 | 4053 | 
| 4056   __ Allocate(JSIteratorResult::kSize, rax, rcx, rdx, &runtime, TAG_OBJECT); | 4054   __ Allocate(JSIteratorResult::kSize, rax, rcx, rdx, &runtime, TAG_OBJECT); | 
| 4057   __ movp(rbx, GlobalObjectOperand()); | 4055   __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, rbx); | 
| 4058   __ movp(rbx, FieldOperand(rbx, JSGlobalObject::kNativeContextOffset)); |  | 
| 4059   __ movp(rbx, ContextOperand(rbx, Context::ITERATOR_RESULT_MAP_INDEX)); |  | 
| 4060   __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); | 4056   __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); | 
| 4061   __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); | 4057   __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); | 
| 4062   __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); | 4058   __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); | 
| 4063   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); | 4059   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); | 
| 4064   __ Pop(FieldOperand(rax, JSIteratorResult::kDoneOffset)); | 4060   __ Pop(FieldOperand(rax, JSIteratorResult::kDoneOffset)); | 
| 4065   __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset)); | 4061   __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset)); | 
| 4066   STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 4062   STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 
| 4067   __ jmp(&done, Label::kNear); | 4063   __ jmp(&done, Label::kNear); | 
| 4068 | 4064 | 
| 4069   __ bind(&runtime); | 4065   __ bind(&runtime); | 
| 4070   __ CallRuntime(Runtime::kCreateIterResultObject, 2); | 4066   __ CallRuntime(Runtime::kCreateIterResultObject, 2); | 
| 4071 | 4067 | 
| 4072   __ bind(&done); | 4068   __ bind(&done); | 
| 4073   context()->Plug(rax); | 4069   context()->Plug(rax); | 
| 4074 } | 4070 } | 
| 4075 | 4071 | 
| 4076 | 4072 | 
| 4077 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4073 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 
| 4078   // Push the builtins object as receiver. | 4074   // Push the builtins object as receiver. | 
| 4079   __ PushRoot(Heap::kUndefinedValueRootIndex); | 4075   __ PushRoot(Heap::kUndefinedValueRootIndex); | 
| 4080 | 4076 | 
| 4081   __ movp(rax, GlobalObjectOperand()); | 4077   __ LoadNativeContextSlot(expr->context_index(), rax); | 
| 4082   __ movp(rax, FieldOperand(rax, JSGlobalObject::kNativeContextOffset)); |  | 
| 4083   __ movp(rax, ContextOperand(rax, expr->context_index())); |  | 
| 4084 } | 4078 } | 
| 4085 | 4079 | 
| 4086 | 4080 | 
| 4087 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4081 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 
| 4088   ZoneList<Expression*>* args = expr->arguments(); | 4082   ZoneList<Expression*>* args = expr->arguments(); | 
| 4089   int arg_count = args->length(); | 4083   int arg_count = args->length(); | 
| 4090 | 4084 | 
| 4091   SetCallPosition(expr, arg_count); | 4085   SetCallPosition(expr, arg_count); | 
| 4092   __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 4086   __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 
| 4093   __ Set(rax, arg_count); | 4087   __ Set(rax, arg_count); | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4163                            : Runtime::kDeleteProperty_Sloppy, | 4157                            : Runtime::kDeleteProperty_Sloppy, | 
| 4164                        2); | 4158                        2); | 
| 4165         context()->Plug(rax); | 4159         context()->Plug(rax); | 
| 4166       } else if (proxy != NULL) { | 4160       } else if (proxy != NULL) { | 
| 4167         Variable* var = proxy->var(); | 4161         Variable* var = proxy->var(); | 
| 4168         // Delete of an unqualified identifier is disallowed in strict mode but | 4162         // Delete of an unqualified identifier is disallowed in strict mode but | 
| 4169         // "delete this" is allowed. | 4163         // "delete this" is allowed. | 
| 4170         bool is_this = var->HasThisName(isolate()); | 4164         bool is_this = var->HasThisName(isolate()); | 
| 4171         DCHECK(is_sloppy(language_mode()) || is_this); | 4165         DCHECK(is_sloppy(language_mode()) || is_this); | 
| 4172         if (var->IsUnallocatedOrGlobalSlot()) { | 4166         if (var->IsUnallocatedOrGlobalSlot()) { | 
| 4173           __ Push(GlobalObjectOperand()); | 4167           __ movp(rax, NativeContextOperand()); | 
|  | 4168           __ Push(ContextOperand(rax, Context::EXTENSION_INDEX)); | 
| 4174           __ Push(var->name()); | 4169           __ Push(var->name()); | 
| 4175           __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); | 4170           __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); | 
| 4176           context()->Plug(rax); | 4171           context()->Plug(rax); | 
| 4177         } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4172         } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 
| 4178           // Result of deleting non-global variables is false.  'this' is | 4173           // Result of deleting non-global variables is false.  'this' is | 
| 4179           // not really a variable, though we implement it as one.  The | 4174           // not really a variable, though we implement it as one.  The | 
| 4180           // subexpression does not have side effects. | 4175           // subexpression does not have side effects. | 
| 4181           context()->Plug(is_this); | 4176           context()->Plug(is_this); | 
| 4182         } else { | 4177         } else { | 
| 4183           // Non-global variable.  Call the runtime to try to delete from the | 4178           // Non-global variable.  Call the runtime to try to delete from the | 
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4725 } | 4720 } | 
| 4726 | 4721 | 
| 4727 | 4722 | 
| 4728 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { | 4723 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { | 
| 4729   Scope* closure_scope = scope()->ClosureScope(); | 4724   Scope* closure_scope = scope()->ClosureScope(); | 
| 4730   if (closure_scope->is_script_scope() || | 4725   if (closure_scope->is_script_scope() || | 
| 4731       closure_scope->is_module_scope()) { | 4726       closure_scope->is_module_scope()) { | 
| 4732     // Contexts nested in the native context have a canonical empty function | 4727     // Contexts nested in the native context have a canonical empty function | 
| 4733     // as their closure, not the anonymous closure containing the global | 4728     // as their closure, not the anonymous closure containing the global | 
| 4734     // code. | 4729     // code. | 
| 4735     __ movp(rax, GlobalObjectOperand()); | 4730     __ movp(rax, NativeContextOperand()); | 
| 4736     __ movp(rax, FieldOperand(rax, JSGlobalObject::kNativeContextOffset)); |  | 
| 4737     __ Push(ContextOperand(rax, Context::CLOSURE_INDEX)); | 4731     __ Push(ContextOperand(rax, Context::CLOSURE_INDEX)); | 
| 4738   } else if (closure_scope->is_eval_scope()) { | 4732   } else if (closure_scope->is_eval_scope()) { | 
| 4739     // Contexts created by a call to eval have the same closure as the | 4733     // Contexts created by a call to eval have the same closure as the | 
| 4740     // context calling eval, not the anonymous closure containing the eval | 4734     // context calling eval, not the anonymous closure containing the eval | 
| 4741     // code.  Fetch it from the context. | 4735     // code.  Fetch it from the context. | 
| 4742     __ Push(ContextOperand(rsi, Context::CLOSURE_INDEX)); | 4736     __ Push(ContextOperand(rsi, Context::CLOSURE_INDEX)); | 
| 4743   } else { | 4737   } else { | 
| 4744     DCHECK(closure_scope->is_function_scope()); | 4738     DCHECK(closure_scope->is_function_scope()); | 
| 4745     __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 4739     __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 
| 4746   } | 4740   } | 
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4887             Assembler::target_address_at(call_target_address, | 4881             Assembler::target_address_at(call_target_address, | 
| 4888                                          unoptimized_code)); | 4882                                          unoptimized_code)); | 
| 4889   return OSR_AFTER_STACK_CHECK; | 4883   return OSR_AFTER_STACK_CHECK; | 
| 4890 } | 4884 } | 
| 4891 | 4885 | 
| 4892 | 4886 | 
| 4893 }  // namespace internal | 4887 }  // namespace internal | 
| 4894 }  // namespace v8 | 4888 }  // namespace v8 | 
| 4895 | 4889 | 
| 4896 #endif  // V8_TARGET_ARCH_X64 | 4890 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|