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

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

Issue 2306403002: Revert of [wasm] reuse the first 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
« 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 enum WasmInstanceFields { 161 const int kWasmModuleFunctionTable = 0;
162 kWasmCompiledModule = 0, 162 const int kWasmModuleCodeTable = 1;
163 kWasmModuleFunctionTable, 163 const int kWasmMemArrayBuffer = 2;
164 kWasmModuleCodeTable, 164 const int kWasmGlobalsArrayBuffer = 3;
165 kWasmMemArrayBuffer, 165 // TODO(clemensh): Remove function name array, extract names from module bytes.
166 kWasmGlobalsArrayBuffer, 166 const int kWasmFunctionNamesArray = 4;
167 // TODO(clemensh): Remove function name array, extract names from module 167 const int kWasmModuleBytesString = 5;
168 // bytes. 168 const int kWasmDebugInfo = 6;
169 kWasmFunctionNamesArray, 169 const int kWasmModuleInternalFieldCount = 7;
170 kWasmModuleBytesString,
171 kWasmDebugInfo,
172 kWasmModuleInternalFieldCount
173 };
174 170
175 // TODO(mtrofin): Unnecessary once we stop using JS Heap for wasm code. 171 // 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. 172 // 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 173 // The elements typed as "maybe" are optional. The others are mandatory. Since
178 // the compiled module is either obtained from the current v8 instance, or from 174 // the compiled module is either obtained from the current v8 instance, or from
179 // a snapshot produced by a compatible (==identical) v8 instance, we simply 175 // a snapshot produced by a compatible (==identical) v8 instance, we simply
180 // fail at instantiation time, in the face of invalid data. 176 // fail at instantiation time, in the face of invalid data.
181 enum CompiledWasmObjectFields { 177 enum CompiledWasmObjectFields {
182 kFunctions, // FixedArray of Code 178 kFunctions, // FixedArray of Code
183 kImportData, // maybe FixedArray of FixedArray respecting the 179 kImportData, // maybe FixedArray of FixedArray respecting the
184 // WasmImportMetadata structure. 180 // WasmImportMetadata structure.
185 kImportMap, // FixedArray. The i-th element is the Code object used for 181 kImportMap, // FixedArray. The i-th element is the Code object used for
186 // import i 182 // import i
187 kExports, // maybe FixedArray of FixedArray of WasmExportMetadata 183 kExports, // maybe FixedArray of FixedArray of WasmExportMetadata
188 // structure 184 // structure
189 kStartupFunction, // maybe FixedArray of WasmExportMetadata structure 185 kStartupFunction, // maybe FixedArray of WasmExportMetadata structure
190 kTableOfIndirectFunctionTables, // maybe FixedArray of FixedArray of 186 kTableOfIndirectFunctionTables, // maybe FixedArray of FixedArray of
191 // WasmIndirectFunctionTableMetadata 187 // WasmIndirectFunctionTableMetadata
192 kModuleBytes, // maybe String 188 kModuleBytes, // maybe String
193 kFunctionNameTable, // maybe ByteArray 189 kFunctionNameTable, // maybe ByteArray
194 kMinRequiredMemory, // Smi. an uint32_t 190 kMinRequiredMemory, // Smi. an uint32_t
195 // The following 2 are either together present or absent: 191 // The following 2 are either together present or absent:
196 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the 192 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the
197 // WasmSegmentInfo structure 193 // WasmSegmentInfo structure
198 kDataSegments, // maybe ByteArray. 194 kDataSegments, // maybe ByteArray.
199 195
200 kGlobalsSize, // Smi. an uint32_t 196 kGlobalsSize, // Smi. an uint32_t
201 kMemSize, // Smi.an uint32_t
202 kMemStart, // MaybeHandle<ArrayBuffer>
203 kExportMem, // Smi. bool 197 kExportMem, // Smi. bool
204 kOrigin, // Smi. ModuleOrigin 198 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. 199 kCompiledWasmObjectTableSize // Sentinel value.
210 }; 200 };
211 201
212 enum WasmImportMetadata { 202 enum WasmImportMetadata {
213 kModuleName, // String 203 kModuleName, // String
214 kFunctionName, // maybe String 204 kFunctionName, // maybe String
215 kOutputCount, // Smi. an uint32_t 205 kOutputCount, // Smi. an uint32_t
216 kSignature, // ByteArray. A copy of the data in FunctionSig 206 kSignature, // ByteArray. A copy of the data in FunctionSig
217 kWasmImportDataTableSize // Sentinel value. 207 kWasmImportDataTableSize // Sentinel value.
218 }; 208 };
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 DCHECK_EQ(0, bytes[i]); 322 DCHECK_EQ(0, bytes[i]);
333 } 323 }
334 #endif 324 #endif
335 325
336 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); 326 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
337 JSArrayBuffer::Setup(buffer, isolate, false, memory, static_cast<int>(size)); 327 JSArrayBuffer::Setup(buffer, isolate, false, memory, static_cast<int>(size));
338 buffer->set_is_neuterable(false); 328 buffer->set_is_neuterable(false);
339 return buffer; 329 return buffer;
340 } 330 }
341 331
342 void RelocateInstanceCode(Handle<JSObject> instance, Address old_start, 332 void RelocateInstanceCode(Handle<JSObject> instance, Address start,
343 Address start, uint32_t prev_size, 333 uint32_t prev_size, uint32_t new_size) {
344 uint32_t new_size) {
345 Handle<FixedArray> functions = Handle<FixedArray>( 334 Handle<FixedArray> functions = Handle<FixedArray>(
346 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); 335 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable)));
347 for (int i = 0; i < functions->length(); ++i) { 336 for (int i = 0; i < functions->length(); ++i) {
348 Handle<Code> function = Handle<Code>(Code::cast(functions->get(i))); 337 Handle<Code> function = Handle<Code>(Code::cast(functions->get(i)));
349 AllowDeferredHandleDereference embedding_raw_address; 338 AllowDeferredHandleDereference embedding_raw_address;
350 int mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE) | 339 int mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE) |
351 (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE); 340 (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
352 for (RelocIterator it(*function, mask); !it.done(); it.next()) { 341 for (RelocIterator it(*function, mask); !it.done(); it.next()) {
353 it.rinfo()->update_wasm_memory_reference(old_start, start, prev_size, 342 it.rinfo()->update_wasm_memory_reference(nullptr, start, prev_size,
354 new_size); 343 new_size);
355 } 344 }
356 } 345 }
357 } 346 }
358 347
359 // Allocate memory for a module instance as a new JSArrayBuffer. 348 // Allocate memory for a module instance as a new JSArrayBuffer.
360 Handle<JSArrayBuffer> AllocateMemory(ErrorThrower* thrower, Isolate* isolate, 349 Handle<JSArrayBuffer> AllocateMemory(ErrorThrower* thrower, Isolate* isolate,
361 uint32_t min_mem_pages) { 350 uint32_t min_mem_pages) {
362 if (min_mem_pages > WasmModule::kMaxMemPages) { 351 if (min_mem_pages > WasmModule::kMaxMemPages) {
363 thrower->Error("Out of memory: wasm memory too large"); 352 thrower->Error("Out of memory: wasm memory too large");
364 return Handle<JSArrayBuffer>::null(); 353 return Handle<JSArrayBuffer>::null();
365 } 354 }
366 Handle<JSArrayBuffer> mem_buffer = 355 Handle<JSArrayBuffer> mem_buffer =
367 NewArrayBuffer(isolate, min_mem_pages * WasmModule::kPageSize); 356 NewArrayBuffer(isolate, min_mem_pages * WasmModule::kPageSize);
368 357
369 if (mem_buffer.is_null()) { 358 if (mem_buffer.is_null()) {
370 thrower->Error("Out of memory: wasm memory"); 359 thrower->Error("Out of memory: wasm memory");
371 } 360 }
372 return mem_buffer; 361 return mem_buffer;
373 } 362 }
374 363
375 void RelocateGlobals(Handle<JSObject> instance, Address old_start, 364 void RelocateGlobals(Handle<JSObject> instance, Address globals_start) {
376 Address globals_start) {
377 Handle<FixedArray> functions = Handle<FixedArray>( 365 Handle<FixedArray> functions = Handle<FixedArray>(
378 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); 366 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable)));
379 uint32_t function_count = static_cast<uint32_t>(functions->length()); 367 uint32_t function_count = static_cast<uint32_t>(functions->length());
380 for (uint32_t i = 0; i < function_count; ++i) { 368 for (uint32_t i = 0; i < function_count; ++i) {
381 Handle<Code> function = Handle<Code>(Code::cast(functions->get(i))); 369 Handle<Code> function = Handle<Code>(Code::cast(functions->get(i)));
382 AllowDeferredHandleDereference embedding_raw_address; 370 AllowDeferredHandleDereference embedding_raw_address;
383 int mask = 1 << RelocInfo::WASM_GLOBAL_REFERENCE; 371 int mask = 1 << RelocInfo::WASM_GLOBAL_REFERENCE;
384 for (RelocIterator it(*function, mask); !it.done(); it.next()) { 372 for (RelocIterator it(*function, mask); !it.done(); it.next()) {
385 it.rinfo()->update_wasm_global_reference(old_start, globals_start); 373 it.rinfo()->update_wasm_global_reference(nullptr, globals_start);
386 } 374 }
387 } 375 }
388 } 376 }
389 377
390 Handle<Code> CreatePlaceholder(Factory* factory, uint32_t index, 378 Handle<Code> CreatePlaceholder(Factory* factory, uint32_t index,
391 Code::Kind kind) { 379 Code::Kind kind) {
392 // Create a placeholder code object and encode the corresponding index in 380 // Create a placeholder code object and encode the corresponding index in
393 // the {constant_pool_offset} field of the code object. 381 // the {constant_pool_offset} field of the code object.
394 // TODO(titzer): placeholder code objects are somewhat dangerous. 382 // TODO(titzer): placeholder code objects are somewhat dangerous.
395 static byte buffer[] = {0, 0, 0, 0, 0, 0, 0, 0}; // fake instructions. 383 static byte buffer[] = {0, 0, 0, 0, 0, 0, 0, 0}; // fake instructions.
(...skipping 10 matching lines...) Expand all
406 std::vector<Handle<Code>>* placeholders, 394 std::vector<Handle<Code>>* placeholders,
407 size_t size) { 395 size_t size) {
408 DCHECK(placeholders->empty()); 396 DCHECK(placeholders->empty());
409 placeholders->reserve(size); 397 placeholders->reserve(size);
410 398
411 for (uint32_t i = 0; i < size; ++i) { 399 for (uint32_t i = 0; i < size; ++i) {
412 placeholders->push_back(CreatePlaceholder(factory, i, Code::WASM_FUNCTION)); 400 placeholders->push_back(CreatePlaceholder(factory, i, Code::WASM_FUNCTION));
413 } 401 }
414 } 402 }
415 403
416 bool LinkFunction(Isolate* isolate, Handle<Code> unlinked, 404 bool LinkFunction(Handle<Code> unlinked,
417 Handle<FixedArray> code_targets, 405 const std::vector<Handle<Code>>& code_targets,
418 Code::Kind kind = Code::WASM_FUNCTION) { 406 Code::Kind kind) {
419 bool modified = false; 407 bool modified = false;
420 int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); 408 int mode_mask = RelocInfo::kCodeTargetMask;
421 AllowDeferredHandleDereference embedding_raw_address; 409 AllowDeferredHandleDereference embedding_raw_address;
422 for (RelocIterator it(*unlinked, mode_mask); !it.done(); it.next()) { 410 for (RelocIterator it(*unlinked, mode_mask); !it.done(); it.next()) {
423 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); 411 RelocInfo::Mode mode = it.rinfo()->rmode();
424 if (target->kind() == kind && 412 if (RelocInfo::IsCodeTarget(mode)) {
425 target->constant_pool_offset() >= kPlaceholderMarker) { 413 Code* target =
426 // Patch direct calls to placeholder code objects. 414 Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
427 uint32_t index = target->constant_pool_offset() - kPlaceholderMarker; 415 if (target->kind() == kind &&
428 CHECK(index < static_cast<uint32_t>(code_targets->length())); 416 target->constant_pool_offset() >= kPlaceholderMarker) {
429 Handle<Code> new_target = 417 // Patch direct calls to placeholder code objects.
430 code_targets->GetValueChecked<Code>(isolate, index); 418 uint32_t index = target->constant_pool_offset() - kPlaceholderMarker;
431 if (target != *new_target) { 419 CHECK(index < code_targets.size());
432 it.rinfo()->set_target_address(new_target->instruction_start(), 420 Handle<Code> new_target = code_targets[index];
433 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH); 421 if (target != *new_target) {
434 modified = true; 422 it.rinfo()->set_target_address(new_target->instruction_start(),
423 UPDATE_WRITE_BARRIER,
424 SKIP_ICACHE_FLUSH);
425 modified = true;
426 }
435 } 427 }
436 } 428 }
437 } 429 }
438 return modified; 430 return modified;
439 } 431 }
440 432
441 void LinkModuleFunctions(Isolate* isolate, Handle<FixedArray> functions) { 433 void LinkModuleFunctions(Isolate* isolate,
442 for (int i = 0; i < functions->length(); ++i) { 434 std::vector<Handle<Code>>& functions) {
443 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i); 435 for (size_t i = 0; i < functions.size(); ++i) {
444 LinkFunction(isolate, code, functions); 436 Handle<Code> code = functions[i];
437 LinkFunction(code, functions, Code::WASM_FUNCTION);
445 } 438 }
446 } 439 }
447 440
448 void FlushAssemblyCache(Isolate* isolate, Handle<FixedArray> functions) { 441 void FlushAssemblyCache(Isolate* isolate, Handle<FixedArray> functions) {
449 for (int i = 0; i < functions->length(); ++i) { 442 for (int i = 0; i < functions->length(); ++i) {
450 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i); 443 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i);
451 Assembler::FlushICache(isolate, code->instruction_start(), 444 Assembler::FlushICache(isolate, code->instruction_start(),
452 code->instruction_size()); 445 code->instruction_size());
453 } 446 }
454 } 447 }
455 448
456 void SetRuntimeSupport(Isolate* isolate, Handle<JSObject> js_object) { 449 void SetRuntimeSupport(Isolate* isolate, Handle<JSObject> js_object) {
457 Handle<FixedArray> functions = Handle<FixedArray>( 450 Handle<FixedArray> functions = Handle<FixedArray>(
458 FixedArray::cast(js_object->GetInternalField(kWasmModuleCodeTable))); 451 FixedArray::cast(js_object->GetInternalField(kWasmModuleCodeTable)));
459 Handle<WeakCell> weak_link = isolate->factory()->NewWeakCell(js_object); 452 Handle<WeakCell> weak_link = isolate->factory()->NewWeakCell(js_object);
460 453
461 for (int i = FLAG_skip_compiling_wasm_funcs; i < functions->length(); ++i) { 454 for (int i = FLAG_skip_compiling_wasm_funcs; i < functions->length(); ++i) {
462 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i); 455 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i);
456 DCHECK(code->deoptimization_data() == nullptr ||
457 code->deoptimization_data()->length() == 0);
463 Handle<FixedArray> deopt_data = 458 Handle<FixedArray> deopt_data =
464 isolate->factory()->NewFixedArray(2, TENURED); 459 isolate->factory()->NewFixedArray(2, TENURED);
465 deopt_data->set(0, *weak_link); 460 deopt_data->set(0, *weak_link);
466 deopt_data->set(1, Smi::FromInt(static_cast<int>(i))); 461 deopt_data->set(1, Smi::FromInt(static_cast<int>(i)));
467 deopt_data->set_length(2); 462 deopt_data->set_length(2);
468 code->set_deoptimization_data(*deopt_data); 463 code->set_deoptimization_data(*deopt_data);
469 } 464 }
470 } 465 }
471 466
472 } // namespace 467 } // namespace
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 for (Handle<Code> c : functions) RecordStats(isolate, *c); 614 for (Handle<Code> c : functions) RecordStats(isolate, *c);
620 } 615 }
621 616
622 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions) { 617 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions) {
623 DisallowHeapAllocation no_gc; 618 DisallowHeapAllocation no_gc;
624 for (int i = 0; i < functions->length(); ++i) { 619 for (int i = 0; i < functions->length(); ++i) {
625 RecordStats(isolate, Code::cast(functions->get(i))); 620 RecordStats(isolate, Code::cast(functions->get(i)));
626 } 621 }
627 } 622 }
628 623
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
640 Handle<FixedArray> GetImportsMetadata(Factory* factory, 624 Handle<FixedArray> GetImportsMetadata(Factory* factory,
641 const WasmModule* module) { 625 const WasmModule* module) {
642 Handle<FixedArray> ret = factory->NewFixedArray( 626 Handle<FixedArray> ret = factory->NewFixedArray(
643 static_cast<int>(module->import_table.size()), TENURED); 627 static_cast<int>(module->import_table.size()), TENURED);
644 for (size_t i = 0; i < module->import_table.size(); ++i) { 628 for (size_t i = 0; i < module->import_table.size(); ++i) {
645 const WasmImport& import = module->import_table[i]; 629 const WasmImport& import = module->import_table[i];
646 WasmName module_name = module->GetNameOrNull(import.module_name_offset, 630 WasmName module_name = module->GetNameOrNull(import.module_name_offset,
647 import.module_name_length); 631 import.module_name_length);
648 WasmName function_name = module->GetNameOrNull(import.function_name_offset, 632 WasmName function_name = module->GetNameOrNull(import.function_name_offset,
649 import.function_name_length); 633 import.function_name_length);
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 } 905 }
922 906
923 MaybeHandle<ByteArray> function_name_table = 907 MaybeHandle<ByteArray> function_name_table =
924 compiled_module->GetValue<ByteArray>(isolate, kFunctionNameTable); 908 compiled_module->GetValue<ByteArray>(isolate, kFunctionNameTable);
925 if (!function_name_table.is_null()) { 909 if (!function_name_table.is_null()) {
926 js_object->SetInternalField(kWasmFunctionNamesArray, 910 js_object->SetInternalField(kWasmFunctionNamesArray,
927 *function_name_table.ToHandleChecked()); 911 *function_name_table.ToHandleChecked());
928 } 912 }
929 } 913 }
930 914
931 bool SetupGlobals(Isolate* isolate, MaybeHandle<JSObject> template_owner, 915 bool SetupGlobals(Isolate* isolate, Handle<FixedArray> compiled_module,
932 Handle<FixedArray> compiled_module, Handle<JSObject> instance, 916 Handle<JSObject> instance, ErrorThrower* thrower) {
933 ErrorThrower* thrower) {
934 uint32_t globals_size = static_cast<uint32_t>( 917 uint32_t globals_size = static_cast<uint32_t>(
935 Smi::cast(compiled_module->get(kGlobalsSize))->value()); 918 Smi::cast(compiled_module->get(kGlobalsSize))->value());
936 if (globals_size > 0) { 919 if (globals_size > 0) {
937 Handle<JSArrayBuffer> globals_buffer = 920 Handle<JSArrayBuffer> globals_buffer =
938 NewArrayBuffer(isolate, globals_size); 921 NewArrayBuffer(isolate, globals_size);
939 if (globals_buffer.is_null()) { 922 if (globals_buffer.is_null()) {
940 thrower->Error("Out of memory: wasm globals"); 923 thrower->Error("Out of memory: wasm globals");
941 return false; 924 return false;
942 } 925 }
943 Address old_address = 926 RelocateGlobals(instance,
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,
950 static_cast<Address>(globals_buffer->backing_store())); 927 static_cast<Address>(globals_buffer->backing_store()));
951 instance->SetInternalField(kWasmGlobalsArrayBuffer, *globals_buffer); 928 instance->SetInternalField(kWasmGlobalsArrayBuffer, *globals_buffer);
952 } 929 }
953 return true; 930 return true;
954 } 931 }
955 932
956 bool SetupInstanceHeap(Isolate* isolate, Handle<FixedArray> compiled_module, 933 bool SetupInstanceHeap(Isolate* isolate, Handle<FixedArray> compiled_module,
957 Handle<JSObject> instance, Handle<JSArrayBuffer> memory, 934 Handle<JSObject> instance, Handle<JSArrayBuffer> memory,
958 ErrorThrower* thrower) { 935 ErrorThrower* thrower) {
959 uint32_t min_mem_pages = static_cast<uint32_t>( 936 uint32_t min_mem_pages = static_cast<uint32_t>(
960 Smi::cast(compiled_module->get(kMinRequiredMemory))->value()); 937 Smi::cast(compiled_module->get(kMinRequiredMemory))->value());
961 isolate->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); 938 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. 939 // TODO(wasm): re-enable counter for max_mem_pages when we use that field.
963 940
964 if (memory.is_null() && min_mem_pages > 0) { 941 if (memory.is_null() && min_mem_pages > 0) {
965 memory = AllocateMemory(thrower, isolate, min_mem_pages); 942 memory = AllocateMemory(thrower, isolate, min_mem_pages);
966 if (memory.is_null()) { 943 if (memory.is_null()) {
967 return false; 944 return false;
968 } 945 }
969 } 946 }
970 947
971 if (!memory.is_null()) { 948 if (!memory.is_null()) {
972 instance->SetInternalField(kWasmMemArrayBuffer, *memory); 949 instance->SetInternalField(kWasmMemArrayBuffer, *memory);
973 Address mem_start = static_cast<Address>(memory->backing_store()); 950 Address mem_start = static_cast<Address>(memory->backing_store());
974 uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number()); 951 uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number());
975 uint32_t old_mem_size = static_cast<uint32_t>( 952 RelocateInstanceCode(instance, mem_start,
976 compiled_module->GetValueChecked<HeapNumber>(isolate, kMemSize) 953 WasmModule::kPageSize * min_mem_pages, mem_size);
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);
986 LoadDataSegments(compiled_module, mem_start, mem_size); 954 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);
990 } 955 }
991 return true; 956 return true;
992 } 957 }
993 958
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
1041 bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module, 959 bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module,
1042 Handle<JSObject> instance, ErrorThrower* thrower, 960 Handle<JSObject> instance, ErrorThrower* thrower,
1043 Handle<JSReceiver> ffi) { 961 Handle<JSReceiver> ffi) {
1044 //------------------------------------------------------------------------- 962 //-------------------------------------------------------------------------
1045 // Compile wrappers to imported functions. 963 // Compile wrappers to imported functions.
1046 //------------------------------------------------------------------------- 964 //-------------------------------------------------------------------------
1047 std::vector<Handle<Code>> import_code; 965 std::vector<Handle<Code>> import_code;
1048 MaybeHandle<FixedArray> maybe_import_data = 966 MaybeHandle<FixedArray> maybe_import_data =
1049 compiled_module->GetValue<FixedArray>(isolate, kImportData); 967 compiled_module->GetValue<FixedArray>(isolate, kImportData);
1050 Handle<FixedArray> import_data; 968 Handle<FixedArray> import_data;
1051 if (maybe_import_data.ToHandle(&import_data)) { 969 if (maybe_import_data.ToHandle(&import_data)) {
1052 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code, 970 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code,
1053 import_data, thrower)) { 971 import_data, thrower)) {
1054 return false; 972 return false;
1055 } 973 }
1056 } 974 }
1057 975
1058 RecordStats(isolate, import_code); 976 RecordStats(isolate, import_code);
977
1059 if (import_code.empty()) return true; 978 if (import_code.empty()) return true;
1060 979
1061 Handle<FixedArray> new_imports = 980 {
981 DisallowHeapAllocation no_gc;
982 std::map<Code*, int> import_to_index;
983 Handle<FixedArray> mapping =
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 }
1013 Handle<FixedArray> new_mapping =
1062 isolate->factory()->NewFixedArray(static_cast<int>(import_code.size())); 1014 isolate->factory()->NewFixedArray(static_cast<int>(import_code.size()));
1063 for (int i = 0; i < new_imports->length(); ++i) { 1015 for (int i = 0; i < new_mapping->length(); ++i) {
1064 new_imports->set(i, *import_code[i]); 1016 new_mapping->set(i, *import_code[i]);
1065 } 1017 }
1066 compiled_module->set(kImportMap, *new_imports); 1018 compiled_module->set(kImportMap, *new_mapping);
1019
1067 return true; 1020 return true;
1068 } 1021 }
1069 1022
1070 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate, 1023 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate,
1071 Handle<JSObject> instance, ErrorThrower* thrower) { 1024 Handle<JSObject> instance, ErrorThrower* thrower) {
1072 Factory* factory = isolate->factory(); 1025 Factory* factory = isolate->factory();
1073 bool mem_export = 1026 bool mem_export =
1074 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value()); 1027 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value());
1075 ModuleOrigin origin = static_cast<ModuleOrigin>( 1028 ModuleOrigin origin = static_cast<ModuleOrigin>(
1076 Smi::cast(compiled_module->get(kOrigin))->value()); 1029 Smi::cast(compiled_module->get(kOrigin))->value());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 // Export the memory as a named property. 1074 // Export the memory as a named property.
1122 Handle<String> name = factory->InternalizeUtf8String("memory"); 1075 Handle<String> name = factory->InternalizeUtf8String("memory");
1123 Handle<JSArrayBuffer> memory = Handle<JSArrayBuffer>( 1076 Handle<JSArrayBuffer> memory = Handle<JSArrayBuffer>(
1124 JSArrayBuffer::cast(instance->GetInternalField(kWasmMemArrayBuffer))); 1077 JSArrayBuffer::cast(instance->GetInternalField(kWasmMemArrayBuffer)));
1125 JSObject::AddProperty(exports_object, name, memory, READ_ONLY); 1078 JSObject::AddProperty(exports_object, name, memory, READ_ONLY);
1126 } 1079 }
1127 } 1080 }
1128 return true; 1081 return true;
1129 } 1082 }
1130 1083
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
1247 } // namespace 1084 } // namespace
1248 1085
1249 MaybeHandle<FixedArray> WasmModule::CompileFunctions( 1086 MaybeHandle<FixedArray> WasmModule::CompileFunctions(
1250 Isolate* isolate, ErrorThrower* thrower) const { 1087 Isolate* isolate, ErrorThrower* thrower) const {
1251 Factory* factory = isolate->factory(); 1088 Factory* factory = isolate->factory();
1252 1089
1253 MaybeHandle<FixedArray> nothing; 1090 MaybeHandle<FixedArray> nothing;
1254 1091
1255 WasmModuleInstance temp_instance_for_compilation(this); 1092 WasmModuleInstance temp_instance_for_compilation(this);
1256 temp_instance_for_compilation.context = isolate->native_context(); 1093 temp_instance_for_compilation.context = isolate->native_context();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 } 1149 }
1313 if (thrower->error()) return nothing; 1150 if (thrower->error()) return nothing;
1314 1151
1315 // At this point, compilation has completed. Update the code table. 1152 // At this point, compilation has completed. Update the code table.
1316 for (size_t i = FLAG_skip_compiling_wasm_funcs; 1153 for (size_t i = FLAG_skip_compiling_wasm_funcs;
1317 i < temp_instance_for_compilation.function_code.size(); ++i) { 1154 i < temp_instance_for_compilation.function_code.size(); ++i) {
1318 Code* code = *temp_instance_for_compilation.function_code[i]; 1155 Code* code = *temp_instance_for_compilation.function_code[i];
1319 compiled_functions->set(static_cast<int>(i), code); 1156 compiled_functions->set(static_cast<int>(i), code);
1320 } 1157 }
1321 1158
1322 LinkModuleFunctions(isolate, compiled_functions);
1323
1324 // TODO(mtrofin): do we need to flush the cache here?
1325 FlushAssemblyCache(isolate, compiled_functions);
1326
1327 // Create the compiled module object, and populate with compiled functions 1159 // Create the compiled module object, and populate with compiled functions
1328 // and information needed at instantiation time. This object needs to be 1160 // and information needed at instantiation time. This object needs to be
1329 // serializable. Instantiation may occur off a deserialized version of this 1161 // serializable. Instantiation may occur off a deserialized version of this
1330 // object. 1162 // object.
1331 Handle<FixedArray> ret = 1163 Handle<FixedArray> ret =
1332 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED); 1164 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED);
1333 ret->set(kFunctions, *compiled_functions); 1165 ret->set(kFunctions, *compiled_functions);
1334 if (!indirect_table.is_null()) { 1166 if (!indirect_table.is_null()) {
1335 ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked()); 1167 ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked());
1336 } 1168 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 } 1244 }
1413 1245
1414 Handle<ByteArray> function_name_table = 1246 Handle<ByteArray> function_name_table =
1415 BuildFunctionNamesTable(isolate, module_env.module); 1247 BuildFunctionNamesTable(isolate, module_env.module);
1416 ret->set(kFunctionNameTable, *function_name_table); 1248 ret->set(kFunctionNameTable, *function_name_table);
1417 ret->set(kMinRequiredMemory, Smi::FromInt(min_mem_pages)); 1249 ret->set(kMinRequiredMemory, Smi::FromInt(min_mem_pages));
1418 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret); 1250 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret);
1419 ret->set(kGlobalsSize, Smi::FromInt(globals_size)); 1251 ret->set(kGlobalsSize, Smi::FromInt(globals_size));
1420 ret->set(kExportMem, Smi::FromInt(mem_export)); 1252 ret->set(kExportMem, Smi::FromInt(mem_export));
1421 ret->set(kOrigin, Smi::FromInt(origin)); 1253 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);
1426 return ret; 1254 return ret;
1427 } 1255 }
1428 1256
1429 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper, 1257 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper,
1430 Handle<Code> new_target) { 1258 Handle<Code> new_target) {
1431 AllowDeferredHandleDereference embedding_raw_address; 1259 AllowDeferredHandleDereference embedding_raw_address;
1432 bool seen = false; 1260 bool seen = false;
1433 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done(); 1261 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done();
1434 it.next()) { 1262 it.next()) {
1435 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); 1263 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
1436 if (target->kind() == Code::WASM_FUNCTION) { 1264 if (target->kind() == Code::WASM_FUNCTION) {
1437 DCHECK(!seen); 1265 DCHECK(!seen);
1438 seen = true; 1266 seen = true;
1439 it.rinfo()->set_target_address(new_target->instruction_start(), 1267 it.rinfo()->set_target_address(new_target->instruction_start(),
1440 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH); 1268 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
1441 } 1269 }
1442 } 1270 }
1443 CHECK(seen); 1271 CHECK(seen);
1444 Assembler::FlushICache(isolate, wrapper->instruction_start(), 1272 Assembler::FlushICache(isolate, wrapper->instruction_start(),
1445 wrapper->instruction_size()); 1273 wrapper->instruction_size());
1446 } 1274 }
1447 1275
1448 Handle<FixedArray> SetupIndirectFunctionTable( 1276 Handle<FixedArray> SetupIndirectFunctionTable(
1449 Isolate* isolate, Handle<FixedArray> wasm_functions, 1277 Isolate* isolate, Handle<FixedArray> wasm_functions,
1450 Handle<FixedArray> indirect_table_template, 1278 Handle<FixedArray> indirect_table_template) {
1451 Handle<FixedArray> tables_to_replace) {
1452 Factory* factory = isolate->factory(); 1279 Factory* factory = isolate->factory();
1453 Handle<FixedArray> cloned_indirect_tables = 1280 Handle<FixedArray> cloned_indirect_tables =
1454 factory->CopyFixedArray(indirect_table_template); 1281 factory->CopyFixedArray(indirect_table_template);
1455 for (int i = 0; i < cloned_indirect_tables->length(); ++i) { 1282 for (int i = 0; i < cloned_indirect_tables->length(); ++i) {
1456 Handle<FixedArray> orig_metadata = 1283 Handle<FixedArray> orig_metadata =
1457 cloned_indirect_tables->GetValueChecked<FixedArray>(isolate, i); 1284 cloned_indirect_tables->GetValueChecked<FixedArray>(isolate, i);
1458 Handle<FixedArray> cloned_metadata = factory->CopyFixedArray(orig_metadata); 1285 Handle<FixedArray> cloned_metadata = factory->CopyFixedArray(orig_metadata);
1459 cloned_indirect_tables->set(i, *cloned_metadata); 1286 cloned_indirect_tables->set(i, *cloned_metadata);
1460 1287
1461 Handle<FixedArray> orig_table = 1288 Handle<FixedArray> orig_table =
1462 cloned_metadata->GetValueChecked<FixedArray>(isolate, kTable); 1289 cloned_metadata->GetValueChecked<FixedArray>(isolate, kTable);
1463 Handle<FixedArray> cloned_table = factory->CopyFixedArray(orig_table); 1290 Handle<FixedArray> cloned_table = factory->CopyFixedArray(orig_table);
1464 cloned_metadata->set(kTable, *cloned_table); 1291 cloned_metadata->set(kTable, *cloned_table);
1465 // Patch the cloned code to refer to the cloned kTable. 1292 // Patch the cloned code to refer to the cloned kTable.
1466 Handle<FixedArray> table_to_replace = 1293 for (int i = 0; i < wasm_functions->length(); ++i) {
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) {
1470 Handle<Code> wasm_function = 1294 Handle<Code> wasm_function =
1471 wasm_functions->GetValueChecked<Code>(isolate, fct_index); 1295 wasm_functions->GetValueChecked<Code>(isolate, i);
1472 PatchFunctionTable(wasm_function, table_to_replace, cloned_table); 1296 PatchFunctionTable(wasm_function, orig_table, cloned_table);
1473 } 1297 }
1474 } 1298 }
1475 return cloned_indirect_tables; 1299 return cloned_indirect_tables;
1476 } 1300 }
1477 1301
1478 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate, 1302 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate,
1479 Handle<FixedArray> original) { 1303 Handle<FixedArray> original) {
1480 Factory* factory = isolate->factory(); 1304 Factory* factory = isolate->factory();
1481 bool is_first =
1482 original->GetValue<WeakCell>(isolate, kOwningInstance).is_null();
1483
1484 if (is_first) {
1485 return original;
1486 }
1487
1488 // We insert the latest clone in front.
1489 Handle<FixedArray> clone = factory->CopyFixedArray(original); 1305 Handle<FixedArray> clone = factory->CopyFixedArray(original);
1490 Handle<WeakCell> weak_link_to_wasm_obj =
1491 original->GetValueChecked<WeakCell>(isolate, kModuleObject);
1492
1493 clone->set(kModuleObject, *weak_link_to_wasm_obj);
1494 Handle<WeakCell> link_to_original = factory->NewWeakCell(original);
1495 clone->set(kNextInstance, *link_to_original);
1496 Handle<WeakCell> link_to_clone = factory->NewWeakCell(clone);
1497 original->set(kPrevInstance, *link_to_clone);
1498 JSObject::cast(weak_link_to_wasm_obj->value())->SetInternalField(0, *clone);
1499 1306
1500 // Clone each wasm code object. 1307 // Clone each wasm code object.
1501 Handle<FixedArray> orig_wasm_functions = 1308 Handle<FixedArray> orig_wasm_functions =
1502 original->GetValueChecked<FixedArray>(isolate, kFunctions); 1309 original->GetValueChecked<FixedArray>(isolate, kFunctions);
1503 Handle<FixedArray> clone_wasm_functions = 1310 Handle<FixedArray> clone_wasm_functions =
1504 factory->CopyFixedArray(orig_wasm_functions); 1311 factory->CopyFixedArray(orig_wasm_functions);
1505 clone->set(kFunctions, *clone_wasm_functions); 1312 clone->set(kFunctions, *clone_wasm_functions);
1506 for (int i = 0; i < clone_wasm_functions->length(); ++i) { 1313 for (int i = 0; i < clone_wasm_functions->length(); ++i) {
1507 Handle<Code> orig_code = 1314 Handle<Code> orig_code =
1508 clone_wasm_functions->GetValueChecked<Code>(isolate, i); 1315 clone_wasm_functions->GetValueChecked<Code>(isolate, i);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 clone->set(kStartupFunction, *startup_metadata); 1356 clone->set(kStartupFunction, *startup_metadata);
1550 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray. 1357 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray.
1551 int startup_fct_index = 1358 int startup_fct_index =
1552 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value(); 1359 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value();
1553 CHECK_GE(startup_fct_index, 0); 1360 CHECK_GE(startup_fct_index, 0);
1554 CHECK_LT(startup_fct_index, clone_wasm_functions->length()); 1361 CHECK_LT(startup_fct_index, clone_wasm_functions->length());
1555 Handle<Code> new_target = 1362 Handle<Code> new_target =
1556 clone_wasm_functions->GetValueChecked<Code>(isolate, startup_fct_index); 1363 clone_wasm_functions->GetValueChecked<Code>(isolate, startup_fct_index);
1557 PatchJSWrapper(isolate, startup_fct_clone, new_target); 1364 PatchJSWrapper(isolate, startup_fct_clone, new_target);
1558 } 1365 }
1559 clone->set(kImportMap, *isolate->factory()->undefined_value());
1560 return clone; 1366 return clone;
1561 } 1367 }
1562 1368
1563 // Instantiates a wasm module as a JSObject. 1369 // Instantiates a wasm module as a JSObject.
1564 // * allocates a backing store of {mem_size} bytes. 1370 // * allocates a backing store of {mem_size} bytes.
1565 // * installs a named property "memory" for that buffer if exported 1371 // * installs a named property "memory" for that buffer if exported
1566 // * installs named properties on the object for exported functions 1372 // * installs named properties on the object for exported functions
1567 // * compiles wasm code to machine code 1373 // * compiles wasm code to machine code
1568 MaybeHandle<JSObject> WasmModule::Instantiate( 1374 MaybeHandle<JSObject> WasmModule::Instantiate(
1569 Isolate* isolate, Handle<FixedArray> compiled_module_template, 1375 Isolate* isolate, Handle<FixedArray> compiled_module,
1570 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) { 1376 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) {
1571 HistogramTimerScope wasm_instantiate_module_time_scope( 1377 HistogramTimerScope wasm_instantiate_module_time_scope(
1572 isolate->counters()->wasm_instantiate_module_time()); 1378 isolate->counters()->wasm_instantiate_module_time());
1573 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); 1379 ErrorThrower thrower(isolate, "WasmModule::Instantiate()");
1574 Factory* factory = isolate->factory(); 1380 Factory* factory = isolate->factory();
1575 1381
1576 Handle<FixedArray> compiled_module = 1382 compiled_module = CloneModuleForInstance(isolate, compiled_module);
1577 CloneModuleForInstance(isolate, compiled_module_template);
1578 1383
1579 bool template_is_owned =
1580 GetOwningInstance(*compiled_module_template) != nullptr;
1581
1582 MaybeHandle<JSObject> template_owner;
1583 if (template_is_owned) {
1584 Handle<WeakCell> weak_owner =
1585 compiled_module_template->GetValueChecked<WeakCell>(isolate,
1586 kOwningInstance);
1587 template_owner = handle(JSObject::cast(weak_owner->value()));
1588 }
1589 // These fields are compulsory. 1384 // These fields are compulsory.
1590 Handle<FixedArray> code_table = 1385 Handle<FixedArray> code_table =
1591 compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions); 1386 compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions);
1592 1387
1388 std::vector<Handle<Code>> functions(
1389 static_cast<size_t>(code_table->length()));
1390 for (int i = 0; i < code_table->length(); ++i) {
1391 functions[static_cast<size_t>(i)] =
1392 code_table->GetValueChecked<Code>(isolate, i);
1393 }
1394 LinkModuleFunctions(isolate, functions);
1395
1593 RecordStats(isolate, code_table); 1396 RecordStats(isolate, code_table);
1594 1397
1595 MaybeHandle<JSObject> nothing; 1398 MaybeHandle<JSObject> nothing;
1596 1399
1597 Handle<Map> map = factory->NewMap( 1400 Handle<Map> map = factory->NewMap(
1598 JS_OBJECT_TYPE, 1401 JS_OBJECT_TYPE,
1599 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 1402 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
1600 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); 1403 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED);
1601 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); 1404 js_object->SetInternalField(kWasmModuleCodeTable, *code_table);
1602 1405
1603 // Remember the old imports, for the case when we are at the first instance -
1604 // they will be replaced with the instance's actual imports in SetupImports.
1605 MaybeHandle<FixedArray> old_imports =
1606 compiled_module_template->GetValue<FixedArray>(isolate, kImportMap);
1607 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, 1406 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory,
1608 &thrower) && 1407 &thrower) &&
1609 SetupGlobals(isolate, template_owner, compiled_module, js_object, 1408 SetupGlobals(isolate, compiled_module, js_object, &thrower) &&
1610 &thrower) &&
1611 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) && 1409 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) &&
1612 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { 1410 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) {
1613 return nothing; 1411 return nothing;
1614 } 1412 }
1615 1413
1616 FixupFunctionsAndImports(
1617 compiled_module_template->GetValueChecked<FixedArray>(isolate,
1618 kFunctions),
1619 code_table, old_imports,
1620 compiled_module->GetValue<FixedArray>(isolate, kImportMap));
1621
1622 SetDebugSupport(factory, compiled_module, js_object); 1414 SetDebugSupport(factory, compiled_module, js_object);
1623 SetRuntimeSupport(isolate, js_object); 1415 SetRuntimeSupport(isolate, js_object);
1624 1416
1625 FlushAssemblyCache(isolate, code_table); 1417 FlushAssemblyCache(isolate, code_table);
1626 1418
1627 { 1419 MaybeHandle<FixedArray> maybe_indirect_tables =
1628 std::vector<Handle<Code>> functions( 1420 compiled_module->GetValue<FixedArray>(isolate,
1629 static_cast<size_t>(code_table->length())); 1421 kTableOfIndirectFunctionTables);
1630 for (int i = 0; i < code_table->length(); ++i) { 1422 Handle<FixedArray> indirect_tables_template;
1631 functions[static_cast<size_t>(i)] = 1423 if (maybe_indirect_tables.ToHandle(&indirect_tables_template)) {
1632 code_table->GetValueChecked<Code>(isolate, i); 1424 Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable(
1425 isolate, code_table, indirect_tables_template);
1426 for (int i = 0; i < indirect_tables->length(); ++i) {
1427 Handle<FixedArray> metadata =
1428 indirect_tables->GetValueChecked<FixedArray>(isolate, i);
1429 uint32_t size = Smi::cast(metadata->get(kSize))->value();
1430 Handle<FixedArray> table =
1431 metadata->GetValueChecked<FixedArray>(isolate, kTable);
1432 wasm::PopulateFunctionTable(table, size, &functions);
1633 } 1433 }
1634 1434 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables);
1635 MaybeHandle<FixedArray> maybe_indirect_tables =
1636 compiled_module->GetValue<FixedArray>(isolate,
1637 kTableOfIndirectFunctionTables);
1638 Handle<FixedArray> indirect_tables_template;
1639 if (maybe_indirect_tables.ToHandle(&indirect_tables_template)) {
1640 Handle<FixedArray> to_replace =
1641 template_owner.is_null()
1642 ? indirect_tables_template
1643 : handle(FixedArray::cast(
1644 template_owner.ToHandleChecked()->GetInternalField(
1645 kWasmModuleFunctionTable)));
1646 Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable(
1647 isolate, code_table, indirect_tables_template, to_replace);
1648 for (int i = 0; i < indirect_tables->length(); ++i) {
1649 Handle<FixedArray> metadata =
1650 indirect_tables->GetValueChecked<FixedArray>(isolate, i);
1651 uint32_t size = Smi::cast(metadata->get(kSize))->value();
1652 Handle<FixedArray> table =
1653 metadata->GetValueChecked<FixedArray>(isolate, kTable);
1654 wasm::PopulateFunctionTable(table, size, &functions);
1655 }
1656 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables);
1657 }
1658 } 1435 }
1659 1436
1660 // Run the start function if one was specified. 1437 // Run the start function if one was specified.
1661 MaybeHandle<FixedArray> maybe_startup_fct = 1438 MaybeHandle<FixedArray> maybe_startup_fct =
1662 compiled_module->GetValue<FixedArray>(isolate, kStartupFunction); 1439 compiled_module->GetValue<FixedArray>(isolate, kStartupFunction);
1663 Handle<FixedArray> metadata; 1440 Handle<FixedArray> metadata;
1664 if (maybe_startup_fct.ToHandle(&metadata)) { 1441 if (maybe_startup_fct.ToHandle(&metadata)) {
1665 HandleScope scope(isolate); 1442 HandleScope scope(isolate);
1666 Handle<Code> startup_code = 1443 Handle<Code> startup_code =
1667 metadata->GetValueChecked<Code>(isolate, kExportCode); 1444 metadata->GetValueChecked<Code>(isolate, kExportCode);
1668 int arity = Smi::cast(metadata->get(kExportArity))->value(); 1445 int arity = Smi::cast(metadata->get(kExportArity))->value();
1669 MaybeHandle<ByteArray> startup_signature = 1446 MaybeHandle<ByteArray> startup_signature =
1670 metadata->GetValue<ByteArray>(isolate, kExportedSignature); 1447 metadata->GetValue<ByteArray>(isolate, kExportedSignature);
1671 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( 1448 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction(
1672 isolate, startup_code, factory->InternalizeUtf8String("start"), arity, 1449 isolate, startup_code, factory->InternalizeUtf8String("start"), arity,
1673 startup_signature, js_object); 1450 startup_signature, js_object);
1674 RecordStats(isolate, *startup_code); 1451 RecordStats(isolate, *startup_code);
1675 // Call the JS function. 1452 // Call the JS function.
1676 Handle<Object> undefined = isolate->factory()->undefined_value(); 1453 Handle<Object> undefined = isolate->factory()->undefined_value();
1677 MaybeHandle<Object> retval = 1454 MaybeHandle<Object> retval =
1678 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); 1455 Execution::Call(isolate, startup_fct, undefined, 0, nullptr);
1679 1456
1680 if (retval.is_null()) { 1457 if (retval.is_null()) {
1681 thrower.Error("WASM.instantiateModule(): start function failed"); 1458 thrower.Error("WASM.instantiateModule(): start function failed");
1682 return nothing; 1459 return nothing;
1683 } 1460 }
1684 } 1461 }
1685 1462
1686 DCHECK(wasm::IsWasmObject(*js_object)); 1463 DCHECK(wasm::IsWasmObject(*js_object));
1687
1688 if (!compiled_module->GetValue<WeakCell>(isolate, kModuleObject).is_null()) {
1689 js_object->SetInternalField(kWasmCompiledModule, *compiled_module);
1690 Handle<WeakCell> link_to_owner = factory->NewWeakCell(js_object);
1691 compiled_module->set(kOwningInstance, *link_to_owner);
1692
1693 Handle<Object> global_handle =
1694 isolate->global_handles()->Create(*js_object);
1695 GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(),
1696 &InstanceFinalizer,
1697 v8::WeakCallbackType::kFinalizer);
1698 }
1699
1700 return js_object; 1464 return js_object;
1701 } 1465 }
1702 1466
1703 // TODO(mtrofin): remove this once we move to WASM_DIRECT_CALL 1467 // TODO(mtrofin): remove this once we move to WASM_DIRECT_CALL
1704 Handle<Code> ModuleEnv::GetCodeOrPlaceholder(uint32_t index) const { 1468 Handle<Code> ModuleEnv::GetCodeOrPlaceholder(uint32_t index) const {
1705 DCHECK(IsValidFunction(index)); 1469 DCHECK(IsValidFunction(index));
1706 if (!placeholders.empty()) return placeholders[index]; 1470 if (!placeholders.empty()) return placeholders[index];
1707 DCHECK_NOT_NULL(instance); 1471 DCHECK_NOT_NULL(instance);
1708 return instance->function_code[index]; 1472 return instance->function_code[index];
1709 } 1473 }
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1877 DCHECK(origin == ModuleOrigin::kAsmJsOrigin); 1641 DCHECK(origin == ModuleOrigin::kAsmJsOrigin);
1878 Handle<Map> map = isolate->factory()->NewMap( 1642 Handle<Map> map = isolate->factory()->NewMap(
1879 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize); 1643 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize);
1880 module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED); 1644 module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED);
1881 } 1645 }
1882 module_obj->SetInternalField(0, *compiled_module); 1646 module_obj->SetInternalField(0, *compiled_module);
1883 if (origin == ModuleOrigin::kWasmOrigin) { 1647 if (origin == ModuleOrigin::kWasmOrigin) {
1884 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); 1648 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
1885 Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check(); 1649 Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check();
1886 } 1650 }
1887 Handle<WeakCell> link_to_module = isolate->factory()->NewWeakCell(module_obj);
1888 compiled_module->set(kModuleObject, *link_to_module);
1889 return module_obj; 1651 return module_obj;
1890 } 1652 }
1891 1653
1892 MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate, 1654 MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate,
1893 const byte* start, 1655 const byte* start,
1894 const byte* end, 1656 const byte* end,
1895 ErrorThrower* thrower, 1657 ErrorThrower* thrower,
1896 ModuleOrigin origin) { 1658 ModuleOrigin origin) {
1897 MaybeHandle<JSObject> nothing; 1659 MaybeHandle<JSObject> nothing;
1898 Zone zone(isolate->allocator()); 1660 Zone zone(isolate->allocator());
1899 ModuleResult result = 1661 ModuleResult result =
1900 DecodeWasmModule(isolate, &zone, start, end, false, origin); 1662 DecodeWasmModule(isolate, &zone, start, end, false, origin);
1901 std::unique_ptr<const WasmModule> decoded_module(result.val); 1663 std::unique_ptr<const WasmModule> decoded_module(result.val);
1902 if (result.failed()) { 1664 if (result.failed()) {
1903 thrower->Failed("Wasm decoding failed", result); 1665 thrower->Failed("Wasm decoding failed", result);
1904 return nothing; 1666 return nothing;
1905 } 1667 }
1906 MaybeHandle<FixedArray> compiled_module = 1668 MaybeHandle<FixedArray> compiled_module =
1907 decoded_module->CompileFunctions(isolate, thrower); 1669 decoded_module->CompileFunctions(isolate, thrower);
1908 if (compiled_module.is_null()) return nothing; 1670 if (compiled_module.is_null()) return nothing;
1909 1671
1910 return CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked(), 1672 return CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked(),
1911 origin); 1673 origin);
1912 } 1674 }
1913 1675
1914 MaybeHandle<JSArrayBuffer> GetInstanceMemory(Isolate* isolate,
1915 Handle<JSObject> instance) {
1916 Object* mem = instance->GetInternalField(kWasmMemArrayBuffer);
1917 DCHECK(IsWasmObject(*instance));
1918 if (mem->IsUndefined(isolate)) return MaybeHandle<JSArrayBuffer>();
1919 return Handle<JSArrayBuffer>(JSArrayBuffer::cast(mem));
1920 }
1921
1922 void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) {
1923 DisallowHeapAllocation no_gc;
1924 DCHECK(IsWasmObject(*instance));
1925 instance->SetInternalField(kWasmMemArrayBuffer, buffer);
1926 Object* module = instance->GetInternalField(kWasmCompiledModule);
1927 if (module->IsFixedArray()) {
1928 HeapNumber::cast(FixedArray::cast(module)->get(kMemSize))
1929 ->set_value(buffer->byte_length()->Number());
1930 }
1931 }
1932
1933 namespace testing { 1676 namespace testing {
1934 1677
1935 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, 1678 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
1936 const byte* module_end, bool asm_js) { 1679 const byte* module_end, bool asm_js) {
1937 HandleScope scope(isolate); 1680 HandleScope scope(isolate);
1938 Zone zone(isolate->allocator()); 1681 Zone zone(isolate->allocator());
1939 ErrorThrower thrower(isolate, "CompileAndRunWasmModule"); 1682 ErrorThrower thrower(isolate, "CompileAndRunWasmModule");
1940 1683
1941 // Decode the module, but don't verify function bodies, since we'll 1684 // Decode the module, but don't verify function bodies, since we'll
1942 // be compiling them anyway. 1685 // be compiling them anyway.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 if (result->IsSmi()) { 1750 if (result->IsSmi()) {
2008 return Smi::cast(*result)->value(); 1751 return Smi::cast(*result)->value();
2009 } 1752 }
2010 if (result->IsHeapNumber()) { 1753 if (result->IsHeapNumber()) {
2011 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); 1754 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
2012 } 1755 }
2013 thrower->Error("WASM.compileRun() failed: Return value should be number"); 1756 thrower->Error("WASM.compileRun() failed: Return value should be number");
2014 return -1; 1757 return -1;
2015 } 1758 }
2016 1759
2017 void ValidateInstancesChain(Isolate* isolate, Handle<JSObject> module_obj,
2018 int instance_count) {
2019 CHECK_GE(instance_count, 0);
2020 DisallowHeapAllocation no_gc;
2021 FixedArray* compiled_module =
2022 FixedArray::cast(module_obj->GetInternalField(0));
2023 CHECK_EQ(JSObject::cast(GetModuleObject(compiled_module)->value()),
2024 *module_obj);
2025 Object* prev = nullptr;
2026 int found_instances = GetOwningInstance(compiled_module) == nullptr ? 0 : 1;
2027 FixedArray* current_instance = compiled_module;
2028 while (GetNextInstance(current_instance) != nullptr) {
2029 CHECK((prev == nullptr && GetPrevInstance(current_instance) == nullptr) ||
2030 GetPrevInstance(current_instance)->value() == prev);
2031 CHECK_EQ(GetModuleObject(current_instance)->value(), *module_obj);
2032 CHECK(IsWasmObject(GetOwningInstance(current_instance)->value()));
2033 prev = current_instance;
2034 current_instance =
2035 FixedArray::cast(GetNextInstance(current_instance)->value());
2036 ++found_instances;
2037 CHECK_LE(found_instances, instance_count);
2038 }
2039 CHECK_EQ(found_instances, instance_count);
2040 }
2041
2042 void ValidateModuleState(Isolate* isolate, Handle<JSObject> module_obj) {
2043 DisallowHeapAllocation no_gc;
2044 FixedArray* compiled_module =
2045 FixedArray::cast(module_obj->GetInternalField(0));
2046 CHECK_NOT_NULL(GetModuleObject(compiled_module));
2047 CHECK_EQ(GetModuleObject(compiled_module)->value(), *module_obj);
2048 CHECK_NULL(GetPrevInstance(compiled_module));
2049 CHECK_NULL(GetNextInstance(compiled_module));
2050 CHECK_NULL(GetOwningInstance(compiled_module));
2051 }
2052
2053 void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance) {
2054 DisallowHeapAllocation no_gc;
2055 CHECK(IsWasmObject(*instance));
2056 FixedArray* compiled_module =
2057 FixedArray::cast(instance->GetInternalField(kWasmCompiledModule));
2058 CHECK_NOT_NULL(GetModuleObject(compiled_module));
2059 CHECK(GetModuleObject(compiled_module)->cleared());
2060 }
2061
2062 } // namespace testing 1760 } // namespace testing
2063 } // namespace wasm 1761 } // namespace wasm
2064 } // namespace internal 1762 } // namespace internal
2065 } // namespace v8 1763 } // 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