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

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

Issue 2305903002: [wasm] reuse the first compiled module (Closed)
Patch Set: use HeapNumber for storing mem size 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
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,
bradnelson 2016/09/02 16:56:59 Optional: Realize the default is zero, but I've so
Mircea Trofin 2016/09/02 20:55:30 Done.
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 ||
bradnelson 2016/09/02 16:57:00 Why?
Mircea Trofin 2016/09/02 20:55:30 Because now the deopt will be valid, but belonging
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->IsNumber());
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 if (!weak_module_obj->cleared()) {
bradnelson 2016/09/02 16:57:00 Why?
Mircea Trofin 2016/09/02 20:55:30 It may be cleared when this happens: var m = new W
1208 JSObject* module_obj = JSObject::cast(weak_module_obj->value());
1209 FixedArray* current_template =
1210 FixedArray::cast(module_obj->GetInternalField(0));
1211 DCHECK_NULL(GetPrevInstance(current_template));
bradnelson 2016/09/02 16:57:00 Separate out the remove from chain operation? Or c
Mircea Trofin 2016/09/02 20:55:30 There nothing else than the delete - we're called
1212 WeakCell* next = GetNextInstance(compiled_module);
1213 WeakCell* prev = GetPrevInstance(compiled_module);
1214
1215 if (current_template == compiled_module) {
1216 if (next == nullptr) {
1217 ResetCompiledModule(isolate, owner, compiled_module);
1218 } else {
1219 DCHECK(next->value()->IsFixedArray());
1220 module_obj->SetInternalField(0, next->value());
1221 DCHECK_NULL(prev);
1222 FixedArray::cast(next->value())->set(kPrevInstance, undefined);
1223 }
1224 } else {
1225 DCHECK(!(prev == nullptr && next == nullptr));
1226 // the only reason prev or next would be cleared is if the
1227 // respective objects got collected, but if that happened,
1228 // we would have relinked the list.
1229 if (prev != nullptr) {
1230 DCHECK(!prev->cleared());
1231 FixedArray::cast(prev->value())
1232 ->set(kNextInstance, next == nullptr ? undefined : next);
1233 }
1234 if (next != nullptr) {
1235 DCHECK(!next->cleared());
1236 FixedArray::cast(next->value())
1237 ->set(kPrevInstance, prev == nullptr ? undefined : prev);
1238 }
1239 }
1240 }
1241 GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
1242 }
1243
1084 } // namespace 1244 } // namespace
1085 1245
1086 MaybeHandle<FixedArray> WasmModule::CompileFunctions( 1246 MaybeHandle<FixedArray> WasmModule::CompileFunctions(
1087 Isolate* isolate, ErrorThrower* thrower) const { 1247 Isolate* isolate, ErrorThrower* thrower) const {
1088 Factory* factory = isolate->factory(); 1248 Factory* factory = isolate->factory();
1089 1249
1090 MaybeHandle<FixedArray> nothing; 1250 MaybeHandle<FixedArray> nothing;
1091 1251
1092 WasmModuleInstance temp_instance_for_compilation(this); 1252 WasmModuleInstance temp_instance_for_compilation(this);
1093 temp_instance_for_compilation.context = isolate->native_context(); 1253 temp_instance_for_compilation.context = isolate->native_context();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 } 1309 }
1150 if (thrower->error()) return nothing; 1310 if (thrower->error()) return nothing;
1151 1311
1152 // At this point, compilation has completed. Update the code table. 1312 // At this point, compilation has completed. Update the code table.
1153 for (size_t i = FLAG_skip_compiling_wasm_funcs; 1313 for (size_t i = FLAG_skip_compiling_wasm_funcs;
1154 i < temp_instance_for_compilation.function_code.size(); ++i) { 1314 i < temp_instance_for_compilation.function_code.size(); ++i) {
1155 Code* code = *temp_instance_for_compilation.function_code[i]; 1315 Code* code = *temp_instance_for_compilation.function_code[i];
1156 compiled_functions->set(static_cast<int>(i), code); 1316 compiled_functions->set(static_cast<int>(i), code);
1157 } 1317 }
1158 1318
1319 LinkModuleFunctions(isolate, compiled_functions);
1320
1321 // TODO(mtrofin): do we need to flush the cache here?
1322 FlushAssemblyCache(isolate, compiled_functions);
bradnelson 2016/09/02 16:56:59 Because the code has never run? Probably not.
Mircea Trofin 2016/09/02 20:55:30 Acknowledged.
1323
1159 // Create the compiled module object, and populate with compiled functions 1324 // Create the compiled module object, and populate with compiled functions
1160 // and information needed at instantiation time. This object needs to be 1325 // and information needed at instantiation time. This object needs to be
1161 // serializable. Instantiation may occur off a deserialized version of this 1326 // serializable. Instantiation may occur off a deserialized version of this
1162 // object. 1327 // object.
1163 Handle<FixedArray> ret = 1328 Handle<FixedArray> ret =
1164 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED); 1329 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED);
1165 ret->set(kFunctions, *compiled_functions); 1330 ret->set(kFunctions, *compiled_functions);
1166 if (!indirect_table.is_null()) { 1331 if (!indirect_table.is_null()) {
1167 ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked()); 1332 ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked());
1168 } 1333 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 } 1409 }
1245 1410
1246 Handle<ByteArray> function_name_table = 1411 Handle<ByteArray> function_name_table =
1247 BuildFunctionNamesTable(isolate, module_env.module); 1412 BuildFunctionNamesTable(isolate, module_env.module);
1248 ret->set(kFunctionNameTable, *function_name_table); 1413 ret->set(kFunctionNameTable, *function_name_table);
1249 ret->set(kMinRequiredMemory, Smi::FromInt(min_mem_pages)); 1414 ret->set(kMinRequiredMemory, Smi::FromInt(min_mem_pages));
1250 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret); 1415 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret);
1251 ret->set(kGlobalsSize, Smi::FromInt(globals_size)); 1416 ret->set(kGlobalsSize, Smi::FromInt(globals_size));
1252 ret->set(kExportMem, Smi::FromInt(mem_export)); 1417 ret->set(kExportMem, Smi::FromInt(mem_export));
1253 ret->set(kOrigin, Smi::FromInt(origin)); 1418 ret->set(kOrigin, Smi::FromInt(origin));
1419 ret->set(kMemSize,
1420 *factory->NewHeapNumber(
1421 static_cast<double>(temp_instance_for_compilation.mem_size),
1422 MUTABLE, TENURED));
1254 return ret; 1423 return ret;
1255 } 1424 }
1256 1425
1257 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper, 1426 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper,
1258 Handle<Code> new_target) { 1427 Handle<Code> new_target) {
1259 AllowDeferredHandleDereference embedding_raw_address; 1428 AllowDeferredHandleDereference embedding_raw_address;
1260 bool seen = false; 1429 bool seen = false;
1261 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done(); 1430 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done();
1262 it.next()) { 1431 it.next()) {
1263 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); 1432 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
1264 if (target->kind() == Code::WASM_FUNCTION) { 1433 if (target->kind() == Code::WASM_FUNCTION) {
1265 DCHECK(!seen); 1434 DCHECK(!seen);
1266 seen = true; 1435 seen = true;
1267 it.rinfo()->set_target_address(new_target->instruction_start(), 1436 it.rinfo()->set_target_address(new_target->instruction_start(),
1268 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH); 1437 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
1269 } 1438 }
1270 } 1439 }
1271 CHECK(seen); 1440 CHECK(seen);
1272 Assembler::FlushICache(isolate, wrapper->instruction_start(), 1441 Assembler::FlushICache(isolate, wrapper->instruction_start(),
1273 wrapper->instruction_size()); 1442 wrapper->instruction_size());
1274 } 1443 }
1275 1444
1276 Handle<FixedArray> SetupIndirectFunctionTable( 1445 Handle<FixedArray> SetupIndirectFunctionTable(
1277 Isolate* isolate, Handle<FixedArray> wasm_functions, 1446 Isolate* isolate, Handle<FixedArray> wasm_functions,
1278 Handle<FixedArray> indirect_table_template) { 1447 Handle<FixedArray> indirect_table_template,
1448 Handle<FixedArray> tables_to_replace) {
1279 Factory* factory = isolate->factory(); 1449 Factory* factory = isolate->factory();
1280 Handle<FixedArray> cloned_indirect_tables = 1450 Handle<FixedArray> cloned_indirect_tables =
1281 factory->CopyFixedArray(indirect_table_template); 1451 factory->CopyFixedArray(indirect_table_template);
1282 for (int i = 0; i < cloned_indirect_tables->length(); ++i) { 1452 for (int i = 0; i < cloned_indirect_tables->length(); ++i) {
1283 Handle<FixedArray> orig_metadata = 1453 Handle<FixedArray> orig_metadata =
1284 cloned_indirect_tables->GetValueChecked<FixedArray>(isolate, i); 1454 cloned_indirect_tables->GetValueChecked<FixedArray>(isolate, i);
1285 Handle<FixedArray> cloned_metadata = factory->CopyFixedArray(orig_metadata); 1455 Handle<FixedArray> cloned_metadata = factory->CopyFixedArray(orig_metadata);
1286 cloned_indirect_tables->set(i, *cloned_metadata); 1456 cloned_indirect_tables->set(i, *cloned_metadata);
1287 1457
1288 Handle<FixedArray> orig_table = 1458 Handle<FixedArray> orig_table =
1289 cloned_metadata->GetValueChecked<FixedArray>(isolate, kTable); 1459 cloned_metadata->GetValueChecked<FixedArray>(isolate, kTable);
1290 Handle<FixedArray> cloned_table = factory->CopyFixedArray(orig_table); 1460 Handle<FixedArray> cloned_table = factory->CopyFixedArray(orig_table);
1291 cloned_metadata->set(kTable, *cloned_table); 1461 cloned_metadata->set(kTable, *cloned_table);
1292 // Patch the cloned code to refer to the cloned kTable. 1462 // Patch the cloned code to refer to the cloned kTable.
1293 for (int i = 0; i < wasm_functions->length(); ++i) { 1463 Handle<FixedArray> table_to_replace =
1464 tables_to_replace->GetValueChecked<FixedArray>(isolate, i)
1465 ->GetValueChecked<FixedArray>(isolate, kTable);
1466 for (int fct_index = 0; fct_index < wasm_functions->length(); ++fct_index) {
1294 Handle<Code> wasm_function = 1467 Handle<Code> wasm_function =
1295 wasm_functions->GetValueChecked<Code>(isolate, i); 1468 wasm_functions->GetValueChecked<Code>(isolate, fct_index);
1296 PatchFunctionTable(wasm_function, orig_table, cloned_table); 1469 PatchFunctionTable(wasm_function, table_to_replace, cloned_table);
1297 } 1470 }
1298 } 1471 }
1299 return cloned_indirect_tables; 1472 return cloned_indirect_tables;
1300 } 1473 }
1301 1474
1302 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate, 1475 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate,
1303 Handle<FixedArray> original) { 1476 Handle<FixedArray> original) {
1304 Factory* factory = isolate->factory(); 1477 Factory* factory = isolate->factory();
1478 bool is_first =
1479 original->GetValue<WeakCell>(isolate, kOwningInstance).is_null();
1480
1481 if (is_first) {
1482 return original;
1483 }
1484
1485 // We insert the latest clone in front.
1305 Handle<FixedArray> clone = factory->CopyFixedArray(original); 1486 Handle<FixedArray> clone = factory->CopyFixedArray(original);
1487 Handle<WeakCell> weak_link_to_wasm_obj =
1488 original->GetValueChecked<WeakCell>(isolate, kModuleObject);
1489
1490 clone->set(kModuleObject, *weak_link_to_wasm_obj);
1491 clone->set(kNextInstance, *factory->NewWeakCell(original));
1492 original->set(kPrevInstance, *factory->NewWeakCell(clone));
1493 JSObject::cast(weak_link_to_wasm_obj->value())->SetInternalField(0, *clone);
1306 1494
1307 // Clone each wasm code object. 1495 // Clone each wasm code object.
1308 Handle<FixedArray> orig_wasm_functions = 1496 Handle<FixedArray> orig_wasm_functions =
1309 original->GetValueChecked<FixedArray>(isolate, kFunctions); 1497 original->GetValueChecked<FixedArray>(isolate, kFunctions);
1310 Handle<FixedArray> clone_wasm_functions = 1498 Handle<FixedArray> clone_wasm_functions =
1311 factory->CopyFixedArray(orig_wasm_functions); 1499 factory->CopyFixedArray(orig_wasm_functions);
1312 clone->set(kFunctions, *clone_wasm_functions); 1500 clone->set(kFunctions, *clone_wasm_functions);
1313 for (int i = 0; i < clone_wasm_functions->length(); ++i) { 1501 for (int i = 0; i < clone_wasm_functions->length(); ++i) {
1314 Handle<Code> orig_code = 1502 Handle<Code> orig_code =
1315 clone_wasm_functions->GetValueChecked<Code>(isolate, i); 1503 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); 1544 clone->set(kStartupFunction, *startup_metadata);
1357 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray. 1545 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray.
1358 int startup_fct_index = 1546 int startup_fct_index =
1359 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value(); 1547 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value();
1360 CHECK_GE(startup_fct_index, 0); 1548 CHECK_GE(startup_fct_index, 0);
1361 CHECK_LT(startup_fct_index, clone_wasm_functions->length()); 1549 CHECK_LT(startup_fct_index, clone_wasm_functions->length());
1362 Handle<Code> new_target = 1550 Handle<Code> new_target =
1363 clone_wasm_functions->GetValueChecked<Code>(isolate, startup_fct_index); 1551 clone_wasm_functions->GetValueChecked<Code>(isolate, startup_fct_index);
1364 PatchJSWrapper(isolate, startup_fct_clone, new_target); 1552 PatchJSWrapper(isolate, startup_fct_clone, new_target);
1365 } 1553 }
1554 clone->set(kImportMap, *isolate->factory()->undefined_value());
1366 return clone; 1555 return clone;
1367 } 1556 }
1368 1557
1369 // Instantiates a wasm module as a JSObject. 1558 // Instantiates a wasm module as a JSObject.
1370 // * allocates a backing store of {mem_size} bytes. 1559 // * allocates a backing store of {mem_size} bytes.
1371 // * installs a named property "memory" for that buffer if exported 1560 // * installs a named property "memory" for that buffer if exported
1372 // * installs named properties on the object for exported functions 1561 // * installs named properties on the object for exported functions
1373 // * compiles wasm code to machine code 1562 // * compiles wasm code to machine code
1374 MaybeHandle<JSObject> WasmModule::Instantiate( 1563 MaybeHandle<JSObject> WasmModule::Instantiate(
1375 Isolate* isolate, Handle<FixedArray> compiled_module, 1564 Isolate* isolate, Handle<FixedArray> compiled_module_template,
1376 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) { 1565 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) {
1377 HistogramTimerScope wasm_instantiate_module_time_scope( 1566 HistogramTimerScope wasm_instantiate_module_time_scope(
1378 isolate->counters()->wasm_instantiate_module_time()); 1567 isolate->counters()->wasm_instantiate_module_time());
1379 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); 1568 ErrorThrower thrower(isolate, "WasmModule::Instantiate()");
1380 Factory* factory = isolate->factory(); 1569 Factory* factory = isolate->factory();
1381 1570
1382 compiled_module = CloneModuleForInstance(isolate, compiled_module); 1571 Handle<FixedArray> compiled_module =
1572 CloneModuleForInstance(isolate, compiled_module_template);
1383 1573
1574 bool template_is_owned =
1575 GetOwningInstance(*compiled_module_template) != nullptr;
1576
1577 MaybeHandle<JSObject> template_owner;
1578 if (template_is_owned) {
1579 Handle<WeakCell> weak_owner =
1580 compiled_module_template->GetValueChecked<WeakCell>(isolate,
1581 kOwningInstance);
1582 template_owner = handle(JSObject::cast(weak_owner->value()));
1583 }
1384 // These fields are compulsory. 1584 // These fields are compulsory.
1385 Handle<FixedArray> code_table = 1585 Handle<FixedArray> code_table =
1386 compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions); 1586 compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions);
1387 1587
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
1396 RecordStats(isolate, code_table); 1588 RecordStats(isolate, code_table);
1397 1589
1398 MaybeHandle<JSObject> nothing; 1590 MaybeHandle<JSObject> nothing;
1399 1591
1400 Handle<Map> map = factory->NewMap( 1592 Handle<Map> map = factory->NewMap(
1401 JS_OBJECT_TYPE, 1593 JS_OBJECT_TYPE,
1402 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 1594 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
1403 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); 1595 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED);
1404 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); 1596 js_object->SetInternalField(kWasmModuleCodeTable, *code_table);
1405 1597
1598 // Remember the old imports, for the case when we are at the first instance -
1599 // they will be
1600 // replaced with the instance's actual imports in SetupImports.
bradnelson 2016/09/02 16:57:00 reflow comment
Mircea Trofin 2016/09/02 20:55:30 Done.
1601 MaybeHandle<FixedArray> old_imports =
1602 compiled_module_template->GetValue<FixedArray>(isolate, kImportMap);
1406 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, 1603 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory,
1407 &thrower) && 1604 &thrower) &&
1408 SetupGlobals(isolate, compiled_module, js_object, &thrower) && 1605 SetupGlobals(isolate, template_owner, compiled_module, js_object,
1606 &thrower) &&
1409 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) && 1607 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) &&
1410 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { 1608 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) {
1411 return nothing; 1609 return nothing;
1412 } 1610 }
1413 1611
1612 FixupFunctionsAndImports(
1613 compiled_module_template->GetValueChecked<FixedArray>(isolate,
1614 kFunctions),
1615 code_table, old_imports,
1616 compiled_module->GetValue<FixedArray>(isolate, kImportMap));
1617
1414 SetDebugSupport(factory, compiled_module, js_object); 1618 SetDebugSupport(factory, compiled_module, js_object);
1415 SetRuntimeSupport(isolate, js_object); 1619 SetRuntimeSupport(isolate, js_object);
1416 1620
1417 FlushAssemblyCache(isolate, code_table); 1621 FlushAssemblyCache(isolate, code_table);
1418 1622
1419 MaybeHandle<FixedArray> maybe_indirect_tables = 1623 {
1420 compiled_module->GetValue<FixedArray>(isolate, 1624 std::vector<Handle<Code>> functions(
1421 kTableOfIndirectFunctionTables); 1625 static_cast<size_t>(code_table->length()));
1422 Handle<FixedArray> indirect_tables_template; 1626 for (int i = 0; i < code_table->length(); ++i) {
1423 if (maybe_indirect_tables.ToHandle(&indirect_tables_template)) { 1627 functions[static_cast<size_t>(i)] =
1424 Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable( 1628 code_table->GetValueChecked<Code>(isolate, i);
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);
1433 } 1629 }
1434 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables); 1630
1631 MaybeHandle<FixedArray> maybe_indirect_tables =
1632 compiled_module->GetValue<FixedArray>(isolate,
1633 kTableOfIndirectFunctionTables);
1634 Handle<FixedArray> indirect_tables_template;
1635 if (maybe_indirect_tables.ToHandle(&indirect_tables_template)) {
1636 Handle<FixedArray> to_replace =
1637 template_owner.is_null()
1638 ? indirect_tables_template
1639 : handle(FixedArray::cast(
1640 template_owner.ToHandleChecked()->GetInternalField(
1641 kWasmModuleFunctionTable)));
1642 Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable(
1643 isolate, code_table, indirect_tables_template, to_replace);
1644 for (int i = 0; i < indirect_tables->length(); ++i) {
1645 Handle<FixedArray> metadata =
1646 indirect_tables->GetValueChecked<FixedArray>(isolate, i);
1647 uint32_t size = Smi::cast(metadata->get(kSize))->value();
1648 Handle<FixedArray> table =
1649 metadata->GetValueChecked<FixedArray>(isolate, kTable);
1650 wasm::PopulateFunctionTable(table, size, &functions);
1651 }
1652 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables);
1653 }
1435 } 1654 }
1436 1655
1437 // Run the start function if one was specified. 1656 // Run the start function if one was specified.
1438 MaybeHandle<FixedArray> maybe_startup_fct = 1657 MaybeHandle<FixedArray> maybe_startup_fct =
1439 compiled_module->GetValue<FixedArray>(isolate, kStartupFunction); 1658 compiled_module->GetValue<FixedArray>(isolate, kStartupFunction);
1440 Handle<FixedArray> metadata; 1659 Handle<FixedArray> metadata;
1441 if (maybe_startup_fct.ToHandle(&metadata)) { 1660 if (maybe_startup_fct.ToHandle(&metadata)) {
1442 HandleScope scope(isolate); 1661 HandleScope scope(isolate);
1443 Handle<Code> startup_code = 1662 Handle<Code> startup_code =
1444 metadata->GetValueChecked<Code>(isolate, kExportCode); 1663 metadata->GetValueChecked<Code>(isolate, kExportCode);
1445 int arity = Smi::cast(metadata->get(kExportArity))->value(); 1664 int arity = Smi::cast(metadata->get(kExportArity))->value();
1446 MaybeHandle<ByteArray> startup_signature = 1665 MaybeHandle<ByteArray> startup_signature =
1447 metadata->GetValue<ByteArray>(isolate, kExportedSignature); 1666 metadata->GetValue<ByteArray>(isolate, kExportedSignature);
1448 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( 1667 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction(
1449 isolate, startup_code, factory->InternalizeUtf8String("start"), arity, 1668 isolate, startup_code, factory->InternalizeUtf8String("start"), arity,
1450 startup_signature, js_object); 1669 startup_signature, js_object);
1451 RecordStats(isolate, *startup_code); 1670 RecordStats(isolate, *startup_code);
1452 // Call the JS function. 1671 // Call the JS function.
1453 Handle<Object> undefined = isolate->factory()->undefined_value(); 1672 Handle<Object> undefined = isolate->factory()->undefined_value();
1454 MaybeHandle<Object> retval = 1673 MaybeHandle<Object> retval =
1455 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); 1674 Execution::Call(isolate, startup_fct, undefined, 0, nullptr);
1456 1675
1457 if (retval.is_null()) { 1676 if (retval.is_null()) {
1458 thrower.Error("WASM.instantiateModule(): start function failed"); 1677 thrower.Error("WASM.instantiateModule(): start function failed");
1459 return nothing; 1678 return nothing;
1460 } 1679 }
1461 } 1680 }
1462 1681
1463 DCHECK(wasm::IsWasmObject(*js_object)); 1682 DCHECK(wasm::IsWasmObject(*js_object));
1683
1684 if (!compiled_module->GetValue<WeakCell>(isolate, kModuleObject).is_null()) {
1685 js_object->SetInternalField(kWasmCompiledModule, *compiled_module);
1686 compiled_module->set(kOwningInstance, *factory->NewWeakCell(js_object));
1687
1688 Handle<Object> global_handle =
1689 isolate->global_handles()->Create(*js_object);
1690 GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(),
1691 &InstanceFinalizer,
1692 v8::WeakCallbackType::kFinalizer);
1693 }
1694
1464 return js_object; 1695 return js_object;
1465 } 1696 }
1466 1697
1467 // TODO(mtrofin): remove this once we move to WASM_DIRECT_CALL 1698 // TODO(mtrofin): remove this once we move to WASM_DIRECT_CALL
1468 Handle<Code> ModuleEnv::GetCodeOrPlaceholder(uint32_t index) const { 1699 Handle<Code> ModuleEnv::GetCodeOrPlaceholder(uint32_t index) const {
1469 DCHECK(IsValidFunction(index)); 1700 DCHECK(IsValidFunction(index));
1470 if (!placeholders.empty()) return placeholders[index]; 1701 if (!placeholders.empty()) return placeholders[index];
1471 DCHECK_NOT_NULL(instance); 1702 DCHECK_NOT_NULL(instance);
1472 return instance->function_code[index]; 1703 return instance->function_code[index];
1473 } 1704 }
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 DCHECK(origin == ModuleOrigin::kAsmJsOrigin); 1872 DCHECK(origin == ModuleOrigin::kAsmJsOrigin);
1642 Handle<Map> map = isolate->factory()->NewMap( 1873 Handle<Map> map = isolate->factory()->NewMap(
1643 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize); 1874 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize);
1644 module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED); 1875 module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED);
1645 } 1876 }
1646 module_obj->SetInternalField(0, *compiled_module); 1877 module_obj->SetInternalField(0, *compiled_module);
1647 if (origin == ModuleOrigin::kWasmOrigin) { 1878 if (origin == ModuleOrigin::kWasmOrigin) {
1648 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); 1879 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
1649 Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check(); 1880 Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check();
1650 } 1881 }
1882 compiled_module->set(kModuleObject,
1883 *isolate->factory()->NewWeakCell(module_obj));
1651 return module_obj; 1884 return module_obj;
1652 } 1885 }
1653 1886
1654 MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate, 1887 MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate,
1655 const byte* start, 1888 const byte* start,
1656 const byte* end, 1889 const byte* end,
1657 ErrorThrower* thrower, 1890 ErrorThrower* thrower,
1658 ModuleOrigin origin) { 1891 ModuleOrigin origin) {
1659 MaybeHandle<JSObject> nothing; 1892 MaybeHandle<JSObject> nothing;
1660 Zone zone(isolate->allocator()); 1893 Zone zone(isolate->allocator());
1661 ModuleResult result = 1894 ModuleResult result =
1662 DecodeWasmModule(isolate, &zone, start, end, false, origin); 1895 DecodeWasmModule(isolate, &zone, start, end, false, origin);
1663 std::unique_ptr<const WasmModule> decoded_module(result.val); 1896 std::unique_ptr<const WasmModule> decoded_module(result.val);
1664 if (result.failed()) { 1897 if (result.failed()) {
1665 thrower->Failed("Wasm decoding failed", result); 1898 thrower->Failed("Wasm decoding failed", result);
1666 return nothing; 1899 return nothing;
1667 } 1900 }
1668 MaybeHandle<FixedArray> compiled_module = 1901 MaybeHandle<FixedArray> compiled_module =
1669 decoded_module->CompileFunctions(isolate, thrower); 1902 decoded_module->CompileFunctions(isolate, thrower);
1670 if (compiled_module.is_null()) return nothing; 1903 if (compiled_module.is_null()) return nothing;
1671 1904
1672 return CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked(), 1905 return CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked(),
1673 origin); 1906 origin);
1674 } 1907 }
1675 1908
1909 MaybeHandle<JSArrayBuffer> GetInstanceMemory(Isolate* isolate,
1910 Handle<JSObject> instance) {
1911 Object* mem = instance->GetInternalField(kWasmMemArrayBuffer);
1912 DCHECK(IsWasmObject(*instance));
1913 if (mem->IsUndefined(isolate)) return MaybeHandle<JSArrayBuffer>();
1914 return Handle<JSArrayBuffer>(JSArrayBuffer::cast(mem));
1915 }
1916
1917 void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) {
1918 DisallowHeapAllocation no_gc;
1919 DCHECK(IsWasmObject(*instance));
1920 instance->SetInternalField(kWasmMemArrayBuffer, buffer);
1921 }
1922
1676 namespace testing { 1923 namespace testing {
1677 1924
1678 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, 1925 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
1679 const byte* module_end, bool asm_js) { 1926 const byte* module_end, bool asm_js) {
1680 HandleScope scope(isolate); 1927 HandleScope scope(isolate);
1681 Zone zone(isolate->allocator()); 1928 Zone zone(isolate->allocator());
1682 ErrorThrower thrower(isolate, "CompileAndRunWasmModule"); 1929 ErrorThrower thrower(isolate, "CompileAndRunWasmModule");
1683 1930
1684 // Decode the module, but don't verify function bodies, since we'll 1931 // Decode the module, but don't verify function bodies, since we'll
1685 // be compiling them anyway. 1932 // be compiling them anyway.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 if (result->IsSmi()) { 1997 if (result->IsSmi()) {
1751 return Smi::cast(*result)->value(); 1998 return Smi::cast(*result)->value();
1752 } 1999 }
1753 if (result->IsHeapNumber()) { 2000 if (result->IsHeapNumber()) {
1754 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); 2001 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
1755 } 2002 }
1756 thrower->Error("WASM.compileRun() failed: Return value should be number"); 2003 thrower->Error("WASM.compileRun() failed: Return value should be number");
1757 return -1; 2004 return -1;
1758 } 2005 }
1759 2006
2007 void ValidateInstancesChain(Isolate* isolate, Handle<JSObject> module_obj,
2008 int instance_count) {
2009 CHECK_GE(instance_count, 0);
2010 DisallowHeapAllocation no_gc;
2011 FixedArray* compiled_module =
2012 FixedArray::cast(module_obj->GetInternalField(0));
2013 CHECK_EQ(JSObject::cast(GetModuleObject(compiled_module)->value()),
2014 *module_obj);
2015 Object* prev = nullptr;
2016 int found_instances = GetOwningInstance(compiled_module) == nullptr ? 0 : 1;
2017 FixedArray* current_instance = compiled_module;
2018 while (GetNextInstance(current_instance) != nullptr) {
2019 CHECK((prev == nullptr && GetPrevInstance(current_instance) == nullptr) ||
2020 GetPrevInstance(current_instance)->value() == prev);
2021 CHECK_EQ(GetModuleObject(current_instance)->value(), *module_obj);
2022 CHECK(IsWasmObject(GetOwningInstance(current_instance)->value()));
2023 prev = current_instance;
2024 current_instance =
2025 FixedArray::cast(GetNextInstance(current_instance)->value());
2026 ++found_instances;
2027 CHECK_LE(found_instances, instance_count);
2028 }
2029 CHECK_EQ(found_instances, instance_count);
2030 }
2031
2032 void ValidateModuleState(Isolate* isolate, Handle<JSObject> module_obj) {
2033 DisallowHeapAllocation no_gc;
2034 FixedArray* compiled_module =
2035 FixedArray::cast(module_obj->GetInternalField(0));
2036 CHECK_NOT_NULL(GetModuleObject(compiled_module));
2037 CHECK_EQ(GetModuleObject(compiled_module)->value(), *module_obj);
2038 CHECK_NULL(GetPrevInstance(compiled_module));
2039 CHECK_NULL(GetNextInstance(compiled_module));
2040 CHECK_NULL(GetOwningInstance(compiled_module));
2041 }
2042
2043 void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance) {
2044 DisallowHeapAllocation no_gc;
2045 CHECK(IsWasmObject(*instance));
2046 FixedArray* compiled_module =
2047 FixedArray::cast(instance->GetInternalField(kWasmCompiledModule));
2048 CHECK_NOT_NULL(GetModuleObject(compiled_module));
2049 CHECK(GetModuleObject(compiled_module)->cleared());
2050 }
2051
1760 } // namespace testing 2052 } // namespace testing
1761 } // namespace wasm 2053 } // namespace wasm
1762 } // namespace internal 2054 } // namespace internal
1763 } // namespace v8 2055 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698