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 |