| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <memory> | 5 #include <memory> |
| 6 | 6 |
| 7 #include "src/base/atomic-utils.h" | 7 #include "src/base/atomic-utils.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 | 9 |
| 10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
| (...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 encoded_import->set( | 629 encoded_import->set( |
| 630 kOutputCount, | 630 kOutputCount, |
| 631 Smi::FromInt(static_cast<int>(import.sig->return_count()))); | 631 Smi::FromInt(static_cast<int>(import.sig->return_count()))); |
| 632 encoded_import->set(kSignature, *sig); | 632 encoded_import->set(kSignature, *sig); |
| 633 ret->set(static_cast<int>(i), *encoded_import); | 633 ret->set(static_cast<int>(i), *encoded_import); |
| 634 } | 634 } |
| 635 return ret; | 635 return ret; |
| 636 } | 636 } |
| 637 | 637 |
| 638 bool CompileWrappersToImportedFunctions(Isolate* isolate, | 638 bool CompileWrappersToImportedFunctions(Isolate* isolate, |
| 639 Handle<Context> context, |
| 639 const Handle<JSReceiver> ffi, | 640 const Handle<JSReceiver> ffi, |
| 640 std::vector<Handle<Code>>& imports, | 641 std::vector<Handle<Code>>& imports, |
| 641 Handle<FixedArray> import_data, | 642 Handle<FixedArray> import_data, |
| 642 ErrorThrower* thrower) { | 643 ErrorThrower* thrower) { |
| 643 uint32_t import_count = static_cast<uint32_t>(import_data->length()); | 644 uint32_t import_count = static_cast<uint32_t>(import_data->length()); |
| 644 if (import_count > 0) { | 645 if (import_count > 0) { |
| 645 imports.reserve(import_count); | 646 imports.reserve(import_count); |
| 646 for (uint32_t index = 0; index < import_count; ++index) { | 647 for (uint32_t index = 0; index < import_count; ++index) { |
| 647 Handle<FixedArray> data = | 648 Handle<FixedArray> data = |
| 648 import_data->GetValueChecked<FixedArray>(isolate, index); | 649 import_data->GetValueChecked<FixedArray>(isolate, index); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 } else { | 702 } else { |
| 702 // Copy the signature to avoid a raw pointer into a heap object when | 703 // Copy the signature to avoid a raw pointer into a heap object when |
| 703 // GC can happen. | 704 // GC can happen. |
| 704 Zone zone(isolate->allocator()); | 705 Zone zone(isolate->allocator()); |
| 705 MachineRepresentation* reps = | 706 MachineRepresentation* reps = |
| 706 zone.NewArray<MachineRepresentation>(sig_data_size); | 707 zone.NewArray<MachineRepresentation>(sig_data_size); |
| 707 memcpy(reps, sig_data->data(), | 708 memcpy(reps, sig_data->data(), |
| 708 sizeof(MachineRepresentation) * sig_data_size); | 709 sizeof(MachineRepresentation) * sig_data_size); |
| 709 FunctionSig sig(ret_count, param_count, reps); | 710 FunctionSig sig(ret_count, param_count, reps); |
| 710 | 711 |
| 711 code = compiler::CompileWasmToJSWrapper(isolate, target, &sig, index, | 712 code = compiler::CompileWasmToJSWrapper( |
| 712 module_name, function_name); | 713 isolate, context, target, &sig, index, module_name, function_name); |
| 713 } | 714 } |
| 714 imports.push_back(code); | 715 imports.push_back(code); |
| 715 } | 716 } |
| 716 } | 717 } |
| 717 return true; | 718 return true; |
| 718 } | 719 } |
| 719 | 720 |
| 720 void InitializeParallelCompilation( | 721 void InitializeParallelCompilation( |
| 721 Isolate* isolate, const std::vector<WasmFunction>& functions, | 722 Isolate* isolate, const std::vector<WasmFunction>& functions, |
| 722 std::vector<compiler::WasmCompilationUnit*>& compilation_units, | 723 std::vector<compiler::WasmCompilationUnit*>& compilation_units, |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 instance->SetInternalField(kWasmMemArrayBuffer, *memory); | 941 instance->SetInternalField(kWasmMemArrayBuffer, *memory); |
| 941 Address mem_start = static_cast<Address>(memory->backing_store()); | 942 Address mem_start = static_cast<Address>(memory->backing_store()); |
| 942 uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number()); | 943 uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number()); |
| 943 RelocateInstanceCode(instance, mem_start, | 944 RelocateInstanceCode(instance, mem_start, |
| 944 WasmModule::kPageSize * min_mem_pages, mem_size); | 945 WasmModule::kPageSize * min_mem_pages, mem_size); |
| 945 LoadDataSegments(compiled_module, mem_start, mem_size); | 946 LoadDataSegments(compiled_module, mem_start, mem_size); |
| 946 } | 947 } |
| 947 return true; | 948 return true; |
| 948 } | 949 } |
| 949 | 950 |
| 950 bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module, | 951 bool SetupImports(Isolate* isolate, Handle<Context> context, |
| 951 Handle<JSObject> instance, ErrorThrower* thrower, | 952 Handle<FixedArray> compiled_module, Handle<JSObject> instance, |
| 952 Handle<JSReceiver> ffi) { | 953 ErrorThrower* thrower, Handle<JSReceiver> ffi) { |
| 953 //------------------------------------------------------------------------- | 954 //------------------------------------------------------------------------- |
| 954 // Compile wrappers to imported functions. | 955 // Compile wrappers to imported functions. |
| 955 //------------------------------------------------------------------------- | 956 //------------------------------------------------------------------------- |
| 956 std::vector<Handle<Code>> import_code; | 957 std::vector<Handle<Code>> import_code; |
| 957 MaybeHandle<FixedArray> maybe_import_data = | 958 MaybeHandle<FixedArray> maybe_import_data = |
| 958 compiled_module->GetValue<FixedArray>(isolate, kImportData); | 959 compiled_module->GetValue<FixedArray>(isolate, kImportData); |
| 959 Handle<FixedArray> import_data; | 960 Handle<FixedArray> import_data; |
| 960 if (maybe_import_data.ToHandle(&import_data)) { | 961 if (maybe_import_data.ToHandle(&import_data)) { |
| 961 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code, | 962 if (!CompileWrappersToImportedFunctions(isolate, context, ffi, import_code, |
| 962 import_data, thrower)) { | 963 import_data, thrower)) { |
| 963 return false; | 964 return false; |
| 964 } | 965 } |
| 965 } | 966 } |
| 966 | 967 |
| 967 RecordStats(isolate, import_code); | 968 RecordStats(isolate, import_code); |
| 968 | 969 |
| 969 Handle<FixedArray> code_table = Handle<FixedArray>( | 970 Handle<FixedArray> code_table = Handle<FixedArray>( |
| 970 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); | 971 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); |
| 971 // TODO(mtrofin): get the code off std::vector and on FixedArray, for | 972 // TODO(mtrofin): get the code off std::vector and on FixedArray, for |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1316 } | 1317 } |
| 1317 return clone; | 1318 return clone; |
| 1318 } | 1319 } |
| 1319 | 1320 |
| 1320 // Instantiates a wasm module as a JSObject. | 1321 // Instantiates a wasm module as a JSObject. |
| 1321 // * allocates a backing store of {mem_size} bytes. | 1322 // * allocates a backing store of {mem_size} bytes. |
| 1322 // * installs a named property "memory" for that buffer if exported | 1323 // * installs a named property "memory" for that buffer if exported |
| 1323 // * installs named properties on the object for exported functions | 1324 // * installs named properties on the object for exported functions |
| 1324 // * compiles wasm code to machine code | 1325 // * compiles wasm code to machine code |
| 1325 MaybeHandle<JSObject> WasmModule::Instantiate( | 1326 MaybeHandle<JSObject> WasmModule::Instantiate( |
| 1326 Isolate* isolate, Handle<FixedArray> compiled_module, | 1327 Isolate* isolate, Handle<Context> context, |
| 1327 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) { | 1328 Handle<FixedArray> compiled_module, Handle<JSReceiver> ffi, |
| 1329 Handle<JSArrayBuffer> memory) { |
| 1328 HistogramTimerScope wasm_instantiate_module_time_scope( | 1330 HistogramTimerScope wasm_instantiate_module_time_scope( |
| 1329 isolate->counters()->wasm_instantiate_module_time()); | 1331 isolate->counters()->wasm_instantiate_module_time()); |
| 1330 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); | 1332 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); |
| 1331 Factory* factory = isolate->factory(); | 1333 Factory* factory = isolate->factory(); |
| 1332 | 1334 |
| 1333 compiled_module = CloneModuleForInstance(isolate, compiled_module); | 1335 compiled_module = CloneModuleForInstance(isolate, compiled_module); |
| 1334 | 1336 |
| 1335 // These fields are compulsory. | 1337 // These fields are compulsory. |
| 1336 Handle<FixedArray> code_table = | 1338 Handle<FixedArray> code_table = |
| 1337 compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions); | 1339 compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1350 | 1352 |
| 1351 Handle<Map> map = factory->NewMap( | 1353 Handle<Map> map = factory->NewMap( |
| 1352 JS_OBJECT_TYPE, | 1354 JS_OBJECT_TYPE, |
| 1353 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); | 1355 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); |
| 1354 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); | 1356 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); |
| 1355 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); | 1357 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); |
| 1356 | 1358 |
| 1357 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, | 1359 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, |
| 1358 &thrower) && | 1360 &thrower) && |
| 1359 SetupGlobals(isolate, compiled_module, js_object, &thrower) && | 1361 SetupGlobals(isolate, compiled_module, js_object, &thrower) && |
| 1360 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) && | 1362 SetupImports(isolate, context, compiled_module, js_object, &thrower, |
| 1363 ffi) && |
| 1361 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { | 1364 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { |
| 1362 return nothing; | 1365 return nothing; |
| 1363 } | 1366 } |
| 1364 | 1367 |
| 1365 SetDebugSupport(factory, compiled_module, js_object); | 1368 SetDebugSupport(factory, compiled_module, js_object); |
| 1366 | 1369 |
| 1367 FlushAssemblyCache(isolate, code_table); | 1370 FlushAssemblyCache(isolate, code_table); |
| 1368 | 1371 |
| 1369 MaybeHandle<FixedArray> maybe_indirect_tables = | 1372 MaybeHandle<FixedArray> maybe_indirect_tables = |
| 1370 compiled_module->GetValue<FixedArray>(isolate, | 1373 compiled_module->GetValue<FixedArray>(isolate, |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1616 if (module->export_table.size() == 0) { | 1619 if (module->export_table.size() == 0) { |
| 1617 thrower.Error("Not supported: module has no exports."); | 1620 thrower.Error("Not supported: module has no exports."); |
| 1618 } | 1621 } |
| 1619 | 1622 |
| 1620 if (thrower.error()) return -1; | 1623 if (thrower.error()) return -1; |
| 1621 MaybeHandle<FixedArray> compiled_module = | 1624 MaybeHandle<FixedArray> compiled_module = |
| 1622 module->CompileFunctions(isolate, &thrower); | 1625 module->CompileFunctions(isolate, &thrower); |
| 1623 | 1626 |
| 1624 if (compiled_module.is_null()) return -1; | 1627 if (compiled_module.is_null()) return -1; |
| 1625 Handle<JSObject> instance = | 1628 Handle<JSObject> instance = |
| 1626 WasmModule::Instantiate(isolate, compiled_module.ToHandleChecked(), | 1629 WasmModule::Instantiate(isolate, handle(isolate->context(), isolate), |
| 1630 compiled_module.ToHandleChecked(), |
| 1627 Handle<JSReceiver>::null(), | 1631 Handle<JSReceiver>::null(), |
| 1628 Handle<JSArrayBuffer>::null()) | 1632 Handle<JSArrayBuffer>::null()) |
| 1629 .ToHandleChecked(); | 1633 .ToHandleChecked(); |
| 1630 | 1634 |
| 1631 return CallFunction(isolate, instance, &thrower, "main", 0, nullptr); | 1635 return CallFunction(isolate, instance, &thrower, "main", 0, nullptr); |
| 1632 } | 1636 } |
| 1633 | 1637 |
| 1634 int32_t CallFunction(Isolate* isolate, Handle<JSObject> instance, | 1638 int32_t CallFunction(Isolate* isolate, Handle<JSObject> instance, |
| 1635 ErrorThrower* thrower, const char* name, int argc, | 1639 ErrorThrower* thrower, const char* name, int argc, |
| 1636 Handle<Object> argv[]) { | 1640 Handle<Object> argv[]) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1663 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); | 1667 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); |
| 1664 } | 1668 } |
| 1665 thrower->Error("WASM.compileRun() failed: Return value should be number"); | 1669 thrower->Error("WASM.compileRun() failed: Return value should be number"); |
| 1666 return -1; | 1670 return -1; |
| 1667 } | 1671 } |
| 1668 | 1672 |
| 1669 } // namespace testing | 1673 } // namespace testing |
| 1670 } // namespace wasm | 1674 } // namespace wasm |
| 1671 } // namespace internal | 1675 } // namespace internal |
| 1672 } // namespace v8 | 1676 } // namespace v8 |
| OLD | NEW |