OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 } | 296 } |
297 | 297 |
298 | 298 |
299 // Input parameters: | 299 // Input parameters: |
300 // R4: arguments descriptor array. | 300 // R4: arguments descriptor array. |
301 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 301 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
302 // Create a stub frame as we are pushing some objects on the stack before | 302 // Create a stub frame as we are pushing some objects on the stack before |
303 // calling into the runtime. | 303 // calling into the runtime. |
304 __ EnterStubFrame(); | 304 __ EnterStubFrame(); |
305 // Setup space on stack for return value and preserve arguments descriptor. | 305 // Setup space on stack for return value and preserve arguments descriptor. |
306 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 306 __ LoadObject(R0, Object::null_object()); |
307 __ PushList((1 << R0) | (1 << R4)); | 307 __ PushList((1 << R0) | (1 << R4)); |
308 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); | 308 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
309 // Get Code object result and restore arguments descriptor array. | 309 // Get Code object result and restore arguments descriptor array. |
310 __ PopList((1 << R0) | (1 << R4)); | 310 __ PopList((1 << R0) | (1 << R4)); |
311 // Remove the stub frame. | 311 // Remove the stub frame. |
312 __ LeaveStubFrame(); | 312 __ LeaveStubFrame(); |
313 // Jump to the dart function. | 313 // Jump to the dart function. |
314 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); | 314 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); |
315 __ bx(R0); | 315 __ bx(R0); |
316 } | 316 } |
317 | 317 |
318 | 318 |
319 // Called from a static call only when an invalid code has been entered | 319 // Called from a static call only when an invalid code has been entered |
320 // (invalid because its function was optimized or deoptimized). | 320 // (invalid because its function was optimized or deoptimized). |
321 // R4: arguments descriptor array. | 321 // R4: arguments descriptor array. |
322 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 322 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
323 // Create a stub frame as we are pushing some objects on the stack before | 323 // Create a stub frame as we are pushing some objects on the stack before |
324 // calling into the runtime. | 324 // calling into the runtime. |
325 __ EnterStubFrame(); | 325 __ EnterStubFrame(); |
326 // Setup space on stack for return value and preserve arguments descriptor. | 326 // Setup space on stack for return value and preserve arguments descriptor. |
327 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 327 __ LoadObject(R0, Object::null_object()); |
328 __ PushList((1 << R0) | (1 << R4)); | 328 __ PushList((1 << R0) | (1 << R4)); |
329 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); | 329 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
330 // Get Code object result and restore arguments descriptor array. | 330 // Get Code object result and restore arguments descriptor array. |
331 __ PopList((1 << R0) | (1 << R4)); | 331 __ PopList((1 << R0) | (1 << R4)); |
332 // Remove the stub frame. | 332 // Remove the stub frame. |
333 __ LeaveStubFrame(); | 333 __ LeaveStubFrame(); |
334 // Jump to the dart function. | 334 // Jump to the dart function. |
335 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); | 335 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); |
336 __ bx(R0); | 336 __ bx(R0); |
337 } | 337 } |
338 | 338 |
339 | 339 |
340 // Called from object allocate instruction when the allocation stub has been | 340 // Called from object allocate instruction when the allocation stub has been |
341 // disabled. | 341 // disabled. |
342 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { | 342 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { |
343 __ EnterStubFrame(); | 343 __ EnterStubFrame(); |
344 // Setup space on stack for return value. | 344 // Setup space on stack for return value. |
345 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 345 __ LoadObject(R0, Object::null_object()); |
346 __ Push(R0); | 346 __ Push(R0); |
347 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 347 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
348 // Get Code object result. | 348 // Get Code object result. |
349 __ Pop(R0); | 349 __ Pop(R0); |
350 // Remove the stub frame. | 350 // Remove the stub frame. |
351 __ LeaveStubFrame(); | 351 __ LeaveStubFrame(); |
352 // Jump to the dart function. | 352 // Jump to the dart function. |
353 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); | 353 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); |
354 __ bx(R0); | 354 __ bx(R0); |
355 } | 355 } |
356 | 356 |
357 | 357 |
358 // Input parameters: | 358 // Input parameters: |
359 // R2: smi-tagged argument count, may be zero. | 359 // R2: smi-tagged argument count, may be zero. |
360 // FP[kParamEndSlotFromFp + 1]: last argument. | 360 // FP[kParamEndSlotFromFp + 1]: last argument. |
361 static void PushArgumentsArray(Assembler* assembler) { | 361 static void PushArgumentsArray(Assembler* assembler) { |
362 // Allocate array to store arguments of caller. | 362 // Allocate array to store arguments of caller. |
363 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); | 363 __ LoadObject(R1, Object::null_object()); |
364 // R1: null element type for raw Array. | 364 // R1: null element type for raw Array. |
365 // R2: smi-tagged argument count, may be zero. | 365 // R2: smi-tagged argument count, may be zero. |
366 __ BranchLink(*StubCode::AllocateArray_entry()); | 366 __ BranchLink(*StubCode::AllocateArray_entry()); |
367 // R0: newly allocated array. | 367 // R0: newly allocated array. |
368 // R2: smi-tagged argument count, may be zero (was preserved by the stub). | 368 // R2: smi-tagged argument count, may be zero (was preserved by the stub). |
369 __ Push(R0); // Array is in R0 and on top of stack. | 369 __ Push(R0); // Array is in R0 and on top of stack. |
370 __ AddImmediate(R1, FP, kParamEndSlotFromFp * kWordSize); | 370 __ AddImmediate(R1, FP, kParamEndSlotFromFp * kWordSize); |
371 __ AddImmediate(R3, R0, Array::data_offset() - kHeapObjectTag); | 371 __ AddImmediate(R3, R0, Array::data_offset() - kHeapObjectTag); |
372 // Copy arguments from stack to array (starting at the end). | 372 // Copy arguments from stack to array (starting at the end). |
373 // R1: address just beyond last argument on stack. | 373 // R1: address just beyond last argument on stack. |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 __ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi. | 556 __ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi. |
557 __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize)); | 557 __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize)); |
558 | 558 |
559 // Preserve IC data and arguments descriptor. | 559 // Preserve IC data and arguments descriptor. |
560 __ PushList((1 << R4) | (1 << R5)); | 560 __ PushList((1 << R4) | (1 << R5)); |
561 | 561 |
562 // Push space for the return value. | 562 // Push space for the return value. |
563 // Push the receiver. | 563 // Push the receiver. |
564 // Push IC data object. | 564 // Push IC data object. |
565 // Push arguments descriptor array. | 565 // Push arguments descriptor array. |
566 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 566 __ LoadObject(IP, Object::null_object()); |
567 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); | 567 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); |
568 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 568 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
569 // Remove arguments. | 569 // Remove arguments. |
570 __ Drop(3); | 570 __ Drop(3); |
571 __ Pop(R0); // Get result into R0 (target function). | 571 __ Pop(R0); // Get result into R0 (target function). |
572 | 572 |
573 // Restore IC data and arguments descriptor. | 573 // Restore IC data and arguments descriptor. |
574 __ PopList((1 << R4) | (1 << R5)); | 574 __ PopList((1 << R4) | (1 << R5)); |
575 | 575 |
576 __ LeaveStubFrame(); | 576 __ LeaveStubFrame(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 | 681 |
682 // Initialize all array elements to raw_null. | 682 // Initialize all array elements to raw_null. |
683 // R0: new object start as a tagged pointer. | 683 // R0: new object start as a tagged pointer. |
684 // R3: allocation stats address. | 684 // R3: allocation stats address. |
685 // R4, R5: null | 685 // R4, R5: null |
686 // R6: iterator which initially points to the start of the variable | 686 // R6: iterator which initially points to the start of the variable |
687 // data area to be initialized. | 687 // data area to be initialized. |
688 // R7: new object end address. | 688 // R7: new object end address. |
689 // R9: allocation size. | 689 // R9: allocation size. |
690 | 690 |
691 __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null())); | 691 __ LoadObject(R4, Object::null_object()); |
692 __ mov(R5, Operand(R4)); | 692 __ mov(R5, Operand(R4)); |
693 __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag); | 693 __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag); |
694 __ InitializeFieldsNoBarrier(R0, R6, R7, R4, R5); | 694 __ InitializeFieldsNoBarrier(R0, R6, R7, R4, R5); |
695 __ IncrementAllocationStatsWithSize(R3, R9, space); | 695 __ IncrementAllocationStatsWithSize(R3, R9, space); |
696 __ Ret(); // Returns the newly allocated object in R0. | 696 __ Ret(); // Returns the newly allocated object in R0. |
697 // Unable to allocate the array using the fast inline code, just call | 697 // Unable to allocate the array using the fast inline code, just call |
698 // into the runtime. | 698 // into the runtime. |
699 __ Bind(&slow_case); | 699 __ Bind(&slow_case); |
700 | 700 |
701 // Create a stub frame as we are pushing some objects on the stack before | 701 // Create a stub frame as we are pushing some objects on the stack before |
702 // calling into the runtime. | 702 // calling into the runtime. |
703 __ EnterStubFrame(); | 703 __ EnterStubFrame(); |
704 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 704 __ LoadObject(IP, Object::null_object()); |
705 // Setup space on stack for return value. | 705 // Setup space on stack for return value. |
706 // Push array length as Smi and element type. | 706 // Push array length as Smi and element type. |
707 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); | 707 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); |
708 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 708 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
709 // Pop arguments; result is popped in IP. | 709 // Pop arguments; result is popped in IP. |
710 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. | 710 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. |
711 __ mov(R0, Operand(IP)); | 711 __ mov(R0, Operand(IP)); |
712 __ LeaveStubFrame(); | 712 __ LeaveStubFrame(); |
713 __ Ret(); | 713 __ Ret(); |
714 } | 714 } |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 // R3: next object start. | 907 // R3: next object start. |
908 // R6: allocation stats address. | 908 // R6: allocation stats address. |
909 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); | 909 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); |
910 | 910 |
911 // Setup the parent field. | 911 // Setup the parent field. |
912 // R0: new object. | 912 // R0: new object. |
913 // R1: number of context variables. | 913 // R1: number of context variables. |
914 // R2: object size. | 914 // R2: object size. |
915 // R3: next object start. | 915 // R3: next object start. |
916 // R6: allocation stats address. | 916 // R6: allocation stats address. |
917 __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null())); | 917 __ LoadObject(R4, Object::null_object()); |
918 __ InitializeFieldNoBarrier(R0, FieldAddress(R0, Context::parent_offset()), | 918 __ InitializeFieldNoBarrier(R0, FieldAddress(R0, Context::parent_offset()), |
919 R4); | 919 R4); |
920 | 920 |
921 // Initialize the context variables. | 921 // Initialize the context variables. |
922 // R0: new object. | 922 // R0: new object. |
923 // R1: number of context variables. | 923 // R1: number of context variables. |
924 // R2: object size. | 924 // R2: object size. |
925 // R3: next object start. | 925 // R3: next object start. |
926 // R4, R5: raw null. | 926 // R4, R5: raw null. |
927 // R6: allocation stats address. | 927 // R6: allocation stats address. |
928 Label loop; | 928 Label loop; |
929 __ AddImmediate(R7, R0, Context::variable_offset(0) - kHeapObjectTag); | 929 __ AddImmediate(R7, R0, Context::variable_offset(0) - kHeapObjectTag); |
930 __ InitializeFieldsNoBarrier(R0, R7, R3, R4, R5); | 930 __ InitializeFieldsNoBarrier(R0, R7, R3, R4, R5); |
931 __ IncrementAllocationStatsWithSize(R6, R2, space); | 931 __ IncrementAllocationStatsWithSize(R6, R2, space); |
932 | 932 |
933 // Done allocating and initializing the context. | 933 // Done allocating and initializing the context. |
934 // R0: new object. | 934 // R0: new object. |
935 __ Ret(); | 935 __ Ret(); |
936 | 936 |
937 __ Bind(&slow_case); | 937 __ Bind(&slow_case); |
938 } | 938 } |
939 // Create a stub frame as we are pushing some objects on the stack before | 939 // Create a stub frame as we are pushing some objects on the stack before |
940 // calling into the runtime. | 940 // calling into the runtime. |
941 __ EnterStubFrame(); | 941 __ EnterStubFrame(); |
942 // Setup space on stack for return value. | 942 // Setup space on stack for return value. |
943 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); | 943 __ LoadObject(R2, Object::null_object()); |
944 __ SmiTag(R1); | 944 __ SmiTag(R1); |
945 __ PushList((1 << R1) | (1 << R2)); | 945 __ PushList((1 << R1) | (1 << R2)); |
946 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. | 946 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. |
947 __ Drop(1); // Pop number of context variables argument. | 947 __ Drop(1); // Pop number of context variables argument. |
948 __ Pop(R0); // Pop the new context object. | 948 __ Pop(R0); // Pop the new context object. |
949 // R0: new object | 949 // R0: new object |
950 // Restore the frame pointer. | 950 // Restore the frame pointer. |
951 __ LeaveStubFrame(); | 951 __ LeaveStubFrame(); |
952 __ Ret(); | 952 __ Ret(); |
953 } | 953 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 // Set the tags. | 1079 // Set the tags. |
1080 uword tags = 0; | 1080 uword tags = 0; |
1081 tags = RawObject::SizeTag::update(instance_size, tags); | 1081 tags = RawObject::SizeTag::update(instance_size, tags); |
1082 ASSERT(cls.id() != kIllegalCid); | 1082 ASSERT(cls.id() != kIllegalCid); |
1083 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1083 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
1084 __ LoadImmediate(R2, tags); | 1084 __ LoadImmediate(R2, tags); |
1085 __ str(R2, Address(R0, Instance::tags_offset())); | 1085 __ str(R2, Address(R0, Instance::tags_offset())); |
1086 __ add(R0, R0, Operand(kHeapObjectTag)); | 1086 __ add(R0, R0, Operand(kHeapObjectTag)); |
1087 | 1087 |
1088 // Initialize the remaining words of the object. | 1088 // Initialize the remaining words of the object. |
1089 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); | 1089 __ LoadObject(R2, Object::null_object()); |
1090 | 1090 |
1091 // R2: raw null. | 1091 // R2: raw null. |
1092 // R0: new object (tagged). | 1092 // R0: new object (tagged). |
1093 // R1: next object start. | 1093 // R1: next object start. |
1094 // R5: allocation stats table. | 1094 // R5: allocation stats table. |
1095 // First try inlining the initialization without a loop. | 1095 // First try inlining the initialization without a loop. |
1096 if (instance_size < (kInlineInstanceSize * kWordSize)) { | 1096 if (instance_size < (kInlineInstanceSize * kWordSize)) { |
1097 // Small objects are initialized using a consecutive set of writes. | 1097 // Small objects are initialized using a consecutive set of writes. |
1098 intptr_t begin_offset = Instance::NextFieldOffset() - kHeapObjectTag; | 1098 intptr_t begin_offset = Instance::NextFieldOffset() - kHeapObjectTag; |
1099 intptr_t end_offset = instance_size - kHeapObjectTag; | 1099 intptr_t end_offset = instance_size - kHeapObjectTag; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 } | 1137 } |
1138 if (is_cls_parameterized) { | 1138 if (is_cls_parameterized) { |
1139 // Load the type arguments. | 1139 // Load the type arguments. |
1140 __ ldr(R4, Address(SP, 0)); | 1140 __ ldr(R4, Address(SP, 0)); |
1141 } | 1141 } |
1142 // If is_cls_parameterized: | 1142 // If is_cls_parameterized: |
1143 // R4: new object type arguments. | 1143 // R4: new object type arguments. |
1144 // Create a stub frame as we are pushing some objects on the stack before | 1144 // Create a stub frame as we are pushing some objects on the stack before |
1145 // calling into the runtime. | 1145 // calling into the runtime. |
1146 __ EnterStubFrame(); // Uses pool pointer to pass cls to runtime. | 1146 __ EnterStubFrame(); // Uses pool pointer to pass cls to runtime. |
1147 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); | 1147 __ LoadObject(R2, Object::null_object()); |
1148 __ Push(R2); // Setup space on stack for return value. | 1148 __ Push(R2); // Setup space on stack for return value. |
1149 __ PushObject(cls); // Push class of object to be allocated. | 1149 __ PushObject(cls); // Push class of object to be allocated. |
1150 if (is_cls_parameterized) { | 1150 if (is_cls_parameterized) { |
1151 // Push type arguments. | 1151 // Push type arguments. |
1152 __ Push(R4); | 1152 __ Push(R4); |
1153 } else { | 1153 } else { |
1154 // Push null type arguments. | 1154 // Push null type arguments. |
1155 __ Push(R2); | 1155 __ Push(R2); |
1156 } | 1156 } |
1157 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. | 1157 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. |
(...skipping 19 matching lines...) Expand all Loading... |
1177 __ EnterStubFrame(); | 1177 __ EnterStubFrame(); |
1178 | 1178 |
1179 // Load the receiver. | 1179 // Load the receiver. |
1180 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 1180 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
1181 __ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi. | 1181 __ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi. |
1182 __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize)); | 1182 __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize)); |
1183 | 1183 |
1184 // Push space for the return value. | 1184 // Push space for the return value. |
1185 // Push the receiver. | 1185 // Push the receiver. |
1186 // Push arguments descriptor array. | 1186 // Push arguments descriptor array. |
1187 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 1187 __ LoadObject(IP, Object::null_object()); |
1188 __ PushList((1 << R4) | (1 << R6) | (1 << IP)); | 1188 __ PushList((1 << R4) | (1 << R6) | (1 << IP)); |
1189 | 1189 |
1190 // R2: Smi-tagged arguments array length. | 1190 // R2: Smi-tagged arguments array length. |
1191 PushArgumentsArray(assembler); | 1191 PushArgumentsArray(assembler); |
1192 | 1192 |
1193 const intptr_t kNumArgs = 3; | 1193 const intptr_t kNumArgs = 3; |
1194 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); | 1194 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); |
1195 // noSuchMethod on closures always throws an error, so it will never return. | 1195 // noSuchMethod on closures always throws an error, so it will never return. |
1196 __ bkpt(0); | 1196 __ bkpt(0); |
1197 } | 1197 } |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1417 __ b(&loop, NE); | 1417 __ b(&loop, NE); |
1418 | 1418 |
1419 __ Comment("IC miss"); | 1419 __ Comment("IC miss"); |
1420 // Compute address of arguments. | 1420 // Compute address of arguments. |
1421 // R7: argument_count - 1 (smi). | 1421 // R7: argument_count - 1 (smi). |
1422 __ add(R7, SP, Operand(R7, LSL, 1)); // R7 is Smi. | 1422 __ add(R7, SP, Operand(R7, LSL, 1)); // R7 is Smi. |
1423 // R7: address of receiver. | 1423 // R7: address of receiver. |
1424 // Create a stub frame as we are pushing some objects on the stack before | 1424 // Create a stub frame as we are pushing some objects on the stack before |
1425 // calling into the runtime. | 1425 // calling into the runtime. |
1426 __ EnterStubFrame(); | 1426 __ EnterStubFrame(); |
1427 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1427 __ LoadObject(R0, Object::null_object()); |
1428 // Preserve IC data object and arguments descriptor array and | 1428 // Preserve IC data object and arguments descriptor array and |
1429 // setup space on stack for result (target code object). | 1429 // setup space on stack for result (target code object). |
1430 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); | 1430 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); |
1431 // Push call arguments. | 1431 // Push call arguments. |
1432 for (intptr_t i = 0; i < num_args; i++) { | 1432 for (intptr_t i = 0; i < num_args; i++) { |
1433 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize); | 1433 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize); |
1434 __ Push(IP); | 1434 __ Push(IP); |
1435 } | 1435 } |
1436 // Pass IC data object. | 1436 // Pass IC data object. |
1437 __ Push(R5); | 1437 __ Push(R5); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1692 __ LeaveStubFrame(); | 1692 __ LeaveStubFrame(); |
1693 | 1693 |
1694 __ ldr(R2, FieldAddress(R0, Function::entry_point_offset())); | 1694 __ ldr(R2, FieldAddress(R0, Function::entry_point_offset())); |
1695 __ bx(R2); | 1695 __ bx(R2); |
1696 } | 1696 } |
1697 | 1697 |
1698 | 1698 |
1699 // R5: Contains an ICData. | 1699 // R5: Contains an ICData. |
1700 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { | 1700 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { |
1701 __ EnterStubFrame(); | 1701 __ EnterStubFrame(); |
1702 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1702 __ LoadObject(R0, Object::null_object()); |
1703 // Preserve arguments descriptor and make room for result. | 1703 // Preserve arguments descriptor and make room for result. |
1704 __ PushList((1 << R0) | (1 << R5)); | 1704 __ PushList((1 << R0) | (1 << R5)); |
1705 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1705 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1706 __ PopList((1 << R0) | (1 << R5)); | 1706 __ PopList((1 << R0) | (1 << R5)); |
1707 __ LeaveStubFrame(); | 1707 __ LeaveStubFrame(); |
1708 __ bx(R0); | 1708 __ bx(R0); |
1709 } | 1709 } |
1710 | 1710 |
1711 | 1711 |
1712 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { | 1712 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { |
1713 __ EnterStubFrame(); | 1713 __ EnterStubFrame(); |
1714 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1714 __ LoadObject(R0, Object::null_object()); |
1715 // Make room for result. | 1715 // Make room for result. |
1716 __ PushList((1 << R0)); | 1716 __ PushList((1 << R0)); |
1717 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1717 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1718 __ PopList((1 << R0)); | 1718 __ PopList((1 << R0)); |
1719 __ LeaveStubFrame(); | 1719 __ LeaveStubFrame(); |
1720 __ bx(R0); | 1720 __ bx(R0); |
1721 } | 1721 } |
1722 | 1722 |
1723 | 1723 |
1724 // Called only from unoptimized code. All relevant registers have been saved. | 1724 // Called only from unoptimized code. All relevant registers have been saved. |
(...skipping 22 matching lines...) Expand all Loading... |
1747 // R1: instantiator type arguments or NULL. | 1747 // R1: instantiator type arguments or NULL. |
1748 // R2: cache array. | 1748 // R2: cache array. |
1749 // Result in R1: null -> not found, otherwise result (true or false). | 1749 // Result in R1: null -> not found, otherwise result (true or false). |
1750 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { | 1750 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { |
1751 ASSERT((1 <= n) && (n <= 3)); | 1751 ASSERT((1 <= n) && (n <= 3)); |
1752 if (n > 1) { | 1752 if (n > 1) { |
1753 // Get instance type arguments. | 1753 // Get instance type arguments. |
1754 __ LoadClass(R3, R0, R4); | 1754 __ LoadClass(R3, R0, R4); |
1755 // Compute instance type arguments into R4. | 1755 // Compute instance type arguments into R4. |
1756 Label has_no_type_arguments; | 1756 Label has_no_type_arguments; |
1757 __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null())); | 1757 __ LoadObject(R4, Object::null_object()); |
1758 __ ldr(R5, FieldAddress(R3, | 1758 __ ldr(R5, FieldAddress(R3, |
1759 Class::type_arguments_field_offset_in_words_offset())); | 1759 Class::type_arguments_field_offset_in_words_offset())); |
1760 __ CompareImmediate(R5, Class::kNoTypeArguments); | 1760 __ CompareImmediate(R5, Class::kNoTypeArguments); |
1761 __ b(&has_no_type_arguments, EQ); | 1761 __ b(&has_no_type_arguments, EQ); |
1762 __ add(R5, R0, Operand(R5, LSL, 2)); | 1762 __ add(R5, R0, Operand(R5, LSL, 2)); |
1763 __ ldr(R4, FieldAddress(R5, 0)); | 1763 __ ldr(R4, FieldAddress(R5, 0)); |
1764 __ Bind(&has_no_type_arguments); | 1764 __ Bind(&has_no_type_arguments); |
1765 } | 1765 } |
1766 __ LoadClassId(R3, R0); | 1766 __ LoadClassId(R3, R0); |
1767 // R0: instance. | 1767 // R0: instance. |
1768 // R1: instantiator type arguments or NULL. | 1768 // R1: instantiator type arguments or NULL. |
1769 // R2: SubtypeTestCache. | 1769 // R2: SubtypeTestCache. |
1770 // R3: instance class id. | 1770 // R3: instance class id. |
1771 // R4: instance type arguments (null if none), used only if n > 1. | 1771 // R4: instance type arguments (null if none), used only if n > 1. |
1772 __ ldr(R2, FieldAddress(R2, SubtypeTestCache::cache_offset())); | 1772 __ ldr(R2, FieldAddress(R2, SubtypeTestCache::cache_offset())); |
1773 __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag); | 1773 __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag); |
1774 | 1774 |
1775 Label loop, found, not_found, next_iteration; | 1775 Label loop, found, not_found, next_iteration; |
1776 // R2: entry start. | 1776 // R2: entry start. |
1777 // R3: instance class id. | 1777 // R3: instance class id. |
1778 // R4: instance type arguments. | 1778 // R4: instance type arguments. |
1779 __ SmiTag(R3); | 1779 __ SmiTag(R3); |
1780 __ Bind(&loop); | 1780 __ Bind(&loop); |
1781 __ ldr(R5, Address(R2, kWordSize * SubtypeTestCache::kInstanceClassId)); | 1781 __ ldr(R5, Address(R2, kWordSize * SubtypeTestCache::kInstanceClassId)); |
1782 __ CompareImmediate(R5, reinterpret_cast<intptr_t>(Object::null())); | 1782 __ CompareObject(R5, Object::null_object()); |
1783 __ b(¬_found, EQ); | 1783 __ b(¬_found, EQ); |
1784 __ cmp(R5, Operand(R3)); | 1784 __ cmp(R5, Operand(R3)); |
1785 if (n == 1) { | 1785 if (n == 1) { |
1786 __ b(&found, EQ); | 1786 __ b(&found, EQ); |
1787 } else { | 1787 } else { |
1788 __ b(&next_iteration, NE); | 1788 __ b(&next_iteration, NE); |
1789 __ ldr(R5, | 1789 __ ldr(R5, |
1790 Address(R2, kWordSize * SubtypeTestCache::kInstanceTypeArguments)); | 1790 Address(R2, kWordSize * SubtypeTestCache::kInstanceTypeArguments)); |
1791 __ cmp(R5, Operand(R4)); | 1791 __ cmp(R5, Operand(R4)); |
1792 if (n == 2) { | 1792 if (n == 2) { |
1793 __ b(&found, EQ); | 1793 __ b(&found, EQ); |
1794 } else { | 1794 } else { |
1795 __ b(&next_iteration, NE); | 1795 __ b(&next_iteration, NE); |
1796 __ ldr(R5, Address(R2, kWordSize * | 1796 __ ldr(R5, Address(R2, kWordSize * |
1797 SubtypeTestCache::kInstantiatorTypeArguments)); | 1797 SubtypeTestCache::kInstantiatorTypeArguments)); |
1798 __ cmp(R5, Operand(R1)); | 1798 __ cmp(R5, Operand(R1)); |
1799 __ b(&found, EQ); | 1799 __ b(&found, EQ); |
1800 } | 1800 } |
1801 } | 1801 } |
1802 __ Bind(&next_iteration); | 1802 __ Bind(&next_iteration); |
1803 __ AddImmediate(R2, kWordSize * SubtypeTestCache::kTestEntryLength); | 1803 __ AddImmediate(R2, kWordSize * SubtypeTestCache::kTestEntryLength); |
1804 __ b(&loop); | 1804 __ b(&loop); |
1805 // Fall through to not found. | 1805 // Fall through to not found. |
1806 __ Bind(¬_found); | 1806 __ Bind(¬_found); |
1807 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); | 1807 __ LoadObject(R1, Object::null_object()); |
1808 __ Ret(); | 1808 __ Ret(); |
1809 | 1809 |
1810 __ Bind(&found); | 1810 __ Bind(&found); |
1811 __ ldr(R1, Address(R2, kWordSize * SubtypeTestCache::kTestResult)); | 1811 __ ldr(R1, Address(R2, kWordSize * SubtypeTestCache::kTestResult)); |
1812 __ Ret(); | 1812 __ Ret(); |
1813 } | 1813 } |
1814 | 1814 |
1815 | 1815 |
1816 // Used to check class and type arguments. Arguments passed in registers: | 1816 // Used to check class and type arguments. Arguments passed in registers: |
1817 // LR: return address. | 1817 // LR: return address. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1882 __ bx(LR); // Jump to the exception handler code. | 1882 __ bx(LR); // Jump to the exception handler code. |
1883 } | 1883 } |
1884 | 1884 |
1885 | 1885 |
1886 // Calls to the runtime to optimize the given function. | 1886 // Calls to the runtime to optimize the given function. |
1887 // R6: function to be reoptimized. | 1887 // R6: function to be reoptimized. |
1888 // R4: argument descriptor (preserved). | 1888 // R4: argument descriptor (preserved). |
1889 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1889 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
1890 __ EnterStubFrame(); | 1890 __ EnterStubFrame(); |
1891 __ Push(R4); | 1891 __ Push(R4); |
1892 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 1892 __ LoadObject(IP, Object::null_object()); |
1893 __ Push(IP); // Setup space on stack for return value. | 1893 __ Push(IP); // Setup space on stack for return value. |
1894 __ Push(R6); | 1894 __ Push(R6); |
1895 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 1895 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
1896 __ Pop(R0); // Discard argument. | 1896 __ Pop(R0); // Discard argument. |
1897 __ Pop(R0); // Get Code object | 1897 __ Pop(R0); // Get Code object |
1898 __ Pop(R4); // Restore argument descriptor. | 1898 __ Pop(R4); // Restore argument descriptor. |
1899 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); | 1899 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); |
1900 __ LeaveStubFrame(); | 1900 __ LeaveStubFrame(); |
1901 __ bx(R0); | 1901 __ bx(R0); |
1902 __ bkpt(0); | 1902 __ bkpt(0); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 // Result: | 2068 // Result: |
2069 // R1: entry point. | 2069 // R1: entry point. |
2070 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2070 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2071 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2071 EmitMegamorphicLookup(assembler, R0, R1, R1); |
2072 __ Ret(); | 2072 __ Ret(); |
2073 } | 2073 } |
2074 | 2074 |
2075 } // namespace dart | 2075 } // namespace dart |
2076 | 2076 |
2077 #endif // defined TARGET_ARCH_ARM | 2077 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |