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 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 __ Addu(at, string, at); | 439 __ Addu(at, string, at); |
440 __ lhu(result, MemOperand(at)); | 440 __ lhu(result, MemOperand(at)); |
441 __ jmp(&done); | 441 __ jmp(&done); |
442 __ bind(&ascii); | 442 __ bind(&ascii); |
443 // Ascii string. | 443 // Ascii string. |
444 __ Addu(at, string, index); | 444 __ Addu(at, string, index); |
445 __ lbu(result, MemOperand(at)); | 445 __ lbu(result, MemOperand(at)); |
446 __ bind(&done); | 446 __ bind(&done); |
447 } | 447 } |
448 | 448 |
449 #undef __ | 449 // nop(CODE_AGE_MARKER_NOP) |
| 450 static const uint32_t kCodeAgePatchFirstInstruction = 0x00010180; |
| 451 |
| 452 static byte* GetNoCodeAgeSequence(uint32_t* length) { |
| 453 // The sequence of instructions that is patched out for aging code is the |
| 454 // following boilerplate stack-building prologue that is found in FUNCTIONS |
| 455 static bool initialized = false; |
| 456 static uint32_t sequence[kNoCodeAgeSequenceLength]; |
| 457 byte* byte_sequence = reinterpret_cast<byte*>(sequence); |
| 458 *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize; |
| 459 if (!initialized) { |
| 460 CodePatcher patcher(byte_sequence, kNoCodeAgeSequenceLength); |
| 461 patcher.masm()->Push(ra, fp, cp, a1); |
| 462 patcher.masm()->LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 463 patcher.masm()->Addu(fp, sp, Operand(2 * kPointerSize)); |
| 464 initialized = true; |
| 465 } |
| 466 return byte_sequence; |
| 467 } |
450 | 468 |
451 | 469 |
452 byte* Code::FindPlatformCodeAgeSequence() { | 470 byte* Code::FindPlatformCodeAgeSequence() { |
453 UNIMPLEMENTED(); | 471 byte* start = instruction_start(); |
454 return NULL; | 472 uint32_t young_length; |
| 473 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 474 if (!memcmp(start, young_sequence, young_length) || |
| 475 Memory::uint32_at(start) == kCodeAgePatchFirstInstruction) { |
| 476 return start; |
| 477 } else { |
| 478 byte* start_after_strict = NULL; |
| 479 if (kind() == FUNCTION) { |
| 480 start_after_strict = start + kSizeOfFullCodegenStrictModePrologue; |
| 481 } else { |
| 482 ASSERT(kind() == OPTIMIZED_FUNCTION); |
| 483 start_after_strict = start + kSizeOfOptimizedStrictModePrologue; |
| 484 } |
| 485 ASSERT(!memcmp(start_after_strict, young_sequence, young_length) || |
| 486 Memory::uint32_at(start_after_strict) == |
| 487 kCodeAgePatchFirstInstruction); |
| 488 return start_after_strict; |
| 489 } |
455 } | 490 } |
456 | 491 |
457 | 492 |
458 bool Code::IsYoungSequence(byte* sequence) { | 493 bool Code::IsYoungSequence(byte* sequence) { |
459 UNIMPLEMENTED(); | 494 uint32_t young_length; |
460 return false; | 495 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 496 bool result = !memcmp(sequence, young_sequence, young_length); |
| 497 ASSERT(result || |
| 498 Memory::uint32_at(sequence) == kCodeAgePatchFirstInstruction); |
| 499 return result; |
461 } | 500 } |
462 | 501 |
463 | 502 |
464 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, | 503 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, |
465 MarkingParity* parity) { | 504 MarkingParity* parity) { |
| 505 if (IsYoungSequence(sequence)) { |
| 506 *age = kNoAge; |
| 507 *parity = NO_MARKING_PARITY; |
| 508 } else { |
| 509 Address target_address = Memory::Address_at( |
| 510 sequence + Assembler::kInstrSize * (kNoCodeAgeSequenceLength - 1)); |
| 511 Code* stub = GetCodeFromTargetAddress(target_address); |
| 512 GetCodeAgeAndParity(stub, age, parity); |
| 513 } |
466 } | 514 } |
467 | 515 |
468 | 516 |
469 void Code::PatchPlatformCodeAge(byte* sequence, | 517 void Code::PatchPlatformCodeAge(byte* sequence, |
470 Code::Age age, | 518 Code::Age age, |
471 MarkingParity parity) { | 519 MarkingParity parity) { |
472 UNIMPLEMENTED(); | 520 uint32_t young_length; |
| 521 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 522 if (age == kNoAge) { |
| 523 memcpy(sequence, young_sequence, young_length); |
| 524 CPU::FlushICache(sequence, young_length); |
| 525 } else { |
| 526 Code* stub = GetCodeAgeStub(age, parity); |
| 527 CodePatcher patcher(sequence, young_length / Assembler::kInstrSize); |
| 528 // Mark this code sequence for FindPlatformCodeAgeSequence() |
| 529 patcher.masm()->nop(Assembler::CODE_AGE_MARKER_NOP); |
| 530 // Save the function's original return address |
| 531 // (it will be clobbered by Call(t9)) |
| 532 patcher.masm()->mov(at, ra); |
| 533 // Load the stub address to t9 and call it |
| 534 patcher.masm()->li(t9, |
| 535 Operand(reinterpret_cast<uint32_t>(stub->instruction_start()))); |
| 536 patcher.masm()->Call(t9); |
| 537 // Record the stub address in the empty space for GetCodeAgeAndParity() |
| 538 patcher.masm()->dd(reinterpret_cast<uint32_t>(stub->instruction_start())); |
| 539 } |
473 } | 540 } |
474 | 541 |
| 542 |
| 543 #undef __ |
| 544 |
475 } } // namespace v8::internal | 545 } } // namespace v8::internal |
476 | 546 |
477 #endif // V8_TARGET_ARCH_MIPS | 547 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |