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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
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/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 // T2: address of first argument in array. | 279 // T2: address of first argument in array. |
280 Label loop, loop_condition; | 280 Label loop, loop_condition; |
281 __ b(&loop_condition); | 281 __ b(&loop_condition); |
282 __ Bind(&loop); | 282 __ Bind(&loop); |
283 __ lw(TMP, Address(T1)); | 283 __ lw(TMP, Address(T1)); |
284 __ sw(TMP, Address(T2)); | 284 __ sw(TMP, Address(T2)); |
285 __ AddImmediate(T1, -kWordSize); | 285 __ AddImmediate(T1, -kWordSize); |
286 __ AddImmediate(T2, kWordSize); | 286 __ AddImmediate(T2, kWordSize); |
287 __ Bind(&loop_condition); | 287 __ Bind(&loop_condition); |
288 __ AddImmediate(A1, -Smi::RawValue(1)); // A1 is Smi. | 288 __ AddImmediate(A1, -Smi::RawValue(1)); // A1 is Smi. |
289 __ BranchGreaterEqual(A1, ZR, &loop); | 289 __ BranchSignedGreaterEqual(A1, ZR, &loop); |
290 } | 290 } |
291 | 291 |
292 | 292 |
293 // Input parameters: | 293 // Input parameters: |
294 // S5: ic-data. | 294 // S5: ic-data. |
295 // S4: arguments descriptor array. | 295 // S4: arguments descriptor array. |
296 // Note: The receiver object is the first argument to the function being | 296 // Note: The receiver object is the first argument to the function being |
297 // called, the stub accesses the receiver from this location directly | 297 // called, the stub accesses the receiver from this location directly |
298 // when trying to resolve the call. | 298 // when trying to resolve the call. |
299 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | 299 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 __ addu(T2, T3, V0); | 513 __ addu(T2, T3, V0); |
514 | 514 |
515 // Check if the allocation fits into the remaining space. | 515 // Check if the allocation fits into the remaining space. |
516 // V0: potential new object start. | 516 // V0: potential new object start. |
517 // A0: array element type. | 517 // A0: array element type. |
518 // A1: array length as Smi. | 518 // A1: array length as Smi. |
519 // T0: points to new space object. | 519 // T0: points to new space object. |
520 // T2: potential next object start. | 520 // T2: potential next object start. |
521 // T3: array size. | 521 // T3: array size. |
522 __ lw(TMP1, Address(T0, Scavenger::end_offset())); | 522 __ lw(TMP1, Address(T0, Scavenger::end_offset())); |
523 __ BranchGreaterEqual(T2, TMP1, &slow_case); | 523 __ BranchUnsignedGreaterEqual(T2, TMP1, &slow_case); |
524 | 524 |
525 // Successfully allocated the object(s), now update top to point to | 525 // Successfully allocated the object(s), now update top to point to |
526 // next object start and initialize the object. | 526 // next object start and initialize the object. |
527 // V0: potential new object start. | 527 // V0: potential new object start. |
528 // T2: potential next object start. | 528 // T2: potential next object start. |
529 // T0: Points to new space object. | 529 // T0: Points to new space object. |
530 __ sw(T2, Address(T0, Scavenger::top_offset())); | 530 __ sw(T2, Address(T0, Scavenger::top_offset())); |
531 __ addiu(V0, V0, Immediate(kHeapObjectTag)); | 531 __ addiu(V0, V0, Immediate(kHeapObjectTag)); |
532 | 532 |
533 // V0: new object start as a tagged pointer. | 533 // V0: new object start as a tagged pointer. |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 | 799 |
800 // Set up arguments for the Dart call. | 800 // Set up arguments for the Dart call. |
801 Label push_arguments; | 801 Label push_arguments; |
802 Label done_push_arguments; | 802 Label done_push_arguments; |
803 __ beq(T1, ZR, &done_push_arguments); // check if there are arguments. | 803 __ beq(T1, ZR, &done_push_arguments); // check if there are arguments. |
804 __ mov(A1, ZR); | 804 __ mov(A1, ZR); |
805 __ Bind(&push_arguments); | 805 __ Bind(&push_arguments); |
806 __ lw(A3, Address(A2)); | 806 __ lw(A3, Address(A2)); |
807 __ Push(A3); | 807 __ Push(A3); |
808 __ addiu(A1, A1, Immediate(1)); | 808 __ addiu(A1, A1, Immediate(1)); |
809 __ BranchLess(A1, T1, &push_arguments); | 809 __ BranchSignedLess(A1, T1, &push_arguments); |
810 __ delay_slot()->addiu(A2, A2, Immediate(kWordSize)); | 810 __ delay_slot()->addiu(A2, A2, Immediate(kWordSize)); |
811 | 811 |
812 __ Bind(&done_push_arguments); | 812 __ Bind(&done_push_arguments); |
813 | 813 |
814 // Call the Dart code entrypoint. | 814 // Call the Dart code entrypoint. |
815 __ jalr(A0); // S4 is the arguments descriptor array. | 815 __ jalr(A0); // S4 is the arguments descriptor array. |
816 __ TraceSimMsg("InvokeDartCodeStub return"); | 816 __ TraceSimMsg("InvokeDartCodeStub return"); |
817 | 817 |
818 // Read the saved new Context pointer. | 818 // Read the saved new Context pointer. |
819 __ lw(CTX, Address(FP, kNewContextOffset)); | 819 __ lw(CTX, Address(FP, kNewContextOffset)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
878 // Check if the allocation fits into the remaining space. | 878 // Check if the allocation fits into the remaining space. |
879 // V0: potential new object. | 879 // V0: potential new object. |
880 // T1: number of context variables. | 880 // T1: number of context variables. |
881 // T2: object size. | 881 // T2: object size. |
882 // T3: potential next object start. | 882 // T3: potential next object start. |
883 __ LoadImmediate(TMP1, heap->EndAddress()); | 883 __ LoadImmediate(TMP1, heap->EndAddress()); |
884 __ lw(TMP1, Address(TMP1, 0)); | 884 __ lw(TMP1, Address(TMP1, 0)); |
885 if (FLAG_use_slow_path) { | 885 if (FLAG_use_slow_path) { |
886 __ b(&slow_case); | 886 __ b(&slow_case); |
887 } else { | 887 } else { |
888 __ BranchGreaterEqual(T3, TMP1, &slow_case); | 888 __ BranchUnsignedGreaterEqual(T3, TMP1, &slow_case); |
889 } | 889 } |
890 | 890 |
891 // Successfully allocated the object, now update top to point to | 891 // Successfully allocated the object, now update top to point to |
892 // next object start and initialize the object. | 892 // next object start and initialize the object. |
893 // V0: new object. | 893 // V0: new object. |
894 // T1: number of context variables. | 894 // T1: number of context variables. |
895 // T2: object size. | 895 // T2: object size. |
896 // T3: next object start. | 896 // T3: next object start. |
897 __ sw(T3, Address(T5, 0)); | 897 __ sw(T3, Address(T5, 0)); |
898 __ addiu(V0, V0, Immediate(kHeapObjectTag)); | 898 __ addiu(V0, V0, Immediate(kHeapObjectTag)); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 // InstantiatedTypeArguments object start. | 1072 // InstantiatedTypeArguments object start. |
1073 } | 1073 } |
1074 // Check if the allocation fits into the remaining space. | 1074 // Check if the allocation fits into the remaining space. |
1075 // T2: potential new object start. | 1075 // T2: potential new object start. |
1076 // T3: potential next object start. | 1076 // T3: potential next object start. |
1077 __ LoadImmediate(TMP1, heap->EndAddress()); | 1077 __ LoadImmediate(TMP1, heap->EndAddress()); |
1078 __ lw(TMP1, Address(TMP1)); | 1078 __ lw(TMP1, Address(TMP1)); |
1079 if (FLAG_use_slow_path) { | 1079 if (FLAG_use_slow_path) { |
1080 __ b(&slow_case); | 1080 __ b(&slow_case); |
1081 } else { | 1081 } else { |
1082 __ BranchGreaterEqual(T3, TMP1, &slow_case); | 1082 __ BranchUnsignedGreaterEqual(T3, TMP1, &slow_case); |
1083 } | 1083 } |
1084 | 1084 |
1085 // Successfully allocated the object(s), now update top to point to | 1085 // Successfully allocated the object(s), now update top to point to |
1086 // next object start and initialize the object. | 1086 // next object start and initialize the object. |
1087 __ sw(T3, Address(T5)); | 1087 __ sw(T3, Address(T5)); |
1088 | 1088 |
1089 if (is_cls_parameterized) { | 1089 if (is_cls_parameterized) { |
1090 // Initialize the type arguments field in the object. | 1090 // Initialize the type arguments field in the object. |
1091 // T2: new object start. | 1091 // T2: new object start. |
1092 // T4: potential new object end and, if T4 != T3, potential new | 1092 // T4: potential new object end and, if T4 != T3, potential new |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 __ addiu(T4, T2, Immediate(sizeof(RawObject))); | 1148 __ addiu(T4, T2, Immediate(sizeof(RawObject))); |
1149 // Loop until the whole object is initialized. | 1149 // Loop until the whole object is initialized. |
1150 // T0: raw null. | 1150 // T0: raw null. |
1151 // T2: new object. | 1151 // T2: new object. |
1152 // T3: next object start. | 1152 // T3: next object start. |
1153 // T4: next word to be initialized. | 1153 // T4: next word to be initialized. |
1154 // T1: new object type arguments (if is_cls_parameterized). | 1154 // T1: new object type arguments (if is_cls_parameterized). |
1155 Label init_loop; | 1155 Label init_loop; |
1156 Label done; | 1156 Label done; |
1157 __ Bind(&init_loop); | 1157 __ Bind(&init_loop); |
1158 __ BranchGreaterEqual(T4, T3, &done); // Done if T4 >= T3. | 1158 __ BranchUnsignedGreaterEqual(T4, T3, &done); // Done if T4 >= T3. |
1159 __ sw(T0, Address(T4)); | 1159 __ sw(T0, Address(T4)); |
1160 __ AddImmediate(T4, kWordSize); | 1160 __ AddImmediate(T4, kWordSize); |
1161 __ b(&init_loop); | 1161 __ b(&init_loop); |
1162 __ Bind(&done); | 1162 __ Bind(&done); |
1163 } | 1163 } |
1164 if (is_cls_parameterized) { | 1164 if (is_cls_parameterized) { |
1165 // R1: new object type arguments. | 1165 // R1: new object type arguments. |
1166 // Set the type arguments in the new object. | 1166 // Set the type arguments in the new object. |
1167 __ sw(T1, Address(T2, cls.type_arguments_field_offset())); | 1167 __ sw(T1, Address(T2, cls.type_arguments_field_offset())); |
1168 } | 1168 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 } | 1243 } |
1244 // Check if the allocation fits into the remaining space. | 1244 // Check if the allocation fits into the remaining space. |
1245 // T2: potential new closure object. | 1245 // T2: potential new closure object. |
1246 // T3: address of top of heap. | 1246 // T3: address of top of heap. |
1247 // T4: potential new context object (only if is_implicit_closure). | 1247 // T4: potential new context object (only if is_implicit_closure). |
1248 __ LoadImmediate(TMP1, heap->EndAddress()); | 1248 __ LoadImmediate(TMP1, heap->EndAddress()); |
1249 __ lw(TMP1, Address(TMP1)); | 1249 __ lw(TMP1, Address(TMP1)); |
1250 if (FLAG_use_slow_path) { | 1250 if (FLAG_use_slow_path) { |
1251 __ b(&slow_case); | 1251 __ b(&slow_case); |
1252 } else { | 1252 } else { |
1253 __ BranchGreaterEqual(T3, TMP1, &slow_case); | 1253 __ BranchUnsignedGreaterEqual(T3, TMP1, &slow_case); |
1254 } | 1254 } |
1255 | 1255 |
1256 // Successfully allocated the object, now update top to point to | 1256 // Successfully allocated the object, now update top to point to |
1257 // next object start and initialize the object. | 1257 // next object start and initialize the object. |
1258 __ sw(T3, Address(T5)); | 1258 __ sw(T3, Address(T5)); |
1259 | 1259 |
1260 // T2: new closure object. | 1260 // T2: new closure object. |
1261 // T4: new context object (only if is_implicit_closure). | 1261 // T4: new context object (only if is_implicit_closure). |
1262 // Set the tags. | 1262 // Set the tags. |
1263 uword tags = 0; | 1263 uword tags = 0; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore. | 1396 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore. |
1397 __ lw(S5, Address(SP, 3 * kWordSize)); | 1397 __ lw(S5, Address(SP, 3 * kWordSize)); |
1398 __ lw(T0, Address(SP, 4 * kWordSize)); | 1398 __ lw(T0, Address(SP, 4 * kWordSize)); |
1399 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Discard argument; | 1399 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Discard argument; |
1400 __ LeaveStubFrame(); | 1400 __ LeaveStubFrame(); |
1401 } | 1401 } |
1402 __ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1402 __ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); |
1403 Label is_hot; | 1403 Label is_hot; |
1404 if (FlowGraphCompiler::CanOptimize()) { | 1404 if (FlowGraphCompiler::CanOptimize()) { |
1405 ASSERT(FLAG_optimization_counter_threshold > 1); | 1405 ASSERT(FLAG_optimization_counter_threshold > 1); |
1406 __ BranchGreaterEqual(T7, FLAG_optimization_counter_threshold, &is_hot); | 1406 __ BranchSignedGreaterEqual(T7, FLAG_optimization_counter_threshold, |
| 1407 &is_hot); |
1407 // As long as VM has no OSR do not optimize in the middle of the function | 1408 // As long as VM has no OSR do not optimize in the middle of the function |
1408 // but only at exit so that we have collected all type feedback before | 1409 // but only at exit so that we have collected all type feedback before |
1409 // optimizing. | 1410 // optimizing. |
1410 } | 1411 } |
1411 __ addiu(T7, T7, Immediate(1)); | 1412 __ addiu(T7, T7, Immediate(1)); |
1412 __ sw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1413 __ sw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); |
1413 __ Bind(&is_hot); | 1414 __ Bind(&is_hot); |
1414 } | 1415 } |
1415 | 1416 |
1416 | 1417 |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2116 __ Bind(&done); | 2117 __ Bind(&done); |
2117 __ lw(T0, Address(SP, 0 * kWordSize)); | 2118 __ lw(T0, Address(SP, 0 * kWordSize)); |
2118 __ lw(T1, Address(SP, 1 * kWordSize)); | 2119 __ lw(T1, Address(SP, 1 * kWordSize)); |
2119 __ Ret(); | 2120 __ Ret(); |
2120 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); | 2121 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); |
2121 } | 2122 } |
2122 | 2123 |
2123 } // namespace dart | 2124 } // namespace dart |
2124 | 2125 |
2125 #endif // defined TARGET_ARCH_MIPS | 2126 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |