OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 int num_parameters = info->scope()->num_parameters(); | 205 int num_parameters = info->scope()->num_parameters(); |
206 int first_parameter = info->scope()->has_this_declaration() ? -1 : 0; | 206 int first_parameter = info->scope()->has_this_declaration() ? -1 : 0; |
207 for (int i = first_parameter; i < num_parameters; i++) { | 207 for (int i = first_parameter; i < num_parameters; i++) { |
208 Variable* var = (i == -1) ? scope()->receiver() : scope()->parameter(i); | 208 Variable* var = (i == -1) ? scope()->receiver() : scope()->parameter(i); |
209 if (var->IsContextSlot()) { | 209 if (var->IsContextSlot()) { |
210 int parameter_offset = StandardFrameConstants::kCallerSPOffset + | 210 int parameter_offset = StandardFrameConstants::kCallerSPOffset + |
211 (num_parameters - 1 - i) * kPointerSize; | 211 (num_parameters - 1 - i) * kPointerSize; |
212 // Load parameter from stack. | 212 // Load parameter from stack. |
213 __ LoadP(r3, MemOperand(fp, parameter_offset), r0); | 213 __ LoadP(r3, MemOperand(fp, parameter_offset), r0); |
214 // Store it in the context. | 214 // Store it in the context. |
215 MemOperand target = ContextOperand(cp, var->index()); | 215 MemOperand target = ContextMemOperand(cp, var->index()); |
216 __ StoreP(r3, target, r0); | 216 __ StoreP(r3, target, r0); |
217 | 217 |
218 // Update the write barrier. | 218 // Update the write barrier. |
219 if (need_write_barrier) { | 219 if (need_write_barrier) { |
220 __ RecordWriteContextSlot(cp, target.offset(), r3, r6, | 220 __ RecordWriteContextSlot(cp, target.offset(), r3, r6, |
221 kLRHasBeenSaved, kDontSaveFPRegs); | 221 kLRHasBeenSaved, kDontSaveFPRegs); |
222 } else if (FLAG_debug_code) { | 222 } else if (FLAG_debug_code) { |
223 Label done; | 223 Label done; |
224 __ JumpIfInNewSpace(cp, r3, &done); | 224 __ JumpIfInNewSpace(cp, r3, &done); |
225 __ Abort(kExpectedNewSpaceObject); | 225 __ Abort(kExpectedNewSpaceObject); |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 } | 678 } |
679 return MemOperand(fp, offset); | 679 return MemOperand(fp, offset); |
680 } | 680 } |
681 | 681 |
682 | 682 |
683 MemOperand FullCodeGenerator::VarOperand(Variable* var, Register scratch) { | 683 MemOperand FullCodeGenerator::VarOperand(Variable* var, Register scratch) { |
684 DCHECK(var->IsContextSlot() || var->IsStackAllocated()); | 684 DCHECK(var->IsContextSlot() || var->IsStackAllocated()); |
685 if (var->IsContextSlot()) { | 685 if (var->IsContextSlot()) { |
686 int context_chain_length = scope()->ContextChainLength(var->scope()); | 686 int context_chain_length = scope()->ContextChainLength(var->scope()); |
687 __ LoadContext(scratch, context_chain_length); | 687 __ LoadContext(scratch, context_chain_length); |
688 return ContextOperand(scratch, var->index()); | 688 return ContextMemOperand(scratch, var->index()); |
689 } else { | 689 } else { |
690 return StackOperand(var); | 690 return StackOperand(var); |
691 } | 691 } |
692 } | 692 } |
693 | 693 |
694 | 694 |
695 void FullCodeGenerator::GetVar(Register dest, Variable* var) { | 695 void FullCodeGenerator::GetVar(Register dest, Variable* var) { |
696 // Use destination as scratch. | 696 // Use destination as scratch. |
697 MemOperand location = VarOperand(var, dest); | 697 MemOperand location = VarOperand(var, dest); |
698 __ LoadP(dest, location, r0); | 698 __ LoadP(dest, location, r0); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 778 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
779 __ StoreP(ip, StackOperand(variable)); | 779 __ StoreP(ip, StackOperand(variable)); |
780 } | 780 } |
781 break; | 781 break; |
782 | 782 |
783 case VariableLocation::CONTEXT: | 783 case VariableLocation::CONTEXT: |
784 if (hole_init) { | 784 if (hole_init) { |
785 Comment cmnt(masm_, "[ VariableDeclaration"); | 785 Comment cmnt(masm_, "[ VariableDeclaration"); |
786 EmitDebugCheckDeclarationContext(variable); | 786 EmitDebugCheckDeclarationContext(variable); |
787 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 787 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
788 __ StoreP(ip, ContextOperand(cp, variable->index()), r0); | 788 __ StoreP(ip, ContextMemOperand(cp, variable->index()), r0); |
789 // No write barrier since the_hole_value is in old space. | 789 // No write barrier since the_hole_value is in old space. |
790 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 790 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
791 } | 791 } |
792 break; | 792 break; |
793 | 793 |
794 case VariableLocation::LOOKUP: { | 794 case VariableLocation::LOOKUP: { |
795 Comment cmnt(masm_, "[ VariableDeclaration"); | 795 Comment cmnt(masm_, "[ VariableDeclaration"); |
796 __ mov(r5, Operand(variable->name())); | 796 __ mov(r5, Operand(variable->name())); |
797 // Declaration nodes are always introduced in one of four modes. | 797 // Declaration nodes are always introduced in one of four modes. |
798 DCHECK(IsDeclaredVariableMode(mode)); | 798 DCHECK(IsDeclaredVariableMode(mode)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 Comment cmnt(masm_, "[ FunctionDeclaration"); | 835 Comment cmnt(masm_, "[ FunctionDeclaration"); |
836 VisitForAccumulatorValue(declaration->fun()); | 836 VisitForAccumulatorValue(declaration->fun()); |
837 __ StoreP(result_register(), StackOperand(variable)); | 837 __ StoreP(result_register(), StackOperand(variable)); |
838 break; | 838 break; |
839 } | 839 } |
840 | 840 |
841 case VariableLocation::CONTEXT: { | 841 case VariableLocation::CONTEXT: { |
842 Comment cmnt(masm_, "[ FunctionDeclaration"); | 842 Comment cmnt(masm_, "[ FunctionDeclaration"); |
843 EmitDebugCheckDeclarationContext(variable); | 843 EmitDebugCheckDeclarationContext(variable); |
844 VisitForAccumulatorValue(declaration->fun()); | 844 VisitForAccumulatorValue(declaration->fun()); |
845 __ StoreP(result_register(), ContextOperand(cp, variable->index()), r0); | 845 __ StoreP(result_register(), ContextMemOperand(cp, variable->index()), |
| 846 r0); |
846 int offset = Context::SlotOffset(variable->index()); | 847 int offset = Context::SlotOffset(variable->index()); |
847 // We know that we have written a function, which is not a smi. | 848 // We know that we have written a function, which is not a smi. |
848 __ RecordWriteContextSlot(cp, offset, result_register(), r5, | 849 __ RecordWriteContextSlot(cp, offset, result_register(), r5, |
849 kLRHasBeenSaved, kDontSaveFPRegs, | 850 kLRHasBeenSaved, kDontSaveFPRegs, |
850 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 851 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
851 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 852 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
852 break; | 853 break; |
853 } | 854 } |
854 | 855 |
855 case VariableLocation::LOOKUP: { | 856 case VariableLocation::LOOKUP: { |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 Label* slow) { | 1229 Label* slow) { |
1229 Register current = cp; | 1230 Register current = cp; |
1230 Register next = r4; | 1231 Register next = r4; |
1231 Register temp = r5; | 1232 Register temp = r5; |
1232 | 1233 |
1233 Scope* s = scope(); | 1234 Scope* s = scope(); |
1234 while (s != NULL) { | 1235 while (s != NULL) { |
1235 if (s->num_heap_slots() > 0) { | 1236 if (s->num_heap_slots() > 0) { |
1236 if (s->calls_sloppy_eval()) { | 1237 if (s->calls_sloppy_eval()) { |
1237 // Check that extension is NULL. | 1238 // Check that extension is NULL. |
1238 __ LoadP(temp, ContextOperand(current, Context::EXTENSION_INDEX)); | 1239 __ LoadP(temp, ContextMemOperand(current, Context::EXTENSION_INDEX)); |
1239 __ cmpi(temp, Operand::Zero()); | 1240 __ cmpi(temp, Operand::Zero()); |
1240 __ bne(slow); | 1241 __ bne(slow); |
1241 } | 1242 } |
1242 // Load next context in chain. | 1243 // Load next context in chain. |
1243 __ LoadP(next, ContextOperand(current, Context::PREVIOUS_INDEX)); | 1244 __ LoadP(next, ContextMemOperand(current, Context::PREVIOUS_INDEX)); |
1244 // Walk the rest of the chain without clobbering cp. | 1245 // Walk the rest of the chain without clobbering cp. |
1245 current = next; | 1246 current = next; |
1246 } | 1247 } |
1247 // If no outer scope calls eval, we do not need to check more | 1248 // If no outer scope calls eval, we do not need to check more |
1248 // context extensions. | 1249 // context extensions. |
1249 if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break; | 1250 if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break; |
1250 s = s->outer_scope(); | 1251 s = s->outer_scope(); |
1251 } | 1252 } |
1252 | 1253 |
1253 if (s->is_eval_scope()) { | 1254 if (s->is_eval_scope()) { |
1254 Label loop, fast; | 1255 Label loop, fast; |
1255 if (!current.is(next)) { | 1256 if (!current.is(next)) { |
1256 __ Move(next, current); | 1257 __ Move(next, current); |
1257 } | 1258 } |
1258 __ bind(&loop); | 1259 __ bind(&loop); |
1259 // Terminate at native context. | 1260 // Terminate at native context. |
1260 __ LoadP(temp, FieldMemOperand(next, HeapObject::kMapOffset)); | 1261 __ LoadP(temp, FieldMemOperand(next, HeapObject::kMapOffset)); |
1261 __ LoadRoot(ip, Heap::kNativeContextMapRootIndex); | 1262 __ LoadRoot(ip, Heap::kNativeContextMapRootIndex); |
1262 __ cmp(temp, ip); | 1263 __ cmp(temp, ip); |
1263 __ beq(&fast); | 1264 __ beq(&fast); |
1264 // Check that extension is NULL. | 1265 // Check that extension is NULL. |
1265 __ LoadP(temp, ContextOperand(next, Context::EXTENSION_INDEX)); | 1266 __ LoadP(temp, ContextMemOperand(next, Context::EXTENSION_INDEX)); |
1266 __ cmpi(temp, Operand::Zero()); | 1267 __ cmpi(temp, Operand::Zero()); |
1267 __ bne(slow); | 1268 __ bne(slow); |
1268 // Load next context in chain. | 1269 // Load next context in chain. |
1269 __ LoadP(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1270 __ LoadP(next, ContextMemOperand(next, Context::PREVIOUS_INDEX)); |
1270 __ b(&loop); | 1271 __ b(&loop); |
1271 __ bind(&fast); | 1272 __ bind(&fast); |
1272 } | 1273 } |
1273 | 1274 |
1274 // All extension objects were empty and it is safe to use a normal global | 1275 // All extension objects were empty and it is safe to use a normal global |
1275 // load machinery. | 1276 // load machinery. |
1276 EmitGlobalVariableLoad(proxy, typeof_mode); | 1277 EmitGlobalVariableLoad(proxy, typeof_mode); |
1277 } | 1278 } |
1278 | 1279 |
1279 | 1280 |
1280 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1281 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1281 Label* slow) { | 1282 Label* slow) { |
1282 DCHECK(var->IsContextSlot()); | 1283 DCHECK(var->IsContextSlot()); |
1283 Register context = cp; | 1284 Register context = cp; |
1284 Register next = r6; | 1285 Register next = r6; |
1285 Register temp = r7; | 1286 Register temp = r7; |
1286 | 1287 |
1287 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { | 1288 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { |
1288 if (s->num_heap_slots() > 0) { | 1289 if (s->num_heap_slots() > 0) { |
1289 if (s->calls_sloppy_eval()) { | 1290 if (s->calls_sloppy_eval()) { |
1290 // Check that extension is NULL. | 1291 // Check that extension is NULL. |
1291 __ LoadP(temp, ContextOperand(context, Context::EXTENSION_INDEX)); | 1292 __ LoadP(temp, ContextMemOperand(context, Context::EXTENSION_INDEX)); |
1292 __ cmpi(temp, Operand::Zero()); | 1293 __ cmpi(temp, Operand::Zero()); |
1293 __ bne(slow); | 1294 __ bne(slow); |
1294 } | 1295 } |
1295 __ LoadP(next, ContextOperand(context, Context::PREVIOUS_INDEX)); | 1296 __ LoadP(next, ContextMemOperand(context, Context::PREVIOUS_INDEX)); |
1296 // Walk the rest of the chain without clobbering cp. | 1297 // Walk the rest of the chain without clobbering cp. |
1297 context = next; | 1298 context = next; |
1298 } | 1299 } |
1299 } | 1300 } |
1300 // Check that last extension is NULL. | 1301 // Check that last extension is NULL. |
1301 __ LoadP(temp, ContextOperand(context, Context::EXTENSION_INDEX)); | 1302 __ LoadP(temp, ContextMemOperand(context, Context::EXTENSION_INDEX)); |
1302 __ cmpi(temp, Operand::Zero()); | 1303 __ cmpi(temp, Operand::Zero()); |
1303 __ bne(slow); | 1304 __ bne(slow); |
1304 | 1305 |
1305 // This function is used only for loads, not stores, so it's safe to | 1306 // This function is used only for loads, not stores, so it's safe to |
1306 // return an cp-based operand (the write barrier cannot be allowed to | 1307 // return an cp-based operand (the write barrier cannot be allowed to |
1307 // destroy the cp register). | 1308 // destroy the cp register). |
1308 return ContextOperand(context, var->index()); | 1309 return ContextMemOperand(context, var->index()); |
1309 } | 1310 } |
1310 | 1311 |
1311 | 1312 |
1312 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, | 1313 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, |
1313 TypeofMode typeof_mode, | 1314 TypeofMode typeof_mode, |
1314 Label* slow, Label* done) { | 1315 Label* slow, Label* done) { |
1315 // Generate fast-case code for variables that might be shadowed by | 1316 // Generate fast-case code for variables that might be shadowed by |
1316 // eval-introduced variables. Eval is used a lot without | 1317 // eval-introduced variables. Eval is used a lot without |
1317 // introducing variables. In those cases, we do not want to | 1318 // introducing variables. In those cases, we do not want to |
1318 // perform a runtime call for all variables in the scope | 1319 // perform a runtime call for all variables in the scope |
(...skipping 20 matching lines...) Expand all Loading... |
1339 __ b(done); | 1340 __ b(done); |
1340 } | 1341 } |
1341 } | 1342 } |
1342 | 1343 |
1343 | 1344 |
1344 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, | 1345 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, |
1345 TypeofMode typeof_mode) { | 1346 TypeofMode typeof_mode) { |
1346 Variable* var = proxy->var(); | 1347 Variable* var = proxy->var(); |
1347 DCHECK(var->IsUnallocatedOrGlobalSlot() || | 1348 DCHECK(var->IsUnallocatedOrGlobalSlot() || |
1348 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); | 1349 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); |
1349 __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1350 __ LoadGlobalObject(LoadDescriptor::ReceiverRegister()); |
1350 __ mov(LoadDescriptor::NameRegister(), Operand(var->name())); | 1351 __ mov(LoadDescriptor::NameRegister(), Operand(var->name())); |
1351 __ mov(LoadDescriptor::SlotRegister(), | 1352 __ mov(LoadDescriptor::SlotRegister(), |
1352 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); | 1353 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); |
1353 CallLoadIC(typeof_mode); | 1354 CallLoadIC(typeof_mode); |
1354 } | 1355 } |
1355 | 1356 |
1356 | 1357 |
1357 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, | 1358 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, |
1358 TypeofMode typeof_mode) { | 1359 TypeofMode typeof_mode) { |
1359 // Record position before possible IC call. | 1360 // Record position before possible IC call. |
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2157 Label allocate, done_allocate; | 2158 Label allocate, done_allocate; |
2158 | 2159 |
2159 __ Allocate(JSIteratorResult::kSize, r3, r5, r6, &allocate, TAG_OBJECT); | 2160 __ Allocate(JSIteratorResult::kSize, r3, r5, r6, &allocate, TAG_OBJECT); |
2160 __ b(&done_allocate); | 2161 __ b(&done_allocate); |
2161 | 2162 |
2162 __ bind(&allocate); | 2163 __ bind(&allocate); |
2163 __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 2164 __ Push(Smi::FromInt(JSIteratorResult::kSize)); |
2164 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 2165 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
2165 | 2166 |
2166 __ bind(&done_allocate); | 2167 __ bind(&done_allocate); |
2167 __ LoadP(r4, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | 2168 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, r4); |
2168 __ LoadP(r4, FieldMemOperand(r4, JSGlobalObject::kNativeContextOffset)); | |
2169 __ LoadP(r4, ContextOperand(r4, Context::ITERATOR_RESULT_MAP_INDEX)); | |
2170 __ pop(r5); | 2169 __ pop(r5); |
2171 __ LoadRoot(r6, | 2170 __ LoadRoot(r6, |
2172 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); | 2171 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); |
2173 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex); | 2172 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex); |
2174 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0); | 2173 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0); |
2175 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); | 2174 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); |
2176 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); | 2175 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); |
2177 __ StoreP(r5, FieldMemOperand(r3, JSIteratorResult::kValueOffset), r0); | 2176 __ StoreP(r5, FieldMemOperand(r3, JSIteratorResult::kValueOffset), r0); |
2178 __ StoreP(r6, FieldMemOperand(r3, JSIteratorResult::kDoneOffset), r0); | 2177 __ StoreP(r6, FieldMemOperand(r3, JSIteratorResult::kDoneOffset), r0); |
2179 } | 2178 } |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2519 kDontSaveFPRegs); | 2518 kDontSaveFPRegs); |
2520 } | 2519 } |
2521 } | 2520 } |
2522 | 2521 |
2523 | 2522 |
2524 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2523 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
2525 FeedbackVectorSlot slot) { | 2524 FeedbackVectorSlot slot) { |
2526 if (var->IsUnallocated()) { | 2525 if (var->IsUnallocated()) { |
2527 // Global var, const, or let. | 2526 // Global var, const, or let. |
2528 __ mov(StoreDescriptor::NameRegister(), Operand(var->name())); | 2527 __ mov(StoreDescriptor::NameRegister(), Operand(var->name())); |
2529 __ LoadP(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2528 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); |
2530 EmitLoadStoreICSlot(slot); | 2529 EmitLoadStoreICSlot(slot); |
2531 CallStoreIC(); | 2530 CallStoreIC(); |
2532 | 2531 |
2533 } else if (var->mode() == LET && op != Token::INIT) { | 2532 } else if (var->mode() == LET && op != Token::INIT) { |
2534 // Non-initializing assignment to let variable needs a write barrier. | 2533 // Non-initializing assignment to let variable needs a write barrier. |
2535 DCHECK(!var->IsLookupSlot()); | 2534 DCHECK(!var->IsLookupSlot()); |
2536 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2535 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2537 Label assign; | 2536 Label assign; |
2538 MemOperand location = VarOperand(var, r4); | 2537 MemOperand location = VarOperand(var, r4); |
2539 __ LoadP(r6, location); | 2538 __ LoadP(r6, location); |
(...skipping 1593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4133 | 4132 |
4134 void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) { | 4133 void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) { |
4135 ZoneList<Expression*>* args = expr->arguments(); | 4134 ZoneList<Expression*>* args = expr->arguments(); |
4136 DCHECK_EQ(2, args->length()); | 4135 DCHECK_EQ(2, args->length()); |
4137 VisitForStackValue(args->at(0)); | 4136 VisitForStackValue(args->at(0)); |
4138 VisitForStackValue(args->at(1)); | 4137 VisitForStackValue(args->at(1)); |
4139 | 4138 |
4140 Label runtime, done; | 4139 Label runtime, done; |
4141 | 4140 |
4142 __ Allocate(JSIteratorResult::kSize, r3, r5, r6, &runtime, TAG_OBJECT); | 4141 __ Allocate(JSIteratorResult::kSize, r3, r5, r6, &runtime, TAG_OBJECT); |
4143 __ LoadP(r4, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | 4142 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, r4); |
4144 __ LoadP(r4, FieldMemOperand(r4, JSGlobalObject::kNativeContextOffset)); | |
4145 __ LoadP(r4, ContextOperand(r4, Context::ITERATOR_RESULT_MAP_INDEX)); | |
4146 __ Pop(r5, r6); | 4143 __ Pop(r5, r6); |
4147 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex); | 4144 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex); |
4148 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0); | 4145 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0); |
4149 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); | 4146 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); |
4150 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); | 4147 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); |
4151 __ StoreP(r5, FieldMemOperand(r3, JSIteratorResult::kValueOffset), r0); | 4148 __ StoreP(r5, FieldMemOperand(r3, JSIteratorResult::kValueOffset), r0); |
4152 __ StoreP(r6, FieldMemOperand(r3, JSIteratorResult::kDoneOffset), r0); | 4149 __ StoreP(r6, FieldMemOperand(r3, JSIteratorResult::kDoneOffset), r0); |
4153 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 4150 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
4154 __ b(&done); | 4151 __ b(&done); |
4155 | 4152 |
4156 __ bind(&runtime); | 4153 __ bind(&runtime); |
4157 __ CallRuntime(Runtime::kCreateIterResultObject, 2); | 4154 __ CallRuntime(Runtime::kCreateIterResultObject, 2); |
4158 | 4155 |
4159 __ bind(&done); | 4156 __ bind(&done); |
4160 context()->Plug(r3); | 4157 context()->Plug(r3); |
4161 } | 4158 } |
4162 | 4159 |
4163 | 4160 |
4164 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4161 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
4165 // Push undefined as the receiver. | 4162 // Push undefined as the receiver. |
4166 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | 4163 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); |
4167 __ push(r3); | 4164 __ push(r3); |
4168 | 4165 |
4169 __ LoadP(r3, GlobalObjectOperand()); | 4166 __ LoadNativeContextSlot(expr->context_index(), r3); |
4170 __ LoadP(r3, FieldMemOperand(r3, JSGlobalObject::kNativeContextOffset)); | |
4171 __ LoadP(r3, ContextOperand(r3, expr->context_index())); | |
4172 } | 4167 } |
4173 | 4168 |
4174 | 4169 |
4175 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4170 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
4176 ZoneList<Expression*>* args = expr->arguments(); | 4171 ZoneList<Expression*>* args = expr->arguments(); |
4177 int arg_count = args->length(); | 4172 int arg_count = args->length(); |
4178 | 4173 |
4179 SetCallPosition(expr, arg_count); | 4174 SetCallPosition(expr, arg_count); |
4180 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 4175 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
4181 __ mov(r3, Operand(arg_count)); | 4176 __ mov(r3, Operand(arg_count)); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4252 : Runtime::kDeleteProperty_Sloppy, | 4247 : Runtime::kDeleteProperty_Sloppy, |
4253 2); | 4248 2); |
4254 context()->Plug(r3); | 4249 context()->Plug(r3); |
4255 } else if (proxy != NULL) { | 4250 } else if (proxy != NULL) { |
4256 Variable* var = proxy->var(); | 4251 Variable* var = proxy->var(); |
4257 // Delete of an unqualified identifier is disallowed in strict mode but | 4252 // Delete of an unqualified identifier is disallowed in strict mode but |
4258 // "delete this" is allowed. | 4253 // "delete this" is allowed. |
4259 bool is_this = var->HasThisName(isolate()); | 4254 bool is_this = var->HasThisName(isolate()); |
4260 DCHECK(is_sloppy(language_mode()) || is_this); | 4255 DCHECK(is_sloppy(language_mode()) || is_this); |
4261 if (var->IsUnallocatedOrGlobalSlot()) { | 4256 if (var->IsUnallocatedOrGlobalSlot()) { |
4262 __ LoadP(r5, GlobalObjectOperand()); | 4257 __ LoadGlobalObject(r5); |
4263 __ mov(r4, Operand(var->name())); | 4258 __ mov(r4, Operand(var->name())); |
4264 __ Push(r5, r4); | 4259 __ Push(r5, r4); |
4265 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); | 4260 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); |
4266 context()->Plug(r3); | 4261 context()->Plug(r3); |
4267 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4262 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4268 // Result of deleting non-global, non-dynamic variables is false. | 4263 // Result of deleting non-global, non-dynamic variables is false. |
4269 // The subexpression does not have side effects. | 4264 // The subexpression does not have side effects. |
4270 context()->Plug(is_this); | 4265 context()->Plug(is_this); |
4271 } else { | 4266 } else { |
4272 // Non-global variable. Call the runtime to try to delete from the | 4267 // Non-global variable. Call the runtime to try to delete from the |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4794 Register FullCodeGenerator::context_register() { return cp; } | 4789 Register FullCodeGenerator::context_register() { return cp; } |
4795 | 4790 |
4796 | 4791 |
4797 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 4792 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
4798 DCHECK_EQ(static_cast<int>(POINTER_SIZE_ALIGN(frame_offset)), frame_offset); | 4793 DCHECK_EQ(static_cast<int>(POINTER_SIZE_ALIGN(frame_offset)), frame_offset); |
4799 __ StoreP(value, MemOperand(fp, frame_offset), r0); | 4794 __ StoreP(value, MemOperand(fp, frame_offset), r0); |
4800 } | 4795 } |
4801 | 4796 |
4802 | 4797 |
4803 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { | 4798 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { |
4804 __ LoadP(dst, ContextOperand(cp, context_index), r0); | 4799 __ LoadP(dst, ContextMemOperand(cp, context_index), r0); |
4805 } | 4800 } |
4806 | 4801 |
4807 | 4802 |
4808 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { | 4803 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { |
4809 Scope* closure_scope = scope()->ClosureScope(); | 4804 Scope* closure_scope = scope()->ClosureScope(); |
4810 if (closure_scope->is_script_scope() || | 4805 if (closure_scope->is_script_scope() || |
4811 closure_scope->is_module_scope()) { | 4806 closure_scope->is_module_scope()) { |
4812 // Contexts nested in the native context have a canonical empty function | 4807 // Contexts nested in the native context have a canonical empty function |
4813 // as their closure, not the anonymous closure containing the global | 4808 // as their closure, not the anonymous closure containing the global |
4814 // code. | 4809 // code. |
4815 __ LoadP(ip, GlobalObjectOperand()); | 4810 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, ip); |
4816 __ LoadP(ip, FieldMemOperand(ip, JSGlobalObject::kNativeContextOffset)); | |
4817 __ LoadP(ip, ContextOperand(ip, Context::CLOSURE_INDEX)); | |
4818 } else if (closure_scope->is_eval_scope()) { | 4811 } else if (closure_scope->is_eval_scope()) { |
4819 // Contexts created by a call to eval have the same closure as the | 4812 // Contexts created by a call to eval have the same closure as the |
4820 // context calling eval, not the anonymous closure containing the eval | 4813 // context calling eval, not the anonymous closure containing the eval |
4821 // code. Fetch it from the context. | 4814 // code. Fetch it from the context. |
4822 __ LoadP(ip, ContextOperand(cp, Context::CLOSURE_INDEX)); | 4815 __ LoadP(ip, ContextMemOperand(cp, Context::CLOSURE_INDEX)); |
4823 } else { | 4816 } else { |
4824 DCHECK(closure_scope->is_function_scope()); | 4817 DCHECK(closure_scope->is_function_scope()); |
4825 __ LoadP(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4818 __ LoadP(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
4826 } | 4819 } |
4827 __ push(ip); | 4820 __ push(ip); |
4828 } | 4821 } |
4829 | 4822 |
4830 | 4823 |
4831 // ---------------------------------------------------------------------------- | 4824 // ---------------------------------------------------------------------------- |
4832 // Non-local control flow support. | 4825 // Non-local control flow support. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4962 return ON_STACK_REPLACEMENT; | 4955 return ON_STACK_REPLACEMENT; |
4963 } | 4956 } |
4964 | 4957 |
4965 DCHECK(interrupt_address == | 4958 DCHECK(interrupt_address == |
4966 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4959 isolate->builtins()->OsrAfterStackCheck()->entry()); |
4967 return OSR_AFTER_STACK_CHECK; | 4960 return OSR_AFTER_STACK_CHECK; |
4968 } | 4961 } |
4969 } // namespace internal | 4962 } // namespace internal |
4970 } // namespace v8 | 4963 } // namespace v8 |
4971 #endif // V8_TARGET_ARCH_PPC | 4964 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |