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