| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/debug/liveedit.h" | 5 #include "src/debug/liveedit.h" |
| 6 | 6 |
| 7 #include "src/ast/scopeinfo.h" | 7 #include "src/ast/scopeinfo.h" |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
| 11 #include "src/compiler.h" | 11 #include "src/compiler.h" |
| 12 #include "src/debug/debug.h" | 12 #include "src/debug/debug.h" |
| 13 #include "src/deoptimizer.h" | 13 #include "src/deoptimizer.h" |
| 14 #include "src/frames-inl.h" | 14 #include "src/frames-inl.h" |
| 15 #include "src/global-handles.h" | 15 #include "src/global-handles.h" |
| 16 #include "src/interpreter/source-position-table.h" | |
| 17 #include "src/isolate-inl.h" | 16 #include "src/isolate-inl.h" |
| 18 #include "src/messages.h" | 17 #include "src/messages.h" |
| 19 #include "src/parsing/parser.h" | 18 #include "src/parsing/parser.h" |
| 19 #include "src/source-position-table.h" |
| 20 #include "src/v8.h" | 20 #include "src/v8.h" |
| 21 #include "src/v8memory.h" | 21 #include "src/v8memory.h" |
| 22 | 22 |
| 23 namespace v8 { | 23 namespace v8 { |
| 24 namespace internal { | 24 namespace internal { |
| 25 | 25 |
| 26 void SetElementSloppy(Handle<JSObject> object, | 26 void SetElementSloppy(Handle<JSObject> object, |
| 27 uint32_t index, | 27 uint32_t index, |
| 28 Handle<Object> value) { | 28 Handle<Object> value) { |
| 29 // Ignore return value from SetElement. It can only be a failure if there | 29 // Ignore return value from SetElement. It can only be a failure if there |
| (...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1189 | 1189 |
| 1190 RelocInfoWriter reloc_info_writer_; | 1190 RelocInfoWriter reloc_info_writer_; |
| 1191 byte* buffer_; | 1191 byte* buffer_; |
| 1192 int buffer_size_; | 1192 int buffer_size_; |
| 1193 | 1193 |
| 1194 static const int kBufferGap = RelocInfoWriter::kMaxSize; | 1194 static const int kBufferGap = RelocInfoWriter::kMaxSize; |
| 1195 static const int kMaximalBufferSize = 512*MB; | 1195 static const int kMaximalBufferSize = 512*MB; |
| 1196 }; | 1196 }; |
| 1197 | 1197 |
| 1198 namespace { | 1198 namespace { |
| 1199 // Patch positions in code (changes relocation info section) and possibly | 1199 Handle<ByteArray> TranslateSourcePositionTable( |
| 1200 // returns new instance of code. | 1200 Handle<ByteArray> source_position_table, |
| 1201 Handle<Code> PatchPositionsInCode(Handle<Code> code, | 1201 Handle<JSArray> position_change_array) { |
| 1202 Handle<JSArray> position_change_array) { | 1202 Isolate* isolate = source_position_table->GetIsolate(); |
| 1203 Isolate* isolate = code->GetIsolate(); | 1203 Zone zone(isolate->allocator()); |
| 1204 SourcePositionTableBuilder builder(isolate, &zone); |
| 1204 | 1205 |
| 1205 RelocInfoBuffer buffer_writer(code->relocation_size(), | 1206 for (SourcePositionTableIterator iterator(*source_position_table); |
| 1206 code->instruction_start()); | |
| 1207 | |
| 1208 { | |
| 1209 for (RelocIterator it(*code); !it.done(); it.next()) { | |
| 1210 RelocInfo* rinfo = it.rinfo(); | |
| 1211 if (RelocInfo::IsPosition(rinfo->rmode())) { | |
| 1212 int position = static_cast<int>(rinfo->data()); | |
| 1213 int new_position = TranslatePosition(position, | |
| 1214 position_change_array); | |
| 1215 if (position != new_position) { | |
| 1216 RelocInfo info_copy(rinfo->isolate(), rinfo->pc(), rinfo->rmode(), | |
| 1217 new_position, NULL); | |
| 1218 buffer_writer.Write(&info_copy); | |
| 1219 continue; | |
| 1220 } | |
| 1221 } | |
| 1222 if (RelocInfo::IsRealRelocMode(rinfo->rmode())) { | |
| 1223 buffer_writer.Write(it.rinfo()); | |
| 1224 } | |
| 1225 } | |
| 1226 } | |
| 1227 | |
| 1228 Vector<byte> buffer = buffer_writer.GetResult(); | |
| 1229 Handle<ByteArray> reloc_info = | |
| 1230 isolate->factory()->NewByteArray(buffer.length(), TENURED); | |
| 1231 | |
| 1232 DisallowHeapAllocation no_gc; | |
| 1233 code->set_relocation_info(*reloc_info); | |
| 1234 CopyBytes(code->relocation_start(), buffer.start(), buffer.length()); | |
| 1235 return code; | |
| 1236 } | |
| 1237 | |
| 1238 void PatchPositionsInBytecodeArray(Handle<BytecodeArray> bytecode, | |
| 1239 Handle<JSArray> position_change_array) { | |
| 1240 Isolate* isolate = bytecode->GetIsolate(); | |
| 1241 Zone zone(isolate->allocator()); | |
| 1242 interpreter::SourcePositionTableBuilder builder(isolate, &zone); | |
| 1243 | |
| 1244 for (interpreter::SourcePositionTableIterator iterator( | |
| 1245 bytecode->source_position_table()); | |
| 1246 !iterator.done(); iterator.Advance()) { | 1207 !iterator.done(); iterator.Advance()) { |
| 1247 int position = iterator.source_position(); | 1208 int position = iterator.source_position(); |
| 1248 int new_position = TranslatePosition(position, position_change_array); | 1209 int new_position = TranslatePosition(position, position_change_array); |
| 1249 builder.AddPosition(iterator.bytecode_offset(), new_position, | 1210 builder.AddPosition(iterator.code_offset(), new_position, |
| 1250 iterator.is_statement()); | 1211 iterator.is_statement()); |
| 1251 } | 1212 } |
| 1252 | 1213 |
| 1253 Handle<ByteArray> source_position_table = builder.ToSourcePositionTable(); | 1214 return builder.ToSourcePositionTable(); |
| 1254 bytecode->set_source_position_table(*source_position_table); | |
| 1255 } | 1215 } |
| 1256 } // namespace | 1216 } // namespace |
| 1257 | 1217 |
| 1258 void LiveEdit::PatchFunctionPositions(Handle<JSArray> shared_info_array, | 1218 void LiveEdit::PatchFunctionPositions(Handle<JSArray> shared_info_array, |
| 1259 Handle<JSArray> position_change_array) { | 1219 Handle<JSArray> position_change_array) { |
| 1260 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 1220 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
| 1261 Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo(); | 1221 Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo(); |
| 1262 | 1222 |
| 1263 int old_function_start = info->start_position(); | 1223 int old_function_start = info->start_position(); |
| 1264 int new_function_start = TranslatePosition(old_function_start, | 1224 int new_function_start = TranslatePosition(old_function_start, |
| 1265 position_change_array); | 1225 position_change_array); |
| 1266 int new_function_end = TranslatePosition(info->end_position(), | 1226 int new_function_end = TranslatePosition(info->end_position(), |
| 1267 position_change_array); | 1227 position_change_array); |
| 1268 int new_function_token_pos = | 1228 int new_function_token_pos = |
| 1269 TranslatePosition(info->function_token_position(), position_change_array); | 1229 TranslatePosition(info->function_token_position(), position_change_array); |
| 1270 | 1230 |
| 1271 info->set_start_position(new_function_start); | 1231 info->set_start_position(new_function_start); |
| 1272 info->set_end_position(new_function_end); | 1232 info->set_end_position(new_function_end); |
| 1273 info->set_function_token_position(new_function_token_pos); | 1233 info->set_function_token_position(new_function_token_pos); |
| 1274 | 1234 |
| 1275 if (info->code()->kind() == Code::FUNCTION) { | 1235 if (info->code()->kind() == Code::FUNCTION) { |
| 1276 // Patch relocation info section of the code. | 1236 Handle<ByteArray> new_source_position_table = TranslateSourcePositionTable( |
| 1277 Handle<Code> patched_code = PatchPositionsInCode(Handle<Code>(info->code()), | 1237 Handle<ByteArray>(info->code()->source_position_table()), |
| 1278 position_change_array); | 1238 position_change_array); |
| 1279 if (*patched_code != info->code()) { | 1239 info->code()->set_source_position_table(*new_source_position_table); |
| 1280 // Replace all references to the code across the heap. In particular, | |
| 1281 // some stubs may refer to this code and this code may be being executed | |
| 1282 // on stack (it is safe to substitute the code object on stack, because | |
| 1283 // we only change the structure of rinfo and leave instructions | |
| 1284 // untouched). | |
| 1285 ReplaceCodeObject(Handle<Code>(info->code()), patched_code); | |
| 1286 } | |
| 1287 } else if (info->HasBytecodeArray()) { | 1240 } else if (info->HasBytecodeArray()) { |
| 1288 PatchPositionsInBytecodeArray(Handle<BytecodeArray>(info->bytecode_array()), | 1241 Handle<ByteArray> new_source_position_table = TranslateSourcePositionTable( |
| 1289 position_change_array); | 1242 Handle<ByteArray>(info->bytecode_array()->source_position_table()), |
| 1243 position_change_array); |
| 1244 info->bytecode_array()->set_source_position_table( |
| 1245 *new_source_position_table); |
| 1246 } |
| 1247 |
| 1248 if (info->HasDebugInfo()) { |
| 1249 // Existing break points will be re-applied. Reset the debug info here. |
| 1250 info->GetIsolate()->debug()->RemoveDebugInfoAndClearFromShared( |
| 1251 handle(info->GetDebugInfo())); |
| 1290 } | 1252 } |
| 1291 } | 1253 } |
| 1292 | 1254 |
| 1293 | 1255 |
| 1294 static Handle<Script> CreateScriptCopy(Handle<Script> original) { | 1256 static Handle<Script> CreateScriptCopy(Handle<Script> original) { |
| 1295 Isolate* isolate = original->GetIsolate(); | 1257 Isolate* isolate = original->GetIsolate(); |
| 1296 | 1258 |
| 1297 Handle<String> original_source(String::cast(original->source())); | 1259 Handle<String> original_source(String::cast(original->source())); |
| 1298 Handle<Script> copy = isolate->factory()->NewScript(original_source); | 1260 Handle<Script> copy = isolate->factory()->NewScript(original_source); |
| 1299 | 1261 |
| (...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2060 scope_info_length++; | 2022 scope_info_length++; |
| 2061 | 2023 |
| 2062 current_scope = current_scope->outer_scope(); | 2024 current_scope = current_scope->outer_scope(); |
| 2063 } | 2025 } |
| 2064 | 2026 |
| 2065 return scope_info_list; | 2027 return scope_info_list; |
| 2066 } | 2028 } |
| 2067 | 2029 |
| 2068 } // namespace internal | 2030 } // namespace internal |
| 2069 } // namespace v8 | 2031 } // namespace v8 |
| OLD | NEW |