| 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 |