OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/wasm/wasm-debug.h" | 5 #include "src/wasm/wasm-debug.h" |
6 | 6 |
7 #include "src/assert-scope.h" | 7 #include "src/assert-scope.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/isolate.h" | 10 #include "src/isolate.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 kWasmDebugInfoNumEntries | 25 kWasmDebugInfoNumEntries |
26 }; | 26 }; |
27 | 27 |
28 ByteArray *GetOrCreateFunctionOffsetTable(Handle<WasmDebugInfo> debug_info) { | 28 ByteArray *GetOrCreateFunctionOffsetTable(Handle<WasmDebugInfo> debug_info) { |
29 Object *offset_table = debug_info->get(kWasmDebugInfoFunctionByteOffsets); | 29 Object *offset_table = debug_info->get(kWasmDebugInfoFunctionByteOffsets); |
30 Isolate *isolate = debug_info->GetIsolate(); | 30 Isolate *isolate = debug_info->GetIsolate(); |
31 if (!offset_table->IsUndefined(isolate)) return ByteArray::cast(offset_table); | 31 if (!offset_table->IsUndefined(isolate)) return ByteArray::cast(offset_table); |
32 | 32 |
33 FunctionOffsetsResult function_offsets; | 33 FunctionOffsetsResult function_offsets; |
34 { | 34 { |
35 Handle<JSObject> wasm_object(debug_info->wasm_object(), isolate); | 35 Handle<JSObject> wasm_instance(debug_info->wasm_instance(), isolate); |
36 uint32_t num_imported_functions = | 36 uint32_t num_imported_functions = |
37 static_cast<uint32_t>(wasm::GetNumImportedFunctions(wasm_object)); | 37 static_cast<uint32_t>(wasm::GetNumImportedFunctions(wasm_instance)); |
38 Handle<SeqOneByteString> wasm_bytes = wasm::GetWasmBytes(wasm_object); | 38 Handle<SeqOneByteString> wasm_bytes = wasm::GetWasmBytes(wasm_instance); |
39 DisallowHeapAllocation no_gc; | 39 DisallowHeapAllocation no_gc; |
40 const byte *bytes_start = wasm_bytes->GetChars(); | 40 const byte *bytes_start = wasm_bytes->GetChars(); |
41 const byte *bytes_end = bytes_start + wasm_bytes->length(); | 41 const byte *bytes_end = bytes_start + wasm_bytes->length(); |
42 function_offsets = wasm::DecodeWasmFunctionOffsets(bytes_start, bytes_end, | 42 function_offsets = wasm::DecodeWasmFunctionOffsets(bytes_start, bytes_end, |
43 num_imported_functions); | 43 num_imported_functions); |
44 } | 44 } |
45 DCHECK(function_offsets.ok()); | 45 DCHECK(function_offsets.ok()); |
46 size_t array_size = 2 * kIntSize * function_offsets.val.size(); | 46 size_t array_size = 2 * kIntSize * function_offsets.val.size(); |
47 CHECK_LE(array_size, static_cast<size_t>(kMaxInt)); | 47 CHECK_LE(array_size, static_cast<size_t>(kMaxInt)); |
48 ByteArray *arr = | 48 ByteArray *arr = |
(...skipping 16 matching lines...) Expand all Loading... |
65 | 65 |
66 int offset = arr->get_int(2 * func_index); | 66 int offset = arr->get_int(2 * func_index); |
67 int length = arr->get_int(2 * func_index + 1); | 67 int length = arr->get_int(2 * func_index + 1); |
68 // Assert that it's distinguishable from the "illegal function index" return. | 68 // Assert that it's distinguishable from the "illegal function index" return. |
69 DCHECK(offset > 0 && length > 0); | 69 DCHECK(offset > 0 && length > 0); |
70 return {offset, length}; | 70 return {offset, length}; |
71 } | 71 } |
72 | 72 |
73 Vector<const uint8_t> GetFunctionBytes(Handle<WasmDebugInfo> debug_info, | 73 Vector<const uint8_t> GetFunctionBytes(Handle<WasmDebugInfo> debug_info, |
74 int func_index) { | 74 int func_index) { |
75 Handle<JSObject> wasm_object(debug_info->wasm_object()); | 75 Handle<JSObject> wasm_instance(debug_info->wasm_instance()); |
76 Handle<SeqOneByteString> module_bytes = wasm::GetWasmBytes(wasm_object); | 76 Handle<SeqOneByteString> module_bytes = wasm::GetWasmBytes(wasm_instance); |
77 std::pair<int, int> offset_and_length = | 77 std::pair<int, int> offset_and_length = |
78 GetFunctionOffsetAndLength(debug_info, func_index); | 78 GetFunctionOffsetAndLength(debug_info, func_index); |
79 return Vector<const uint8_t>( | 79 return Vector<const uint8_t>( |
80 module_bytes->GetChars() + offset_and_length.first, | 80 module_bytes->GetChars() + offset_and_length.first, |
81 offset_and_length.second); | 81 offset_and_length.second); |
82 } | 82 } |
83 | 83 |
84 FixedArray *GetOffsetTables(Handle<WasmDebugInfo> debug_info, | 84 FixedArray *GetOffsetTables(Handle<WasmDebugInfo> debug_info, |
85 Isolate *isolate) { | 85 Isolate *isolate) { |
86 Object *offset_tables = debug_info->get(kWasmDebugInfoAsmJsOffsets); | 86 Object *offset_tables = debug_info->get(kWasmDebugInfoAsmJsOffsets); |
87 if (!offset_tables->IsUndefined(isolate)) { | 87 if (!offset_tables->IsUndefined(isolate)) { |
88 return FixedArray::cast(offset_tables); | 88 return FixedArray::cast(offset_tables); |
89 } | 89 } |
90 | 90 |
91 AsmJsOffsetsResult asm_offsets; | 91 AsmJsOffsetsResult asm_offsets; |
92 { | 92 { |
93 Handle<JSObject> wasm_object(debug_info->wasm_object(), isolate); | 93 Handle<JSObject> wasm_instance(debug_info->wasm_instance(), isolate); |
94 Handle<WasmCompiledModule> compiled_module = | 94 Handle<WasmCompiledModule> compiled_module = |
95 handle(GetCompiledModule(*wasm_object), isolate); | 95 handle(GetCompiledModule(*wasm_instance), isolate); |
96 DCHECK(compiled_module->has_asm_js_offset_tables()); | 96 DCHECK(compiled_module->has_asm_js_offset_tables()); |
97 Handle<ByteArray> asm_offset_tables = | 97 Handle<ByteArray> asm_offset_tables = |
98 compiled_module->asm_js_offset_tables(); | 98 compiled_module->asm_js_offset_tables(); |
99 uint32_t num_imported_functions = | 99 uint32_t num_imported_functions = |
100 static_cast<uint32_t>(wasm::GetNumImportedFunctions(wasm_object)); | 100 static_cast<uint32_t>(wasm::GetNumImportedFunctions(wasm_instance)); |
101 DisallowHeapAllocation no_gc; | 101 DisallowHeapAllocation no_gc; |
102 const byte *bytes_start = asm_offset_tables->GetDataStartAddress(); | 102 const byte *bytes_start = asm_offset_tables->GetDataStartAddress(); |
103 const byte *bytes_end = bytes_start + asm_offset_tables->length(); | 103 const byte *bytes_end = bytes_start + asm_offset_tables->length(); |
104 asm_offsets = wasm::DecodeAsmJsOffsets(bytes_start, bytes_end, | 104 asm_offsets = wasm::DecodeAsmJsOffsets(bytes_start, bytes_end, |
105 num_imported_functions); | 105 num_imported_functions); |
106 } | 106 } |
107 // Wasm bytes must be valid and must contain asm.js offset table. | 107 // Wasm bytes must be valid and must contain asm.js offset table. |
108 DCHECK(asm_offsets.ok()); | 108 DCHECK(asm_offsets.ok()); |
109 DCHECK_GE(static_cast<size_t>(kMaxInt), asm_offsets.val.size()); | 109 DCHECK_GE(static_cast<size_t>(kMaxInt), asm_offsets.val.size()); |
110 int num_functions = static_cast<int>(asm_offsets.val.size()); | 110 int num_functions = static_cast<int>(asm_offsets.val.size()); |
111 DCHECK_EQ(wasm::GetNumberOfFunctions(handle(debug_info->wasm_object())), | 111 DCHECK_EQ(wasm::GetNumberOfFunctions(handle(debug_info->wasm_instance())), |
112 num_functions); | 112 num_functions); |
113 Handle<FixedArray> all_tables = | 113 Handle<FixedArray> all_tables = |
114 isolate->factory()->NewFixedArray(num_functions); | 114 isolate->factory()->NewFixedArray(num_functions); |
115 debug_info->set(kWasmDebugInfoAsmJsOffsets, *all_tables); | 115 debug_info->set(kWasmDebugInfoAsmJsOffsets, *all_tables); |
116 for (int func = 0; func < num_functions; ++func) { | 116 for (int func = 0; func < num_functions; ++func) { |
117 std::vector<std::pair<int, int>> &func_asm_offsets = asm_offsets.val[func]; | 117 std::vector<std::pair<int, int>> &func_asm_offsets = asm_offsets.val[func]; |
118 if (func_asm_offsets.empty()) continue; | 118 if (func_asm_offsets.empty()) continue; |
119 size_t array_size = 2 * kIntSize * func_asm_offsets.size(); | 119 size_t array_size = 2 * kIntSize * func_asm_offsets.size(); |
120 CHECK_LE(array_size, static_cast<size_t>(kMaxInt)); | 120 CHECK_LE(array_size, static_cast<size_t>(kMaxInt)); |
121 ByteArray *arr = | 121 ByteArray *arr = |
(...skipping 29 matching lines...) Expand all Loading... |
151 arr->set(kWasmDebugInfoWasmBytesHash, *hash_obj); | 151 arr->set(kWasmDebugInfoWasmBytesHash, *hash_obj); |
152 | 152 |
153 return Handle<WasmDebugInfo>::cast(arr); | 153 return Handle<WasmDebugInfo>::cast(arr); |
154 } | 154 } |
155 | 155 |
156 bool WasmDebugInfo::IsDebugInfo(Object *object) { | 156 bool WasmDebugInfo::IsDebugInfo(Object *object) { |
157 if (!object->IsFixedArray()) return false; | 157 if (!object->IsFixedArray()) return false; |
158 FixedArray *arr = FixedArray::cast(object); | 158 FixedArray *arr = FixedArray::cast(object); |
159 Isolate *isolate = arr->GetIsolate(); | 159 Isolate *isolate = arr->GetIsolate(); |
160 return arr->length() == kWasmDebugInfoNumEntries && | 160 return arr->length() == kWasmDebugInfoNumEntries && |
161 IsWasmObject(arr->get(kWasmDebugInfoWasmObj)) && | 161 IsWasmInstance(arr->get(kWasmDebugInfoWasmObj)) && |
162 arr->get(kWasmDebugInfoWasmBytesHash)->IsNumber() && | 162 arr->get(kWasmDebugInfoWasmBytesHash)->IsNumber() && |
163 (arr->get(kWasmDebugInfoFunctionByteOffsets)->IsUndefined(isolate) || | 163 (arr->get(kWasmDebugInfoFunctionByteOffsets)->IsUndefined(isolate) || |
164 arr->get(kWasmDebugInfoFunctionByteOffsets)->IsByteArray()) && | 164 arr->get(kWasmDebugInfoFunctionByteOffsets)->IsByteArray()) && |
165 (arr->get(kWasmDebugInfoFunctionScripts)->IsUndefined(isolate) || | 165 (arr->get(kWasmDebugInfoFunctionScripts)->IsUndefined(isolate) || |
166 arr->get(kWasmDebugInfoFunctionScripts)->IsFixedArray()); | 166 arr->get(kWasmDebugInfoFunctionScripts)->IsFixedArray()); |
167 } | 167 } |
168 | 168 |
169 WasmDebugInfo *WasmDebugInfo::cast(Object *object) { | 169 WasmDebugInfo *WasmDebugInfo::cast(Object *object) { |
170 DCHECK(IsDebugInfo(object)); | 170 DCHECK(IsDebugInfo(object)); |
171 return reinterpret_cast<WasmDebugInfo *>(object); | 171 return reinterpret_cast<WasmDebugInfo *>(object); |
172 } | 172 } |
173 | 173 |
174 JSObject *WasmDebugInfo::wasm_object() { | 174 JSObject *WasmDebugInfo::wasm_instance() { |
175 return JSObject::cast(get(kWasmDebugInfoWasmObj)); | 175 return JSObject::cast(get(kWasmDebugInfoWasmObj)); |
176 } | 176 } |
177 | 177 |
178 Script *WasmDebugInfo::GetFunctionScript(Handle<WasmDebugInfo> debug_info, | 178 Script *WasmDebugInfo::GetFunctionScript(Handle<WasmDebugInfo> debug_info, |
179 int func_index) { | 179 int func_index) { |
180 Isolate *isolate = debug_info->GetIsolate(); | 180 Isolate *isolate = debug_info->GetIsolate(); |
181 Object *scripts_obj = debug_info->get(kWasmDebugInfoFunctionScripts); | 181 Object *scripts_obj = debug_info->get(kWasmDebugInfoFunctionScripts); |
182 Handle<FixedArray> scripts; | 182 Handle<FixedArray> scripts; |
183 if (scripts_obj->IsUndefined(isolate)) { | 183 if (scripts_obj->IsUndefined(isolate)) { |
184 Handle<JSObject> wasm_object(debug_info->wasm_object(), isolate); | 184 Handle<JSObject> wasm_instance(debug_info->wasm_instance(), isolate); |
185 int num_functions = wasm::GetNumberOfFunctions(wasm_object); | 185 int num_functions = wasm::GetNumberOfFunctions(wasm_instance); |
186 scripts = isolate->factory()->NewFixedArray(num_functions, TENURED); | 186 scripts = isolate->factory()->NewFixedArray(num_functions, TENURED); |
187 debug_info->set(kWasmDebugInfoFunctionScripts, *scripts); | 187 debug_info->set(kWasmDebugInfoFunctionScripts, *scripts); |
188 } else { | 188 } else { |
189 scripts = handle(FixedArray::cast(scripts_obj), isolate); | 189 scripts = handle(FixedArray::cast(scripts_obj), isolate); |
190 } | 190 } |
191 | 191 |
192 DCHECK(func_index >= 0 && func_index < scripts->length()); | 192 DCHECK(func_index >= 0 && func_index < scripts->length()); |
193 Object *script_or_undef = scripts->get(func_index); | 193 Object *script_or_undef = scripts->get(func_index); |
194 if (!script_or_undef->IsUndefined(isolate)) { | 194 if (!script_or_undef->IsUndefined(isolate)) { |
195 return Script::cast(script_or_undef); | 195 return Script::cast(script_or_undef); |
196 } | 196 } |
197 | 197 |
198 Handle<Script> script = | 198 Handle<Script> script = |
199 isolate->factory()->NewScript(isolate->factory()->empty_string()); | 199 isolate->factory()->NewScript(isolate->factory()->empty_string()); |
200 scripts->set(func_index, *script); | 200 scripts->set(func_index, *script); |
201 | 201 |
202 script->set_type(Script::TYPE_WASM); | 202 script->set_type(Script::TYPE_WASM); |
203 script->set_wasm_object(debug_info->wasm_object()); | 203 script->set_wasm_instance(debug_info->wasm_instance()); |
204 script->set_wasm_function_index(func_index); | 204 script->set_wasm_function_index(func_index); |
205 | 205 |
206 int hash = 0; | 206 int hash = 0; |
207 debug_info->get(kWasmDebugInfoWasmBytesHash)->ToInt32(&hash); | 207 debug_info->get(kWasmDebugInfoWasmBytesHash)->ToInt32(&hash); |
208 char buffer[32]; | 208 char buffer[32]; |
209 SNPrintF(ArrayVector(buffer), "wasm://%08x/%d", hash, func_index); | 209 SNPrintF(ArrayVector(buffer), "wasm://%08x/%d", hash, func_index); |
210 Handle<String> source_url = | 210 Handle<String> source_url = |
211 isolate->factory()->NewStringFromAsciiChecked(buffer, TENURED); | 211 isolate->factory()->NewStringFromAsciiChecked(buffer, TENURED); |
212 script->set_source_url(*source_url); | 212 script->set_source_url(*source_url); |
213 | 213 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 left = mid; | 307 left = mid; |
308 } else { | 308 } else { |
309 right = mid; | 309 right = mid; |
310 } | 310 } |
311 } | 311 } |
312 // There should be an entry for each position that could show up on the stack | 312 // There should be an entry for each position that could show up on the stack |
313 // trace: | 313 // trace: |
314 DCHECK_EQ(byte_offset, offset_table->get_int(2 * left)); | 314 DCHECK_EQ(byte_offset, offset_table->get_int(2 * left)); |
315 return offset_table->get_int(2 * left + 1); | 315 return offset_table->get_int(2 * left + 1); |
316 } | 316 } |
OLD | NEW |