Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Side by Side Diff: runtime/vm/stub_code_mips.cc

Issue 14061012: Enables API tests on MIPS (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 // .... 334 // ....
335 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); 335 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry);
336 // Remove arguments. 336 // Remove arguments.
337 __ lw(V0, Address(SP, 4 * kWordSize)); 337 __ lw(V0, Address(SP, 4 * kWordSize));
338 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Get result into V0. 338 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Get result into V0.
339 __ LeaveStubFrame(); 339 __ LeaveStubFrame();
340 __ Ret(); 340 __ Ret();
341 } 341 }
342 342
343 343
344 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
345 intptr_t deopt_reason,
346 uword saved_registers_address);
347
348 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp);
349
350
351 // Used by eager and lazy deoptimization. Preserve result in V0 if necessary.
352 // This stub translates optimized frame into unoptimized frame. The optimized
353 // frame can contain values in registers and on stack, the unoptimized
354 // frame contains all values on stack.
355 // Deoptimization occurs in following steps:
356 // - Push all registers that can contain values.
357 // - Call C routine to copy the stack and saved registers into temporary buffer.
358 // - Adjust caller's frame to correct unoptimized frame size.
359 // - Fill the unoptimized frame.
360 // - Materialize objects that require allocation (e.g. Double instances).
361 // GC can occur only after frame is fully rewritten.
362 // Stack after EnterFrame(...) below:
363 // +------------------+
364 // | Saved FP | <- TOS
365 // +------------------+
366 // | return-address | (deoptimization point)
367 // +------------------+
368 // | optimized frame |
369 // | ... |
370 //
371 // Parts of the code cannot GC, part of the code can GC.
372 static void GenerateDeoptimizationSequence(Assembler* assembler,
373 bool preserve_result) {
374 const intptr_t kPushedRegistersSize =
375 kNumberOfCpuRegisters * kWordSize +
376 2 * kWordSize + // FP and RA.
377 kNumberOfFRegisters * kWordSize;
378
379 __ addiu(SP, SP, Immediate(-kPushedRegistersSize * kWordSize));
380 __ sw(RA, Address(SP, kPushedRegistersSize - 1 * kWordSize));
381 __ sw(FP, Address(SP, kPushedRegistersSize - 2 * kWordSize));
382 __ addiu(FP, SP, Immediate(kPushedRegistersSize - 2 * kWordSize));
383
384
385 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
386 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
387 const intptr_t saved_v0_offset_from_fp = -(kNumberOfCpuRegisters - V0);
388 // Result in V0 is preserved as part of pushing all registers below.
389
390 // Push registers in their enumeration order: lowest register number at
391 // lowest address.
392 for (int i = 0; i < kNumberOfCpuRegisters; i++) {
393 const int slot = 2 + kNumberOfCpuRegisters - i;
394 Register reg = static_cast<Register>(i);
395 __ sw(reg, Address(SP, kPushedRegistersSize - slot * kWordSize));
396 }
397 for (int i = 0; i < kNumberOfFRegisters; i++) {
398 // These go below the CPU registers.
399 const int slot = 2 + kNumberOfCpuRegisters + kNumberOfFRegisters - i;
400 FRegister reg = static_cast<FRegister>(i);
401 __ swc1(reg, Address(SP, kPushedRegistersSize - slot * kWordSize));
402 }
403
404 __ mov(A0, SP); // Pass address of saved registers block.
405 __ ReserveAlignedFrameSpace(0);
406 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry);
407 // Result (V0) is stack-size (FP - SP) in bytes, incl. the return address.
408
409 if (preserve_result) {
410 // Restore result into T1 temporarily.
411 __ lw(T1, Address(FP, saved_v0_offset_from_fp * kWordSize));
412 }
413
414 __ mov(SP, FP);
415 __ lw(FP, Address(SP, 0 * kWordSize));
416 __ lw(RA, Address(SP, 1 * kWordSize));
417 __ addiu(SP, SP, Immediate(2 * kWordSize));
418
419 __ subu(SP, FP, V0);
420
421 __ addiu(SP, SP, Immediate(-2 * kWordSize));
422 __ sw(RA, Address(SP, 1 * kWordSize));
423 __ sw(FP, Address(SP, 0 * kWordSize));
424 __ mov(FP, SP);
425
426 __ mov(A0, SP); // Get last FP address.
427 if (preserve_result) {
428 __ Push(T1); // Preserve result.
429 }
430 __ ReserveAlignedFrameSpace(0);
431 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in A0.
432 // Result (V0) is our FP.
433 if (preserve_result) {
434 // Restore result into T1.
435 __ lw(T1, Address(FP, -1 * kWordSize));
436 }
437 // Code above cannot cause GC.
438 __ mov(SP, FP);
439 __ lw(FP, Address(SP, 0 * kWordSize));
440 __ lw(RA, Address(SP, 1 * kWordSize));
441 __ addiu(SP, SP, Immediate(2 * kWordSize));
442 __ mov(FP, V0);
443
444 // Frame is fully rewritten at this point and it is safe to perform a GC.
445 // Materialize any objects that were deferred by FillFrame because they
446 // require allocation.
447 __ EnterStubFrame();
448 if (preserve_result) {
449 __ Push(T1); // Preserve result, it will be GC-d here.
450 }
451 __ CallRuntime(kDeoptimizeMaterializeDoublesRuntimeEntry);
452 if (preserve_result) {
453 __ Pop(V0); // Restore result.
454 }
455 __ LeaveStubFrame();
456 __ Ret();
457 }
458
459
344 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) { 460 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
345 __ Unimplemented("DeoptimizeLazy stub"); 461 __ Unimplemented("DeoptimizeLazy stub");
346 } 462 }
347 463
348 464
349 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 465 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
350 __ Unimplemented("Deoptimize stub"); 466 GenerateDeoptimizationSequence(assembler, false); // Don't preserve V0.
351 } 467 }
352 468
353 469
354 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 470 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
355 __ Unimplemented("MegamorphicMiss stub"); 471 __ Unimplemented("MegamorphicMiss stub");
356 } 472 }
357 473
358 474
359 // Called for inline allocation of arrays. 475 // Called for inline allocation of arrays.
360 // Input parameters: 476 // Input parameters:
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 __ LeaveStubFrame(true); 1370 __ LeaveStubFrame(true);
1255 __ Ret(); 1371 __ Ret();
1256 } 1372 }
1257 1373
1258 1374
1259 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1375 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1260 __ Unimplemented("CallNoSuchMethodFunction stub"); 1376 __ Unimplemented("CallNoSuchMethodFunction stub");
1261 } 1377 }
1262 1378
1263 1379
1380 // T0: function object.
1381 // S5: inline cache data object.
1382 // S4: arguments descriptor array.
1264 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1383 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1265 __ Unimplemented("OptimizedUsageCounterIncrement stub"); 1384 __ TraceSimMsg("OptimizedUsageCounterIncrement");
1385 Register ic_reg = S5;
1386 Register func_reg = T0;
1387 if (FLAG_trace_optimized_ic_calls) {
1388 __ EnterStubFrame();
1389 __ addiu(SP, SP, Immediate(-5 * kWordSize));
1390 __ sw(T0, Address(SP, 4 * kWordSize));
1391 __ sw(S5, Address(SP, 3 * kWordSize));
1392 __ sw(S4, Address(SP, 2 * kWordSize)); // Preserve.
1393 __ sw(ic_reg, Address(SP, 1 * kWordSize)); // Argument.
1394 __ sw(func_reg, Address(SP, 0 * kWordSize)); // Argument.
1395 __ CallRuntime(kTraceICCallRuntimeEntry);
1396 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore.
1397 __ lw(S5, Address(SP, 3 * kWordSize));
1398 __ lw(T0, Address(SP, 4 * kWordSize));
1399 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Discard argument;
1400 __ LeaveStubFrame();
1401 }
1402 __ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset()));
1403 Label is_hot;
1404 if (FlowGraphCompiler::CanOptimize()) {
1405 ASSERT(FLAG_optimization_counter_threshold > 1);
1406 __ BranchGreaterEqual(T7, FLAG_optimization_counter_threshold, &is_hot);
1407 // 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 // optimizing.
1410 }
1411 __ addiu(T7, T7, Immediate(1));
1412 __ sw(T7, FieldAddress(func_reg, Function::usage_counter_offset()));
1413 __ Bind(&is_hot);
1266 } 1414 }
1267 1415
1268 1416
1269 // Loads function into 'temp_reg'. 1417 // Loads function into 'temp_reg'.
1270 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1418 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1271 Register temp_reg) { 1419 Register temp_reg) {
1272 __ TraceSimMsg("UsageCounterIncrement"); 1420 __ TraceSimMsg("UsageCounterIncrement");
1273 Register ic_reg = S5; 1421 Register ic_reg = S5;
1274 Register func_reg = temp_reg; 1422 Register func_reg = temp_reg;
1275 ASSERT(temp_reg == T0); 1423 ASSERT(temp_reg == T0);
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after
1968 __ Bind(&done); 2116 __ Bind(&done);
1969 __ lw(T0, Address(SP, 0 * kWordSize)); 2117 __ lw(T0, Address(SP, 0 * kWordSize));
1970 __ lw(T1, Address(SP, 1 * kWordSize)); 2118 __ lw(T1, Address(SP, 1 * kWordSize));
1971 __ Ret(); 2119 __ Ret();
1972 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); 2120 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize));
1973 } 2121 }
1974 2122
1975 } // namespace dart 2123 } // namespace dart
1976 2124
1977 #endif // defined TARGET_ARCH_MIPS 2125 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698