OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 static void ZapCodeRange(Address start, Address end) { | 48 static void ZapCodeRange(Address start, Address end) { |
49 #ifdef DEBUG | 49 #ifdef DEBUG |
50 ASSERT(start <= end); | 50 ASSERT(start <= end); |
51 int size = end - start; | 51 int size = end - start; |
52 CodePatcher destroyer(start, size); | 52 CodePatcher destroyer(start, size); |
53 while (size-- > 0) destroyer.masm()->int3(); | 53 while (size-- > 0) destroyer.masm()->int3(); |
54 #endif | 54 #endif |
55 } | 55 } |
56 | 56 |
57 | 57 |
| 58 void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) { |
| 59 HandleScope scope; |
| 60 |
| 61 // Compute the size of relocation information needed for the code |
| 62 // patching in Deoptimizer::DeoptimizeFunction. |
| 63 int min_reloc_size = 0; |
| 64 Address prev_reloc_address = code->instruction_start(); |
| 65 Address code_start_address = code->instruction_start(); |
| 66 SafepointTable table(*code); |
| 67 for (unsigned i = 0; i < table.length(); ++i) { |
| 68 Address curr_reloc_address = code_start_address + table.GetPcOffset(i); |
| 69 ASSERT_GE(curr_reloc_address, prev_reloc_address); |
| 70 SafepointEntry safepoint_entry = table.GetEntry(i); |
| 71 int deoptimization_index = safepoint_entry.deoptimization_index(); |
| 72 if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) { |
| 73 // The gap code is needed to get to the state expected at the |
| 74 // bailout and we need to skip the call opcode to get to the |
| 75 // address that needs reloc. |
| 76 curr_reloc_address += safepoint_entry.gap_code_size() + 1; |
| 77 int pc_delta = curr_reloc_address - prev_reloc_address; |
| 78 // We use RUNTIME_ENTRY reloc info which has a size of 2 bytes |
| 79 // if encodable with small pc delta encoding and up to 6 bytes |
| 80 // otherwise. |
| 81 if (pc_delta <= RelocInfo::kMaxSmallPCDelta) { |
| 82 min_reloc_size += 2; |
| 83 } else { |
| 84 min_reloc_size += 6; |
| 85 } |
| 86 prev_reloc_address = curr_reloc_address; |
| 87 } |
| 88 } |
| 89 |
| 90 // If the relocation information is not big enough we create a new |
| 91 // relocation info object that is padded with comments to make it |
| 92 // big enough for lazy doptimization. |
| 93 int reloc_length = code->relocation_info()->length(); |
| 94 if (min_reloc_size > reloc_length) { |
| 95 int comment_reloc_size = RelocInfo::kMinRelocCommentSize; |
| 96 // Padding needed. |
| 97 int min_padding = min_reloc_size - reloc_length; |
| 98 // Number of comments needed to take up at least that much space. |
| 99 int additional_comments = |
| 100 (min_padding + comment_reloc_size - 1) / comment_reloc_size; |
| 101 // Actual padding size. |
| 102 int padding = additional_comments * comment_reloc_size; |
| 103 // Allocate new relocation info and copy old relocation to the end |
| 104 // of the new relocation info array because relocation info is |
| 105 // written and read backwards. |
| 106 Factory* factory = code->GetIsolate()->factory(); |
| 107 Handle<ByteArray> new_reloc = |
| 108 factory->NewByteArray(reloc_length + padding, TENURED); |
| 109 memcpy(new_reloc->GetDataStartAddress() + padding, |
| 110 code->relocation_info()->GetDataStartAddress(), |
| 111 reloc_length); |
| 112 // Create a relocation writer to write the comments in the padding |
| 113 // space. Use position 0 for everything to ensure short encoding. |
| 114 RelocInfoWriter reloc_info_writer( |
| 115 new_reloc->GetDataStartAddress() + padding, 0); |
| 116 intptr_t comment_string |
| 117 = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString); |
| 118 RelocInfo rinfo(0, RelocInfo::COMMENT, comment_string); |
| 119 for (int i = 0; i < additional_comments; ++i) { |
| 120 #ifdef DEBUG |
| 121 byte* pos_before = reloc_info_writer.pos(); |
| 122 #endif |
| 123 reloc_info_writer.Write(&rinfo); |
| 124 ASSERT(RelocInfo::kMinRelocCommentSize == |
| 125 pos_before - reloc_info_writer.pos()); |
| 126 } |
| 127 // Replace relocation information on the code object. |
| 128 code->set_relocation_info(*new_reloc); |
| 129 } |
| 130 } |
| 131 |
| 132 |
58 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { | 133 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { |
59 HandleScope scope; | 134 HandleScope scope; |
60 AssertNoAllocation no_allocation; | 135 AssertNoAllocation no_allocation; |
61 | 136 |
62 if (!function->IsOptimized()) return; | 137 if (!function->IsOptimized()) return; |
63 | 138 |
64 // Get the optimized code. | 139 // Get the optimized code. |
65 Code* code = function->code(); | 140 Code* code = function->code(); |
66 Address code_start_address = code->instruction_start(); | 141 Address code_start_address = code->instruction_start(); |
67 | 142 |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 } | 742 } |
668 __ bind(&done); | 743 __ bind(&done); |
669 } | 744 } |
670 | 745 |
671 #undef __ | 746 #undef __ |
672 | 747 |
673 | 748 |
674 } } // namespace v8::internal | 749 } } // namespace v8::internal |
675 | 750 |
676 #endif // V8_TARGET_ARCH_IA32 | 751 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |