OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 <memory> | 5 #include <memory> |
6 | 6 |
7 #include "src/base/atomic-utils.h" | 7 #include "src/base/atomic-utils.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 | 9 |
10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 kWasmMemArrayBuffer, | 165 kWasmMemArrayBuffer, |
166 kWasmGlobalsArrayBuffer, | 166 kWasmGlobalsArrayBuffer, |
167 // TODO(clemensh): Remove function name array, extract names from module | 167 // TODO(clemensh): Remove function name array, extract names from module |
168 // bytes. | 168 // bytes. |
169 kWasmFunctionNamesArray, | 169 kWasmFunctionNamesArray, |
170 kWasmModuleBytesString, | 170 kWasmModuleBytesString, |
171 kWasmDebugInfo, | 171 kWasmDebugInfo, |
172 kWasmModuleInternalFieldCount | 172 kWasmModuleInternalFieldCount |
173 }; | 173 }; |
174 | 174 |
175 // TODO(mtrofin): Unnecessary once we stop using JS Heap for wasm code. | 175 // // TODO(mtrofin): Unnecessary once we stop using JS Heap for wasm code. |
176 // For now, each field is expected to have the type commented by its side. | 176 // // For now, each field is expected to have the type commented by its side. |
177 // The elements typed as "maybe" are optional. The others are mandatory. Since | 177 // // The elements typed as "maybe" are optional. The others are mandatory. |
178 // the compiled module is either obtained from the current v8 instance, or from | 178 // Since |
179 // a snapshot produced by a compatible (==identical) v8 instance, we simply | 179 // // the compiled module is either obtained from the current v8 instance, or |
180 // fail at instantiation time, in the face of invalid data. | 180 // from |
181 enum CompiledWasmObjectFields { | 181 // // a snapshot produced by a compatible (==identical) v8 instance, we simply |
182 kFunctions, // FixedArray of Code | 182 // // fail at instantiation time, in the face of invalid data. |
183 kImportData, // maybe FixedArray of FixedArray respecting the | |
184 // WasmImportMetadata structure. | |
185 kImportMap, // FixedArray. The i-th element is the Code object used for | |
186 // import i | |
187 kExports, // maybe FixedArray of FixedArray of WasmExportMetadata | |
188 // structure | |
189 kStartupFunction, // maybe FixedArray of WasmExportMetadata structure | |
190 kTableOfIndirectFunctionTables, // maybe FixedArray of FixedArray of | |
191 // WasmIndirectFunctionTableMetadata | |
192 kModuleBytes, // maybe String | |
193 kFunctionNameTable, // maybe ByteArray | |
194 kMinRequiredMemory, // Smi. an uint32_t | |
195 // The following 2 are either together present or absent: | |
196 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the | |
197 // WasmSegmentInfo structure | |
198 kDataSegments, // maybe ByteArray. | |
199 | |
200 kGlobalsSize, // Smi. an uint32_t | |
201 kMemSize, // Smi.an uint32_t | |
202 kMemStart, // MaybeHandle<ArrayBuffer> | |
203 kExportMem, // Smi. bool | |
204 kOrigin, // Smi. ModuleOrigin | |
205 kNextInstance, // WeakCell. See compiled code cloning. | |
206 kPrevInstance, // WeakCell. See compiled code cloning. | |
207 kOwningInstance, // WeakCell, pointing to the owning instance. | |
208 kModuleObject, // WeakCell, pointing to the module object. | |
209 kCompiledWasmObjectTableSize // Sentinel value. | |
210 }; | |
211 | |
212 enum WasmImportMetadata { | 183 enum WasmImportMetadata { |
213 kModuleName, // String | 184 kModuleName, // String |
214 kFunctionName, // maybe String | 185 kFunctionName, // maybe String |
215 kOutputCount, // Smi. an uint32_t | 186 kOutputCount, // Smi. an uint32_t |
216 kSignature, // ByteArray. A copy of the data in FunctionSig | 187 kSignature, // ByteArray. A copy of the data in FunctionSig |
217 kWasmImportDataTableSize // Sentinel value. | 188 kWasmImportDataTableSize // Sentinel value. |
218 }; | 189 }; |
219 | 190 |
220 enum WasmExportMetadata { | 191 enum WasmExportMetadata { |
221 kExportCode, // Code | 192 kExportCode, // Code |
(...skipping 13 matching lines...) Expand all Loading... |
235 enum WasmIndirectFunctionTableMetadata { | 206 enum WasmIndirectFunctionTableMetadata { |
236 kSize, // Smi. an uint32_t | 207 kSize, // Smi. an uint32_t |
237 kTable, // FixedArray of indirect function table | 208 kTable, // FixedArray of indirect function table |
238 kWasmIndirectFunctionTableMetadataSize // Sentinel value. | 209 kWasmIndirectFunctionTableMetadataSize // Sentinel value. |
239 }; | 210 }; |
240 | 211 |
241 uint32_t GetMinModuleMemSize(const WasmModule* module) { | 212 uint32_t GetMinModuleMemSize(const WasmModule* module) { |
242 return WasmModule::kPageSize * module->min_mem_pages; | 213 return WasmModule::kPageSize * module->min_mem_pages; |
243 } | 214 } |
244 | 215 |
245 void LoadDataSegments(Handle<FixedArray> compiled_module, Address mem_addr, | 216 void LoadDataSegments(Handle<WasmCompiledModule> compiled_module, |
246 size_t mem_size) { | 217 Address mem_addr, size_t mem_size) { |
247 Isolate* isolate = compiled_module->GetIsolate(); | 218 Isolate* isolate = compiled_module->GetIsolate(); |
248 MaybeHandle<ByteArray> maybe_data = | |
249 compiled_module->GetValue<ByteArray>(isolate, kDataSegments); | |
250 MaybeHandle<FixedArray> maybe_segments = | |
251 compiled_module->GetValue<FixedArray>(isolate, kDataSegmentsInfo); | |
252 | 219 |
253 // We either have both or neither. | 220 // We either have both or neither. |
254 CHECK(maybe_data.is_null() == maybe_segments.is_null()); | 221 CHECK(compiled_module->has_data_segments() == |
| 222 compiled_module->has_data_segments_info()); |
255 // If we have neither, we're done. | 223 // If we have neither, we're done. |
256 if (maybe_data.is_null()) return; | 224 if (!compiled_module->has_data_segments()) return; |
257 | 225 |
258 Handle<ByteArray> data = maybe_data.ToHandleChecked(); | 226 Handle<ByteArray> data = compiled_module->data_segments(); |
259 Handle<FixedArray> segments = maybe_segments.ToHandleChecked(); | 227 Handle<FixedArray> segments = compiled_module->data_segments_info(); |
260 | 228 |
261 uint32_t last_extraction_pos = 0; | 229 uint32_t last_extraction_pos = 0; |
262 for (int i = 0; i < segments->length(); ++i) { | 230 for (int i = 0; i < segments->length(); ++i) { |
263 Handle<ByteArray> segment = | 231 Handle<ByteArray> segment = |
264 Handle<ByteArray>(ByteArray::cast(segments->get(i))); | 232 Handle<ByteArray>(ByteArray::cast(segments->get(i))); |
265 uint32_t dest_addr = static_cast<uint32_t>(segment->get_int(kDestAddr)); | 233 uint32_t dest_addr = static_cast<uint32_t>(segment->get_int(kDestAddr)); |
266 uint32_t source_size = static_cast<uint32_t>(segment->get_int(kSourceSize)); | 234 uint32_t source_size = static_cast<uint32_t>(segment->get_int(kSourceSize)); |
267 CHECK_LT(dest_addr, mem_size); | 235 CHECK_LT(dest_addr, mem_size); |
268 CHECK_LE(source_size, mem_size); | 236 CHECK_LE(source_size, mem_size); |
269 CHECK_LE(dest_addr, mem_size - source_size); | 237 CHECK_LE(dest_addr, mem_size - source_size); |
270 byte* addr = mem_addr + dest_addr; | 238 byte* addr = mem_addr + dest_addr; |
271 data->copy_out(last_extraction_pos, addr, source_size); | 239 data->copy_out(last_extraction_pos, addr, source_size); |
272 last_extraction_pos += source_size; | 240 last_extraction_pos += source_size; |
273 } | 241 } |
274 } | 242 } |
275 | 243 |
276 void SaveDataSegmentInfo(Factory* factory, const WasmModule* module, | 244 void SaveDataSegmentInfo(Factory* factory, const WasmModule* module, |
277 Handle<FixedArray> compiled_module) { | 245 Handle<WasmCompiledModule> compiled_module) { |
278 Handle<FixedArray> segments = factory->NewFixedArray( | 246 Handle<FixedArray> segments = factory->NewFixedArray( |
279 static_cast<int>(module->data_segments.size()), TENURED); | 247 static_cast<int>(module->data_segments.size()), TENURED); |
280 uint32_t data_size = 0; | 248 uint32_t data_size = 0; |
281 for (const WasmDataSegment& segment : module->data_segments) { | 249 for (const WasmDataSegment& segment : module->data_segments) { |
282 if (!segment.init) continue; | 250 if (!segment.init) continue; |
283 if (segment.source_size == 0) continue; | 251 if (segment.source_size == 0) continue; |
284 data_size += segment.source_size; | 252 data_size += segment.source_size; |
285 } | 253 } |
286 Handle<ByteArray> data = factory->NewByteArray(data_size, TENURED); | 254 Handle<ByteArray> data = factory->NewByteArray(data_size, TENURED); |
287 | 255 |
288 uint32_t last_insertion_pos = 0; | 256 uint32_t last_insertion_pos = 0; |
289 for (uint32_t i = 0; i < module->data_segments.size(); ++i) { | 257 for (uint32_t i = 0; i < module->data_segments.size(); ++i) { |
290 const WasmDataSegment& segment = module->data_segments[i]; | 258 const WasmDataSegment& segment = module->data_segments[i]; |
291 if (!segment.init) continue; | 259 if (!segment.init) continue; |
292 if (segment.source_size == 0) continue; | 260 if (segment.source_size == 0) continue; |
293 Handle<ByteArray> js_segment = | 261 Handle<ByteArray> js_segment = |
294 factory->NewByteArray(kWasmSegmentInfoSize * sizeof(uint32_t), TENURED); | 262 factory->NewByteArray(kWasmSegmentInfoSize * sizeof(uint32_t), TENURED); |
295 js_segment->set_int(kDestAddr, segment.dest_addr); | 263 js_segment->set_int(kDestAddr, segment.dest_addr); |
296 js_segment->set_int(kSourceSize, segment.source_size); | 264 js_segment->set_int(kSourceSize, segment.source_size); |
297 segments->set(i, *js_segment); | 265 segments->set(i, *js_segment); |
298 data->copy_in(last_insertion_pos, | 266 data->copy_in(last_insertion_pos, |
299 module->module_start + segment.source_offset, | 267 module->module_start + segment.source_offset, |
300 segment.source_size); | 268 segment.source_size); |
301 last_insertion_pos += segment.source_size; | 269 last_insertion_pos += segment.source_size; |
302 } | 270 } |
303 compiled_module->set(kDataSegmentsInfo, *segments); | 271 compiled_module->set_data_segments_info(segments); |
304 compiled_module->set(kDataSegments, *data); | 272 compiled_module->set_data_segments(data); |
305 } | 273 } |
306 | 274 |
307 void PatchFunctionTable(Handle<Code> code, | 275 void PatchFunctionTable(Handle<Code> code, |
308 Handle<FixedArray> old_indirect_table, | 276 Handle<FixedArray> old_indirect_table, |
309 Handle<FixedArray> new_indirect_table) { | 277 Handle<FixedArray> new_indirect_table) { |
310 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done(); | 278 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done(); |
311 it.next()) { | 279 it.next()) { |
312 if (it.rinfo()->target_object() == *old_indirect_table) { | 280 if (it.rinfo()->target_object() == *old_indirect_table) { |
313 it.rinfo()->set_target_object(*new_indirect_table); | 281 it.rinfo()->set_target_object(*new_indirect_table); |
314 } | 282 } |
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 if (code.is_null()) { | 871 if (code.is_null()) { |
904 thrower->Error("Compilation of #%d:%.*s failed.", i, str.length(), | 872 thrower->Error("Compilation of #%d:%.*s failed.", i, str.length(), |
905 str.start()); | 873 str.start()); |
906 break; | 874 break; |
907 } | 875 } |
908 // Install the code into the linker table. | 876 // Install the code into the linker table. |
909 functions[i] = code; | 877 functions[i] = code; |
910 } | 878 } |
911 } | 879 } |
912 | 880 |
913 void SetDebugSupport(Factory* factory, Handle<FixedArray> compiled_module, | 881 void SetDebugSupport(Factory* factory, |
| 882 Handle<WasmCompiledModule> compiled_module, |
914 Handle<JSObject> js_object) { | 883 Handle<JSObject> js_object) { |
915 Isolate* isolate = compiled_module->GetIsolate(); | 884 Isolate* isolate = compiled_module->GetIsolate(); |
916 MaybeHandle<String> module_bytes_string = | 885 if (compiled_module->has_module_bytes()) { |
917 compiled_module->GetValue<String>(isolate, kModuleBytes); | |
918 if (!module_bytes_string.is_null()) { | |
919 js_object->SetInternalField(kWasmModuleBytesString, | 886 js_object->SetInternalField(kWasmModuleBytesString, |
920 *module_bytes_string.ToHandleChecked()); | 887 *compiled_module->module_bytes()); |
921 } | 888 } |
922 | 889 |
923 MaybeHandle<ByteArray> function_name_table = | 890 if (compiled_module->has_function_names()) { |
924 compiled_module->GetValue<ByteArray>(isolate, kFunctionNameTable); | |
925 if (!function_name_table.is_null()) { | |
926 js_object->SetInternalField(kWasmFunctionNamesArray, | 891 js_object->SetInternalField(kWasmFunctionNamesArray, |
927 *function_name_table.ToHandleChecked()); | 892 *compiled_module->function_names()); |
928 } | 893 } |
929 } | 894 } |
930 | 895 |
931 bool SetupGlobals(Isolate* isolate, MaybeHandle<JSObject> template_owner, | 896 bool SetupGlobals(Isolate* isolate, MaybeHandle<JSObject> template_owner, |
932 Handle<FixedArray> compiled_module, Handle<JSObject> instance, | 897 Handle<WasmCompiledModule> compiled_module, |
933 ErrorThrower* thrower) { | 898 Handle<JSObject> instance, ErrorThrower* thrower) { |
934 uint32_t globals_size = static_cast<uint32_t>( | 899 uint32_t globals_size = compiled_module->globals_size(); |
935 Smi::cast(compiled_module->get(kGlobalsSize))->value()); | |
936 if (globals_size > 0) { | 900 if (globals_size > 0) { |
937 Handle<JSArrayBuffer> globals_buffer = | 901 Handle<JSArrayBuffer> globals_buffer = |
938 NewArrayBuffer(isolate, globals_size); | 902 NewArrayBuffer(isolate, globals_size); |
939 if (globals_buffer.is_null()) { | 903 if (globals_buffer.is_null()) { |
940 thrower->Error("Out of memory: wasm globals"); | 904 thrower->Error("Out of memory: wasm globals"); |
941 return false; | 905 return false; |
942 } | 906 } |
943 Address old_address = | 907 Address old_address = |
944 template_owner.is_null() | 908 template_owner.is_null() |
945 ? nullptr | 909 ? nullptr |
946 : GetGlobalStartAddressFromCodeTemplate( | 910 : GetGlobalStartAddressFromCodeTemplate( |
947 *isolate->factory()->undefined_value(), | 911 *isolate->factory()->undefined_value(), |
948 JSObject::cast(*template_owner.ToHandleChecked())); | 912 JSObject::cast(*template_owner.ToHandleChecked())); |
949 RelocateGlobals(instance, old_address, | 913 RelocateGlobals(instance, old_address, |
950 static_cast<Address>(globals_buffer->backing_store())); | 914 static_cast<Address>(globals_buffer->backing_store())); |
951 instance->SetInternalField(kWasmGlobalsArrayBuffer, *globals_buffer); | 915 instance->SetInternalField(kWasmGlobalsArrayBuffer, *globals_buffer); |
952 } | 916 } |
953 return true; | 917 return true; |
954 } | 918 } |
955 | 919 |
956 bool SetupInstanceHeap(Isolate* isolate, Handle<FixedArray> compiled_module, | 920 bool SetupInstanceHeap(Isolate* isolate, |
| 921 Handle<WasmCompiledModule> compiled_module, |
957 Handle<JSObject> instance, Handle<JSArrayBuffer> memory, | 922 Handle<JSObject> instance, Handle<JSArrayBuffer> memory, |
958 ErrorThrower* thrower) { | 923 ErrorThrower* thrower) { |
959 uint32_t min_mem_pages = static_cast<uint32_t>( | 924 uint32_t min_mem_pages = compiled_module->min_required_memory(); |
960 Smi::cast(compiled_module->get(kMinRequiredMemory))->value()); | |
961 isolate->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); | 925 isolate->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); |
962 // TODO(wasm): re-enable counter for max_mem_pages when we use that field. | 926 // TODO(wasm): re-enable counter for max_mem_pages when we use that field. |
963 | 927 |
964 if (memory.is_null() && min_mem_pages > 0) { | 928 if (memory.is_null() && min_mem_pages > 0) { |
965 memory = AllocateMemory(thrower, isolate, min_mem_pages); | 929 memory = AllocateMemory(thrower, isolate, min_mem_pages); |
966 if (memory.is_null()) { | 930 if (memory.is_null()) { |
967 return false; | 931 return false; |
968 } | 932 } |
969 } | 933 } |
970 | 934 |
971 if (!memory.is_null()) { | 935 if (!memory.is_null()) { |
972 instance->SetInternalField(kWasmMemArrayBuffer, *memory); | 936 instance->SetInternalField(kWasmMemArrayBuffer, *memory); |
973 Address mem_start = static_cast<Address>(memory->backing_store()); | 937 Address mem_start = static_cast<Address>(memory->backing_store()); |
974 uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number()); | 938 uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number()); |
975 uint32_t old_mem_size = static_cast<uint32_t>( | 939 uint32_t old_mem_size = compiled_module->mem_size(); |
976 compiled_module->GetValueChecked<HeapNumber>(isolate, kMemSize) | |
977 ->value()); | |
978 MaybeHandle<JSArrayBuffer> old_mem = | |
979 compiled_module->GetValue<JSArrayBuffer>(isolate, kMemStart); | |
980 Address old_mem_start = | 940 Address old_mem_start = |
981 old_mem.is_null() | 941 compiled_module->has_mem_start() |
982 ? nullptr | 942 ? static_cast<Address>( |
983 : static_cast<Address>(old_mem.ToHandleChecked()->backing_store()); | 943 compiled_module->mem_start()->backing_store()) |
| 944 : nullptr; |
984 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size, | 945 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size, |
985 mem_size); | 946 mem_size); |
986 LoadDataSegments(compiled_module, mem_start, mem_size); | 947 LoadDataSegments(compiled_module, mem_start, mem_size); |
987 compiled_module->GetValueChecked<HeapNumber>(isolate, kMemSize) | 948 compiled_module->set_mem_size(mem_size); |
988 ->set_value(static_cast<double>(mem_size)); | 949 compiled_module->set_mem_start(memory); |
989 compiled_module->set(kMemStart, *memory); | |
990 } | 950 } |
991 return true; | 951 return true; |
992 } | 952 } |
993 | 953 |
994 void FixupFunctionsAndImports(Handle<FixedArray> old_functions, | 954 void FixupFunctionsAndImports(Handle<FixedArray> old_functions, |
995 Handle<FixedArray> new_functions, | 955 Handle<FixedArray> new_functions, |
996 MaybeHandle<FixedArray> maybe_old_imports, | 956 MaybeHandle<FixedArray> maybe_old_imports, |
997 MaybeHandle<FixedArray> maybe_new_imports) { | 957 MaybeHandle<FixedArray> maybe_new_imports) { |
998 DCHECK_EQ(new_functions->length(), old_functions->length()); | 958 DCHECK_EQ(new_functions->length(), old_functions->length()); |
999 | 959 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 DCHECK(new_code->kind() == Code::WASM_FUNCTION); | 991 DCHECK(new_code->kind() == Code::WASM_FUNCTION); |
1032 continue; | 992 continue; |
1033 } | 993 } |
1034 it.rinfo()->set_target_address(new_code->instruction_start(), | 994 it.rinfo()->set_target_address(new_code->instruction_start(), |
1035 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH); | 995 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH); |
1036 } | 996 } |
1037 } | 997 } |
1038 } | 998 } |
1039 } | 999 } |
1040 | 1000 |
1041 bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module, | 1001 bool SetupImports(Isolate* isolate, Handle<WasmCompiledModule> compiled_module, |
1042 Handle<JSObject> instance, ErrorThrower* thrower, | 1002 Handle<JSObject> instance, ErrorThrower* thrower, |
1043 Handle<JSReceiver> ffi) { | 1003 Handle<JSReceiver> ffi) { |
1044 //------------------------------------------------------------------------- | 1004 //------------------------------------------------------------------------- |
1045 // Compile wrappers to imported functions. | 1005 // Compile wrappers to imported functions. |
1046 //------------------------------------------------------------------------- | 1006 //------------------------------------------------------------------------- |
1047 std::vector<Handle<Code>> import_code; | 1007 std::vector<Handle<Code>> import_code; |
1048 MaybeHandle<FixedArray> maybe_import_data = | 1008 if (compiled_module->has_import_data()) { |
1049 compiled_module->GetValue<FixedArray>(isolate, kImportData); | |
1050 Handle<FixedArray> import_data; | |
1051 if (maybe_import_data.ToHandle(&import_data)) { | |
1052 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code, | 1009 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code, |
1053 import_data, thrower)) { | 1010 compiled_module->import_data(), |
| 1011 thrower)) { |
1054 return false; | 1012 return false; |
1055 } | 1013 } |
1056 } | 1014 } |
1057 | 1015 |
1058 RecordStats(isolate, import_code); | 1016 RecordStats(isolate, import_code); |
1059 if (import_code.empty()) return true; | 1017 if (import_code.empty()) return true; |
1060 | 1018 |
1061 Handle<FixedArray> new_imports = | 1019 Handle<FixedArray> new_imports = |
1062 isolate->factory()->NewFixedArray(static_cast<int>(import_code.size())); | 1020 isolate->factory()->NewFixedArray(static_cast<int>(import_code.size())); |
1063 for (int i = 0; i < new_imports->length(); ++i) { | 1021 for (int i = 0; i < new_imports->length(); ++i) { |
1064 new_imports->set(i, *import_code[i]); | 1022 new_imports->set(i, *import_code[i]); |
1065 } | 1023 } |
1066 compiled_module->set(kImportMap, *new_imports); | 1024 compiled_module->set_import_map(new_imports); |
1067 return true; | 1025 return true; |
1068 } | 1026 } |
1069 | 1027 |
1070 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate, | 1028 bool SetupExportsObject(Handle<WasmCompiledModule> compiled_module, |
1071 Handle<JSObject> instance, ErrorThrower* thrower) { | 1029 Isolate* isolate, Handle<JSObject> instance, |
| 1030 ErrorThrower* thrower) { |
1072 Factory* factory = isolate->factory(); | 1031 Factory* factory = isolate->factory(); |
1073 bool mem_export = | 1032 bool mem_export = compiled_module->export_memory(); |
1074 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value()); | 1033 ModuleOrigin origin = compiled_module->origin(); |
1075 ModuleOrigin origin = static_cast<ModuleOrigin>( | |
1076 Smi::cast(compiled_module->get(kOrigin))->value()); | |
1077 | 1034 |
1078 MaybeHandle<FixedArray> maybe_exports = | 1035 if (compiled_module->has_exports() || mem_export) { |
1079 compiled_module->GetValue<FixedArray>(isolate, kExports); | |
1080 if (!maybe_exports.is_null() || mem_export) { | |
1081 PropertyDescriptor desc; | 1036 PropertyDescriptor desc; |
1082 desc.set_writable(false); | 1037 desc.set_writable(false); |
1083 | 1038 |
1084 Handle<JSObject> exports_object = instance; | 1039 Handle<JSObject> exports_object = instance; |
1085 if (origin == kWasmOrigin) { | 1040 if (origin == kWasmOrigin) { |
1086 // Create the "exports" object. | 1041 // Create the "exports" object. |
1087 Handle<JSFunction> object_function = Handle<JSFunction>( | 1042 Handle<JSFunction> object_function = Handle<JSFunction>( |
1088 isolate->native_context()->object_function(), isolate); | 1043 isolate->native_context()->object_function(), isolate); |
1089 exports_object = factory->NewJSObject(object_function, TENURED); | 1044 exports_object = factory->NewJSObject(object_function, TENURED); |
1090 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); | 1045 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); |
1091 JSObject::AddProperty(instance, exports_name, exports_object, READ_ONLY); | 1046 JSObject::AddProperty(instance, exports_name, exports_object, READ_ONLY); |
1092 } | 1047 } |
1093 Handle<FixedArray> exports; | 1048 if (compiled_module->has_exports()) { |
1094 if (maybe_exports.ToHandle(&exports)) { | 1049 Handle<FixedArray> exports = compiled_module->exports(); |
1095 int exports_size = exports->length(); | 1050 int exports_size = exports->length(); |
1096 for (int i = 0; i < exports_size; ++i) { | 1051 for (int i = 0; i < exports_size; ++i) { |
1097 if (thrower->error()) return false; | 1052 if (thrower->error()) return false; |
1098 Handle<FixedArray> export_metadata = | 1053 Handle<FixedArray> export_metadata = |
1099 exports->GetValueChecked<FixedArray>(isolate, i); | 1054 exports->GetValueChecked<FixedArray>(isolate, i); |
1100 Handle<Code> export_code = | 1055 Handle<Code> export_code = |
1101 export_metadata->GetValueChecked<Code>(isolate, kExportCode); | 1056 export_metadata->GetValueChecked<Code>(isolate, kExportCode); |
1102 RecordStats(isolate, *export_code); | 1057 RecordStats(isolate, *export_code); |
1103 Handle<String> name = | 1058 Handle<String> name = |
1104 export_metadata->GetValueChecked<String>(isolate, kExportName); | 1059 export_metadata->GetValueChecked<String>(isolate, kExportName); |
(...skipping 16 matching lines...) Expand all Loading... |
1121 // Export the memory as a named property. | 1076 // Export the memory as a named property. |
1122 Handle<String> name = factory->InternalizeUtf8String("memory"); | 1077 Handle<String> name = factory->InternalizeUtf8String("memory"); |
1123 Handle<JSArrayBuffer> memory = Handle<JSArrayBuffer>( | 1078 Handle<JSArrayBuffer> memory = Handle<JSArrayBuffer>( |
1124 JSArrayBuffer::cast(instance->GetInternalField(kWasmMemArrayBuffer))); | 1079 JSArrayBuffer::cast(instance->GetInternalField(kWasmMemArrayBuffer))); |
1125 JSObject::AddProperty(exports_object, name, memory, READ_ONLY); | 1080 JSObject::AddProperty(exports_object, name, memory, READ_ONLY); |
1126 } | 1081 } |
1127 } | 1082 } |
1128 return true; | 1083 return true; |
1129 } | 1084 } |
1130 | 1085 |
1131 #define GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(Field) \ | |
1132 WeakCell* Get##Field(const FixedArray* compiled_module) { \ | |
1133 Object* obj = compiled_module->get(k##Field); \ | |
1134 DCHECK_NOT_NULL(obj); \ | |
1135 if (obj->IsWeakCell()) { \ | |
1136 return WeakCell::cast(obj); \ | |
1137 } else { \ | |
1138 return nullptr; \ | |
1139 } \ | |
1140 } | |
1141 | |
1142 GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(NextInstance) | |
1143 GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(PrevInstance) | |
1144 GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(OwningInstance) | |
1145 GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(ModuleObject) | |
1146 | |
1147 static void ResetCompiledModule(Isolate* isolate, JSObject* owner, | 1086 static void ResetCompiledModule(Isolate* isolate, JSObject* owner, |
1148 FixedArray* compiled_module) { | 1087 WasmCompiledModule* compiled_module) { |
1149 Object* undefined = *isolate->factory()->undefined_value(); | 1088 Object* undefined = *isolate->factory()->undefined_value(); |
1150 Object* mem_size_obj = compiled_module->get(kMemSize); | 1089 uint32_t old_mem_size = compiled_module->mem_size(); |
1151 DCHECK(mem_size_obj->IsMutableHeapNumber()); | 1090 Object* mem_start = compiled_module->ptr_to_mem_start(); |
1152 uint32_t old_mem_size = | |
1153 static_cast<uint32_t>(HeapNumber::cast(mem_size_obj)->value()); | |
1154 Object* mem_start = compiled_module->get(kMemStart); | |
1155 Address old_mem_address = nullptr; | 1091 Address old_mem_address = nullptr; |
1156 Address globals_start = | 1092 Address globals_start = |
1157 GetGlobalStartAddressFromCodeTemplate(undefined, owner); | 1093 GetGlobalStartAddressFromCodeTemplate(undefined, owner); |
1158 | 1094 |
1159 if (old_mem_size > 0) { | 1095 if (old_mem_size > 0) { |
1160 CHECK_NE(mem_start, undefined); | 1096 CHECK_NE(mem_start, undefined); |
1161 old_mem_address = | 1097 old_mem_address = |
1162 static_cast<Address>(JSArrayBuffer::cast(mem_start)->backing_store()); | 1098 static_cast<Address>(JSArrayBuffer::cast(mem_start)->backing_store()); |
1163 } | 1099 } |
1164 int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_REFERENCE) | | 1100 int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_REFERENCE) | |
1165 RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_SIZE_REFERENCE) | | 1101 RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_SIZE_REFERENCE) | |
1166 RelocInfo::ModeMask(RelocInfo::WASM_GLOBAL_REFERENCE); | 1102 RelocInfo::ModeMask(RelocInfo::WASM_GLOBAL_REFERENCE); |
1167 | 1103 |
1168 Object* fct_obj = compiled_module->get(kFunctions); | 1104 Object* fct_obj = compiled_module->ptr_to_functions(); |
1169 if (fct_obj != nullptr && fct_obj != undefined && | 1105 if (fct_obj != nullptr && fct_obj != undefined && |
1170 (old_mem_size > 0 || globals_start != nullptr)) { | 1106 (old_mem_size > 0 || globals_start != nullptr)) { |
1171 FixedArray* functions = FixedArray::cast(fct_obj); | 1107 FixedArray* functions = FixedArray::cast(fct_obj); |
1172 for (int i = 0; i < functions->length(); ++i) { | 1108 for (int i = 0; i < functions->length(); ++i) { |
1173 Code* code = Code::cast(functions->get(i)); | 1109 Code* code = Code::cast(functions->get(i)); |
1174 bool changed = false; | 1110 bool changed = false; |
1175 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { | 1111 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { |
1176 RelocInfo::Mode mode = it.rinfo()->rmode(); | 1112 RelocInfo::Mode mode = it.rinfo()->rmode(); |
1177 if (RelocInfo::IsWasmMemoryReference(mode) || | 1113 if (RelocInfo::IsWasmMemoryReference(mode) || |
1178 RelocInfo::IsWasmMemorySizeReference(mode)) { | 1114 RelocInfo::IsWasmMemorySizeReference(mode)) { |
1179 it.rinfo()->update_wasm_memory_reference(old_mem_address, nullptr, | 1115 it.rinfo()->update_wasm_memory_reference(old_mem_address, nullptr, |
1180 old_mem_size, old_mem_size); | 1116 old_mem_size, old_mem_size); |
1181 changed = true; | 1117 changed = true; |
1182 } else { | 1118 } else { |
1183 CHECK(RelocInfo::IsWasmGlobalReference(mode)); | 1119 CHECK(RelocInfo::IsWasmGlobalReference(mode)); |
1184 it.rinfo()->update_wasm_global_reference(globals_start, nullptr); | 1120 it.rinfo()->update_wasm_global_reference(globals_start, nullptr); |
1185 changed = true; | 1121 changed = true; |
1186 } | 1122 } |
1187 } | 1123 } |
1188 if (changed) { | 1124 if (changed) { |
1189 Assembler::FlushICache(isolate, code->instruction_start(), | 1125 Assembler::FlushICache(isolate, code->instruction_start(), |
1190 code->instruction_size()); | 1126 code->instruction_size()); |
1191 } | 1127 } |
1192 } | 1128 } |
1193 } | 1129 } |
1194 compiled_module->set(kOwningInstance, undefined); | 1130 compiled_module->reset_weak_owning_instance(isolate); |
1195 compiled_module->set(kMemStart, undefined); | 1131 compiled_module->reset_mem_start(isolate); |
1196 } | 1132 } |
1197 | 1133 |
1198 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { | 1134 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { |
1199 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter()); | 1135 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter()); |
1200 JSObject* owner = *p; | 1136 JSObject* owner = *p; |
1201 FixedArray* compiled_module = | 1137 WasmCompiledModule* compiled_module = |
1202 FixedArray::cast(owner->GetInternalField(kWasmCompiledModule)); | 1138 WasmCompiledModule::cast(owner->GetInternalField(kWasmCompiledModule)); |
1203 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate()); | 1139 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate()); |
1204 Object* undefined = *isolate->factory()->undefined_value(); | 1140 Object* undefined = *isolate->factory()->undefined_value(); |
1205 WeakCell* weak_module_obj = GetModuleObject(compiled_module); | 1141 DCHECK(compiled_module->has_weak_module_object()); |
1206 DCHECK_NOT_NULL(weak_module_obj); | 1142 WeakCell* weak_module_obj = compiled_module->ptr_to_weak_module_object(); |
1207 // weak_module_obj may have been cleared, meaning the module object | 1143 // weak_module_obj may have been cleared, meaning the module object |
1208 // was GC-ed. In that case, there won't be any new instances created, | 1144 // was GC-ed. In that case, there won't be any new instances created, |
1209 // and we don't need to maintain the links between instances. | 1145 // and we don't need to maintain the links between instances. |
1210 if (!weak_module_obj->cleared()) { | 1146 if (!weak_module_obj->cleared()) { |
1211 JSObject* module_obj = JSObject::cast(weak_module_obj->value()); | 1147 JSObject* module_obj = JSObject::cast(weak_module_obj->value()); |
1212 FixedArray* current_template = | 1148 WasmCompiledModule* current_template = |
1213 FixedArray::cast(module_obj->GetInternalField(0)); | 1149 WasmCompiledModule::cast(module_obj->GetInternalField(0)); |
1214 DCHECK_NULL(GetPrevInstance(current_template)); | 1150 DCHECK(!current_template->has_weak_prev_instance()); |
1215 WeakCell* next = GetNextInstance(compiled_module); | 1151 WeakCell* next = compiled_module->ptr_to_weak_next_instance(); |
1216 WeakCell* prev = GetPrevInstance(compiled_module); | 1152 WeakCell* prev = compiled_module->ptr_to_weak_prev_instance(); |
1217 | 1153 |
1218 if (current_template == compiled_module) { | 1154 if (current_template == compiled_module) { |
1219 if (next == nullptr) { | 1155 if (next == nullptr) { |
1220 ResetCompiledModule(isolate, owner, compiled_module); | 1156 ResetCompiledModule(isolate, owner, compiled_module); |
1221 } else { | 1157 } else { |
1222 DCHECK(next->value()->IsFixedArray()); | 1158 DCHECK(next->value()->IsFixedArray()); |
1223 module_obj->SetInternalField(0, next->value()); | 1159 module_obj->SetInternalField(0, next->value()); |
1224 DCHECK_NULL(prev); | 1160 DCHECK_NULL(prev); |
1225 FixedArray::cast(next->value())->set(kPrevInstance, undefined); | 1161 WasmCompiledModule::cast(next->value()) |
| 1162 ->reset_weak_prev_instance(isolate); |
1226 } | 1163 } |
1227 } else { | 1164 } else { |
1228 DCHECK(!(prev == nullptr && next == nullptr)); | 1165 DCHECK(!(prev == nullptr && next == nullptr)); |
1229 // the only reason prev or next would be cleared is if the | 1166 // the only reason prev or next would be cleared is if the |
1230 // respective objects got collected, but if that happened, | 1167 // respective objects got collected, but if that happened, |
1231 // we would have relinked the list. | 1168 // we would have relinked the list. |
1232 if (prev != nullptr) { | 1169 if (prev != nullptr) { |
1233 DCHECK(!prev->cleared()); | 1170 DCHECK(!prev->cleared()); |
1234 FixedArray::cast(prev->value()) | 1171 if (next == nullptr) { |
1235 ->set(kNextInstance, next == nullptr ? undefined : next); | 1172 WasmCompiledModule::cast(prev->value()) |
| 1173 ->reset_weak_next_instance(isolate); |
| 1174 } else { |
| 1175 WasmCompiledModule::cast(prev->value()) |
| 1176 ->set_ptr_to_weak_next_instance(next); |
| 1177 } |
1236 } | 1178 } |
1237 if (next != nullptr) { | 1179 if (next != nullptr) { |
1238 DCHECK(!next->cleared()); | 1180 DCHECK(!next->cleared()); |
1239 FixedArray::cast(next->value()) | 1181 if (prev == nullptr) { |
1240 ->set(kPrevInstance, prev == nullptr ? undefined : prev); | 1182 WasmCompiledModule::cast(next->value()) |
| 1183 ->reset_weak_prev_instance(isolate); |
| 1184 } else { |
| 1185 WasmCompiledModule::cast(next->value()) |
| 1186 ->set_ptr_to_weak_prev_instance(prev); |
| 1187 } |
1241 } | 1188 } |
1242 } | 1189 } |
1243 } | 1190 } |
1244 GlobalHandles::Destroy(reinterpret_cast<Object**>(p)); | 1191 GlobalHandles::Destroy(reinterpret_cast<Object**>(p)); |
1245 } | 1192 } |
1246 | 1193 |
1247 } // namespace | 1194 } // namespace |
1248 | 1195 |
1249 MaybeHandle<FixedArray> WasmModule::CompileFunctions( | 1196 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( |
1250 Isolate* isolate, ErrorThrower* thrower) const { | 1197 Isolate* isolate, ErrorThrower* thrower) const { |
1251 Factory* factory = isolate->factory(); | 1198 Factory* factory = isolate->factory(); |
1252 | 1199 |
1253 MaybeHandle<FixedArray> nothing; | 1200 MaybeHandle<WasmCompiledModule> nothing; |
1254 | 1201 |
1255 WasmModuleInstance temp_instance_for_compilation(this); | 1202 WasmModuleInstance temp_instance_for_compilation(this); |
1256 temp_instance_for_compilation.context = isolate->native_context(); | 1203 temp_instance_for_compilation.context = isolate->native_context(); |
1257 temp_instance_for_compilation.mem_size = GetMinModuleMemSize(this); | 1204 temp_instance_for_compilation.mem_size = GetMinModuleMemSize(this); |
1258 temp_instance_for_compilation.mem_start = nullptr; | 1205 temp_instance_for_compilation.mem_start = nullptr; |
1259 temp_instance_for_compilation.globals_start = nullptr; | 1206 temp_instance_for_compilation.globals_start = nullptr; |
1260 | 1207 |
1261 MaybeHandle<FixedArray> indirect_table = | 1208 MaybeHandle<FixedArray> indirect_table = |
1262 function_tables.size() | 1209 function_tables.size() |
1263 ? factory->NewFixedArray(static_cast<int>(function_tables.size()), | 1210 ? factory->NewFixedArray(static_cast<int>(function_tables.size()), |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1321 | 1268 |
1322 LinkModuleFunctions(isolate, compiled_functions); | 1269 LinkModuleFunctions(isolate, compiled_functions); |
1323 | 1270 |
1324 // TODO(mtrofin): do we need to flush the cache here? | 1271 // TODO(mtrofin): do we need to flush the cache here? |
1325 FlushAssemblyCache(isolate, compiled_functions); | 1272 FlushAssemblyCache(isolate, compiled_functions); |
1326 | 1273 |
1327 // Create the compiled module object, and populate with compiled functions | 1274 // Create the compiled module object, and populate with compiled functions |
1328 // and information needed at instantiation time. This object needs to be | 1275 // and information needed at instantiation time. This object needs to be |
1329 // serializable. Instantiation may occur off a deserialized version of this | 1276 // serializable. Instantiation may occur off a deserialized version of this |
1330 // object. | 1277 // object. |
1331 Handle<FixedArray> ret = | 1278 Handle<WasmCompiledModule> ret = WasmCompiledModule::New(isolate); |
1332 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED); | 1279 |
1333 ret->set(kFunctions, *compiled_functions); | 1280 ret->set_functions(compiled_functions); |
1334 if (!indirect_table.is_null()) { | 1281 if (!indirect_table.is_null()) { |
1335 ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked()); | 1282 ret->set_indirect_function_tables(indirect_table.ToHandleChecked()); |
1336 } | 1283 } |
1337 if (!maybe_imports.is_null()) { | 1284 if (!maybe_imports.is_null()) { |
1338 ret->set(kImportMap, *maybe_imports.ToHandleChecked()); | 1285 ret->set_import_map(maybe_imports.ToHandleChecked()); |
1339 } | 1286 } |
1340 Handle<FixedArray> import_data = GetImportsMetadata(factory, this); | 1287 Handle<FixedArray> import_data = GetImportsMetadata(factory, this); |
1341 ret->set(kImportData, *import_data); | 1288 ret->set_import_data(import_data); |
1342 | 1289 |
1343 // Compile export functions. | 1290 // Compile export functions. |
1344 int export_size = static_cast<int>(export_table.size()); | 1291 int export_size = static_cast<int>(export_table.size()); |
1345 Handle<Code> startup_fct; | 1292 Handle<Code> startup_fct; |
1346 if (export_size > 0) { | 1293 if (export_size > 0) { |
1347 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED); | 1294 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED); |
1348 for (int i = 0; i < export_size; ++i) { | 1295 for (int i = 0; i < export_size; ++i) { |
1349 Handle<FixedArray> export_metadata = | 1296 Handle<FixedArray> export_metadata = |
1350 factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED); | 1297 factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED); |
1351 const WasmExport& exp = export_table[i]; | 1298 const WasmExport& exp = export_table[i]; |
(...skipping 18 matching lines...) Expand all Loading... |
1370 export_metadata->set( | 1317 export_metadata->set( |
1371 kExportArity, Smi::FromInt(static_cast<int>( | 1318 kExportArity, Smi::FromInt(static_cast<int>( |
1372 functions[exp.func_index].sig->parameter_count()))); | 1319 functions[exp.func_index].sig->parameter_count()))); |
1373 export_metadata->set(kExportedFunctionIndex, | 1320 export_metadata->set(kExportedFunctionIndex, |
1374 Smi::FromInt(static_cast<int>(exp.func_index))); | 1321 Smi::FromInt(static_cast<int>(exp.func_index))); |
1375 exports->set(i, *export_metadata); | 1322 exports->set(i, *export_metadata); |
1376 if (exp.func_index == start_function_index) { | 1323 if (exp.func_index == start_function_index) { |
1377 startup_fct = export_code; | 1324 startup_fct = export_code; |
1378 } | 1325 } |
1379 } | 1326 } |
1380 ret->set(kExports, *exports); | 1327 ret->set_exports(exports); |
1381 } | 1328 } |
1382 | 1329 |
1383 // Compile startup function, if we haven't already. | 1330 // Compile startup function, if we haven't already. |
1384 if (start_function_index >= 0) { | 1331 if (start_function_index >= 0) { |
1385 uint32_t index = static_cast<uint32_t>(start_function_index); | 1332 uint32_t index = static_cast<uint32_t>(start_function_index); |
1386 HandleScope scope(isolate); | 1333 HandleScope scope(isolate); |
1387 if (startup_fct.is_null()) { | 1334 if (startup_fct.is_null()) { |
1388 Handle<Code> code = temp_instance_for_compilation.function_code[index]; | 1335 Handle<Code> code = temp_instance_for_compilation.function_code[index]; |
1389 DCHECK_EQ(0, functions[index].sig->parameter_count()); | 1336 DCHECK_EQ(0, functions[index].sig->parameter_count()); |
1390 startup_fct = | 1337 startup_fct = |
1391 compiler::CompileJSToWasmWrapper(isolate, &module_env, code, index); | 1338 compiler::CompileJSToWasmWrapper(isolate, &module_env, code, index); |
1392 } | 1339 } |
1393 Handle<FixedArray> metadata = | 1340 Handle<FixedArray> metadata = |
1394 factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED); | 1341 factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED); |
1395 metadata->set(kExportCode, *startup_fct); | 1342 metadata->set(kExportCode, *startup_fct); |
1396 metadata->set(kExportArity, Smi::FromInt(0)); | 1343 metadata->set(kExportArity, Smi::FromInt(0)); |
1397 metadata->set(kExportedFunctionIndex, Smi::FromInt(start_function_index)); | 1344 metadata->set(kExportedFunctionIndex, Smi::FromInt(start_function_index)); |
1398 ret->set(kStartupFunction, *metadata); | 1345 ret->set_startup_function(metadata); |
1399 } | 1346 } |
1400 | 1347 |
1401 // TODO(wasm): saving the module bytes for debugging is wasteful. We should | 1348 // TODO(wasm): saving the module bytes for debugging is wasteful. We should |
1402 // consider downloading this on-demand. | 1349 // consider downloading this on-demand. |
1403 { | 1350 { |
1404 size_t module_bytes_len = module_end - module_start; | 1351 size_t module_bytes_len = module_end - module_start; |
1405 DCHECK_LE(module_bytes_len, static_cast<size_t>(kMaxInt)); | 1352 DCHECK_LE(module_bytes_len, static_cast<size_t>(kMaxInt)); |
1406 Vector<const uint8_t> module_bytes_vec(module_start, | 1353 Vector<const uint8_t> module_bytes_vec(module_start, |
1407 static_cast<int>(module_bytes_len)); | 1354 static_cast<int>(module_bytes_len)); |
1408 Handle<String> module_bytes_string = | 1355 Handle<String> module_bytes_string = |
1409 factory->NewStringFromOneByte(module_bytes_vec, TENURED) | 1356 factory->NewStringFromOneByte(module_bytes_vec, TENURED) |
1410 .ToHandleChecked(); | 1357 .ToHandleChecked(); |
1411 ret->set(kModuleBytes, *module_bytes_string); | 1358 ret->set_module_bytes(module_bytes_string); |
1412 } | 1359 } |
1413 | 1360 |
1414 Handle<ByteArray> function_name_table = | 1361 Handle<ByteArray> function_name_table = |
1415 BuildFunctionNamesTable(isolate, module_env.module); | 1362 BuildFunctionNamesTable(isolate, module_env.module); |
1416 ret->set(kFunctionNameTable, *function_name_table); | 1363 ret->set_function_names(function_name_table); |
1417 ret->set(kMinRequiredMemory, Smi::FromInt(min_mem_pages)); | 1364 ret->set_min_required_memory(min_mem_pages); |
1418 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret); | 1365 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret); |
1419 ret->set(kGlobalsSize, Smi::FromInt(globals_size)); | 1366 ret->set_globals_size(globals_size); |
1420 ret->set(kExportMem, Smi::FromInt(mem_export)); | 1367 ret->set_export_memory(mem_export); |
1421 ret->set(kOrigin, Smi::FromInt(origin)); | 1368 ret->set_origin(origin); |
1422 Handle<HeapNumber> size_as_object = factory->NewHeapNumber( | 1369 ret->set_mem_size(temp_instance_for_compilation.mem_size); |
1423 static_cast<double>(temp_instance_for_compilation.mem_size), MUTABLE, | |
1424 TENURED); | |
1425 ret->set(kMemSize, *size_as_object); | |
1426 return ret; | 1370 return ret; |
1427 } | 1371 } |
1428 | 1372 |
1429 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper, | 1373 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper, |
1430 Handle<Code> new_target) { | 1374 Handle<Code> new_target) { |
1431 AllowDeferredHandleDereference embedding_raw_address; | 1375 AllowDeferredHandleDereference embedding_raw_address; |
1432 bool seen = false; | 1376 bool seen = false; |
1433 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done(); | 1377 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done(); |
1434 it.next()) { | 1378 it.next()) { |
1435 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); | 1379 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1468 ->GetValueChecked<FixedArray>(isolate, kTable); | 1412 ->GetValueChecked<FixedArray>(isolate, kTable); |
1469 for (int fct_index = 0; fct_index < wasm_functions->length(); ++fct_index) { | 1413 for (int fct_index = 0; fct_index < wasm_functions->length(); ++fct_index) { |
1470 Handle<Code> wasm_function = | 1414 Handle<Code> wasm_function = |
1471 wasm_functions->GetValueChecked<Code>(isolate, fct_index); | 1415 wasm_functions->GetValueChecked<Code>(isolate, fct_index); |
1472 PatchFunctionTable(wasm_function, table_to_replace, cloned_table); | 1416 PatchFunctionTable(wasm_function, table_to_replace, cloned_table); |
1473 } | 1417 } |
1474 } | 1418 } |
1475 return cloned_indirect_tables; | 1419 return cloned_indirect_tables; |
1476 } | 1420 } |
1477 | 1421 |
1478 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate, | 1422 Handle<WasmCompiledModule> CloneModuleForInstance( |
1479 Handle<JSObject> module_object, | 1423 Isolate* isolate, Handle<JSObject> module_object, bool* template_is_owned, |
1480 bool* template_is_owned, | 1424 Handle<WasmCompiledModule>* module_template) { |
1481 Handle<FixedArray>* module_template) { | |
1482 Factory* factory = isolate->factory(); | 1425 Factory* factory = isolate->factory(); |
1483 | 1426 |
1484 Handle<FixedArray> original; | 1427 Handle<WasmCompiledModule> original; |
1485 for (int i = 0; i < 2; ++i) { | 1428 for (int i = 0; i < 2; ++i) { |
1486 original = handle(FixedArray::cast(module_object->GetInternalField(0))); | 1429 original = |
1487 if (GetOwningInstance(*original) == nullptr) { | 1430 handle(WasmCompiledModule::cast(module_object->GetInternalField(0))); |
| 1431 if (!original->has_weak_owning_instance()) { |
1488 *template_is_owned = false; | 1432 *template_is_owned = false; |
1489 *module_template = original; | 1433 *module_template = original; |
1490 return original; | 1434 return original; |
1491 } | 1435 } |
1492 if (i < 1) { | 1436 if (i < 1) { |
1493 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 1437 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
1494 GarbageCollectionReason::kRuntime); | 1438 GarbageCollectionReason::kRuntime); |
1495 } | 1439 } |
1496 } | 1440 } |
1497 *template_is_owned = true; | 1441 *template_is_owned = true; |
1498 *module_template = original; | 1442 *module_template = original; |
1499 | 1443 |
1500 // We insert the latest clone in front. | 1444 // We insert the latest clone in front. |
1501 Handle<FixedArray> clone = factory->CopyFixedArray(original); | 1445 Handle<WasmCompiledModule> clone = |
1502 Handle<WeakCell> weak_link_to_wasm_obj = | 1446 Handle<WasmCompiledModule>::cast(factory->CopyFixedArray(original)); |
1503 original->GetValueChecked<WeakCell>(isolate, kModuleObject); | 1447 Handle<WeakCell> weak_link_to_wasm_obj = original->weak_module_object(); |
1504 | 1448 |
1505 clone->set(kModuleObject, *weak_link_to_wasm_obj); | 1449 clone->set_weak_module_object(weak_link_to_wasm_obj); |
1506 Handle<WeakCell> link_to_original = factory->NewWeakCell(original); | 1450 Handle<WeakCell> link_to_original = factory->NewWeakCell(original); |
1507 clone->set(kNextInstance, *link_to_original); | 1451 clone->set_weak_next_instance(link_to_original); |
1508 Handle<WeakCell> link_to_clone = factory->NewWeakCell(clone); | 1452 Handle<WeakCell> link_to_clone = factory->NewWeakCell(clone); |
1509 original->set(kPrevInstance, *link_to_clone); | 1453 original->set_weak_prev_instance(link_to_clone); |
1510 JSObject::cast(weak_link_to_wasm_obj->value())->SetInternalField(0, *clone); | 1454 JSObject::cast(weak_link_to_wasm_obj->value())->SetInternalField(0, *clone); |
1511 | 1455 |
1512 // Clone each wasm code object. | 1456 // Clone each wasm code object. |
1513 Handle<FixedArray> orig_wasm_functions = | 1457 Handle<FixedArray> orig_wasm_functions = original->functions(); |
1514 original->GetValueChecked<FixedArray>(isolate, kFunctions); | |
1515 Handle<FixedArray> clone_wasm_functions = | 1458 Handle<FixedArray> clone_wasm_functions = |
1516 factory->CopyFixedArray(orig_wasm_functions); | 1459 factory->CopyFixedArray(orig_wasm_functions); |
1517 clone->set(kFunctions, *clone_wasm_functions); | 1460 clone->set_functions(clone_wasm_functions); |
1518 for (int i = 0; i < clone_wasm_functions->length(); ++i) { | 1461 for (int i = 0; i < clone_wasm_functions->length(); ++i) { |
1519 Handle<Code> orig_code = | 1462 Handle<Code> orig_code = |
1520 clone_wasm_functions->GetValueChecked<Code>(isolate, i); | 1463 clone_wasm_functions->GetValueChecked<Code>(isolate, i); |
1521 Handle<Code> cloned_code = factory->CopyCode(orig_code); | 1464 Handle<Code> cloned_code = factory->CopyCode(orig_code); |
1522 clone_wasm_functions->set(i, *cloned_code); | 1465 clone_wasm_functions->set(i, *cloned_code); |
1523 } | 1466 } |
1524 | 1467 |
1525 MaybeHandle<FixedArray> maybe_orig_exports = | 1468 if (original->has_exports()) { |
1526 original->GetValue<FixedArray>(isolate, kExports); | 1469 Handle<FixedArray> orig_exports = original->exports(); |
1527 Handle<FixedArray> orig_exports; | |
1528 if (maybe_orig_exports.ToHandle(&orig_exports)) { | |
1529 Handle<FixedArray> cloned_exports = factory->CopyFixedArray(orig_exports); | 1470 Handle<FixedArray> cloned_exports = factory->CopyFixedArray(orig_exports); |
1530 clone->set(kExports, *cloned_exports); | 1471 clone->set_exports(cloned_exports); |
1531 for (int i = 0; i < orig_exports->length(); ++i) { | 1472 for (int i = 0; i < orig_exports->length(); ++i) { |
1532 Handle<FixedArray> export_metadata = | 1473 Handle<FixedArray> export_metadata = |
1533 orig_exports->GetValueChecked<FixedArray>(isolate, i); | 1474 orig_exports->GetValueChecked<FixedArray>(isolate, i); |
1534 Handle<FixedArray> clone_metadata = | 1475 Handle<FixedArray> clone_metadata = |
1535 factory->CopyFixedArray(export_metadata); | 1476 factory->CopyFixedArray(export_metadata); |
1536 cloned_exports->set(i, *clone_metadata); | 1477 cloned_exports->set(i, *clone_metadata); |
1537 Handle<Code> orig_code = | 1478 Handle<Code> orig_code = |
1538 export_metadata->GetValueChecked<Code>(isolate, kExportCode); | 1479 export_metadata->GetValueChecked<Code>(isolate, kExportCode); |
1539 Handle<Code> cloned_code = factory->CopyCode(orig_code); | 1480 Handle<Code> cloned_code = factory->CopyCode(orig_code); |
1540 clone_metadata->set(kExportCode, *cloned_code); | 1481 clone_metadata->set(kExportCode, *cloned_code); |
1541 // TODO(wasm): This is actually a uint32_t, but since FixedArray indexes | 1482 // TODO(wasm): This is actually a uint32_t, but since FixedArray indexes |
1542 // in int, we are taking the risk of invalid values. | 1483 // in int, we are taking the risk of invalid values. |
1543 int exported_fct_index = | 1484 int exported_fct_index = |
1544 Smi::cast(export_metadata->get(kExportedFunctionIndex))->value(); | 1485 Smi::cast(export_metadata->get(kExportedFunctionIndex))->value(); |
1545 CHECK_GE(exported_fct_index, 0); | 1486 CHECK_GE(exported_fct_index, 0); |
1546 CHECK_LT(exported_fct_index, clone_wasm_functions->length()); | 1487 CHECK_LT(exported_fct_index, clone_wasm_functions->length()); |
1547 Handle<Code> new_target = clone_wasm_functions->GetValueChecked<Code>( | 1488 Handle<Code> new_target = clone_wasm_functions->GetValueChecked<Code>( |
1548 isolate, exported_fct_index); | 1489 isolate, exported_fct_index); |
1549 PatchJSWrapper(isolate, cloned_code, new_target); | 1490 PatchJSWrapper(isolate, cloned_code, new_target); |
1550 } | 1491 } |
1551 } | 1492 } |
1552 | 1493 |
1553 MaybeHandle<FixedArray> maybe_startup = | 1494 if (original->has_startup_function()) { |
1554 original->GetValue<FixedArray>(isolate, kStartupFunction); | |
1555 if (!maybe_startup.is_null()) { | |
1556 Handle<FixedArray> startup_metadata = | 1495 Handle<FixedArray> startup_metadata = |
1557 factory->CopyFixedArray(maybe_startup.ToHandleChecked()); | 1496 factory->CopyFixedArray(original->startup_function()); |
1558 Handle<Code> startup_fct_clone = factory->CopyCode( | 1497 Handle<Code> startup_fct_clone = factory->CopyCode( |
1559 startup_metadata->GetValueChecked<Code>(isolate, kExportCode)); | 1498 startup_metadata->GetValueChecked<Code>(isolate, kExportCode)); |
1560 startup_metadata->set(kExportCode, *startup_fct_clone); | 1499 startup_metadata->set(kExportCode, *startup_fct_clone); |
1561 clone->set(kStartupFunction, *startup_metadata); | 1500 clone->set_startup_function(startup_metadata); |
1562 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray. | 1501 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray. |
1563 int startup_fct_index = | 1502 int startup_fct_index = |
1564 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value(); | 1503 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value(); |
1565 CHECK_GE(startup_fct_index, 0); | 1504 CHECK_GE(startup_fct_index, 0); |
1566 CHECK_LT(startup_fct_index, clone_wasm_functions->length()); | 1505 CHECK_LT(startup_fct_index, clone_wasm_functions->length()); |
1567 Handle<Code> new_target = | 1506 Handle<Code> new_target = |
1568 clone_wasm_functions->GetValueChecked<Code>(isolate, startup_fct_index); | 1507 clone_wasm_functions->GetValueChecked<Code>(isolate, startup_fct_index); |
1569 PatchJSWrapper(isolate, startup_fct_clone, new_target); | 1508 PatchJSWrapper(isolate, startup_fct_clone, new_target); |
1570 } | 1509 } |
1571 clone->set(kImportMap, *isolate->factory()->undefined_value()); | 1510 clone->reset_import_map(isolate); |
1572 return clone; | 1511 return clone; |
1573 } | 1512 } |
1574 | 1513 |
1575 // Instantiates a wasm module as a JSObject. | 1514 // Instantiates a wasm module as a JSObject. |
1576 // * allocates a backing store of {mem_size} bytes. | 1515 // * allocates a backing store of {mem_size} bytes. |
1577 // * installs a named property "memory" for that buffer if exported | 1516 // * installs a named property "memory" for that buffer if exported |
1578 // * installs named properties on the object for exported functions | 1517 // * installs named properties on the object for exported functions |
1579 // * compiles wasm code to machine code | 1518 // * compiles wasm code to machine code |
1580 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, | 1519 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, |
1581 Handle<JSObject> module_object, | 1520 Handle<JSObject> module_object, |
1582 Handle<JSReceiver> ffi, | 1521 Handle<JSReceiver> ffi, |
1583 Handle<JSArrayBuffer> memory) { | 1522 Handle<JSArrayBuffer> memory) { |
1584 HistogramTimerScope wasm_instantiate_module_time_scope( | 1523 HistogramTimerScope wasm_instantiate_module_time_scope( |
1585 isolate->counters()->wasm_instantiate_module_time()); | 1524 isolate->counters()->wasm_instantiate_module_time()); |
1586 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); | 1525 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); |
1587 Factory* factory = isolate->factory(); | 1526 Factory* factory = isolate->factory(); |
1588 | 1527 |
1589 bool template_is_owned = false; | 1528 bool template_is_owned = false; |
1590 Handle<FixedArray> compiled_module_template; | 1529 Handle<WasmCompiledModule> compiled_module_template; |
1591 Handle<FixedArray> compiled_module = CloneModuleForInstance( | 1530 Handle<WasmCompiledModule> compiled_module = CloneModuleForInstance( |
1592 isolate, module_object, &template_is_owned, &compiled_module_template); | 1531 isolate, module_object, &template_is_owned, &compiled_module_template); |
1593 | 1532 |
1594 MaybeHandle<JSObject> template_owner; | 1533 MaybeHandle<JSObject> template_owner; |
1595 if (template_is_owned) { | 1534 if (template_is_owned) { |
1596 Handle<WeakCell> weak_owner = | 1535 template_owner = compiled_module_template->owning_instance(); |
1597 compiled_module_template->GetValueChecked<WeakCell>(isolate, | |
1598 kOwningInstance); | |
1599 template_owner = handle(JSObject::cast(weak_owner->value())); | |
1600 } | 1536 } |
1601 // These fields are compulsory. | 1537 // These fields are compulsory. |
1602 Handle<FixedArray> code_table = | 1538 Handle<FixedArray> code_table = compiled_module->functions(); |
1603 compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions); | |
1604 | |
1605 RecordStats(isolate, code_table); | 1539 RecordStats(isolate, code_table); |
1606 | 1540 |
1607 MaybeHandle<JSObject> nothing; | 1541 MaybeHandle<JSObject> nothing; |
1608 | 1542 |
1609 Handle<Map> map = factory->NewMap( | 1543 Handle<Map> map = factory->NewMap( |
1610 JS_OBJECT_TYPE, | 1544 JS_OBJECT_TYPE, |
1611 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); | 1545 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); |
1612 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); | 1546 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); |
1613 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); | 1547 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); |
1614 | 1548 |
1615 // Remember the old imports, for the case when we are at the first instance - | 1549 // Remember the old imports, for the case when we are at the first instance - |
1616 // they will be replaced with the instance's actual imports in SetupImports. | 1550 // they will be replaced with the instance's actual imports in SetupImports. |
1617 MaybeHandle<FixedArray> old_imports = | 1551 MaybeHandle<FixedArray> old_imports = |
1618 compiled_module_template->GetValue<FixedArray>(isolate, kImportMap); | 1552 compiled_module_template->maybe_import_map(); |
1619 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, | 1553 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, |
1620 &thrower) && | 1554 &thrower) && |
1621 SetupGlobals(isolate, template_owner, compiled_module, js_object, | 1555 SetupGlobals(isolate, template_owner, compiled_module, js_object, |
1622 &thrower) && | 1556 &thrower) && |
1623 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) && | 1557 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) && |
1624 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { | 1558 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { |
1625 return nothing; | 1559 return nothing; |
1626 } | 1560 } |
1627 | 1561 |
1628 FixupFunctionsAndImports( | 1562 FixupFunctionsAndImports(compiled_module_template->functions(), code_table, |
1629 compiled_module_template->GetValueChecked<FixedArray>(isolate, | 1563 old_imports, compiled_module->maybe_import_map()); |
1630 kFunctions), | |
1631 code_table, old_imports, | |
1632 compiled_module->GetValue<FixedArray>(isolate, kImportMap)); | |
1633 | 1564 |
1634 SetDebugSupport(factory, compiled_module, js_object); | 1565 SetDebugSupport(factory, compiled_module, js_object); |
1635 SetRuntimeSupport(isolate, js_object); | 1566 SetRuntimeSupport(isolate, js_object); |
1636 | 1567 |
1637 FlushAssemblyCache(isolate, code_table); | 1568 FlushAssemblyCache(isolate, code_table); |
1638 | 1569 |
1639 { | 1570 { |
1640 std::vector<Handle<Code>> functions( | 1571 std::vector<Handle<Code>> functions( |
1641 static_cast<size_t>(code_table->length())); | 1572 static_cast<size_t>(code_table->length())); |
1642 for (int i = 0; i < code_table->length(); ++i) { | 1573 for (int i = 0; i < code_table->length(); ++i) { |
1643 functions[static_cast<size_t>(i)] = | 1574 functions[static_cast<size_t>(i)] = |
1644 code_table->GetValueChecked<Code>(isolate, i); | 1575 code_table->GetValueChecked<Code>(isolate, i); |
1645 } | 1576 } |
1646 | 1577 |
1647 MaybeHandle<FixedArray> maybe_indirect_tables = | 1578 if (compiled_module->has_indirect_function_tables()) { |
1648 compiled_module->GetValue<FixedArray>(isolate, | 1579 Handle<FixedArray> indirect_tables_template = |
1649 kTableOfIndirectFunctionTables); | 1580 compiled_module->indirect_function_tables(); |
1650 Handle<FixedArray> indirect_tables_template; | |
1651 if (maybe_indirect_tables.ToHandle(&indirect_tables_template)) { | |
1652 Handle<FixedArray> to_replace = | 1581 Handle<FixedArray> to_replace = |
1653 template_owner.is_null() | 1582 template_owner.is_null() |
1654 ? indirect_tables_template | 1583 ? indirect_tables_template |
1655 : handle(FixedArray::cast( | 1584 : handle(FixedArray::cast( |
1656 template_owner.ToHandleChecked()->GetInternalField( | 1585 template_owner.ToHandleChecked()->GetInternalField( |
1657 kWasmModuleFunctionTable))); | 1586 kWasmModuleFunctionTable))); |
1658 Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable( | 1587 Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable( |
1659 isolate, code_table, indirect_tables_template, to_replace); | 1588 isolate, code_table, indirect_tables_template, to_replace); |
1660 for (int i = 0; i < indirect_tables->length(); ++i) { | 1589 for (int i = 0; i < indirect_tables->length(); ++i) { |
1661 Handle<FixedArray> metadata = | 1590 Handle<FixedArray> metadata = |
1662 indirect_tables->GetValueChecked<FixedArray>(isolate, i); | 1591 indirect_tables->GetValueChecked<FixedArray>(isolate, i); |
1663 uint32_t size = Smi::cast(metadata->get(kSize))->value(); | 1592 uint32_t size = Smi::cast(metadata->get(kSize))->value(); |
1664 Handle<FixedArray> table = | 1593 Handle<FixedArray> table = |
1665 metadata->GetValueChecked<FixedArray>(isolate, kTable); | 1594 metadata->GetValueChecked<FixedArray>(isolate, kTable); |
1666 wasm::PopulateFunctionTable(table, size, &functions); | 1595 wasm::PopulateFunctionTable(table, size, &functions); |
1667 } | 1596 } |
1668 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables); | 1597 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables); |
1669 } | 1598 } |
1670 } | 1599 } |
1671 | 1600 |
1672 // Run the start function if one was specified. | 1601 // Run the start function if one was specified. |
1673 MaybeHandle<FixedArray> maybe_startup_fct = | 1602 if (compiled_module->has_startup_function()) { |
1674 compiled_module->GetValue<FixedArray>(isolate, kStartupFunction); | 1603 Handle<FixedArray> metadata = compiled_module->startup_function(); |
1675 Handle<FixedArray> metadata; | |
1676 if (maybe_startup_fct.ToHandle(&metadata)) { | |
1677 HandleScope scope(isolate); | 1604 HandleScope scope(isolate); |
1678 Handle<Code> startup_code = | 1605 Handle<Code> startup_code = |
1679 metadata->GetValueChecked<Code>(isolate, kExportCode); | 1606 metadata->GetValueChecked<Code>(isolate, kExportCode); |
1680 int arity = Smi::cast(metadata->get(kExportArity))->value(); | 1607 int arity = Smi::cast(metadata->get(kExportArity))->value(); |
1681 MaybeHandle<ByteArray> startup_signature = | 1608 MaybeHandle<ByteArray> startup_signature = |
1682 metadata->GetValue<ByteArray>(isolate, kExportedSignature); | 1609 metadata->GetValue<ByteArray>(isolate, kExportedSignature); |
1683 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( | 1610 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( |
1684 isolate, startup_code, factory->InternalizeUtf8String("start"), arity, | 1611 isolate, startup_code, factory->InternalizeUtf8String("start"), arity, |
1685 startup_signature, js_object); | 1612 startup_signature, js_object); |
1686 RecordStats(isolate, *startup_code); | 1613 RecordStats(isolate, *startup_code); |
1687 // Call the JS function. | 1614 // Call the JS function. |
1688 Handle<Object> undefined = isolate->factory()->undefined_value(); | 1615 Handle<Object> undefined = isolate->factory()->undefined_value(); |
1689 MaybeHandle<Object> retval = | 1616 MaybeHandle<Object> retval = |
1690 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); | 1617 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); |
1691 | 1618 |
1692 if (retval.is_null()) { | 1619 if (retval.is_null()) { |
1693 thrower.Error("WASM.instantiateModule(): start function failed"); | 1620 thrower.Error("WASM.instantiateModule(): start function failed"); |
1694 return nothing; | 1621 return nothing; |
1695 } | 1622 } |
1696 } | 1623 } |
1697 | 1624 |
1698 DCHECK(wasm::IsWasmObject(*js_object)); | 1625 DCHECK(wasm::IsWasmObject(*js_object)); |
1699 | 1626 |
1700 if (!compiled_module->GetValue<WeakCell>(isolate, kModuleObject).is_null()) { | 1627 if (compiled_module->has_weak_module_object()) { |
1701 js_object->SetInternalField(kWasmCompiledModule, *compiled_module); | 1628 js_object->SetInternalField(kWasmCompiledModule, *compiled_module); |
1702 Handle<WeakCell> link_to_owner = factory->NewWeakCell(js_object); | 1629 Handle<WeakCell> link_to_owner = factory->NewWeakCell(js_object); |
1703 compiled_module->set(kOwningInstance, *link_to_owner); | 1630 compiled_module->set_weak_owning_instance(link_to_owner); |
1704 | 1631 |
1705 Handle<Object> global_handle = | 1632 Handle<Object> global_handle = |
1706 isolate->global_handles()->Create(*js_object); | 1633 isolate->global_handles()->Create(*js_object); |
1707 GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(), | 1634 GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(), |
1708 &InstanceFinalizer, | 1635 &InstanceFinalizer, |
1709 v8::WeakCallbackType::kFinalizer); | 1636 v8::WeakCallbackType::kFinalizer); |
1710 } | 1637 } |
1711 | 1638 |
1712 return js_object; | 1639 return js_object; |
1713 } | 1640 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1890 Handle<Map> map = isolate->factory()->NewMap( | 1817 Handle<Map> map = isolate->factory()->NewMap( |
1891 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize); | 1818 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize); |
1892 module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED); | 1819 module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED); |
1893 } | 1820 } |
1894 module_obj->SetInternalField(0, *compiled_module); | 1821 module_obj->SetInternalField(0, *compiled_module); |
1895 if (origin == ModuleOrigin::kWasmOrigin) { | 1822 if (origin == ModuleOrigin::kWasmOrigin) { |
1896 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); | 1823 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); |
1897 Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check(); | 1824 Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check(); |
1898 } | 1825 } |
1899 Handle<WeakCell> link_to_module = isolate->factory()->NewWeakCell(module_obj); | 1826 Handle<WeakCell> link_to_module = isolate->factory()->NewWeakCell(module_obj); |
1900 compiled_module->set(kModuleObject, *link_to_module); | 1827 WasmCompiledModule::cast(*compiled_module) |
| 1828 ->set_weak_module_object(link_to_module); |
1901 return module_obj; | 1829 return module_obj; |
1902 } | 1830 } |
1903 | 1831 |
1904 MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate, | 1832 MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate, |
1905 const byte* start, | 1833 const byte* start, |
1906 const byte* end, | 1834 const byte* end, |
1907 ErrorThrower* thrower, | 1835 ErrorThrower* thrower, |
1908 ModuleOrigin origin) { | 1836 ModuleOrigin origin) { |
1909 MaybeHandle<JSObject> nothing; | 1837 MaybeHandle<JSObject> nothing; |
1910 Zone zone(isolate->allocator()); | 1838 Zone zone(isolate->allocator()); |
(...skipping 19 matching lines...) Expand all Loading... |
1930 if (mem->IsUndefined(isolate)) return MaybeHandle<JSArrayBuffer>(); | 1858 if (mem->IsUndefined(isolate)) return MaybeHandle<JSArrayBuffer>(); |
1931 return Handle<JSArrayBuffer>(JSArrayBuffer::cast(mem)); | 1859 return Handle<JSArrayBuffer>(JSArrayBuffer::cast(mem)); |
1932 } | 1860 } |
1933 | 1861 |
1934 void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) { | 1862 void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) { |
1935 DisallowHeapAllocation no_gc; | 1863 DisallowHeapAllocation no_gc; |
1936 DCHECK(IsWasmObject(*instance)); | 1864 DCHECK(IsWasmObject(*instance)); |
1937 instance->SetInternalField(kWasmMemArrayBuffer, buffer); | 1865 instance->SetInternalField(kWasmMemArrayBuffer, buffer); |
1938 Object* module = instance->GetInternalField(kWasmCompiledModule); | 1866 Object* module = instance->GetInternalField(kWasmCompiledModule); |
1939 if (module->IsFixedArray()) { | 1867 if (module->IsFixedArray()) { |
1940 HeapNumber::cast(FixedArray::cast(module)->get(kMemSize)) | 1868 WasmCompiledModule::cast(module)->set_mem_size( |
1941 ->set_value(buffer->byte_length()->Number()); | 1869 buffer->byte_length()->Number()); |
1942 } | 1870 } |
1943 } | 1871 } |
1944 | 1872 |
1945 namespace testing { | 1873 namespace testing { |
1946 | 1874 |
1947 void ValidateInstancesChain(Isolate* isolate, Handle<JSObject> module_obj, | 1875 void ValidateInstancesChain(Isolate* isolate, Handle<JSObject> module_obj, |
1948 int instance_count) { | 1876 int instance_count) { |
1949 CHECK_GE(instance_count, 0); | 1877 CHECK_GE(instance_count, 0); |
1950 DisallowHeapAllocation no_gc; | 1878 DisallowHeapAllocation no_gc; |
1951 FixedArray* compiled_module = | 1879 WasmCompiledModule* compiled_module = |
1952 FixedArray::cast(module_obj->GetInternalField(0)); | 1880 WasmCompiledModule::cast(module_obj->GetInternalField(0)); |
1953 CHECK_EQ(JSObject::cast(GetModuleObject(compiled_module)->value()), | 1881 CHECK_EQ( |
1954 *module_obj); | 1882 JSObject::cast(compiled_module->ptr_to_weak_module_object()->value()), |
| 1883 *module_obj); |
1955 Object* prev = nullptr; | 1884 Object* prev = nullptr; |
1956 int found_instances = GetOwningInstance(compiled_module) == nullptr ? 0 : 1; | 1885 int found_instances = compiled_module->has_weak_owning_instance() ? 1 : 0; |
1957 FixedArray* current_instance = compiled_module; | 1886 WasmCompiledModule* current_instance = compiled_module; |
1958 while (GetNextInstance(current_instance) != nullptr) { | 1887 while (current_instance->has_weak_next_instance()) { |
1959 CHECK((prev == nullptr && GetPrevInstance(current_instance) == nullptr) || | 1888 CHECK((prev == nullptr && !current_instance->has_weak_prev_instance()) || |
1960 GetPrevInstance(current_instance)->value() == prev); | 1889 current_instance->ptr_to_weak_prev_instance()->value() == prev); |
1961 CHECK_EQ(GetModuleObject(current_instance)->value(), *module_obj); | 1890 CHECK_EQ(current_instance->ptr_to_weak_module_object()->value(), |
1962 CHECK(IsWasmObject(GetOwningInstance(current_instance)->value())); | 1891 *module_obj); |
| 1892 CHECK( |
| 1893 IsWasmObject(current_instance->ptr_to_weak_owning_instance()->value())); |
1963 prev = current_instance; | 1894 prev = current_instance; |
1964 current_instance = | 1895 current_instance = WasmCompiledModule::cast( |
1965 FixedArray::cast(GetNextInstance(current_instance)->value()); | 1896 current_instance->ptr_to_weak_next_instance()->value()); |
1966 ++found_instances; | 1897 ++found_instances; |
1967 CHECK_LE(found_instances, instance_count); | 1898 CHECK_LE(found_instances, instance_count); |
1968 } | 1899 } |
1969 CHECK_EQ(found_instances, instance_count); | 1900 CHECK_EQ(found_instances, instance_count); |
1970 } | 1901 } |
1971 | 1902 |
1972 void ValidateModuleState(Isolate* isolate, Handle<JSObject> module_obj) { | 1903 void ValidateModuleState(Isolate* isolate, Handle<JSObject> module_obj) { |
1973 DisallowHeapAllocation no_gc; | 1904 DisallowHeapAllocation no_gc; |
1974 FixedArray* compiled_module = | 1905 WasmCompiledModule* compiled_module = |
1975 FixedArray::cast(module_obj->GetInternalField(0)); | 1906 WasmCompiledModule::cast(module_obj->GetInternalField(0)); |
1976 CHECK_NOT_NULL(GetModuleObject(compiled_module)); | 1907 CHECK(compiled_module->has_weak_module_object()); |
1977 CHECK_EQ(GetModuleObject(compiled_module)->value(), *module_obj); | 1908 CHECK_EQ(compiled_module->ptr_to_weak_module_object()->value(), *module_obj); |
1978 CHECK_NULL(GetPrevInstance(compiled_module)); | 1909 CHECK(!compiled_module->has_weak_prev_instance()); |
1979 CHECK_NULL(GetNextInstance(compiled_module)); | 1910 CHECK(!compiled_module->has_weak_next_instance()); |
1980 CHECK_NULL(GetOwningInstance(compiled_module)); | 1911 CHECK(!compiled_module->has_weak_owning_instance()); |
1981 } | 1912 } |
1982 | 1913 |
1983 void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance) { | 1914 void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance) { |
1984 DisallowHeapAllocation no_gc; | 1915 DisallowHeapAllocation no_gc; |
1985 CHECK(IsWasmObject(*instance)); | 1916 CHECK(IsWasmObject(*instance)); |
1986 FixedArray* compiled_module = | 1917 WasmCompiledModule* compiled_module = |
1987 FixedArray::cast(instance->GetInternalField(kWasmCompiledModule)); | 1918 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); |
1988 CHECK_NOT_NULL(GetModuleObject(compiled_module)); | 1919 CHECK(compiled_module->has_weak_module_object()); |
1989 CHECK(GetModuleObject(compiled_module)->cleared()); | 1920 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); |
1990 } | 1921 } |
1991 | 1922 |
1992 } // namespace testing | 1923 } // namespace testing |
1993 } // namespace wasm | 1924 } // namespace wasm |
1994 } // namespace internal | 1925 } // namespace internal |
1995 } // namespace v8 | 1926 } // namespace v8 |
OLD | NEW |