OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 allocator_->Initialize(); | 210 allocator_->Initialize(); |
211 | 211 |
212 #ifdef DEBUG | 212 #ifdef DEBUG |
213 if (strlen(FLAG_stop_at) > 0 && | 213 if (strlen(FLAG_stop_at) > 0 && |
214 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 214 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
215 frame_->SpillAll(); | 215 frame_->SpillAll(); |
216 __ stop("stop-at"); | 216 __ stop("stop-at"); |
217 } | 217 } |
218 #endif | 218 #endif |
219 | 219 |
220 if (info->mode() == CompilationInfo::PRIMARY) { | 220 frame_->Enter(); |
221 frame_->Enter(); | 221 // tos: code slot |
222 // tos: code slot | |
223 | 222 |
224 // Allocate space for locals and initialize them. This also checks | 223 // Allocate space for locals and initialize them. This also checks |
225 // for stack overflow. | 224 // for stack overflow. |
226 frame_->AllocateStackSlots(); | 225 frame_->AllocateStackSlots(); |
227 | 226 |
228 frame_->AssertIsSpilled(); | 227 frame_->AssertIsSpilled(); |
229 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 228 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
230 if (heap_slots > 0) { | 229 if (heap_slots > 0) { |
231 // Allocate local context. | 230 // Allocate local context. |
232 // Get outer context and create a new context based on it. | 231 // Get outer context and create a new context based on it. |
233 __ ldr(r0, frame_->Function()); | 232 __ ldr(r0, frame_->Function()); |
234 frame_->EmitPush(r0); | 233 frame_->EmitPush(r0); |
235 if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 234 if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
236 FastNewContextStub stub(heap_slots); | 235 FastNewContextStub stub(heap_slots); |
237 frame_->CallStub(&stub, 1); | 236 frame_->CallStub(&stub, 1); |
238 } else { | 237 } else { |
239 frame_->CallRuntime(Runtime::kNewContext, 1); | 238 frame_->CallRuntime(Runtime::kNewContext, 1); |
240 } | 239 } |
241 | 240 |
242 #ifdef DEBUG | 241 #ifdef DEBUG |
243 JumpTarget verified_true; | 242 JumpTarget verified_true; |
244 __ cmp(r0, cp); | 243 __ cmp(r0, cp); |
245 verified_true.Branch(eq); | 244 verified_true.Branch(eq); |
246 __ stop("NewContext: r0 is expected to be the same as cp"); | 245 __ stop("NewContext: r0 is expected to be the same as cp"); |
247 verified_true.Bind(); | 246 verified_true.Bind(); |
248 #endif | 247 #endif |
249 // Update context local. | 248 // Update context local. |
250 __ str(cp, frame_->Context()); | 249 __ str(cp, frame_->Context()); |
251 } | 250 } |
252 | 251 |
253 // TODO(1241774): Improve this code: | 252 // TODO(1241774): Improve this code: |
254 // 1) only needed if we have a context | 253 // 1) only needed if we have a context |
255 // 2) no need to recompute context ptr every single time | 254 // 2) no need to recompute context ptr every single time |
256 // 3) don't copy parameter operand code from SlotOperand! | 255 // 3) don't copy parameter operand code from SlotOperand! |
257 { | 256 { |
258 Comment cmnt2(masm_, "[ copy context parameters into .context"); | 257 Comment cmnt2(masm_, "[ copy context parameters into .context"); |
259 // Note that iteration order is relevant here! If we have the same | 258 // Note that iteration order is relevant here! If we have the same |
260 // parameter twice (e.g., function (x, y, x)), and that parameter | 259 // parameter twice (e.g., function (x, y, x)), and that parameter |
261 // needs to be copied into the context, it must be the last argument | 260 // needs to be copied into the context, it must be the last argument |
262 // passed to the parameter that needs to be copied. This is a rare | 261 // passed to the parameter that needs to be copied. This is a rare |
263 // case so we don't check for it, instead we rely on the copying | 262 // case so we don't check for it, instead we rely on the copying |
264 // order: such a parameter is copied repeatedly into the same | 263 // order: such a parameter is copied repeatedly into the same |
265 // context location and thus the last value is what is seen inside | 264 // context location and thus the last value is what is seen inside |
266 // the function. | 265 // the function. |
267 frame_->AssertIsSpilled(); | 266 frame_->AssertIsSpilled(); |
268 for (int i = 0; i < scope()->num_parameters(); i++) { | 267 for (int i = 0; i < scope()->num_parameters(); i++) { |
269 Variable* par = scope()->parameter(i); | 268 Variable* par = scope()->parameter(i); |
270 Slot* slot = par->slot(); | 269 Slot* slot = par->slot(); |
271 if (slot != NULL && slot->type() == Slot::CONTEXT) { | 270 if (slot != NULL && slot->type() == Slot::CONTEXT) { |
272 ASSERT(!scope()->is_global_scope()); // No params in global scope. | 271 ASSERT(!scope()->is_global_scope()); // No params in global scope. |
273 __ ldr(r1, frame_->ParameterAt(i)); | 272 __ ldr(r1, frame_->ParameterAt(i)); |
274 // Loads r2 with context; used below in RecordWrite. | 273 // Loads r2 with context; used below in RecordWrite. |
275 __ str(r1, SlotOperand(slot, r2)); | 274 __ str(r1, SlotOperand(slot, r2)); |
276 // Load the offset into r3. | 275 // Load the offset into r3. |
277 int slot_offset = | 276 int slot_offset = |
278 FixedArray::kHeaderSize + slot->index() * kPointerSize; | 277 FixedArray::kHeaderSize + slot->index() * kPointerSize; |
279 __ RecordWrite(r2, Operand(slot_offset), r3, r1); | 278 __ RecordWrite(r2, Operand(slot_offset), r3, r1); |
280 } | |
281 } | 279 } |
282 } | 280 } |
283 | |
284 // Store the arguments object. This must happen after context | |
285 // initialization because the arguments object may be stored in | |
286 // the context. | |
287 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { | |
288 StoreArgumentsObject(true); | |
289 } | |
290 | |
291 // Initialize ThisFunction reference if present. | |
292 if (scope()->is_function_scope() && scope()->function() != NULL) { | |
293 frame_->EmitPushRoot(Heap::kTheHoleValueRootIndex); | |
294 StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT); | |
295 } | |
296 } else { | |
297 // When used as the secondary compiler for splitting, r1, cp, | |
298 // fp, and lr have been pushed on the stack. Adjust the virtual | |
299 // frame to match this state. | |
300 frame_->Adjust(4); | |
301 | |
302 // Bind all the bailout labels to the beginning of the function. | |
303 List<CompilationInfo::Bailout*>* bailouts = info->bailouts(); | |
304 for (int i = 0; i < bailouts->length(); i++) { | |
305 __ bind(bailouts->at(i)->label()); | |
306 } | |
307 } | 281 } |
308 | 282 |
| 283 // Store the arguments object. This must happen after context |
| 284 // initialization because the arguments object may be stored in |
| 285 // the context. |
| 286 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { |
| 287 StoreArgumentsObject(true); |
| 288 } |
| 289 |
| 290 // Initialize ThisFunction reference if present. |
| 291 if (scope()->is_function_scope() && scope()->function() != NULL) { |
| 292 frame_->EmitPushRoot(Heap::kTheHoleValueRootIndex); |
| 293 StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT); |
| 294 } |
| 295 |
309 // Initialize the function return target after the locals are set | 296 // Initialize the function return target after the locals are set |
310 // up, because it needs the expected frame height from the frame. | 297 // up, because it needs the expected frame height from the frame. |
311 function_return_.SetExpectedHeight(); | 298 function_return_.SetExpectedHeight(); |
312 function_return_is_shadowed_ = false; | 299 function_return_is_shadowed_ = false; |
313 | 300 |
314 // Generate code to 'execute' declarations and initialize functions | 301 // Generate code to 'execute' declarations and initialize functions |
315 // (source elements). In case of an illegal redeclaration we need to | 302 // (source elements). In case of an illegal redeclaration we need to |
316 // handle that instead of processing the declarations. | 303 // handle that instead of processing the declarations. |
317 if (scope()->HasIllegalRedeclaration()) { | 304 if (scope()->HasIllegalRedeclaration()) { |
318 Comment cmnt(masm_, "[ illegal redeclarations"); | 305 Comment cmnt(masm_, "[ illegal redeclarations"); |
(...skipping 11257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11576 __ bind(&string_add_runtime); | 11563 __ bind(&string_add_runtime); |
11577 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 11564 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
11578 } | 11565 } |
11579 | 11566 |
11580 | 11567 |
11581 #undef __ | 11568 #undef __ |
11582 | 11569 |
11583 } } // namespace v8::internal | 11570 } } // namespace v8::internal |
11584 | 11571 |
11585 #endif // V8_TARGET_ARCH_ARM | 11572 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |