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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 // ----------------------------------- | 112 // ----------------------------------- |
113 Label generic_array_code, one_or_more_arguments, two_or_more_arguments; | 113 Label generic_array_code, one_or_more_arguments, two_or_more_arguments; |
114 | 114 |
115 // Get the InternalArray function. | 115 // Get the InternalArray function. |
116 GenerateLoadInternalArrayFunction(masm, r1); | 116 GenerateLoadInternalArrayFunction(masm, r1); |
117 | 117 |
118 if (FLAG_debug_code) { | 118 if (FLAG_debug_code) { |
119 // Initial map for the builtin InternalArray functions should be maps. | 119 // Initial map for the builtin InternalArray functions should be maps. |
120 __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); | 120 __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); |
121 __ SmiTst(r2); | 121 __ SmiTst(r2); |
122 __ Assert(ne, "Unexpected initial map for InternalArray function"); | 122 __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction); |
123 __ CompareObjectType(r2, r3, r4, MAP_TYPE); | 123 __ CompareObjectType(r2, r3, r4, MAP_TYPE); |
124 __ Assert(eq, "Unexpected initial map for InternalArray function"); | 124 __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction); |
125 } | 125 } |
126 | 126 |
127 // Run the native code for the InternalArray function called as a normal | 127 // Run the native code for the InternalArray function called as a normal |
128 // function. | 128 // function. |
129 // tail call a stub | 129 // tail call a stub |
130 InternalArrayConstructorStub stub(masm->isolate()); | 130 InternalArrayConstructorStub stub(masm->isolate()); |
131 __ TailCallStub(&stub); | 131 __ TailCallStub(&stub); |
132 } | 132 } |
133 | 133 |
134 | 134 |
135 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { | 135 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { |
136 // ----------- S t a t e ------------- | 136 // ----------- S t a t e ------------- |
137 // -- r0 : number of arguments | 137 // -- r0 : number of arguments |
138 // -- lr : return address | 138 // -- lr : return address |
139 // -- sp[...]: constructor arguments | 139 // -- sp[...]: constructor arguments |
140 // ----------------------------------- | 140 // ----------------------------------- |
141 Label generic_array_code, one_or_more_arguments, two_or_more_arguments; | 141 Label generic_array_code, one_or_more_arguments, two_or_more_arguments; |
142 | 142 |
143 // Get the Array function. | 143 // Get the Array function. |
144 GenerateLoadArrayFunction(masm, r1); | 144 GenerateLoadArrayFunction(masm, r1); |
145 | 145 |
146 if (FLAG_debug_code) { | 146 if (FLAG_debug_code) { |
147 // Initial map for the builtin Array functions should be maps. | 147 // Initial map for the builtin Array functions should be maps. |
148 __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); | 148 __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); |
149 __ SmiTst(r2); | 149 __ SmiTst(r2); |
150 __ Assert(ne, "Unexpected initial map for Array function"); | 150 __ Assert(ne, kUnexpectedInitialMapForArrayFunction); |
151 __ CompareObjectType(r2, r3, r4, MAP_TYPE); | 151 __ CompareObjectType(r2, r3, r4, MAP_TYPE); |
152 __ Assert(eq, "Unexpected initial map for Array function"); | 152 __ Assert(eq, kUnexpectedInitialMapForArrayFunction); |
153 } | 153 } |
154 | 154 |
155 // Run the native code for the Array function called as a normal function. | 155 // Run the native code for the Array function called as a normal function. |
156 // tail call a stub | 156 // tail call a stub |
157 Handle<Object> undefined_sentinel( | 157 Handle<Object> undefined_sentinel( |
158 masm->isolate()->heap()->undefined_value(), | 158 masm->isolate()->heap()->undefined_value(), |
159 masm->isolate()); | 159 masm->isolate()); |
160 __ mov(r2, Operand(undefined_sentinel)); | 160 __ mov(r2, Operand(undefined_sentinel)); |
161 ArrayConstructorStub stub(masm->isolate()); | 161 ArrayConstructorStub stub(masm->isolate()); |
162 __ TailCallStub(&stub); | 162 __ TailCallStub(&stub); |
163 } | 163 } |
164 | 164 |
165 | 165 |
166 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { | 166 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { |
167 // ----------- S t a t e ------------- | 167 // ----------- S t a t e ------------- |
168 // -- r0 : number of arguments | 168 // -- r0 : number of arguments |
169 // -- r1 : constructor function | 169 // -- r1 : constructor function |
170 // -- lr : return address | 170 // -- lr : return address |
171 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) | 171 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) |
172 // -- sp[argc * 4] : receiver | 172 // -- sp[argc * 4] : receiver |
173 // ----------------------------------- | 173 // ----------------------------------- |
174 Counters* counters = masm->isolate()->counters(); | 174 Counters* counters = masm->isolate()->counters(); |
175 __ IncrementCounter(counters->string_ctor_calls(), 1, r2, r3); | 175 __ IncrementCounter(counters->string_ctor_calls(), 1, r2, r3); |
176 | 176 |
177 Register function = r1; | 177 Register function = r1; |
178 if (FLAG_debug_code) { | 178 if (FLAG_debug_code) { |
179 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, r2); | 179 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, r2); |
180 __ cmp(function, Operand(r2)); | 180 __ cmp(function, Operand(r2)); |
181 __ Assert(eq, "Unexpected String function"); | 181 __ Assert(eq, kUnexpectedStringFunction); |
182 } | 182 } |
183 | 183 |
184 // Load the first arguments in r0 and get rid of the rest. | 184 // Load the first arguments in r0 and get rid of the rest. |
185 Label no_arguments; | 185 Label no_arguments; |
186 __ cmp(r0, Operand::Zero()); | 186 __ cmp(r0, Operand::Zero()); |
187 __ b(eq, &no_arguments); | 187 __ b(eq, &no_arguments); |
188 // First args = sp[(argc - 1) * 4]. | 188 // First args = sp[(argc - 1) * 4]. |
189 __ sub(r0, r0, Operand(1)); | 189 __ sub(r0, r0, Operand(1)); |
190 __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); | 190 __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); |
191 // sp now point to args[0], drop args[0] + receiver. | 191 // sp now point to args[0], drop args[0] + receiver. |
(...skipping 25 matching lines...) Expand all Loading... |
217 r4, // Scratch. | 217 r4, // Scratch. |
218 &gc_required, | 218 &gc_required, |
219 TAG_OBJECT); | 219 TAG_OBJECT); |
220 | 220 |
221 // Initialising the String Object. | 221 // Initialising the String Object. |
222 Register map = r3; | 222 Register map = r3; |
223 __ LoadGlobalFunctionInitialMap(function, map, r4); | 223 __ LoadGlobalFunctionInitialMap(function, map, r4); |
224 if (FLAG_debug_code) { | 224 if (FLAG_debug_code) { |
225 __ ldrb(r4, FieldMemOperand(map, Map::kInstanceSizeOffset)); | 225 __ ldrb(r4, FieldMemOperand(map, Map::kInstanceSizeOffset)); |
226 __ cmp(r4, Operand(JSValue::kSize >> kPointerSizeLog2)); | 226 __ cmp(r4, Operand(JSValue::kSize >> kPointerSizeLog2)); |
227 __ Assert(eq, "Unexpected string wrapper instance size"); | 227 __ Assert(eq, kUnexpectedStringWrapperInstanceSize); |
228 __ ldrb(r4, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset)); | 228 __ ldrb(r4, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset)); |
229 __ cmp(r4, Operand::Zero()); | 229 __ cmp(r4, Operand::Zero()); |
230 __ Assert(eq, "Unexpected unused properties of string wrapper"); | 230 __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper); |
231 } | 231 } |
232 __ str(map, FieldMemOperand(r0, HeapObject::kMapOffset)); | 232 __ str(map, FieldMemOperand(r0, HeapObject::kMapOffset)); |
233 | 233 |
234 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex); | 234 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex); |
235 __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset)); | 235 __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset)); |
236 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset)); | 236 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset)); |
237 | 237 |
238 __ str(argument, FieldMemOperand(r0, JSValue::kValueOffset)); | 238 __ str(argument, FieldMemOperand(r0, JSValue::kValueOffset)); |
239 | 239 |
240 // Ensure the object is fully initialized. | 240 // Ensure the object is fully initialized. |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize); | 464 ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize); |
465 __ LoadRoot(r7, Heap::kUndefinedValueRootIndex); | 465 __ LoadRoot(r7, Heap::kUndefinedValueRootIndex); |
466 if (count_constructions) { | 466 if (count_constructions) { |
467 __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset)); | 467 __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset)); |
468 __ Ubfx(r0, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, | 468 __ Ubfx(r0, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, |
469 kBitsPerByte); | 469 kBitsPerByte); |
470 __ add(r0, r5, Operand(r0, LSL, kPointerSizeLog2)); | 470 __ add(r0, r5, Operand(r0, LSL, kPointerSizeLog2)); |
471 // r0: offset of first field after pre-allocated fields | 471 // r0: offset of first field after pre-allocated fields |
472 if (FLAG_debug_code) { | 472 if (FLAG_debug_code) { |
473 __ cmp(r0, r6); | 473 __ cmp(r0, r6); |
474 __ Assert(le, "Unexpected number of pre-allocated property fields."); | 474 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); |
475 } | 475 } |
476 __ InitializeFieldsWithFiller(r5, r0, r7); | 476 __ InitializeFieldsWithFiller(r5, r0, r7); |
477 // To allow for truncation. | 477 // To allow for truncation. |
478 __ LoadRoot(r7, Heap::kOnePointerFillerMapRootIndex); | 478 __ LoadRoot(r7, Heap::kOnePointerFillerMapRootIndex); |
479 } | 479 } |
480 __ InitializeFieldsWithFiller(r5, r6, r7); | 480 __ InitializeFieldsWithFiller(r5, r6, r7); |
481 | 481 |
482 // Add the object tag to make the JSObject real, so that we can continue | 482 // Add the object tag to make the JSObject real, so that we can continue |
483 // and jump into the continuation code at any time from now on. Any | 483 // and jump into the continuation code at any time from now on. Any |
484 // failures need to undo the allocation, so that the heap is in a | 484 // failures need to undo the allocation, so that the heap is in a |
(...skipping 11 matching lines...) Expand all Loading... |
496 __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset)); | 496 __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset)); |
497 __ Ubfx(r6, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, | 497 __ Ubfx(r6, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, |
498 kBitsPerByte); | 498 kBitsPerByte); |
499 __ add(r3, r3, Operand(r6)); | 499 __ add(r3, r3, Operand(r6)); |
500 __ Ubfx(r6, r0, Map::kInObjectPropertiesByte * kBitsPerByte, | 500 __ Ubfx(r6, r0, Map::kInObjectPropertiesByte * kBitsPerByte, |
501 kBitsPerByte); | 501 kBitsPerByte); |
502 __ sub(r3, r3, Operand(r6), SetCC); | 502 __ sub(r3, r3, Operand(r6), SetCC); |
503 | 503 |
504 // Done if no extra properties are to be allocated. | 504 // Done if no extra properties are to be allocated. |
505 __ b(eq, &allocated); | 505 __ b(eq, &allocated); |
506 __ Assert(pl, "Property allocation count failed."); | 506 __ Assert(pl, kPropertyAllocationCountFailed); |
507 | 507 |
508 // Scale the number of elements by pointer size and add the header for | 508 // Scale the number of elements by pointer size and add the header for |
509 // FixedArrays to the start of the next object calculation from above. | 509 // FixedArrays to the start of the next object calculation from above. |
510 // r1: constructor | 510 // r1: constructor |
511 // r3: number of elements in properties array | 511 // r3: number of elements in properties array |
512 // r4: JSObject | 512 // r4: JSObject |
513 // r5: start of next object | 513 // r5: start of next object |
514 __ add(r0, r3, Operand(FixedArray::kHeaderSize / kPointerSize)); | 514 __ add(r0, r3, Operand(FixedArray::kHeaderSize / kPointerSize)); |
515 __ Allocate( | 515 __ Allocate( |
516 r0, | 516 r0, |
(...skipping 23 matching lines...) Expand all Loading... |
540 // r4: JSObject | 540 // r4: JSObject |
541 // r5: FixedArray (not tagged) | 541 // r5: FixedArray (not tagged) |
542 __ add(r6, r2, Operand(r3, LSL, kPointerSizeLog2)); // End of object. | 542 __ add(r6, r2, Operand(r3, LSL, kPointerSizeLog2)); // End of object. |
543 ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize); | 543 ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize); |
544 { Label loop, entry; | 544 { Label loop, entry; |
545 if (count_constructions) { | 545 if (count_constructions) { |
546 __ LoadRoot(r7, Heap::kUndefinedValueRootIndex); | 546 __ LoadRoot(r7, Heap::kUndefinedValueRootIndex); |
547 } else if (FLAG_debug_code) { | 547 } else if (FLAG_debug_code) { |
548 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); | 548 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); |
549 __ cmp(r7, r8); | 549 __ cmp(r7, r8); |
550 __ Assert(eq, "Undefined value not loaded."); | 550 __ Assert(eq, kUndefinedValueNotLoaded); |
551 } | 551 } |
552 __ b(&entry); | 552 __ b(&entry); |
553 __ bind(&loop); | 553 __ bind(&loop); |
554 __ str(r7, MemOperand(r2, kPointerSize, PostIndex)); | 554 __ str(r7, MemOperand(r2, kPointerSize, PostIndex)); |
555 __ bind(&entry); | 555 __ bind(&entry); |
556 __ cmp(r2, r6); | 556 __ cmp(r2, r6); |
557 __ b(lt, &loop); | 557 __ b(lt, &loop); |
558 } | 558 } |
559 | 559 |
560 // Store the initialized FixedArray into the properties field of | 560 // Store the initialized FixedArray into the properties field of |
(...skipping 914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1475 __ bind(&dont_adapt_arguments); | 1475 __ bind(&dont_adapt_arguments); |
1476 __ Jump(r3); | 1476 __ Jump(r3); |
1477 } | 1477 } |
1478 | 1478 |
1479 | 1479 |
1480 #undef __ | 1480 #undef __ |
1481 | 1481 |
1482 } } // namespace v8::internal | 1482 } } // namespace v8::internal |
1483 | 1483 |
1484 #endif // V8_TARGET_ARCH_ARM | 1484 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |