Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(397)

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2340623003: [wasm] Strongly typed compiled module (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/wasm/wasm-module.h ('K') | « src/wasm/wasm-module.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« src/wasm/wasm-module.h ('K') | « src/wasm/wasm-module.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698