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

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

Issue 2305903002: [wasm] reuse the first compiled module (Closed)
Patch Set: GC before cloning 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
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/mjsunit/wasm/compiled-module-management.js » ('j') | 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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 DCHECK_NOT_NULL(deopt_data); 151 DCHECK_NOT_NULL(deopt_data);
152 DCHECK(deopt_data->length() == 2); 152 DCHECK(deopt_data->length() == 2);
153 Object* weak_link = deopt_data->get(0); 153 Object* weak_link = deopt_data->get(0);
154 if (weak_link == undefined) return undefined; 154 if (weak_link == undefined) return undefined;
155 WeakCell* cell = WeakCell::cast(weak_link); 155 WeakCell* cell = WeakCell::cast(weak_link);
156 return cell->value(); 156 return cell->value();
157 } 157 }
158 158
159 namespace { 159 namespace {
160 // Internal constants for the layout of the module object. 160 // Internal constants for the layout of the module object.
161 const int kWasmModuleFunctionTable = 0; 161 enum WasmInstanceFields {
162 const int kWasmModuleCodeTable = 1; 162 kWasmCompiledModule = 0,
163 const int kWasmMemArrayBuffer = 2; 163 kWasmModuleFunctionTable,
164 const int kWasmGlobalsArrayBuffer = 3; 164 kWasmModuleCodeTable,
165 // TODO(clemensh): Remove function name array, extract names from module bytes. 165 kWasmMemArrayBuffer,
166 const int kWasmFunctionNamesArray = 4; 166 kWasmGlobalsArrayBuffer,
167 const int kWasmModuleBytesString = 5; 167 // TODO(clemensh): Remove function name array, extract names from module
168 const int kWasmDebugInfo = 6; 168 // bytes.
169 const int kWasmModuleInternalFieldCount = 7; 169 kWasmFunctionNamesArray,
170 kWasmModuleBytesString,
171 kWasmDebugInfo,
172 kWasmModuleInternalFieldCount
173 };
170 174
171 // 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.
172 // 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.
173 // The elements typed as "maybe" are optional. The others are mandatory. Since 177 // The elements typed as "maybe" are optional. The others are mandatory. Since
174 // the compiled module is either obtained from the current v8 instance, or from 178 // the compiled module is either obtained from the current v8 instance, or from
175 // a snapshot produced by a compatible (==identical) v8 instance, we simply 179 // a snapshot produced by a compatible (==identical) v8 instance, we simply
176 // fail at instantiation time, in the face of invalid data. 180 // fail at instantiation time, in the face of invalid data.
177 enum CompiledWasmObjectFields { 181 enum CompiledWasmObjectFields {
178 kFunctions, // FixedArray of Code 182 kFunctions, // FixedArray of Code
179 kImportData, // maybe FixedArray of FixedArray respecting the 183 kImportData, // maybe FixedArray of FixedArray respecting the
180 // WasmImportMetadata structure. 184 // WasmImportMetadata structure.
181 kImportMap, // FixedArray. The i-th element is the Code object used for 185 kImportMap, // FixedArray. The i-th element is the Code object used for
182 // import i 186 // import i
183 kExports, // maybe FixedArray of FixedArray of WasmExportMetadata 187 kExports, // maybe FixedArray of FixedArray of WasmExportMetadata
184 // structure 188 // structure
185 kStartupFunction, // maybe FixedArray of WasmExportMetadata structure 189 kStartupFunction, // maybe FixedArray of WasmExportMetadata structure
186 kTableOfIndirectFunctionTables, // maybe FixedArray of FixedArray of 190 kTableOfIndirectFunctionTables, // maybe FixedArray of FixedArray of
187 // WasmIndirectFunctionTableMetadata 191 // WasmIndirectFunctionTableMetadata
188 kModuleBytes, // maybe String 192 kModuleBytes, // maybe String
189 kFunctionNameTable, // maybe ByteArray 193 kFunctionNameTable, // maybe ByteArray
190 kMinRequiredMemory, // Smi. an uint32_t 194 kMinRequiredMemory, // Smi. an uint32_t
191 // The following 2 are either together present or absent: 195 // The following 2 are either together present or absent:
192 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the 196 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the
193 // WasmSegmentInfo structure 197 // WasmSegmentInfo structure
194 kDataSegments, // maybe ByteArray. 198 kDataSegments, // maybe ByteArray.
195 199
196 kGlobalsSize, // Smi. an uint32_t 200 kGlobalsSize, // Smi. an uint32_t
201 kMemSize, // Smi.an uint32_t
202 kMemStart, // MaybeHandle<ArrayBuffer>
197 kExportMem, // Smi. bool 203 kExportMem, // Smi. bool
198 kOrigin, // Smi. ModuleOrigin 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.
199 kCompiledWasmObjectTableSize // Sentinel value. 209 kCompiledWasmObjectTableSize // Sentinel value.
200 }; 210 };
201 211
202 enum WasmImportMetadata { 212 enum WasmImportMetadata {
203 kModuleName, // String 213 kModuleName, // String
204 kFunctionName, // maybe String 214 kFunctionName, // maybe String
205 kOutputCount, // Smi. an uint32_t 215 kOutputCount, // Smi. an uint32_t
206 kSignature, // ByteArray. A copy of the data in FunctionSig 216 kSignature, // ByteArray. A copy of the data in FunctionSig
207 kWasmImportDataTableSize // Sentinel value. 217 kWasmImportDataTableSize // Sentinel value.
208 }; 218 };
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 DCHECK_EQ(0, bytes[i]); 332 DCHECK_EQ(0, bytes[i]);
323 } 333 }
324 #endif 334 #endif
325 335
326 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); 336 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
327 JSArrayBuffer::Setup(buffer, isolate, false, memory, static_cast<int>(size)); 337 JSArrayBuffer::Setup(buffer, isolate, false, memory, static_cast<int>(size));
328 buffer->set_is_neuterable(false); 338 buffer->set_is_neuterable(false);
329 return buffer; 339 return buffer;
330 } 340 }
331 341
332 void RelocateInstanceCode(Handle<JSObject> instance, Address start, 342 void RelocateInstanceCode(Handle<JSObject> instance, Address old_start,
333 uint32_t prev_size, uint32_t new_size) { 343 Address start, uint32_t prev_size,
344 uint32_t new_size) {
334 Handle<FixedArray> functions = Handle<FixedArray>( 345 Handle<FixedArray> functions = Handle<FixedArray>(
335 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); 346 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable)));
336 for (int i = 0; i < functions->length(); ++i) { 347 for (int i = 0; i < functions->length(); ++i) {
337 Handle<Code> function = Handle<Code>(Code::cast(functions->get(i))); 348 Handle<Code> function = Handle<Code>(Code::cast(functions->get(i)));
338 AllowDeferredHandleDereference embedding_raw_address; 349 AllowDeferredHandleDereference embedding_raw_address;
339 int mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE) | 350 int mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE) |
340 (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE); 351 (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
341 for (RelocIterator it(*function, mask); !it.done(); it.next()) { 352 for (RelocIterator it(*function, mask); !it.done(); it.next()) {
342 it.rinfo()->update_wasm_memory_reference(nullptr, start, prev_size, 353 it.rinfo()->update_wasm_memory_reference(old_start, start, prev_size,
343 new_size); 354 new_size);
344 } 355 }
345 } 356 }
346 } 357 }
347 358
348 // Allocate memory for a module instance as a new JSArrayBuffer. 359 // Allocate memory for a module instance as a new JSArrayBuffer.
349 Handle<JSArrayBuffer> AllocateMemory(ErrorThrower* thrower, Isolate* isolate, 360 Handle<JSArrayBuffer> AllocateMemory(ErrorThrower* thrower, Isolate* isolate,
350 uint32_t min_mem_pages) { 361 uint32_t min_mem_pages) {
351 if (min_mem_pages > WasmModule::kMaxMemPages) { 362 if (min_mem_pages > WasmModule::kMaxMemPages) {
352 thrower->Error("Out of memory: wasm memory too large"); 363 thrower->Error("Out of memory: wasm memory too large");
353 return Handle<JSArrayBuffer>::null(); 364 return Handle<JSArrayBuffer>::null();
354 } 365 }
355 Handle<JSArrayBuffer> mem_buffer = 366 Handle<JSArrayBuffer> mem_buffer =
356 NewArrayBuffer(isolate, min_mem_pages * WasmModule::kPageSize); 367 NewArrayBuffer(isolate, min_mem_pages * WasmModule::kPageSize);
357 368
358 if (mem_buffer.is_null()) { 369 if (mem_buffer.is_null()) {
359 thrower->Error("Out of memory: wasm memory"); 370 thrower->Error("Out of memory: wasm memory");
360 } 371 }
361 return mem_buffer; 372 return mem_buffer;
362 } 373 }
363 374
364 void RelocateGlobals(Handle<JSObject> instance, Address globals_start) { 375 void RelocateGlobals(Handle<JSObject> instance, Address old_start,
376 Address globals_start) {
365 Handle<FixedArray> functions = Handle<FixedArray>( 377 Handle<FixedArray> functions = Handle<FixedArray>(
366 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); 378 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable)));
367 uint32_t function_count = static_cast<uint32_t>(functions->length()); 379 uint32_t function_count = static_cast<uint32_t>(functions->length());
368 for (uint32_t i = 0; i < function_count; ++i) { 380 for (uint32_t i = 0; i < function_count; ++i) {
369 Handle<Code> function = Handle<Code>(Code::cast(functions->get(i))); 381 Handle<Code> function = Handle<Code>(Code::cast(functions->get(i)));
370 AllowDeferredHandleDereference embedding_raw_address; 382 AllowDeferredHandleDereference embedding_raw_address;
371 int mask = 1 << RelocInfo::WASM_GLOBAL_REFERENCE; 383 int mask = 1 << RelocInfo::WASM_GLOBAL_REFERENCE;
372 for (RelocIterator it(*function, mask); !it.done(); it.next()) { 384 for (RelocIterator it(*function, mask); !it.done(); it.next()) {
373 it.rinfo()->update_wasm_global_reference(nullptr, globals_start); 385 it.rinfo()->update_wasm_global_reference(old_start, globals_start);
374 } 386 }
375 } 387 }
376 } 388 }
377 389
378 Handle<Code> CreatePlaceholder(Factory* factory, uint32_t index, 390 Handle<Code> CreatePlaceholder(Factory* factory, uint32_t index,
379 Code::Kind kind) { 391 Code::Kind kind) {
380 // Create a placeholder code object and encode the corresponding index in 392 // Create a placeholder code object and encode the corresponding index in
381 // the {constant_pool_offset} field of the code object. 393 // the {constant_pool_offset} field of the code object.
382 // TODO(titzer): placeholder code objects are somewhat dangerous. 394 // TODO(titzer): placeholder code objects are somewhat dangerous.
383 static byte buffer[] = {0, 0, 0, 0, 0, 0, 0, 0}; // fake instructions. 395 static byte buffer[] = {0, 0, 0, 0, 0, 0, 0, 0}; // fake instructions.
(...skipping 10 matching lines...) Expand all
394 std::vector<Handle<Code>>* placeholders, 406 std::vector<Handle<Code>>* placeholders,
395 size_t size) { 407 size_t size) {
396 DCHECK(placeholders->empty()); 408 DCHECK(placeholders->empty());
397 placeholders->reserve(size); 409 placeholders->reserve(size);
398 410
399 for (uint32_t i = 0; i < size; ++i) { 411 for (uint32_t i = 0; i < size; ++i) {
400 placeholders->push_back(CreatePlaceholder(factory, i, Code::WASM_FUNCTION)); 412 placeholders->push_back(CreatePlaceholder(factory, i, Code::WASM_FUNCTION));
401 } 413 }
402 } 414 }
403 415
404 bool LinkFunction(Handle<Code> unlinked, 416 bool LinkFunction(Isolate* isolate, Handle<Code> unlinked,
405 const std::vector<Handle<Code>>& code_targets, 417 Handle<FixedArray> code_targets,
406 Code::Kind kind) { 418 Code::Kind kind = Code::WASM_FUNCTION) {
407 bool modified = false; 419 bool modified = false;
408 int mode_mask = RelocInfo::kCodeTargetMask; 420 int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
409 AllowDeferredHandleDereference embedding_raw_address; 421 AllowDeferredHandleDereference embedding_raw_address;
410 for (RelocIterator it(*unlinked, mode_mask); !it.done(); it.next()) { 422 for (RelocIterator it(*unlinked, mode_mask); !it.done(); it.next()) {
411 RelocInfo::Mode mode = it.rinfo()->rmode(); 423 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
412 if (RelocInfo::IsCodeTarget(mode)) { 424 if (target->kind() == kind &&
413 Code* target = 425 target->constant_pool_offset() >= kPlaceholderMarker) {
414 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); 426 // Patch direct calls to placeholder code objects.
415 if (target->kind() == kind && 427 uint32_t index = target->constant_pool_offset() - kPlaceholderMarker;
416 target->constant_pool_offset() >= kPlaceholderMarker) { 428 CHECK(index < static_cast<uint32_t>(code_targets->length()));
417 // Patch direct calls to placeholder code objects. 429 Handle<Code> new_target =
418 uint32_t index = target->constant_pool_offset() - kPlaceholderMarker; 430 code_targets->GetValueChecked<Code>(isolate, index);
419 CHECK(index < code_targets.size()); 431 if (target != *new_target) {
420 Handle<Code> new_target = code_targets[index]; 432 it.rinfo()->set_target_address(new_target->instruction_start(),
421 if (target != *new_target) { 433 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
422 it.rinfo()->set_target_address(new_target->instruction_start(), 434 modified = true;
423 UPDATE_WRITE_BARRIER,
424 SKIP_ICACHE_FLUSH);
425 modified = true;
426 }
427 } 435 }
428 } 436 }
429 } 437 }
430 return modified; 438 return modified;
431 } 439 }
432 440
433 void LinkModuleFunctions(Isolate* isolate, 441 void LinkModuleFunctions(Isolate* isolate, Handle<FixedArray> functions) {
434 std::vector<Handle<Code>>& functions) { 442 for (int i = 0; i < functions->length(); ++i) {
435 for (size_t i = 0; i < functions.size(); ++i) { 443 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i);
436 Handle<Code> code = functions[i]; 444 LinkFunction(isolate, code, functions);
437 LinkFunction(code, functions, Code::WASM_FUNCTION);
438 } 445 }
439 } 446 }
440 447
441 void FlushAssemblyCache(Isolate* isolate, Handle<FixedArray> functions) { 448 void FlushAssemblyCache(Isolate* isolate, Handle<FixedArray> functions) {
442 for (int i = 0; i < functions->length(); ++i) { 449 for (int i = 0; i < functions->length(); ++i) {
443 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i); 450 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i);
444 Assembler::FlushICache(isolate, code->instruction_start(), 451 Assembler::FlushICache(isolate, code->instruction_start(),
445 code->instruction_size()); 452 code->instruction_size());
446 } 453 }
447 } 454 }
448 455
449 void SetRuntimeSupport(Isolate* isolate, Handle<JSObject> js_object) { 456 void SetRuntimeSupport(Isolate* isolate, Handle<JSObject> js_object) {
450 Handle<FixedArray> functions = Handle<FixedArray>( 457 Handle<FixedArray> functions = Handle<FixedArray>(
451 FixedArray::cast(js_object->GetInternalField(kWasmModuleCodeTable))); 458 FixedArray::cast(js_object->GetInternalField(kWasmModuleCodeTable)));
452 Handle<WeakCell> weak_link = isolate->factory()->NewWeakCell(js_object); 459 Handle<WeakCell> weak_link = isolate->factory()->NewWeakCell(js_object);
453 460
454 for (int i = FLAG_skip_compiling_wasm_funcs; i < functions->length(); ++i) { 461 for (int i = FLAG_skip_compiling_wasm_funcs; i < functions->length(); ++i) {
455 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i); 462 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i);
456 DCHECK(code->deoptimization_data() == nullptr ||
457 code->deoptimization_data()->length() == 0);
458 Handle<FixedArray> deopt_data = 463 Handle<FixedArray> deopt_data =
459 isolate->factory()->NewFixedArray(2, TENURED); 464 isolate->factory()->NewFixedArray(2, TENURED);
460 deopt_data->set(0, *weak_link); 465 deopt_data->set(0, *weak_link);
461 deopt_data->set(1, Smi::FromInt(static_cast<int>(i))); 466 deopt_data->set(1, Smi::FromInt(static_cast<int>(i)));
462 deopt_data->set_length(2); 467 deopt_data->set_length(2);
463 code->set_deoptimization_data(*deopt_data); 468 code->set_deoptimization_data(*deopt_data);
464 } 469 }
465 } 470 }
466 471
467 } // namespace 472 } // namespace
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 for (Handle<Code> c : functions) RecordStats(isolate, *c); 619 for (Handle<Code> c : functions) RecordStats(isolate, *c);
615 } 620 }
616 621
617 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions) { 622 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions) {
618 DisallowHeapAllocation no_gc; 623 DisallowHeapAllocation no_gc;
619 for (int i = 0; i < functions->length(); ++i) { 624 for (int i = 0; i < functions->length(); ++i) {
620 RecordStats(isolate, Code::cast(functions->get(i))); 625 RecordStats(isolate, Code::cast(functions->get(i)));
621 } 626 }
622 } 627 }
623 628
629 Address GetGlobalStartAddressFromCodeTemplate(Object* undefined,
630 JSObject* owner) {
631 Address old_address = nullptr;
632 Object* stored_value = owner->GetInternalField(kWasmGlobalsArrayBuffer);
633 if (stored_value != undefined) {
634 old_address = static_cast<Address>(
635 JSArrayBuffer::cast(stored_value)->backing_store());
636 }
637 return old_address;
638 }
639
624 Handle<FixedArray> GetImportsMetadata(Factory* factory, 640 Handle<FixedArray> GetImportsMetadata(Factory* factory,
625 const WasmModule* module) { 641 const WasmModule* module) {
626 Handle<FixedArray> ret = factory->NewFixedArray( 642 Handle<FixedArray> ret = factory->NewFixedArray(
627 static_cast<int>(module->import_table.size()), TENURED); 643 static_cast<int>(module->import_table.size()), TENURED);
628 for (size_t i = 0; i < module->import_table.size(); ++i) { 644 for (size_t i = 0; i < module->import_table.size(); ++i) {
629 const WasmImport& import = module->import_table[i]; 645 const WasmImport& import = module->import_table[i];
630 WasmName module_name = module->GetNameOrNull(import.module_name_offset, 646 WasmName module_name = module->GetNameOrNull(import.module_name_offset,
631 import.module_name_length); 647 import.module_name_length);
632 WasmName function_name = module->GetNameOrNull(import.function_name_offset, 648 WasmName function_name = module->GetNameOrNull(import.function_name_offset,
633 import.function_name_length); 649 import.function_name_length);
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 } 921 }
906 922
907 MaybeHandle<ByteArray> function_name_table = 923 MaybeHandle<ByteArray> function_name_table =
908 compiled_module->GetValue<ByteArray>(isolate, kFunctionNameTable); 924 compiled_module->GetValue<ByteArray>(isolate, kFunctionNameTable);
909 if (!function_name_table.is_null()) { 925 if (!function_name_table.is_null()) {
910 js_object->SetInternalField(kWasmFunctionNamesArray, 926 js_object->SetInternalField(kWasmFunctionNamesArray,
911 *function_name_table.ToHandleChecked()); 927 *function_name_table.ToHandleChecked());
912 } 928 }
913 } 929 }
914 930
915 bool SetupGlobals(Isolate* isolate, Handle<FixedArray> compiled_module, 931 bool SetupGlobals(Isolate* isolate, MaybeHandle<JSObject> template_owner,
916 Handle<JSObject> instance, ErrorThrower* thrower) { 932 Handle<FixedArray> compiled_module, Handle<JSObject> instance,
933 ErrorThrower* thrower) {
917 uint32_t globals_size = static_cast<uint32_t>( 934 uint32_t globals_size = static_cast<uint32_t>(
918 Smi::cast(compiled_module->get(kGlobalsSize))->value()); 935 Smi::cast(compiled_module->get(kGlobalsSize))->value());
919 if (globals_size > 0) { 936 if (globals_size > 0) {
920 Handle<JSArrayBuffer> globals_buffer = 937 Handle<JSArrayBuffer> globals_buffer =
921 NewArrayBuffer(isolate, globals_size); 938 NewArrayBuffer(isolate, globals_size);
922 if (globals_buffer.is_null()) { 939 if (globals_buffer.is_null()) {
923 thrower->Error("Out of memory: wasm globals"); 940 thrower->Error("Out of memory: wasm globals");
924 return false; 941 return false;
925 } 942 }
926 RelocateGlobals(instance, 943 Address old_address =
944 template_owner.is_null()
945 ? nullptr
946 : GetGlobalStartAddressFromCodeTemplate(
947 *isolate->factory()->undefined_value(),
948 JSObject::cast(*template_owner.ToHandleChecked()));
949 RelocateGlobals(instance, old_address,
927 static_cast<Address>(globals_buffer->backing_store())); 950 static_cast<Address>(globals_buffer->backing_store()));
928 instance->SetInternalField(kWasmGlobalsArrayBuffer, *globals_buffer); 951 instance->SetInternalField(kWasmGlobalsArrayBuffer, *globals_buffer);
929 } 952 }
930 return true; 953 return true;
931 } 954 }
932 955
933 bool SetupInstanceHeap(Isolate* isolate, Handle<FixedArray> compiled_module, 956 bool SetupInstanceHeap(Isolate* isolate, Handle<FixedArray> compiled_module,
934 Handle<JSObject> instance, Handle<JSArrayBuffer> memory, 957 Handle<JSObject> instance, Handle<JSArrayBuffer> memory,
935 ErrorThrower* thrower) { 958 ErrorThrower* thrower) {
936 uint32_t min_mem_pages = static_cast<uint32_t>( 959 uint32_t min_mem_pages = static_cast<uint32_t>(
937 Smi::cast(compiled_module->get(kMinRequiredMemory))->value()); 960 Smi::cast(compiled_module->get(kMinRequiredMemory))->value());
938 isolate->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); 961 isolate->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages);
939 // TODO(wasm): re-enable counter for max_mem_pages when we use that field. 962 // TODO(wasm): re-enable counter for max_mem_pages when we use that field.
940 963
941 if (memory.is_null() && min_mem_pages > 0) { 964 if (memory.is_null() && min_mem_pages > 0) {
942 memory = AllocateMemory(thrower, isolate, min_mem_pages); 965 memory = AllocateMemory(thrower, isolate, min_mem_pages);
943 if (memory.is_null()) { 966 if (memory.is_null()) {
944 return false; 967 return false;
945 } 968 }
946 } 969 }
947 970
948 if (!memory.is_null()) { 971 if (!memory.is_null()) {
949 instance->SetInternalField(kWasmMemArrayBuffer, *memory); 972 instance->SetInternalField(kWasmMemArrayBuffer, *memory);
950 Address mem_start = static_cast<Address>(memory->backing_store()); 973 Address mem_start = static_cast<Address>(memory->backing_store());
951 uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number()); 974 uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number());
952 RelocateInstanceCode(instance, mem_start, 975 uint32_t old_mem_size = static_cast<uint32_t>(
953 WasmModule::kPageSize * min_mem_pages, 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 =
981 old_mem.is_null()
982 ? nullptr
983 : static_cast<Address>(old_mem.ToHandleChecked()->backing_store());
984 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size,
985 mem_size);
954 LoadDataSegments(compiled_module, mem_start, mem_size); 986 LoadDataSegments(compiled_module, mem_start, mem_size);
987 compiled_module->GetValueChecked<HeapNumber>(isolate, kMemSize)
988 ->set_value(static_cast<double>(mem_size));
989 compiled_module->set(kMemStart, *memory);
955 } 990 }
956 return true; 991 return true;
957 } 992 }
958 993
994 void FixupFunctionsAndImports(Handle<FixedArray> old_functions,
995 Handle<FixedArray> new_functions,
996 MaybeHandle<FixedArray> maybe_old_imports,
997 MaybeHandle<FixedArray> maybe_new_imports) {
998 DCHECK_EQ(new_functions->length(), old_functions->length());
999
1000 DisallowHeapAllocation no_gc;
1001 std::map<Code*, Code*> old_to_new_code;
1002 for (int i = 0; i < new_functions->length(); ++i) {
1003 old_to_new_code.insert(std::make_pair(Code::cast(old_functions->get(i)),
1004 Code::cast(new_functions->get(i))));
1005 }
1006 DCHECK_EQ(maybe_old_imports.is_null(), maybe_new_imports.is_null());
1007 if (!maybe_old_imports.is_null()) {
1008 Handle<FixedArray> old_imports = maybe_old_imports.ToHandleChecked();
1009 Handle<FixedArray> new_imports = maybe_new_imports.ToHandleChecked();
1010 DCHECK_EQ(new_imports->length(), old_imports->length());
1011 for (int i = 0; i < new_imports->length(); ++i) {
1012 old_to_new_code.insert(std::make_pair(Code::cast(old_imports->get(i)),
1013 Code::cast(new_imports->get(i))));
1014 }
1015 }
1016 int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
1017 AllowDeferredHandleDereference embedding_raw_address;
1018 for (int i = 0; i < new_functions->length(); ++i) {
1019 Code* wasm_function = Code::cast(new_functions->get(i));
1020 for (RelocIterator it(wasm_function, mode_mask); !it.done(); it.next()) {
1021 Code* old_code =
1022 Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
1023 if (old_code->kind() == Code::WASM_TO_JS_FUNCTION ||
1024 old_code->kind() == Code::WASM_FUNCTION) {
1025 auto found = old_to_new_code.find(old_code);
1026 DCHECK(found != old_to_new_code.end());
1027 Code* new_code = found->second;
1028 // Avoid redundant updates, expected for wasm functions, if we're at the
1029 // first instance.
1030 if (new_code == old_code) {
1031 DCHECK(new_code->kind() == Code::WASM_FUNCTION);
1032 continue;
1033 }
1034 it.rinfo()->set_target_address(new_code->instruction_start(),
1035 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
1036 }
1037 }
1038 }
1039 }
1040
959 bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module, 1041 bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module,
960 Handle<JSObject> instance, ErrorThrower* thrower, 1042 Handle<JSObject> instance, ErrorThrower* thrower,
961 Handle<JSReceiver> ffi) { 1043 Handle<JSReceiver> ffi) {
962 //------------------------------------------------------------------------- 1044 //-------------------------------------------------------------------------
963 // Compile wrappers to imported functions. 1045 // Compile wrappers to imported functions.
964 //------------------------------------------------------------------------- 1046 //-------------------------------------------------------------------------
965 std::vector<Handle<Code>> import_code; 1047 std::vector<Handle<Code>> import_code;
966 MaybeHandle<FixedArray> maybe_import_data = 1048 MaybeHandle<FixedArray> maybe_import_data =
967 compiled_module->GetValue<FixedArray>(isolate, kImportData); 1049 compiled_module->GetValue<FixedArray>(isolate, kImportData);
968 Handle<FixedArray> import_data; 1050 Handle<FixedArray> import_data;
969 if (maybe_import_data.ToHandle(&import_data)) { 1051 if (maybe_import_data.ToHandle(&import_data)) {
970 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code, 1052 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code,
971 import_data, thrower)) { 1053 import_data, thrower)) {
972 return false; 1054 return false;
973 } 1055 }
974 } 1056 }
975 1057
976 RecordStats(isolate, import_code); 1058 RecordStats(isolate, import_code);
977
978 if (import_code.empty()) return true; 1059 if (import_code.empty()) return true;
979 1060
980 { 1061 Handle<FixedArray> new_imports =
981 DisallowHeapAllocation no_gc; 1062 isolate->factory()->NewFixedArray(static_cast<int>(import_code.size()));
982 std::map<Code*, int> import_to_index; 1063 for (int i = 0; i < new_imports->length(); ++i) {
983 Handle<FixedArray> mapping = 1064 new_imports->set(i, *import_code[i]);
984 compiled_module->GetValueChecked<FixedArray>(isolate, kImportMap);
985 for (int i = 0; i < mapping->length(); ++i) {
986 import_to_index.insert(std::make_pair(Code::cast(mapping->get(i)), i));
987 }
988
989 Handle<FixedArray> code_table = Handle<FixedArray>(
990 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable)));
991
992 int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
993 AllowDeferredHandleDereference embedding_raw_address;
994 for (int i = 0; i < code_table->length(); ++i) {
995 Handle<Code> wasm_function =
996 code_table->GetValueChecked<Code>(isolate, i);
997 for (RelocIterator it(*wasm_function, mode_mask); !it.done(); it.next()) {
998 Code* target =
999 Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
1000 if (target->kind() == Code::WASM_TO_JS_FUNCTION) {
1001 auto found_index = import_to_index.find(target);
1002 CHECK(found_index != import_to_index.end());
1003 int index = found_index->second;
1004 CHECK(index < static_cast<int>(import_code.size()));
1005 Handle<Code> new_target = import_code[index];
1006 it.rinfo()->set_target_address(new_target->instruction_start(),
1007 UPDATE_WRITE_BARRIER,
1008 SKIP_ICACHE_FLUSH);
1009 }
1010 }
1011 }
1012 } 1065 }
1013 Handle<FixedArray> new_mapping = 1066 compiled_module->set(kImportMap, *new_imports);
1014 isolate->factory()->NewFixedArray(static_cast<int>(import_code.size()));
1015 for (int i = 0; i < new_mapping->length(); ++i) {
1016 new_mapping->set(i, *import_code[i]);
1017 }
1018 compiled_module->set(kImportMap, *new_mapping);
1019
1020 return true; 1067 return true;
1021 } 1068 }
1022 1069
1023 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate, 1070 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate,
1024 Handle<JSObject> instance, ErrorThrower* thrower) { 1071 Handle<JSObject> instance, ErrorThrower* thrower) {
1025 Factory* factory = isolate->factory(); 1072 Factory* factory = isolate->factory();
1026 bool mem_export = 1073 bool mem_export =
1027 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value()); 1074 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value());
1028 ModuleOrigin origin = static_cast<ModuleOrigin>( 1075 ModuleOrigin origin = static_cast<ModuleOrigin>(
1029 Smi::cast(compiled_module->get(kOrigin))->value()); 1076 Smi::cast(compiled_module->get(kOrigin))->value());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 // Export the memory as a named property. 1121 // Export the memory as a named property.
1075 Handle<String> name = factory->InternalizeUtf8String("memory"); 1122 Handle<String> name = factory->InternalizeUtf8String("memory");
1076 Handle<JSArrayBuffer> memory = Handle<JSArrayBuffer>( 1123 Handle<JSArrayBuffer> memory = Handle<JSArrayBuffer>(
1077 JSArrayBuffer::cast(instance->GetInternalField(kWasmMemArrayBuffer))); 1124 JSArrayBuffer::cast(instance->GetInternalField(kWasmMemArrayBuffer)));
1078 JSObject::AddProperty(exports_object, name, memory, READ_ONLY); 1125 JSObject::AddProperty(exports_object, name, memory, READ_ONLY);
1079 } 1126 }
1080 } 1127 }
1081 return true; 1128 return true;
1082 } 1129 }
1083 1130
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,
1148 FixedArray* compiled_module) {
1149 Object* undefined = *isolate->factory()->undefined_value();
1150 Object* mem_size_obj = compiled_module->get(kMemSize);
1151 DCHECK(mem_size_obj->IsMutableHeapNumber());
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;
1156 Address globals_start =
1157 GetGlobalStartAddressFromCodeTemplate(undefined, owner);
1158
1159 if (old_mem_size > 0) {
1160 CHECK_NE(mem_start, undefined);
1161 old_mem_address =
1162 static_cast<Address>(JSArrayBuffer::cast(mem_start)->backing_store());
1163 }
1164 int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_REFERENCE) |
1165 RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_SIZE_REFERENCE) |
1166 RelocInfo::ModeMask(RelocInfo::WASM_GLOBAL_REFERENCE);
1167
1168 Object* fct_obj = compiled_module->get(kFunctions);
1169 if (fct_obj != nullptr && fct_obj != undefined &&
1170 (old_mem_size > 0 || globals_start != nullptr)) {
1171 FixedArray* functions = FixedArray::cast(fct_obj);
1172 for (int i = 0; i < functions->length(); ++i) {
1173 Code* code = Code::cast(functions->get(i));
1174 bool changed = false;
1175 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
1176 RelocInfo::Mode mode = it.rinfo()->rmode();
1177 if (RelocInfo::IsWasmMemoryReference(mode) ||
1178 RelocInfo::IsWasmMemorySizeReference(mode)) {
1179 it.rinfo()->update_wasm_memory_reference(old_mem_address, nullptr,
1180 old_mem_size, old_mem_size);
1181 changed = true;
1182 } else {
1183 CHECK(RelocInfo::IsWasmGlobalReference(mode));
1184 it.rinfo()->update_wasm_global_reference(globals_start, nullptr);
1185 changed = true;
1186 }
1187 }
1188 if (changed) {
1189 Assembler::FlushICache(isolate, code->instruction_start(),
1190 code->instruction_size());
1191 }
1192 }
1193 }
1194 compiled_module->set(kOwningInstance, undefined);
1195 compiled_module->set(kMemStart, undefined);
1196 }
1197
1198 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
1199 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter());
1200 JSObject* owner = *p;
1201 FixedArray* compiled_module =
1202 FixedArray::cast(owner->GetInternalField(kWasmCompiledModule));
1203 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
1204 Object* undefined = *isolate->factory()->undefined_value();
1205 WeakCell* weak_module_obj = GetModuleObject(compiled_module);
1206 DCHECK_NOT_NULL(weak_module_obj);
1207 // 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,
1209 // and we don't need to maintain the links between instances.
1210 if (!weak_module_obj->cleared()) {
1211 JSObject* module_obj = JSObject::cast(weak_module_obj->value());
1212 FixedArray* current_template =
1213 FixedArray::cast(module_obj->GetInternalField(0));
1214 DCHECK_NULL(GetPrevInstance(current_template));
1215 WeakCell* next = GetNextInstance(compiled_module);
1216 WeakCell* prev = GetPrevInstance(compiled_module);
1217
1218 if (current_template == compiled_module) {
1219 if (next == nullptr) {
1220 ResetCompiledModule(isolate, owner, compiled_module);
1221 } else {
1222 DCHECK(next->value()->IsFixedArray());
1223 module_obj->SetInternalField(0, next->value());
1224 DCHECK_NULL(prev);
1225 FixedArray::cast(next->value())->set(kPrevInstance, undefined);
1226 }
1227 } else {
1228 DCHECK(!(prev == nullptr && next == nullptr));
1229 // the only reason prev or next would be cleared is if the
1230 // respective objects got collected, but if that happened,
1231 // we would have relinked the list.
1232 if (prev != nullptr) {
1233 DCHECK(!prev->cleared());
1234 FixedArray::cast(prev->value())
1235 ->set(kNextInstance, next == nullptr ? undefined : next);
1236 }
1237 if (next != nullptr) {
1238 DCHECK(!next->cleared());
1239 FixedArray::cast(next->value())
1240 ->set(kPrevInstance, prev == nullptr ? undefined : prev);
1241 }
1242 }
1243 }
1244 GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
1245 }
1246
1084 } // namespace 1247 } // namespace
1085 1248
1086 MaybeHandle<FixedArray> WasmModule::CompileFunctions( 1249 MaybeHandle<FixedArray> WasmModule::CompileFunctions(
1087 Isolate* isolate, ErrorThrower* thrower) const { 1250 Isolate* isolate, ErrorThrower* thrower) const {
1088 Factory* factory = isolate->factory(); 1251 Factory* factory = isolate->factory();
1089 1252
1090 MaybeHandle<FixedArray> nothing; 1253 MaybeHandle<FixedArray> nothing;
1091 1254
1092 WasmModuleInstance temp_instance_for_compilation(this); 1255 WasmModuleInstance temp_instance_for_compilation(this);
1093 temp_instance_for_compilation.context = isolate->native_context(); 1256 temp_instance_for_compilation.context = isolate->native_context();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 } 1312 }
1150 if (thrower->error()) return nothing; 1313 if (thrower->error()) return nothing;
1151 1314
1152 // At this point, compilation has completed. Update the code table. 1315 // At this point, compilation has completed. Update the code table.
1153 for (size_t i = FLAG_skip_compiling_wasm_funcs; 1316 for (size_t i = FLAG_skip_compiling_wasm_funcs;
1154 i < temp_instance_for_compilation.function_code.size(); ++i) { 1317 i < temp_instance_for_compilation.function_code.size(); ++i) {
1155 Code* code = *temp_instance_for_compilation.function_code[i]; 1318 Code* code = *temp_instance_for_compilation.function_code[i];
1156 compiled_functions->set(static_cast<int>(i), code); 1319 compiled_functions->set(static_cast<int>(i), code);
1157 } 1320 }
1158 1321
1322 LinkModuleFunctions(isolate, compiled_functions);
1323
1324 // TODO(mtrofin): do we need to flush the cache here?
1325 FlushAssemblyCache(isolate, compiled_functions);
1326
1159 // Create the compiled module object, and populate with compiled functions 1327 // Create the compiled module object, and populate with compiled functions
1160 // and information needed at instantiation time. This object needs to be 1328 // and information needed at instantiation time. This object needs to be
1161 // serializable. Instantiation may occur off a deserialized version of this 1329 // serializable. Instantiation may occur off a deserialized version of this
1162 // object. 1330 // object.
1163 Handle<FixedArray> ret = 1331 Handle<FixedArray> ret =
1164 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED); 1332 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED);
1165 ret->set(kFunctions, *compiled_functions); 1333 ret->set(kFunctions, *compiled_functions);
1166 if (!indirect_table.is_null()) { 1334 if (!indirect_table.is_null()) {
1167 ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked()); 1335 ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked());
1168 } 1336 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 } 1412 }
1245 1413
1246 Handle<ByteArray> function_name_table = 1414 Handle<ByteArray> function_name_table =
1247 BuildFunctionNamesTable(isolate, module_env.module); 1415 BuildFunctionNamesTable(isolate, module_env.module);
1248 ret->set(kFunctionNameTable, *function_name_table); 1416 ret->set(kFunctionNameTable, *function_name_table);
1249 ret->set(kMinRequiredMemory, Smi::FromInt(min_mem_pages)); 1417 ret->set(kMinRequiredMemory, Smi::FromInt(min_mem_pages));
1250 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret); 1418 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret);
1251 ret->set(kGlobalsSize, Smi::FromInt(globals_size)); 1419 ret->set(kGlobalsSize, Smi::FromInt(globals_size));
1252 ret->set(kExportMem, Smi::FromInt(mem_export)); 1420 ret->set(kExportMem, Smi::FromInt(mem_export));
1253 ret->set(kOrigin, Smi::FromInt(origin)); 1421 ret->set(kOrigin, Smi::FromInt(origin));
1422 Handle<HeapNumber> size_as_object = factory->NewHeapNumber(
1423 static_cast<double>(temp_instance_for_compilation.mem_size), MUTABLE,
1424 TENURED);
1425 ret->set(kMemSize, *size_as_object);
1254 return ret; 1426 return ret;
1255 } 1427 }
1256 1428
1257 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper, 1429 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper,
1258 Handle<Code> new_target) { 1430 Handle<Code> new_target) {
1259 AllowDeferredHandleDereference embedding_raw_address; 1431 AllowDeferredHandleDereference embedding_raw_address;
1260 bool seen = false; 1432 bool seen = false;
1261 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done(); 1433 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done();
1262 it.next()) { 1434 it.next()) {
1263 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); 1435 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
1264 if (target->kind() == Code::WASM_FUNCTION) { 1436 if (target->kind() == Code::WASM_FUNCTION) {
1265 DCHECK(!seen); 1437 DCHECK(!seen);
1266 seen = true; 1438 seen = true;
1267 it.rinfo()->set_target_address(new_target->instruction_start(), 1439 it.rinfo()->set_target_address(new_target->instruction_start(),
1268 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH); 1440 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
1269 } 1441 }
1270 } 1442 }
1271 CHECK(seen); 1443 CHECK(seen);
1272 Assembler::FlushICache(isolate, wrapper->instruction_start(), 1444 Assembler::FlushICache(isolate, wrapper->instruction_start(),
1273 wrapper->instruction_size()); 1445 wrapper->instruction_size());
1274 } 1446 }
1275 1447
1276 Handle<FixedArray> SetupIndirectFunctionTable( 1448 Handle<FixedArray> SetupIndirectFunctionTable(
1277 Isolate* isolate, Handle<FixedArray> wasm_functions, 1449 Isolate* isolate, Handle<FixedArray> wasm_functions,
1278 Handle<FixedArray> indirect_table_template) { 1450 Handle<FixedArray> indirect_table_template,
1451 Handle<FixedArray> tables_to_replace) {
1279 Factory* factory = isolate->factory(); 1452 Factory* factory = isolate->factory();
1280 Handle<FixedArray> cloned_indirect_tables = 1453 Handle<FixedArray> cloned_indirect_tables =
1281 factory->CopyFixedArray(indirect_table_template); 1454 factory->CopyFixedArray(indirect_table_template);
1282 for (int i = 0; i < cloned_indirect_tables->length(); ++i) { 1455 for (int i = 0; i < cloned_indirect_tables->length(); ++i) {
1283 Handle<FixedArray> orig_metadata = 1456 Handle<FixedArray> orig_metadata =
1284 cloned_indirect_tables->GetValueChecked<FixedArray>(isolate, i); 1457 cloned_indirect_tables->GetValueChecked<FixedArray>(isolate, i);
1285 Handle<FixedArray> cloned_metadata = factory->CopyFixedArray(orig_metadata); 1458 Handle<FixedArray> cloned_metadata = factory->CopyFixedArray(orig_metadata);
1286 cloned_indirect_tables->set(i, *cloned_metadata); 1459 cloned_indirect_tables->set(i, *cloned_metadata);
1287 1460
1288 Handle<FixedArray> orig_table = 1461 Handle<FixedArray> orig_table =
1289 cloned_metadata->GetValueChecked<FixedArray>(isolate, kTable); 1462 cloned_metadata->GetValueChecked<FixedArray>(isolate, kTable);
1290 Handle<FixedArray> cloned_table = factory->CopyFixedArray(orig_table); 1463 Handle<FixedArray> cloned_table = factory->CopyFixedArray(orig_table);
1291 cloned_metadata->set(kTable, *cloned_table); 1464 cloned_metadata->set(kTable, *cloned_table);
1292 // Patch the cloned code to refer to the cloned kTable. 1465 // Patch the cloned code to refer to the cloned kTable.
1293 for (int i = 0; i < wasm_functions->length(); ++i) { 1466 Handle<FixedArray> table_to_replace =
1467 tables_to_replace->GetValueChecked<FixedArray>(isolate, i)
1468 ->GetValueChecked<FixedArray>(isolate, kTable);
1469 for (int fct_index = 0; fct_index < wasm_functions->length(); ++fct_index) {
1294 Handle<Code> wasm_function = 1470 Handle<Code> wasm_function =
1295 wasm_functions->GetValueChecked<Code>(isolate, i); 1471 wasm_functions->GetValueChecked<Code>(isolate, fct_index);
1296 PatchFunctionTable(wasm_function, orig_table, cloned_table); 1472 PatchFunctionTable(wasm_function, table_to_replace, cloned_table);
1297 } 1473 }
1298 } 1474 }
1299 return cloned_indirect_tables; 1475 return cloned_indirect_tables;
1300 } 1476 }
1301 1477
1302 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate, 1478 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate,
1303 Handle<FixedArray> original) { 1479 Handle<JSObject> module_object,
1480 bool* template_is_owned,
1481 Handle<FixedArray>* module_template) {
1304 Factory* factory = isolate->factory(); 1482 Factory* factory = isolate->factory();
1483
1484 Handle<FixedArray> original;
1485 for (int i = 0; i < 2; ++i) {
1486 original = handle(FixedArray::cast(module_object->GetInternalField(0)));
1487 if (GetOwningInstance(*original) == nullptr) {
1488 *template_is_owned = false;
1489 *module_template = original;
1490 return original;
1491 }
1492 if (i < 1) {
1493 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
1494 GarbageCollectionReason::kRuntime);
1495 }
1496 }
1497 *template_is_owned = true;
1498 *module_template = original;
1499
1500 // We insert the latest clone in front.
1305 Handle<FixedArray> clone = factory->CopyFixedArray(original); 1501 Handle<FixedArray> clone = factory->CopyFixedArray(original);
1502 Handle<WeakCell> weak_link_to_wasm_obj =
1503 original->GetValueChecked<WeakCell>(isolate, kModuleObject);
1504
1505 clone->set(kModuleObject, *weak_link_to_wasm_obj);
1506 Handle<WeakCell> link_to_original = factory->NewWeakCell(original);
1507 clone->set(kNextInstance, *link_to_original);
1508 Handle<WeakCell> link_to_clone = factory->NewWeakCell(clone);
1509 original->set(kPrevInstance, *link_to_clone);
1510 JSObject::cast(weak_link_to_wasm_obj->value())->SetInternalField(0, *clone);
1306 1511
1307 // Clone each wasm code object. 1512 // Clone each wasm code object.
1308 Handle<FixedArray> orig_wasm_functions = 1513 Handle<FixedArray> orig_wasm_functions =
1309 original->GetValueChecked<FixedArray>(isolate, kFunctions); 1514 original->GetValueChecked<FixedArray>(isolate, kFunctions);
1310 Handle<FixedArray> clone_wasm_functions = 1515 Handle<FixedArray> clone_wasm_functions =
1311 factory->CopyFixedArray(orig_wasm_functions); 1516 factory->CopyFixedArray(orig_wasm_functions);
1312 clone->set(kFunctions, *clone_wasm_functions); 1517 clone->set(kFunctions, *clone_wasm_functions);
1313 for (int i = 0; i < clone_wasm_functions->length(); ++i) { 1518 for (int i = 0; i < clone_wasm_functions->length(); ++i) {
1314 Handle<Code> orig_code = 1519 Handle<Code> orig_code =
1315 clone_wasm_functions->GetValueChecked<Code>(isolate, i); 1520 clone_wasm_functions->GetValueChecked<Code>(isolate, i);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 clone->set(kStartupFunction, *startup_metadata); 1561 clone->set(kStartupFunction, *startup_metadata);
1357 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray. 1562 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray.
1358 int startup_fct_index = 1563 int startup_fct_index =
1359 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value(); 1564 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value();
1360 CHECK_GE(startup_fct_index, 0); 1565 CHECK_GE(startup_fct_index, 0);
1361 CHECK_LT(startup_fct_index, clone_wasm_functions->length()); 1566 CHECK_LT(startup_fct_index, clone_wasm_functions->length());
1362 Handle<Code> new_target = 1567 Handle<Code> new_target =
1363 clone_wasm_functions->GetValueChecked<Code>(isolate, startup_fct_index); 1568 clone_wasm_functions->GetValueChecked<Code>(isolate, startup_fct_index);
1364 PatchJSWrapper(isolate, startup_fct_clone, new_target); 1569 PatchJSWrapper(isolate, startup_fct_clone, new_target);
1365 } 1570 }
1571 clone->set(kImportMap, *isolate->factory()->undefined_value());
1366 return clone; 1572 return clone;
1367 } 1573 }
1368 1574
1369 // Instantiates a wasm module as a JSObject. 1575 // Instantiates a wasm module as a JSObject.
1370 // * allocates a backing store of {mem_size} bytes. 1576 // * allocates a backing store of {mem_size} bytes.
1371 // * installs a named property "memory" for that buffer if exported 1577 // * installs a named property "memory" for that buffer if exported
1372 // * installs named properties on the object for exported functions 1578 // * installs named properties on the object for exported functions
1373 // * compiles wasm code to machine code 1579 // * compiles wasm code to machine code
1374 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, 1580 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
1375 Handle<JSObject> module_object, 1581 Handle<JSObject> module_object,
1376 Handle<JSReceiver> ffi, 1582 Handle<JSReceiver> ffi,
1377 Handle<JSArrayBuffer> memory) { 1583 Handle<JSArrayBuffer> memory) {
1378 HistogramTimerScope wasm_instantiate_module_time_scope( 1584 HistogramTimerScope wasm_instantiate_module_time_scope(
1379 isolate->counters()->wasm_instantiate_module_time()); 1585 isolate->counters()->wasm_instantiate_module_time());
1380 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); 1586 ErrorThrower thrower(isolate, "WasmModule::Instantiate()");
1381 Factory* factory = isolate->factory(); 1587 Factory* factory = isolate->factory();
1382 1588
1383 Handle<FixedArray> compiled_module = 1589 bool template_is_owned = false;
1384 handle(FixedArray::cast(module_object->GetInternalField(0))); 1590 Handle<FixedArray> compiled_module_template;
1385 compiled_module = CloneModuleForInstance(isolate, compiled_module); 1591 Handle<FixedArray> compiled_module = CloneModuleForInstance(
1592 isolate, module_object, &template_is_owned, &compiled_module_template);
1386 1593
1594 MaybeHandle<JSObject> template_owner;
1595 if (template_is_owned) {
1596 Handle<WeakCell> weak_owner =
1597 compiled_module_template->GetValueChecked<WeakCell>(isolate,
1598 kOwningInstance);
1599 template_owner = handle(JSObject::cast(weak_owner->value()));
1600 }
1387 // These fields are compulsory. 1601 // These fields are compulsory.
1388 Handle<FixedArray> code_table = 1602 Handle<FixedArray> code_table =
1389 compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions); 1603 compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions);
1390 1604
1391 std::vector<Handle<Code>> functions(
1392 static_cast<size_t>(code_table->length()));
1393 for (int i = 0; i < code_table->length(); ++i) {
1394 functions[static_cast<size_t>(i)] =
1395 code_table->GetValueChecked<Code>(isolate, i);
1396 }
1397 LinkModuleFunctions(isolate, functions);
1398
1399 RecordStats(isolate, code_table); 1605 RecordStats(isolate, code_table);
1400 1606
1401 MaybeHandle<JSObject> nothing; 1607 MaybeHandle<JSObject> nothing;
1402 1608
1403 Handle<Map> map = factory->NewMap( 1609 Handle<Map> map = factory->NewMap(
1404 JS_OBJECT_TYPE, 1610 JS_OBJECT_TYPE,
1405 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 1611 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
1406 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); 1612 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED);
1407 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); 1613 js_object->SetInternalField(kWasmModuleCodeTable, *code_table);
1408 1614
1615 // 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.
1617 MaybeHandle<FixedArray> old_imports =
1618 compiled_module_template->GetValue<FixedArray>(isolate, kImportMap);
1409 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, 1619 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory,
1410 &thrower) && 1620 &thrower) &&
1411 SetupGlobals(isolate, compiled_module, js_object, &thrower) && 1621 SetupGlobals(isolate, template_owner, compiled_module, js_object,
1622 &thrower) &&
1412 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) && 1623 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) &&
1413 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { 1624 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) {
1414 return nothing; 1625 return nothing;
1415 } 1626 }
1416 1627
1628 FixupFunctionsAndImports(
1629 compiled_module_template->GetValueChecked<FixedArray>(isolate,
1630 kFunctions),
1631 code_table, old_imports,
1632 compiled_module->GetValue<FixedArray>(isolate, kImportMap));
1633
1417 SetDebugSupport(factory, compiled_module, js_object); 1634 SetDebugSupport(factory, compiled_module, js_object);
1418 SetRuntimeSupport(isolate, js_object); 1635 SetRuntimeSupport(isolate, js_object);
1419 1636
1420 FlushAssemblyCache(isolate, code_table); 1637 FlushAssemblyCache(isolate, code_table);
1421 1638
1422 MaybeHandle<FixedArray> maybe_indirect_tables = 1639 {
1423 compiled_module->GetValue<FixedArray>(isolate, 1640 std::vector<Handle<Code>> functions(
1424 kTableOfIndirectFunctionTables); 1641 static_cast<size_t>(code_table->length()));
1425 Handle<FixedArray> indirect_tables_template; 1642 for (int i = 0; i < code_table->length(); ++i) {
1426 if (maybe_indirect_tables.ToHandle(&indirect_tables_template)) { 1643 functions[static_cast<size_t>(i)] =
1427 Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable( 1644 code_table->GetValueChecked<Code>(isolate, i);
1428 isolate, code_table, indirect_tables_template);
1429 for (int i = 0; i < indirect_tables->length(); ++i) {
1430 Handle<FixedArray> metadata =
1431 indirect_tables->GetValueChecked<FixedArray>(isolate, i);
1432 uint32_t size = Smi::cast(metadata->get(kSize))->value();
1433 Handle<FixedArray> table =
1434 metadata->GetValueChecked<FixedArray>(isolate, kTable);
1435 wasm::PopulateFunctionTable(table, size, &functions);
1436 } 1645 }
1437 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables); 1646
1647 MaybeHandle<FixedArray> maybe_indirect_tables =
1648 compiled_module->GetValue<FixedArray>(isolate,
1649 kTableOfIndirectFunctionTables);
1650 Handle<FixedArray> indirect_tables_template;
1651 if (maybe_indirect_tables.ToHandle(&indirect_tables_template)) {
1652 Handle<FixedArray> to_replace =
1653 template_owner.is_null()
1654 ? indirect_tables_template
1655 : handle(FixedArray::cast(
1656 template_owner.ToHandleChecked()->GetInternalField(
1657 kWasmModuleFunctionTable)));
1658 Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable(
1659 isolate, code_table, indirect_tables_template, to_replace);
1660 for (int i = 0; i < indirect_tables->length(); ++i) {
1661 Handle<FixedArray> metadata =
1662 indirect_tables->GetValueChecked<FixedArray>(isolate, i);
1663 uint32_t size = Smi::cast(metadata->get(kSize))->value();
1664 Handle<FixedArray> table =
1665 metadata->GetValueChecked<FixedArray>(isolate, kTable);
1666 wasm::PopulateFunctionTable(table, size, &functions);
1667 }
1668 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables);
1669 }
1438 } 1670 }
1439 1671
1440 // Run the start function if one was specified. 1672 // Run the start function if one was specified.
1441 MaybeHandle<FixedArray> maybe_startup_fct = 1673 MaybeHandle<FixedArray> maybe_startup_fct =
1442 compiled_module->GetValue<FixedArray>(isolate, kStartupFunction); 1674 compiled_module->GetValue<FixedArray>(isolate, kStartupFunction);
1443 Handle<FixedArray> metadata; 1675 Handle<FixedArray> metadata;
1444 if (maybe_startup_fct.ToHandle(&metadata)) { 1676 if (maybe_startup_fct.ToHandle(&metadata)) {
1445 HandleScope scope(isolate); 1677 HandleScope scope(isolate);
1446 Handle<Code> startup_code = 1678 Handle<Code> startup_code =
1447 metadata->GetValueChecked<Code>(isolate, kExportCode); 1679 metadata->GetValueChecked<Code>(isolate, kExportCode);
1448 int arity = Smi::cast(metadata->get(kExportArity))->value(); 1680 int arity = Smi::cast(metadata->get(kExportArity))->value();
1449 MaybeHandle<ByteArray> startup_signature = 1681 MaybeHandle<ByteArray> startup_signature =
1450 metadata->GetValue<ByteArray>(isolate, kExportedSignature); 1682 metadata->GetValue<ByteArray>(isolate, kExportedSignature);
1451 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( 1683 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction(
1452 isolate, startup_code, factory->InternalizeUtf8String("start"), arity, 1684 isolate, startup_code, factory->InternalizeUtf8String("start"), arity,
1453 startup_signature, js_object); 1685 startup_signature, js_object);
1454 RecordStats(isolate, *startup_code); 1686 RecordStats(isolate, *startup_code);
1455 // Call the JS function. 1687 // Call the JS function.
1456 Handle<Object> undefined = isolate->factory()->undefined_value(); 1688 Handle<Object> undefined = isolate->factory()->undefined_value();
1457 MaybeHandle<Object> retval = 1689 MaybeHandle<Object> retval =
1458 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); 1690 Execution::Call(isolate, startup_fct, undefined, 0, nullptr);
1459 1691
1460 if (retval.is_null()) { 1692 if (retval.is_null()) {
1461 thrower.Error("WASM.instantiateModule(): start function failed"); 1693 thrower.Error("WASM.instantiateModule(): start function failed");
1462 return nothing; 1694 return nothing;
1463 } 1695 }
1464 } 1696 }
1465 1697
1466 DCHECK(wasm::IsWasmObject(*js_object)); 1698 DCHECK(wasm::IsWasmObject(*js_object));
1699
1700 if (!compiled_module->GetValue<WeakCell>(isolate, kModuleObject).is_null()) {
1701 js_object->SetInternalField(kWasmCompiledModule, *compiled_module);
1702 Handle<WeakCell> link_to_owner = factory->NewWeakCell(js_object);
1703 compiled_module->set(kOwningInstance, *link_to_owner);
1704
1705 Handle<Object> global_handle =
1706 isolate->global_handles()->Create(*js_object);
1707 GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(),
1708 &InstanceFinalizer,
1709 v8::WeakCallbackType::kFinalizer);
1710 }
1711
1467 return js_object; 1712 return js_object;
1468 } 1713 }
1469 1714
1470 // TODO(mtrofin): remove this once we move to WASM_DIRECT_CALL 1715 // TODO(mtrofin): remove this once we move to WASM_DIRECT_CALL
1471 Handle<Code> ModuleEnv::GetCodeOrPlaceholder(uint32_t index) const { 1716 Handle<Code> ModuleEnv::GetCodeOrPlaceholder(uint32_t index) const {
1472 DCHECK(IsValidFunction(index)); 1717 DCHECK(IsValidFunction(index));
1473 if (!placeholders.empty()) return placeholders[index]; 1718 if (!placeholders.empty()) return placeholders[index];
1474 DCHECK_NOT_NULL(instance); 1719 DCHECK_NOT_NULL(instance);
1475 return instance->function_code[index]; 1720 return instance->function_code[index];
1476 } 1721 }
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1644 DCHECK(origin == ModuleOrigin::kAsmJsOrigin); 1889 DCHECK(origin == ModuleOrigin::kAsmJsOrigin);
1645 Handle<Map> map = isolate->factory()->NewMap( 1890 Handle<Map> map = isolate->factory()->NewMap(
1646 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize); 1891 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize);
1647 module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED); 1892 module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED);
1648 } 1893 }
1649 module_obj->SetInternalField(0, *compiled_module); 1894 module_obj->SetInternalField(0, *compiled_module);
1650 if (origin == ModuleOrigin::kWasmOrigin) { 1895 if (origin == ModuleOrigin::kWasmOrigin) {
1651 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); 1896 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
1652 Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check(); 1897 Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check();
1653 } 1898 }
1899 Handle<WeakCell> link_to_module = isolate->factory()->NewWeakCell(module_obj);
1900 compiled_module->set(kModuleObject, *link_to_module);
1654 return module_obj; 1901 return module_obj;
1655 } 1902 }
1656 1903
1657 MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate, 1904 MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate,
1658 const byte* start, 1905 const byte* start,
1659 const byte* end, 1906 const byte* end,
1660 ErrorThrower* thrower, 1907 ErrorThrower* thrower,
1661 ModuleOrigin origin) { 1908 ModuleOrigin origin) {
1662 MaybeHandle<JSObject> nothing; 1909 MaybeHandle<JSObject> nothing;
1663 Zone zone(isolate->allocator()); 1910 Zone zone(isolate->allocator());
1664 ModuleResult result = 1911 ModuleResult result =
1665 DecodeWasmModule(isolate, &zone, start, end, false, origin); 1912 DecodeWasmModule(isolate, &zone, start, end, false, origin);
1666 std::unique_ptr<const WasmModule> decoded_module(result.val); 1913 std::unique_ptr<const WasmModule> decoded_module(result.val);
1667 if (result.failed()) { 1914 if (result.failed()) {
1668 thrower->Failed("Wasm decoding failed", result); 1915 thrower->Failed("Wasm decoding failed", result);
1669 return nothing; 1916 return nothing;
1670 } 1917 }
1671 MaybeHandle<FixedArray> compiled_module = 1918 MaybeHandle<FixedArray> compiled_module =
1672 decoded_module->CompileFunctions(isolate, thrower); 1919 decoded_module->CompileFunctions(isolate, thrower);
1673 if (compiled_module.is_null()) return nothing; 1920 if (compiled_module.is_null()) return nothing;
1674 1921
1675 return CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked(), 1922 return CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked(),
1676 origin); 1923 origin);
1677 } 1924 }
1925
1926 MaybeHandle<JSArrayBuffer> GetInstanceMemory(Isolate* isolate,
1927 Handle<JSObject> instance) {
1928 Object* mem = instance->GetInternalField(kWasmMemArrayBuffer);
1929 DCHECK(IsWasmObject(*instance));
1930 if (mem->IsUndefined(isolate)) return MaybeHandle<JSArrayBuffer>();
1931 return Handle<JSArrayBuffer>(JSArrayBuffer::cast(mem));
1932 }
1933
1934 void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) {
1935 DisallowHeapAllocation no_gc;
1936 DCHECK(IsWasmObject(*instance));
1937 instance->SetInternalField(kWasmMemArrayBuffer, buffer);
1938 Object* module = instance->GetInternalField(kWasmCompiledModule);
1939 if (module->IsFixedArray()) {
1940 HeapNumber::cast(FixedArray::cast(module)->get(kMemSize))
1941 ->set_value(buffer->byte_length()->Number());
1942 }
1943 }
1944
1945 namespace testing {
1946
1947 void ValidateInstancesChain(Isolate* isolate, Handle<JSObject> module_obj,
1948 int instance_count) {
1949 CHECK_GE(instance_count, 0);
1950 DisallowHeapAllocation no_gc;
1951 FixedArray* compiled_module =
1952 FixedArray::cast(module_obj->GetInternalField(0));
1953 CHECK_EQ(JSObject::cast(GetModuleObject(compiled_module)->value()),
1954 *module_obj);
1955 Object* prev = nullptr;
1956 int found_instances = GetOwningInstance(compiled_module) == nullptr ? 0 : 1;
1957 FixedArray* current_instance = compiled_module;
1958 while (GetNextInstance(current_instance) != nullptr) {
1959 CHECK((prev == nullptr && GetPrevInstance(current_instance) == nullptr) ||
1960 GetPrevInstance(current_instance)->value() == prev);
1961 CHECK_EQ(GetModuleObject(current_instance)->value(), *module_obj);
1962 CHECK(IsWasmObject(GetOwningInstance(current_instance)->value()));
1963 prev = current_instance;
1964 current_instance =
1965 FixedArray::cast(GetNextInstance(current_instance)->value());
1966 ++found_instances;
1967 CHECK_LE(found_instances, instance_count);
1968 }
1969 CHECK_EQ(found_instances, instance_count);
1970 }
1971
1972 void ValidateModuleState(Isolate* isolate, Handle<JSObject> module_obj) {
1973 DisallowHeapAllocation no_gc;
1974 FixedArray* compiled_module =
1975 FixedArray::cast(module_obj->GetInternalField(0));
1976 CHECK_NOT_NULL(GetModuleObject(compiled_module));
1977 CHECK_EQ(GetModuleObject(compiled_module)->value(), *module_obj);
1978 CHECK_NULL(GetPrevInstance(compiled_module));
1979 CHECK_NULL(GetNextInstance(compiled_module));
1980 CHECK_NULL(GetOwningInstance(compiled_module));
1981 }
1982
1983 void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance) {
1984 DisallowHeapAllocation no_gc;
1985 CHECK(IsWasmObject(*instance));
1986 FixedArray* compiled_module =
1987 FixedArray::cast(instance->GetInternalField(kWasmCompiledModule));
1988 CHECK_NOT_NULL(GetModuleObject(compiled_module));
1989 CHECK(GetModuleObject(compiled_module)->cleared());
1990 }
1991
1992 } // namespace testing
1678 } // namespace wasm 1993 } // namespace wasm
1679 } // namespace internal 1994 } // namespace internal
1680 } // namespace v8 1995 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/mjsunit/wasm/compiled-module-management.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698