OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 TAG_OBJECT); | 103 TAG_OBJECT); |
104 | 104 |
105 __ IncrementCounter(counters->fast_new_closure_total(), 1, t2, t3); | 105 __ IncrementCounter(counters->fast_new_closure_total(), 1, t2, t3); |
106 | 106 |
107 int map_index = (language_mode_ == CLASSIC_MODE) | 107 int map_index = (language_mode_ == CLASSIC_MODE) |
108 ? Context::FUNCTION_MAP_INDEX | 108 ? Context::FUNCTION_MAP_INDEX |
109 : Context::STRICT_MODE_FUNCTION_MAP_INDEX; | 109 : Context::STRICT_MODE_FUNCTION_MAP_INDEX; |
110 | 110 |
111 // Compute the function map in the current native context and set that | 111 // Compute the function map in the current native context and set that |
112 // as the map of the allocated object. | 112 // as the map of the allocated object. |
113 __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); | 113 __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
114 __ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset)); | 114 __ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset)); |
115 __ lw(t1, MemOperand(a2, Context::SlotOffset(map_index))); | 115 __ lw(t1, MemOperand(a2, Context::SlotOffset(map_index))); |
116 __ sw(t1, FieldMemOperand(v0, HeapObject::kMapOffset)); | 116 __ sw(t1, FieldMemOperand(v0, HeapObject::kMapOffset)); |
117 | 117 |
118 // Initialize the rest of the function. We don't have to update the | 118 // Initialize the rest of the function. We don't have to update the |
119 // write barrier because the allocated object is in new space. | 119 // write barrier because the allocated object is in new space. |
120 __ LoadRoot(a1, Heap::kEmptyFixedArrayRootIndex); | 120 __ LoadRoot(a1, Heap::kEmptyFixedArrayRootIndex); |
121 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex); | 121 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex); |
122 __ sw(a1, FieldMemOperand(v0, JSObject::kPropertiesOffset)); | 122 __ sw(a1, FieldMemOperand(v0, JSObject::kPropertiesOffset)); |
123 __ sw(a1, FieldMemOperand(v0, JSObject::kElementsOffset)); | 123 __ sw(a1, FieldMemOperand(v0, JSObject::kElementsOffset)); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 // Load the function from the stack. | 237 // Load the function from the stack. |
238 __ lw(a3, MemOperand(sp, 0)); | 238 __ lw(a3, MemOperand(sp, 0)); |
239 | 239 |
240 // Set up the object header. | 240 // Set up the object header. |
241 __ LoadRoot(a1, Heap::kFunctionContextMapRootIndex); | 241 __ LoadRoot(a1, Heap::kFunctionContextMapRootIndex); |
242 __ li(a2, Operand(Smi::FromInt(length))); | 242 __ li(a2, Operand(Smi::FromInt(length))); |
243 __ sw(a2, FieldMemOperand(v0, FixedArray::kLengthOffset)); | 243 __ sw(a2, FieldMemOperand(v0, FixedArray::kLengthOffset)); |
244 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); | 244 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); |
245 | 245 |
246 // Set up the fixed slots, copy the global object from the previous context. | 246 // Set up the fixed slots, copy the global object from the previous context. |
247 __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); | 247 __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
248 __ li(a1, Operand(Smi::FromInt(0))); | 248 __ li(a1, Operand(Smi::FromInt(0))); |
249 __ sw(a3, MemOperand(v0, Context::SlotOffset(Context::CLOSURE_INDEX))); | 249 __ sw(a3, MemOperand(v0, Context::SlotOffset(Context::CLOSURE_INDEX))); |
250 __ sw(cp, MemOperand(v0, Context::SlotOffset(Context::PREVIOUS_INDEX))); | 250 __ sw(cp, MemOperand(v0, Context::SlotOffset(Context::PREVIOUS_INDEX))); |
251 __ sw(a1, MemOperand(v0, Context::SlotOffset(Context::EXTENSION_INDEX))); | 251 __ sw(a1, MemOperand(v0, Context::SlotOffset(Context::EXTENSION_INDEX))); |
252 __ sw(a2, MemOperand(v0, Context::SlotOffset(Context::GLOBAL_INDEX))); | 252 __ sw(a2, MemOperand(v0, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
253 | 253 |
254 // Initialize the rest of the slots to undefined. | 254 // Initialize the rest of the slots to undefined. |
255 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); | 255 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); |
256 for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) { | 256 for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) { |
257 __ sw(a1, MemOperand(v0, Context::SlotOffset(i))); | 257 __ sw(a1, MemOperand(v0, Context::SlotOffset(i))); |
258 } | 258 } |
259 | 259 |
260 // Remove the on-stack argument and return. | 260 // Remove the on-stack argument and return. |
261 __ mov(cp, v0); | 261 __ mov(cp, v0); |
262 __ DropAndRet(1); | 262 __ DropAndRet(1); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 if (FLAG_debug_code) { | 300 if (FLAG_debug_code) { |
301 const char* message = "Expected 0 as a Smi sentinel"; | 301 const char* message = "Expected 0 as a Smi sentinel"; |
302 __ Assert(eq, message, a3, Operand(zero_reg)); | 302 __ Assert(eq, message, a3, Operand(zero_reg)); |
303 } | 303 } |
304 __ lw(a3, GlobalObjectOperand()); | 304 __ lw(a3, GlobalObjectOperand()); |
305 __ lw(a3, FieldMemOperand(a3, GlobalObject::kNativeContextOffset)); | 305 __ lw(a3, FieldMemOperand(a3, GlobalObject::kNativeContextOffset)); |
306 __ lw(a3, ContextOperand(a3, Context::CLOSURE_INDEX)); | 306 __ lw(a3, ContextOperand(a3, Context::CLOSURE_INDEX)); |
307 __ bind(&after_sentinel); | 307 __ bind(&after_sentinel); |
308 | 308 |
309 // Set up the fixed slots, copy the global object from the previous context. | 309 // Set up the fixed slots, copy the global object from the previous context. |
310 __ lw(a2, ContextOperand(cp, Context::GLOBAL_INDEX)); | 310 __ lw(a2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); |
311 __ sw(a3, ContextOperand(v0, Context::CLOSURE_INDEX)); | 311 __ sw(a3, ContextOperand(v0, Context::CLOSURE_INDEX)); |
312 __ sw(cp, ContextOperand(v0, Context::PREVIOUS_INDEX)); | 312 __ sw(cp, ContextOperand(v0, Context::PREVIOUS_INDEX)); |
313 __ sw(a1, ContextOperand(v0, Context::EXTENSION_INDEX)); | 313 __ sw(a1, ContextOperand(v0, Context::EXTENSION_INDEX)); |
314 __ sw(a2, ContextOperand(v0, Context::GLOBAL_INDEX)); | 314 __ sw(a2, ContextOperand(v0, Context::GLOBAL_OBJECT_INDEX)); |
315 | 315 |
316 // Initialize the rest of the slots to the hole value. | 316 // Initialize the rest of the slots to the hole value. |
317 __ LoadRoot(a1, Heap::kTheHoleValueRootIndex); | 317 __ LoadRoot(a1, Heap::kTheHoleValueRootIndex); |
318 for (int i = 0; i < slots_; i++) { | 318 for (int i = 0; i < slots_; i++) { |
319 __ sw(a1, ContextOperand(v0, i + Context::MIN_CONTEXT_SLOTS)); | 319 __ sw(a1, ContextOperand(v0, i + Context::MIN_CONTEXT_SLOTS)); |
320 } | 320 } |
321 | 321 |
322 // Remove the on-stack argument and return. | 322 // Remove the on-stack argument and return. |
323 __ mov(cp, v0); | 323 __ mov(cp, v0); |
324 __ DropAndRet(2); | 324 __ DropAndRet(2); |
(...skipping 4314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4639 __ Addu(t5, t5, Operand(FixedArray::kHeaderSize)); | 4639 __ Addu(t5, t5, Operand(FixedArray::kHeaderSize)); |
4640 | 4640 |
4641 // 3. Arguments object. | 4641 // 3. Arguments object. |
4642 __ Addu(t5, t5, Operand(Heap::kArgumentsObjectSize)); | 4642 __ Addu(t5, t5, Operand(Heap::kArgumentsObjectSize)); |
4643 | 4643 |
4644 // Do the allocation of all three objects in one go. | 4644 // Do the allocation of all three objects in one go. |
4645 __ AllocateInNewSpace(t5, v0, a3, t0, &runtime, TAG_OBJECT); | 4645 __ AllocateInNewSpace(t5, v0, a3, t0, &runtime, TAG_OBJECT); |
4646 | 4646 |
4647 // v0 = address of new object(s) (tagged) | 4647 // v0 = address of new object(s) (tagged) |
4648 // a2 = argument count (tagged) | 4648 // a2 = argument count (tagged) |
4649 // Get the arguments boilerplate from the current (global) context into t0. | 4649 // Get the arguments boilerplate from the current native context into t0. |
4650 const int kNormalOffset = | 4650 const int kNormalOffset = |
4651 Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX); | 4651 Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX); |
4652 const int kAliasedOffset = | 4652 const int kAliasedOffset = |
4653 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX); | 4653 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX); |
4654 | 4654 |
4655 __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); | 4655 __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
4656 __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset)); | 4656 __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset)); |
4657 Label skip2_ne, skip2_eq; | 4657 Label skip2_ne, skip2_eq; |
4658 __ Branch(&skip2_ne, ne, a1, Operand(zero_reg)); | 4658 __ Branch(&skip2_ne, ne, a1, Operand(zero_reg)); |
4659 __ lw(t0, MemOperand(t0, kNormalOffset)); | 4659 __ lw(t0, MemOperand(t0, kNormalOffset)); |
4660 __ bind(&skip2_ne); | 4660 __ bind(&skip2_ne); |
4661 | 4661 |
4662 __ Branch(&skip2_eq, eq, a1, Operand(zero_reg)); | 4662 __ Branch(&skip2_eq, eq, a1, Operand(zero_reg)); |
4663 __ lw(t0, MemOperand(t0, kAliasedOffset)); | 4663 __ lw(t0, MemOperand(t0, kAliasedOffset)); |
4664 __ bind(&skip2_eq); | 4664 __ bind(&skip2_eq); |
4665 | 4665 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4834 | 4834 |
4835 // Do the allocation of both objects in one go. | 4835 // Do the allocation of both objects in one go. |
4836 __ AllocateInNewSpace(a1, | 4836 __ AllocateInNewSpace(a1, |
4837 v0, | 4837 v0, |
4838 a2, | 4838 a2, |
4839 a3, | 4839 a3, |
4840 &runtime, | 4840 &runtime, |
4841 static_cast<AllocationFlags>(TAG_OBJECT | | 4841 static_cast<AllocationFlags>(TAG_OBJECT | |
4842 SIZE_IN_WORDS)); | 4842 SIZE_IN_WORDS)); |
4843 | 4843 |
4844 // Get the arguments boilerplate from the current (global) context. | 4844 // Get the arguments boilerplate from the current native context. |
4845 __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); | 4845 __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
4846 __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset)); | 4846 __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset)); |
4847 __ lw(t0, MemOperand(t0, Context::SlotOffset( | 4847 __ lw(t0, MemOperand(t0, Context::SlotOffset( |
4848 Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX))); | 4848 Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX))); |
4849 | 4849 |
4850 // Copy the JS object part. | 4850 // Copy the JS object part. |
4851 __ CopyFields(v0, t0, a3.bit(), JSObject::kHeaderSize / kPointerSize); | 4851 __ CopyFields(v0, t0, a3.bit(), JSObject::kHeaderSize / kPointerSize); |
4852 | 4852 |
4853 // Get the length (smi tagged) and set that as an in-object property too. | 4853 // Get the length (smi tagged) and set that as an in-object property too. |
4854 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 4854 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
4855 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); | 4855 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5370 &slowcase, | 5370 &slowcase, |
5371 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); | 5371 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); |
5372 // v0: Start of allocated area, object-tagged. | 5372 // v0: Start of allocated area, object-tagged. |
5373 // a1: Number of elements in array, as smi. | 5373 // a1: Number of elements in array, as smi. |
5374 // t1: Number of elements, untagged. | 5374 // t1: Number of elements, untagged. |
5375 | 5375 |
5376 // Set JSArray map to global.regexp_result_map(). | 5376 // Set JSArray map to global.regexp_result_map(). |
5377 // Set empty properties FixedArray. | 5377 // Set empty properties FixedArray. |
5378 // Set elements to point to FixedArray allocated right after the JSArray. | 5378 // Set elements to point to FixedArray allocated right after the JSArray. |
5379 // Interleave operations for better latency. | 5379 // Interleave operations for better latency. |
5380 __ lw(a2, ContextOperand(cp, Context::GLOBAL_INDEX)); | 5380 __ lw(a2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); |
5381 __ Addu(a3, v0, Operand(JSRegExpResult::kSize)); | 5381 __ Addu(a3, v0, Operand(JSRegExpResult::kSize)); |
5382 __ li(t0, Operand(masm->isolate()->factory()->empty_fixed_array())); | 5382 __ li(t0, Operand(masm->isolate()->factory()->empty_fixed_array())); |
5383 __ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset)); | 5383 __ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset)); |
5384 __ sw(a3, FieldMemOperand(v0, JSObject::kElementsOffset)); | 5384 __ sw(a3, FieldMemOperand(v0, JSObject::kElementsOffset)); |
5385 __ lw(a2, ContextOperand(a2, Context::REGEXP_RESULT_MAP_INDEX)); | 5385 __ lw(a2, ContextOperand(a2, Context::REGEXP_RESULT_MAP_INDEX)); |
5386 __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset)); | 5386 __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset)); |
5387 __ sw(a2, FieldMemOperand(v0, HeapObject::kMapOffset)); | 5387 __ sw(a2, FieldMemOperand(v0, HeapObject::kMapOffset)); |
5388 | 5388 |
5389 // Set input, index and length fields from arguments. | 5389 // Set input, index and length fields from arguments. |
5390 __ lw(a1, MemOperand(sp, kPointerSize * 0)); | 5390 __ lw(a1, MemOperand(sp, kPointerSize * 0)); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5482 // function stub. | 5482 // function stub. |
5483 if (ReceiverMightBeImplicit()) { | 5483 if (ReceiverMightBeImplicit()) { |
5484 Label call; | 5484 Label call; |
5485 // Get the receiver from the stack. | 5485 // Get the receiver from the stack. |
5486 // function, receiver [, arguments] | 5486 // function, receiver [, arguments] |
5487 __ lw(t0, MemOperand(sp, argc_ * kPointerSize)); | 5487 __ lw(t0, MemOperand(sp, argc_ * kPointerSize)); |
5488 // Call as function is indicated with the hole. | 5488 // Call as function is indicated with the hole. |
5489 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 5489 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
5490 __ Branch(&call, ne, t0, Operand(at)); | 5490 __ Branch(&call, ne, t0, Operand(at)); |
5491 // Patch the receiver on the stack with the global receiver object. | 5491 // Patch the receiver on the stack with the global receiver object. |
5492 __ lw(a3, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); | 5492 __ lw(a3, |
| 5493 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
5493 __ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset)); | 5494 __ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset)); |
5494 __ sw(a3, MemOperand(sp, argc_ * kPointerSize)); | 5495 __ sw(a3, MemOperand(sp, argc_ * kPointerSize)); |
5495 __ bind(&call); | 5496 __ bind(&call); |
5496 } | 5497 } |
5497 | 5498 |
5498 // Check that the function is really a JavaScript function. | 5499 // Check that the function is really a JavaScript function. |
5499 // a1: pushed function (to be verified) | 5500 // a1: pushed function (to be verified) |
5500 __ JumpIfSmi(a1, &non_function); | 5501 __ JumpIfSmi(a1, &non_function); |
5501 // Get the map of the function object. | 5502 // Get the map of the function object. |
5502 __ GetObjectType(a1, a3, a3); | 5503 __ GetObjectType(a1, a3, a3); |
(...skipping 2322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7825 __ Pop(ra, t1, a1); | 7826 __ Pop(ra, t1, a1); |
7826 __ Ret(); | 7827 __ Ret(); |
7827 } | 7828 } |
7828 | 7829 |
7829 | 7830 |
7830 #undef __ | 7831 #undef __ |
7831 | 7832 |
7832 } } // namespace v8::internal | 7833 } } // namespace v8::internal |
7833 | 7834 |
7834 #endif // V8_TARGET_ARCH_MIPS | 7835 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |