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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 kInternalSignature | 48 kInternalSignature |
49 }; | 49 }; |
50 | 50 |
51 // Internal constants for the layout of the module object. | 51 // Internal constants for the layout of the module object. |
52 enum WasmInstanceObjectFields { | 52 enum WasmInstanceObjectFields { |
53 kWasmCompiledModule = 0, | 53 kWasmCompiledModule = 0, |
54 kWasmModuleFunctionTable, | 54 kWasmModuleFunctionTable, |
55 kWasmModuleCodeTable, | 55 kWasmModuleCodeTable, |
56 kWasmMemArrayBuffer, | 56 kWasmMemArrayBuffer, |
57 kWasmGlobalsArrayBuffer, | 57 kWasmGlobalsArrayBuffer, |
58 // TODO(clemensh): Remove function name array, extract names from module | |
59 // bytes. | |
60 kWasmFunctionNamesArray, | |
61 kWasmModuleBytesString, | |
62 kWasmDebugInfo, | 58 kWasmDebugInfo, |
63 kWasmNumImportedFunctions, | |
64 kWasmModuleInternalFieldCount | 59 kWasmModuleInternalFieldCount |
65 }; | 60 }; |
66 | 61 |
67 enum WasmImportData { | 62 enum WasmImportData { |
68 kImportKind, // Smi. an ExternalKind | 63 kImportKind, // Smi. an ExternalKind |
69 kImportGlobalType, // Smi. Type for globals. | 64 kImportGlobalType, // Smi. Type for globals. |
70 kImportIndex, // Smi. index for the import. | 65 kImportIndex, // Smi. index for the import. |
71 kModuleName, // String | 66 kModuleName, // String |
72 kFunctionName, // maybe String | 67 kFunctionName, // maybe String |
73 kOutputCount, // Smi. an uint32_t | 68 kOutputCount, // Smi. an uint32_t |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 Address old_address = nullptr; | 340 Address old_address = nullptr; |
346 Object* stored_value = owner->GetInternalField(kWasmGlobalsArrayBuffer); | 341 Object* stored_value = owner->GetInternalField(kWasmGlobalsArrayBuffer); |
347 if (stored_value != undefined) { | 342 if (stored_value != undefined) { |
348 old_address = static_cast<Address>( | 343 old_address = static_cast<Address>( |
349 JSArrayBuffer::cast(stored_value)->backing_store()); | 344 JSArrayBuffer::cast(stored_value)->backing_store()); |
350 } | 345 } |
351 return old_address; | 346 return old_address; |
352 } | 347 } |
353 | 348 |
354 Handle<FixedArray> EncodeImports(Factory* factory, const WasmModule* module) { | 349 Handle<FixedArray> EncodeImports(Factory* factory, const WasmModule* module) { |
| 350 // TODO(wasm): Encode this in one big FixedArray. |
355 Handle<FixedArray> ret = factory->NewFixedArray( | 351 Handle<FixedArray> ret = factory->NewFixedArray( |
356 static_cast<int>(module->import_table.size()), TENURED); | 352 static_cast<int>(module->import_table.size()), TENURED); |
357 | 353 |
358 for (size_t i = 0; i < module->import_table.size(); ++i) { | 354 for (size_t i = 0; i < module->import_table.size(); ++i) { |
359 const WasmImport& import = module->import_table[i]; | 355 const WasmImport& import = module->import_table[i]; |
360 Handle<FixedArray> encoded_import = | 356 Handle<FixedArray> encoded_import = |
361 factory->NewFixedArray(kWasmImportDataSize, TENURED); | 357 factory->NewFixedArray(kWasmImportDataSize, TENURED); |
362 encoded_import->set(kImportKind, Smi::FromInt(import.kind)); | 358 encoded_import->set(kImportKind, Smi::FromInt(import.kind)); |
363 encoded_import->set(kImportIndex, Smi::FromInt(import.index)); | 359 encoded_import->set(kImportIndex, Smi::FromInt(import.index)); |
364 | 360 |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 DisallowHeapAllocation no_gc; | 841 DisallowHeapAllocation no_gc; |
846 FixedArray* deopt_data = code->deoptimization_data(); | 842 FixedArray* deopt_data = code->deoptimization_data(); |
847 DCHECK_NOT_NULL(deopt_data); | 843 DCHECK_NOT_NULL(deopt_data); |
848 DCHECK(deopt_data->length() == 2); | 844 DCHECK(deopt_data->length() == 2); |
849 Object* weak_link = deopt_data->get(0); | 845 Object* weak_link = deopt_data->get(0); |
850 if (!weak_link->IsWeakCell()) return nullptr; | 846 if (!weak_link->IsWeakCell()) return nullptr; |
851 WeakCell* cell = WeakCell::cast(weak_link); | 847 WeakCell* cell = WeakCell::cast(weak_link); |
852 return cell->value(); | 848 return cell->value(); |
853 } | 849 } |
854 | 850 |
855 uint32_t GetNumImportedFunctions(Handle<JSObject> wasm_object) { | 851 int GetNumImportedFunctions(Handle<JSObject> wasm_object) { |
856 return static_cast<uint32_t>( | 852 // TODO(wasm): Cache this number if it ever becomes a performance problem. |
857 Smi::cast(wasm_object->GetInternalField(kWasmNumImportedFunctions)) | 853 DCHECK(IsWasmObject(*wasm_object)); |
858 ->value()); | 854 Object* compiled_module = wasm_object->GetInternalField(kWasmCompiledModule); |
| 855 Handle<FixedArray> imports = |
| 856 WasmCompiledModule::cast(compiled_module)->imports(); |
| 857 int num_imports = imports->length(); |
| 858 int num_imported_functions = 0; |
| 859 for (int i = 0; i < num_imports; ++i) { |
| 860 FixedArray* encoded_import = FixedArray::cast(imports->get(i)); |
| 861 int kind = Smi::cast(encoded_import->get(kImportKind))->value(); |
| 862 if (kind == kExternalFunction) ++num_imported_functions; |
| 863 } |
| 864 return num_imported_functions; |
859 } | 865 } |
860 | 866 |
861 WasmModule::WasmModule(byte* module_start) | 867 WasmModule::WasmModule(byte* module_start) |
862 : module_start(module_start), | 868 : module_start(module_start), |
863 module_end(nullptr), | 869 module_end(nullptr), |
864 min_mem_pages(0), | 870 min_mem_pages(0), |
865 max_mem_pages(0), | 871 max_mem_pages(0), |
866 mem_export(false), | 872 mem_export(false), |
867 start_function_index(-1), | 873 start_function_index(-1), |
868 origin(kWasmOrigin), | 874 origin(kWasmOrigin), |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 //-------------------------------------------------------------------------- | 1306 //-------------------------------------------------------------------------- |
1301 int num_imported_functions = ProcessImports(globals, code_table); | 1307 int num_imported_functions = ProcessImports(globals, code_table); |
1302 if (num_imported_functions < 0) return nothing; | 1308 if (num_imported_functions < 0) return nothing; |
1303 | 1309 |
1304 //-------------------------------------------------------------------------- | 1310 //-------------------------------------------------------------------------- |
1305 // Process the initialization for the module's globals. | 1311 // Process the initialization for the module's globals. |
1306 //-------------------------------------------------------------------------- | 1312 //-------------------------------------------------------------------------- |
1307 ProcessInits(globals); | 1313 ProcessInits(globals); |
1308 | 1314 |
1309 //-------------------------------------------------------------------------- | 1315 //-------------------------------------------------------------------------- |
1310 // Set up the debug support for the new instance. | |
1311 //-------------------------------------------------------------------------- | |
1312 // TODO(clemensh): avoid referencing this stuff from the instance, use it | |
1313 // off the compiled module instead. See the following 3 assignments: | |
1314 if (compiled_module_->has_module_bytes()) { | |
1315 instance->SetInternalField(kWasmModuleBytesString, | |
1316 compiled_module_->ptr_to_module_bytes()); | |
1317 } | |
1318 | |
1319 if (compiled_module_->has_function_names()) { | |
1320 instance->SetInternalField(kWasmFunctionNamesArray, | |
1321 compiled_module_->ptr_to_function_names()); | |
1322 } | |
1323 | |
1324 { | |
1325 Handle<Object> handle = factory->NewNumber(num_imported_functions); | |
1326 instance->SetInternalField(kWasmNumImportedFunctions, *handle); | |
1327 } | |
1328 | |
1329 //-------------------------------------------------------------------------- | |
1330 // Set up the runtime support for the new instance. | 1316 // Set up the runtime support for the new instance. |
1331 //-------------------------------------------------------------------------- | 1317 //-------------------------------------------------------------------------- |
1332 Handle<WeakCell> weak_link = factory->NewWeakCell(instance); | 1318 Handle<WeakCell> weak_link = factory->NewWeakCell(instance); |
1333 | 1319 |
1334 for (int i = num_imported_functions + FLAG_skip_compiling_wasm_funcs; | 1320 for (int i = num_imported_functions + FLAG_skip_compiling_wasm_funcs; |
1335 i < code_table->length(); ++i) { | 1321 i < code_table->length(); ++i) { |
1336 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i); | 1322 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i); |
1337 if (code->kind() == Code::WASM_FUNCTION) { | 1323 if (code->kind() == Code::WASM_FUNCTION) { |
1338 Handle<FixedArray> deopt_data = factory->NewFixedArray(2, TENURED); | 1324 Handle<FixedArray> deopt_data = factory->NewFixedArray(2, TENURED); |
1339 deopt_data->set(0, *weak_link); | 1325 deopt_data->set(0, *weak_link); |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1927 current = | 1913 current = |
1928 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value()); | 1914 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value()); |
1929 } | 1915 } |
1930 PrintF("\n"); | 1916 PrintF("\n"); |
1931 #endif | 1917 #endif |
1932 } | 1918 } |
1933 | 1919 |
1934 Handle<Object> GetWasmFunctionNameOrNull(Isolate* isolate, Handle<Object> wasm, | 1920 Handle<Object> GetWasmFunctionNameOrNull(Isolate* isolate, Handle<Object> wasm, |
1935 uint32_t func_index) { | 1921 uint32_t func_index) { |
1936 if (!wasm->IsUndefined(isolate)) { | 1922 if (!wasm->IsUndefined(isolate)) { |
1937 Handle<ByteArray> func_names_arr_obj( | 1923 DCHECK(IsWasmObject(*wasm)); |
1938 ByteArray::cast(Handle<JSObject>::cast(wasm)->GetInternalField( | 1924 WasmCompiledModule* compiled_module = WasmCompiledModule::cast( |
1939 kWasmFunctionNamesArray)), | 1925 Handle<JSObject>::cast(wasm)->GetInternalField(kWasmCompiledModule)); |
1940 isolate); | 1926 Handle<ByteArray> func_names = compiled_module->function_names(); |
1941 // TODO(clemens): Extract this from the module bytes; skip whole function | 1927 // TODO(clemens): Extract this from the module bytes; skip whole function |
1942 // name table. | 1928 // name table. |
1943 Handle<Object> name; | 1929 Handle<Object> name; |
1944 if (GetWasmFunctionNameFromTable(func_names_arr_obj, func_index) | 1930 if (GetWasmFunctionNameFromTable(func_names, func_index).ToHandle(&name)) { |
1945 .ToHandle(&name)) { | |
1946 return name; | 1931 return name; |
1947 } | 1932 } |
1948 } | 1933 } |
1949 return isolate->factory()->null_value(); | 1934 return isolate->factory()->null_value(); |
1950 } | 1935 } |
1951 | 1936 |
1952 Handle<String> GetWasmFunctionName(Isolate* isolate, Handle<Object> wasm, | 1937 Handle<String> GetWasmFunctionName(Isolate* isolate, Handle<Object> wasm, |
1953 uint32_t func_index) { | 1938 uint32_t func_index) { |
1954 Handle<Object> name_or_null = | 1939 Handle<Object> name_or_null = |
1955 GetWasmFunctionNameOrNull(isolate, wasm, func_index); | 1940 GetWasmFunctionNameOrNull(isolate, wasm, func_index); |
1956 if (!name_or_null->IsNull(isolate)) { | 1941 if (!name_or_null->IsNull(isolate)) { |
1957 return Handle<String>::cast(name_or_null); | 1942 return Handle<String>::cast(name_or_null); |
1958 } | 1943 } |
1959 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); | 1944 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); |
1960 } | 1945 } |
1961 | 1946 |
1962 bool IsWasmObject(Object* object) { | 1947 bool IsWasmObject(Object* object) { |
1963 if (!object->IsJSObject()) return false; | 1948 if (!object->IsJSObject()) return false; |
1964 | 1949 |
1965 JSObject* obj = JSObject::cast(object); | 1950 JSObject* obj = JSObject::cast(object); |
1966 Isolate* isolate = obj->GetIsolate(); | 1951 Isolate* isolate = obj->GetIsolate(); |
1967 if (obj->GetInternalFieldCount() != kWasmModuleInternalFieldCount) { | 1952 if (obj->GetInternalFieldCount() != kWasmModuleInternalFieldCount) { |
1968 return false; | 1953 return false; |
1969 } | 1954 } |
1970 | 1955 |
1971 Object* mem = obj->GetInternalField(kWasmMemArrayBuffer); | 1956 Object* mem = obj->GetInternalField(kWasmMemArrayBuffer); |
1972 if (!obj->GetInternalField(kWasmModuleCodeTable)->IsFixedArray() || | 1957 if (!obj->GetInternalField(kWasmModuleCodeTable)->IsFixedArray() || |
1973 !(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) || | 1958 !(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) || |
1974 !obj->GetInternalField(kWasmFunctionNamesArray)->IsByteArray() || | |
1975 !WasmCompiledModule::IsWasmCompiledModule( | 1959 !WasmCompiledModule::IsWasmCompiledModule( |
1976 obj->GetInternalField(kWasmCompiledModule))) { | 1960 obj->GetInternalField(kWasmCompiledModule))) { |
1977 return false; | 1961 return false; |
1978 } | 1962 } |
1979 | 1963 |
1980 // All checks passed. | 1964 // All checks passed. |
1981 return true; | 1965 return true; |
1982 } | 1966 } |
1983 | 1967 |
1984 SeqOneByteString* GetWasmBytes(JSObject* wasm) { | 1968 Handle<SeqOneByteString> GetWasmBytes(Handle<JSObject> wasm) { |
1985 return SeqOneByteString::cast(wasm->GetInternalField(kWasmModuleBytesString)); | 1969 DCHECK(IsWasmObject(*wasm)); |
| 1970 Object* compiled_module = wasm->GetInternalField(kWasmCompiledModule); |
| 1971 return WasmCompiledModule::cast(compiled_module)->module_bytes(); |
1986 } | 1972 } |
1987 | 1973 |
1988 Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm) { | 1974 Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm) { |
1989 Handle<Object> info(wasm->GetInternalField(kWasmDebugInfo), | 1975 Handle<Object> info(wasm->GetInternalField(kWasmDebugInfo), |
1990 wasm->GetIsolate()); | 1976 wasm->GetIsolate()); |
1991 if (!info->IsUndefined(wasm->GetIsolate())) | 1977 if (!info->IsUndefined(wasm->GetIsolate())) |
1992 return Handle<WasmDebugInfo>::cast(info); | 1978 return Handle<WasmDebugInfo>::cast(info); |
1993 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(wasm); | 1979 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(wasm); |
1994 wasm->SetInternalField(kWasmDebugInfo, *new_info); | 1980 wasm->SetInternalField(kWasmDebugInfo, *new_info); |
1995 return new_info; | 1981 return new_info; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2054 const std::vector<Handle<Code>>* code_table) { | 2040 const std::vector<Handle<Code>>* code_table) { |
2055 uint32_t max_size = table->length() / 2; | 2041 uint32_t max_size = table->length() / 2; |
2056 for (uint32_t i = max_size; i < max_size + table_size; ++i) { | 2042 for (uint32_t i = max_size; i < max_size + table_size; ++i) { |
2057 int index = Smi::cast(table->get(static_cast<int>(i)))->value(); | 2043 int index = Smi::cast(table->get(static_cast<int>(i)))->value(); |
2058 DCHECK_GE(index, 0); | 2044 DCHECK_GE(index, 0); |
2059 DCHECK_LT(static_cast<size_t>(index), code_table->size()); | 2045 DCHECK_LT(static_cast<size_t>(index), code_table->size()); |
2060 table->set(static_cast<int>(i), *(*code_table)[index]); | 2046 table->set(static_cast<int>(i), *(*code_table)[index]); |
2061 } | 2047 } |
2062 } | 2048 } |
2063 | 2049 |
2064 int GetNumberOfFunctions(JSObject* wasm) { | 2050 int GetNumberOfFunctions(Handle<JSObject> wasm) { |
2065 Object* func_names_obj = wasm->GetInternalField(kWasmFunctionNamesArray); | 2051 DCHECK(IsWasmObject(*wasm)); |
| 2052 WasmCompiledModule* compiled_module = |
| 2053 WasmCompiledModule::cast(wasm->GetInternalField(kWasmCompiledModule)); |
| 2054 ByteArray* func_names_arr = compiled_module->ptr_to_function_names(); |
2066 // TODO(clemensh): this looks inside an array constructed elsewhere. Refactor. | 2055 // TODO(clemensh): this looks inside an array constructed elsewhere. Refactor. |
2067 return ByteArray::cast(func_names_obj)->get_int(0); | 2056 return func_names_arr->get_int(0); |
2068 } | 2057 } |
2069 | 2058 |
2070 Handle<JSObject> CreateCompiledModuleObject(Isolate* isolate, | 2059 Handle<JSObject> CreateCompiledModuleObject(Isolate* isolate, |
2071 Handle<FixedArray> compiled_module, | 2060 Handle<FixedArray> compiled_module, |
2072 ModuleOrigin origin) { | 2061 ModuleOrigin origin) { |
2073 Handle<JSObject> module_obj; | 2062 Handle<JSObject> module_obj; |
2074 if (origin == ModuleOrigin::kWasmOrigin) { | 2063 if (origin == ModuleOrigin::kWasmOrigin) { |
2075 Handle<JSFunction> module_cons( | 2064 Handle<JSFunction> module_cons( |
2076 isolate->native_context()->wasm_module_constructor()); | 2065 isolate->native_context()->wasm_module_constructor()); |
2077 module_obj = isolate->factory()->NewJSObject(module_cons); | 2066 module_obj = isolate->factory()->NewJSObject(module_cons); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2251 WasmCompiledModule* compiled_module = | 2240 WasmCompiledModule* compiled_module = |
2252 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); | 2241 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); |
2253 CHECK(compiled_module->has_weak_module_object()); | 2242 CHECK(compiled_module->has_weak_module_object()); |
2254 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); | 2243 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); |
2255 } | 2244 } |
2256 | 2245 |
2257 } // namespace testing | 2246 } // namespace testing |
2258 } // namespace wasm | 2247 } // namespace wasm |
2259 } // namespace internal | 2248 } // namespace internal |
2260 } // namespace v8 | 2249 } // namespace v8 |
OLD | NEW |