| 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) { | 58 void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) { |
| 59 HandleScope scope; | 59 Isolate* isolate = code->GetIsolate(); |
| 60 HandleScope scope(isolate); |
| 60 | 61 |
| 61 // Compute the size of relocation information needed for the code | 62 // Compute the size of relocation information needed for the code |
| 62 // patching in Deoptimizer::DeoptimizeFunction. | 63 // patching in Deoptimizer::DeoptimizeFunction. |
| 63 int min_reloc_size = 0; | 64 int min_reloc_size = 0; |
| 64 Address prev_reloc_address = code->instruction_start(); | 65 Address prev_reloc_address = code->instruction_start(); |
| 65 Address code_start_address = code->instruction_start(); | 66 Address code_start_address = code->instruction_start(); |
| 66 SafepointTable table(*code); | 67 SafepointTable table(*code); |
| 67 for (unsigned i = 0; i < table.length(); ++i) { | 68 for (unsigned i = 0; i < table.length(); ++i) { |
| 68 Address curr_reloc_address = code_start_address + table.GetPcOffset(i); | 69 Address curr_reloc_address = code_start_address + table.GetPcOffset(i); |
| 69 ASSERT_GE(curr_reloc_address, prev_reloc_address); | 70 ASSERT_GE(curr_reloc_address, prev_reloc_address); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 96 // Padding needed. | 97 // Padding needed. |
| 97 int min_padding = min_reloc_size - reloc_length; | 98 int min_padding = min_reloc_size - reloc_length; |
| 98 // Number of comments needed to take up at least that much space. | 99 // Number of comments needed to take up at least that much space. |
| 99 int additional_comments = | 100 int additional_comments = |
| 100 (min_padding + comment_reloc_size - 1) / comment_reloc_size; | 101 (min_padding + comment_reloc_size - 1) / comment_reloc_size; |
| 101 // Actual padding size. | 102 // Actual padding size. |
| 102 int padding = additional_comments * comment_reloc_size; | 103 int padding = additional_comments * comment_reloc_size; |
| 103 // Allocate new relocation info and copy old relocation to the end | 104 // Allocate new relocation info and copy old relocation to the end |
| 104 // of the new relocation info array because relocation info is | 105 // of the new relocation info array because relocation info is |
| 105 // written and read backwards. | 106 // written and read backwards. |
| 106 Factory* factory = code->GetIsolate()->factory(); | 107 Factory* factory = isolate->factory(); |
| 107 Handle<ByteArray> new_reloc = | 108 Handle<ByteArray> new_reloc = |
| 108 factory->NewByteArray(reloc_length + padding, TENURED); | 109 factory->NewByteArray(reloc_length + padding, TENURED); |
| 109 memcpy(new_reloc->GetDataStartAddress() + padding, | 110 memcpy(new_reloc->GetDataStartAddress() + padding, |
| 110 code->relocation_info()->GetDataStartAddress(), | 111 code->relocation_info()->GetDataStartAddress(), |
| 111 reloc_length); | 112 reloc_length); |
| 112 // Create a relocation writer to write the comments in the padding | 113 // Create a relocation writer to write the comments in the padding |
| 113 // space. Use position 0 for everything to ensure short encoding. | 114 // space. Use position 0 for everything to ensure short encoding. |
| 114 RelocInfoWriter reloc_info_writer( | 115 RelocInfoWriter reloc_info_writer( |
| 115 new_reloc->GetDataStartAddress() + padding, 0); | 116 new_reloc->GetDataStartAddress() + padding, 0); |
| 116 intptr_t comment_string | 117 intptr_t comment_string |
| 117 = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString); | 118 = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString); |
| 118 RelocInfo rinfo(0, RelocInfo::COMMENT, comment_string); | 119 RelocInfo rinfo(0, RelocInfo::COMMENT, comment_string); |
| 119 for (int i = 0; i < additional_comments; ++i) { | 120 for (int i = 0; i < additional_comments; ++i) { |
| 120 #ifdef DEBUG | 121 #ifdef DEBUG |
| 121 byte* pos_before = reloc_info_writer.pos(); | 122 byte* pos_before = reloc_info_writer.pos(); |
| 122 #endif | 123 #endif |
| 123 reloc_info_writer.Write(&rinfo); | 124 reloc_info_writer.Write(&rinfo); |
| 124 ASSERT(RelocInfo::kMinRelocCommentSize == | 125 ASSERT(RelocInfo::kMinRelocCommentSize == |
| 125 pos_before - reloc_info_writer.pos()); | 126 pos_before - reloc_info_writer.pos()); |
| 126 } | 127 } |
| 127 // Replace relocation information on the code object. | 128 // Replace relocation information on the code object. |
| 128 code->set_relocation_info(*new_reloc); | 129 code->set_relocation_info(*new_reloc); |
| 129 } | 130 } |
| 130 } | 131 } |
| 131 | 132 |
| 132 | 133 |
| 133 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { | 134 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { |
| 134 HandleScope scope; | 135 if (!function->IsOptimized()) return; |
| 136 |
| 137 Isolate* isolate = function->GetIsolate(); |
| 138 HandleScope scope(isolate); |
| 135 AssertNoAllocation no_allocation; | 139 AssertNoAllocation no_allocation; |
| 136 | 140 |
| 137 if (!function->IsOptimized()) return; | |
| 138 | |
| 139 // Get the optimized code. | 141 // Get the optimized code. |
| 140 Code* code = function->code(); | 142 Code* code = function->code(); |
| 141 Address code_start_address = code->instruction_start(); | 143 Address code_start_address = code->instruction_start(); |
| 142 | 144 |
| 143 // We will overwrite the code's relocation info in-place. Relocation info | 145 // We will overwrite the code's relocation info in-place. Relocation info |
| 144 // is written backward. The relocation info is the payload of a byte | 146 // is written backward. The relocation info is the payload of a byte |
| 145 // array. Later on we will slide this to the start of the byte array and | 147 // array. Later on we will slide this to the start of the byte array and |
| 146 // create a filler object in the remaining space. | 148 // create a filler object in the remaining space. |
| 147 ByteArray* reloc_info = code->relocation_info(); | 149 ByteArray* reloc_info = code->relocation_info(); |
| 148 Address reloc_end_address = reloc_info->address() + reloc_info->Size(); | 150 Address reloc_end_address = reloc_info->address() + reloc_info->Size(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 int new_reloc_size = reloc_end_address - reloc_info_writer.pos(); | 189 int new_reloc_size = reloc_end_address - reloc_info_writer.pos(); |
| 188 memmove(code->relocation_start(), reloc_info_writer.pos(), new_reloc_size); | 190 memmove(code->relocation_start(), reloc_info_writer.pos(), new_reloc_size); |
| 189 | 191 |
| 190 // The relocation info is in place, update the size. | 192 // The relocation info is in place, update the size. |
| 191 reloc_info->set_length(new_reloc_size); | 193 reloc_info->set_length(new_reloc_size); |
| 192 | 194 |
| 193 // Handle the junk part after the new relocation info. We will create | 195 // Handle the junk part after the new relocation info. We will create |
| 194 // a non-live object in the extra space at the end of the former reloc info. | 196 // a non-live object in the extra space at the end of the former reloc info. |
| 195 Address junk_address = reloc_info->address() + reloc_info->Size(); | 197 Address junk_address = reloc_info->address() + reloc_info->Size(); |
| 196 ASSERT(junk_address <= reloc_end_address); | 198 ASSERT(junk_address <= reloc_end_address); |
| 197 HEAP->CreateFillerObjectAt(junk_address, reloc_end_address - junk_address); | 199 isolate->heap()->CreateFillerObjectAt(junk_address, |
| 200 reloc_end_address - junk_address); |
| 198 | 201 |
| 199 // Add the deoptimizing code to the list. | 202 // Add the deoptimizing code to the list. |
| 200 DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code); | 203 DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code); |
| 201 DeoptimizerData* data = code->GetIsolate()->deoptimizer_data(); | 204 DeoptimizerData* data = isolate->deoptimizer_data(); |
| 202 node->set_next(data->deoptimizing_code_list_); | 205 node->set_next(data->deoptimizing_code_list_); |
| 203 data->deoptimizing_code_list_ = node; | 206 data->deoptimizing_code_list_ = node; |
| 204 | 207 |
| 205 // Set the code for the function to non-optimized version. | 208 // Set the code for the function to non-optimized version. |
| 206 function->ReplaceCode(function->shared()->code()); | 209 function->ReplaceCode(function->shared()->code()); |
| 207 | 210 |
| 208 if (FLAG_trace_deopt) { | 211 if (FLAG_trace_deopt) { |
| 209 PrintF("[forced deoptimization: "); | 212 PrintF("[forced deoptimization: "); |
| 210 function->PrintName(); | 213 function->PrintName(); |
| 211 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); | 214 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 } | 745 } |
| 743 __ bind(&done); | 746 __ bind(&done); |
| 744 } | 747 } |
| 745 | 748 |
| 746 #undef __ | 749 #undef __ |
| 747 | 750 |
| 748 | 751 |
| 749 } } // namespace v8::internal | 752 } } // namespace v8::internal |
| 750 | 753 |
| 751 #endif // V8_TARGET_ARCH_IA32 | 754 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |