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 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1120 // TODO(wasm): saving the module bytes for debugging is wasteful. We should | 1120 // TODO(wasm): saving the module bytes for debugging is wasteful. We should |
1121 // consider downloading this on-demand. | 1121 // consider downloading this on-demand. |
1122 { | 1122 { |
1123 size_t module_bytes_len = module_end - module_start; | 1123 size_t module_bytes_len = module_end - module_start; |
1124 DCHECK_LE(module_bytes_len, static_cast<size_t>(kMaxInt)); | 1124 DCHECK_LE(module_bytes_len, static_cast<size_t>(kMaxInt)); |
1125 Vector<const uint8_t> module_bytes_vec(module_start, | 1125 Vector<const uint8_t> module_bytes_vec(module_start, |
1126 static_cast<int>(module_bytes_len)); | 1126 static_cast<int>(module_bytes_len)); |
1127 Handle<String> module_bytes_string = | 1127 Handle<String> module_bytes_string = |
1128 factory->NewStringFromOneByte(module_bytes_vec, TENURED) | 1128 factory->NewStringFromOneByte(module_bytes_vec, TENURED) |
1129 .ToHandleChecked(); | 1129 .ToHandleChecked(); |
1130 ret->set_module_bytes(module_bytes_string); | 1130 DCHECK(module_bytes_string->IsSeqOneByteString()); |
| 1131 ret->set_module_bytes(Handle<SeqOneByteString>::cast(module_bytes_string)); |
1131 } | 1132 } |
1132 | 1133 |
1133 Handle<ByteArray> function_name_table = | 1134 Handle<ByteArray> function_name_table = |
1134 BuildFunctionNamesTable(isolate, module_env.module); | 1135 BuildFunctionNamesTable(isolate, module_env.module); |
1135 ret->set_function_names(function_name_table); | 1136 ret->set_function_names(function_name_table); |
1136 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret); | 1137 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret); |
1137 DCHECK_EQ(ret->default_mem_size(), temp_instance.mem_size); | 1138 DCHECK_EQ(ret->default_mem_size(), temp_instance.mem_size); |
1138 return ret; | 1139 return ret; |
1139 } | 1140 } |
1140 | 1141 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1301 if (num_imported_functions < 0) return nothing; | 1302 if (num_imported_functions < 0) return nothing; |
1302 | 1303 |
1303 //-------------------------------------------------------------------------- | 1304 //-------------------------------------------------------------------------- |
1304 // Process the initialization for the module's globals. | 1305 // Process the initialization for the module's globals. |
1305 //-------------------------------------------------------------------------- | 1306 //-------------------------------------------------------------------------- |
1306 ProcessInits(globals); | 1307 ProcessInits(globals); |
1307 | 1308 |
1308 //-------------------------------------------------------------------------- | 1309 //-------------------------------------------------------------------------- |
1309 // Set up the debug support for the new instance. | 1310 // Set up the debug support for the new instance. |
1310 //-------------------------------------------------------------------------- | 1311 //-------------------------------------------------------------------------- |
1311 // TODO(wasm): avoid referencing this stuff from the instance, use it off | 1312 // TODO(clemensh): avoid referencing this stuff from the instance, use it |
1312 // the compiled module instead. See the following 3 assignments: | 1313 // off the compiled module instead. See the following 3 assignments: |
1313 if (compiled_module_->has_module_bytes()) { | 1314 if (compiled_module_->has_module_bytes()) { |
1314 instance->SetInternalField(kWasmModuleBytesString, | 1315 instance->SetInternalField(kWasmModuleBytesString, |
1315 compiled_module_->ptr_to_module_bytes()); | 1316 compiled_module_->ptr_to_module_bytes()); |
1316 } | 1317 } |
1317 | 1318 |
1318 if (compiled_module_->has_function_names()) { | 1319 if (compiled_module_->has_function_names()) { |
1319 instance->SetInternalField(kWasmFunctionNamesArray, | 1320 instance->SetInternalField(kWasmFunctionNamesArray, |
1320 compiled_module_->ptr_to_function_names()); | 1321 compiled_module_->ptr_to_function_names()); |
1321 } | 1322 } |
1322 | 1323 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 Handle<Object> undefined = factory->undefined_value(); | 1407 Handle<Object> undefined = factory->undefined_value(); |
1407 MaybeHandle<Object> retval = | 1408 MaybeHandle<Object> retval = |
1408 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); | 1409 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); |
1409 | 1410 |
1410 if (retval.is_null()) { | 1411 if (retval.is_null()) { |
1411 thrower_->Error("WASM.instantiateModule(): start function failed"); | 1412 thrower_->Error("WASM.instantiateModule(): start function failed"); |
1412 return nothing; | 1413 return nothing; |
1413 } | 1414 } |
1414 } | 1415 } |
1415 | 1416 |
1416 DCHECK(wasm::IsWasmObject(*instance)); | |
1417 | |
1418 { | 1417 { |
1419 Handle<WeakCell> link_to_owner = factory->NewWeakCell(instance); | 1418 Handle<WeakCell> link_to_owner = factory->NewWeakCell(instance); |
1420 | 1419 |
1421 Handle<Object> global_handle = | 1420 Handle<Object> global_handle = |
1422 isolate_->global_handles()->Create(*instance); | 1421 isolate_->global_handles()->Create(*instance); |
1423 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module_); | 1422 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module_); |
1424 { | 1423 { |
1425 DisallowHeapAllocation no_gc; | 1424 DisallowHeapAllocation no_gc; |
1426 compiled_module_->set_weak_owning_instance(link_to_owner); | 1425 compiled_module_->set_weak_owning_instance(link_to_owner); |
1427 Handle<WeakCell> next; | 1426 Handle<WeakCell> next; |
1428 if (link_to_original.ToHandle(&next) && !next->cleared()) { | 1427 if (link_to_original.ToHandle(&next) && !next->cleared()) { |
1429 WasmCompiledModule* original = | 1428 WasmCompiledModule* original = |
1430 WasmCompiledModule::cast(next->value()); | 1429 WasmCompiledModule::cast(next->value()); |
1431 DCHECK(original->has_weak_owning_instance()); | 1430 DCHECK(original->has_weak_owning_instance()); |
1432 DCHECK(!original->weak_owning_instance()->cleared()); | 1431 DCHECK(!original->weak_owning_instance()->cleared()); |
1433 compiled_module_->set_weak_next_instance(next); | 1432 compiled_module_->set_weak_next_instance(next); |
1434 original->set_weak_prev_instance(link_to_clone); | 1433 original->set_weak_prev_instance(link_to_clone); |
1435 } | 1434 } |
1436 | 1435 |
1437 compiled_module_->set_weak_owning_instance(link_to_owner); | 1436 compiled_module_->set_weak_owning_instance(link_to_owner); |
1438 instance->SetInternalField(kWasmCompiledModule, *compiled_module_); | 1437 instance->SetInternalField(kWasmCompiledModule, *compiled_module_); |
1439 GlobalHandles::MakeWeak(global_handle.location(), | 1438 GlobalHandles::MakeWeak(global_handle.location(), |
1440 global_handle.location(), &InstanceFinalizer, | 1439 global_handle.location(), &InstanceFinalizer, |
1441 v8::WeakCallbackType::kFinalizer); | 1440 v8::WeakCallbackType::kFinalizer); |
1442 } | 1441 } |
1443 } | 1442 } |
| 1443 |
| 1444 DCHECK(wasm::IsWasmObject(*instance)); |
| 1445 |
1444 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); | 1446 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); |
1445 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); | 1447 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); |
1446 return instance; | 1448 return instance; |
1447 } | 1449 } |
1448 | 1450 |
1449 private: | 1451 private: |
1450 Isolate* isolate_; | 1452 Isolate* isolate_; |
1451 ErrorThrower* thrower_; | 1453 ErrorThrower* thrower_; |
1452 Handle<JSObject> module_object_; | 1454 Handle<JSObject> module_object_; |
1453 Handle<JSReceiver> ffi_; | 1455 Handle<JSReceiver> ffi_; |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1864 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED); | 1866 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED); |
1865 // Globals size is expected to fit into an int without overflow. This is not | 1867 // Globals size is expected to fit into an int without overflow. This is not |
1866 // supported by the spec at the moment, however, we don't support array | 1868 // supported by the spec at the moment, however, we don't support array |
1867 // buffer sizes over 1g, so, for now, we avoid alocating a HeapNumber for | 1869 // buffer sizes over 1g, so, for now, we avoid alocating a HeapNumber for |
1868 // the globals size. The CHECK guards this assumption. | 1870 // the globals size. The CHECK guards this assumption. |
1869 CHECK_GE(static_cast<int>(globals_size), 0); | 1871 CHECK_GE(static_cast<int>(globals_size), 0); |
1870 ret->set(kID_min_memory_pages, | 1872 ret->set(kID_min_memory_pages, |
1871 Smi::FromInt(static_cast<int>(min_memory_pages))); | 1873 Smi::FromInt(static_cast<int>(min_memory_pages))); |
1872 ret->set(kID_globals_size, Smi::FromInt(static_cast<int>(globals_size))); | 1874 ret->set(kID_globals_size, Smi::FromInt(static_cast<int>(globals_size))); |
1873 ret->set(kID_origin, Smi::FromInt(static_cast<int>(origin))); | 1875 ret->set(kID_origin, Smi::FromInt(static_cast<int>(origin))); |
1874 WasmCompiledModule::cast(*ret)->Init(); | 1876 |
1875 return handle(WasmCompiledModule::cast(*ret)); | 1877 // WasmCompiledModule::cast would fail since module bytes are not set yet. |
| 1878 Handle<WasmCompiledModule> module(reinterpret_cast<WasmCompiledModule*>(*ret), |
| 1879 isolate); |
| 1880 module->Init(); |
| 1881 return module; |
1876 } | 1882 } |
1877 | 1883 |
1878 void WasmCompiledModule::Init() { | 1884 void WasmCompiledModule::Init() { |
1879 #if DEBUG | 1885 #if DEBUG |
1880 static uint32_t instance_id_counter = 0; | 1886 static uint32_t instance_id_counter = 0; |
1881 set(kID_instance_id, Smi::FromInt(instance_id_counter++)); | 1887 set(kID_instance_id, Smi::FromInt(instance_id_counter++)); |
1882 TRACE("New compiled module id: %d\n", instance_id()); | 1888 TRACE("New compiled module id: %d\n", instance_id()); |
1883 #endif | 1889 #endif |
1884 } | 1890 } |
1885 | 1891 |
| 1892 bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) { |
| 1893 if (!obj->IsFixedArray()) return false; |
| 1894 FixedArray* arr = FixedArray::cast(obj); |
| 1895 if (arr->length() != PropertyIndices::Count) return false; |
| 1896 Isolate* isolate = arr->GetIsolate(); |
| 1897 #define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) \ |
| 1898 if (!arr->get(kID_##NAME)->IsSmi()) return false; |
| 1899 #define WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) \ |
| 1900 if (!arr->get(kID_##NAME)->IsUndefined(isolate) && \ |
| 1901 !arr->get(kID_##NAME)->Is##TYPE()) \ |
| 1902 return false; |
| 1903 #define WCM_CHECK_OBJECT(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) |
| 1904 #define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(WeakCell, NAME) |
| 1905 #define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME) |
| 1906 WCM_PROPERTY_TABLE(WCM_CHECK) |
| 1907 #undef WCM_CHECK |
| 1908 |
| 1909 WasmCompiledModule* compiled_module = |
| 1910 reinterpret_cast<WasmCompiledModule*>(obj); |
| 1911 if (!compiled_module->has_module_bytes()) return false; |
| 1912 SeqOneByteString* module_bytes = compiled_module->ptr_to_module_bytes(); |
| 1913 if (module_bytes->length() < 4) return false; |
| 1914 if (memcmp(module_bytes->GetChars(), "\0asm", 4)) return false; |
| 1915 |
| 1916 // All checks passed. |
| 1917 return true; |
| 1918 } |
| 1919 |
1886 void WasmCompiledModule::PrintInstancesChain() { | 1920 void WasmCompiledModule::PrintInstancesChain() { |
1887 #if DEBUG | 1921 #if DEBUG |
1888 if (!FLAG_trace_wasm_instances) return; | 1922 if (!FLAG_trace_wasm_instances) return; |
1889 for (WasmCompiledModule* current = this; current != nullptr;) { | 1923 for (WasmCompiledModule* current = this; current != nullptr;) { |
1890 PrintF("->%d", current->instance_id()); | 1924 PrintF("->%d", current->instance_id()); |
1891 if (current->ptr_to_weak_next_instance() == nullptr) break; | 1925 if (current->ptr_to_weak_next_instance() == nullptr) break; |
1892 CHECK(!current->ptr_to_weak_next_instance()->cleared()); | 1926 CHECK(!current->ptr_to_weak_next_instance()->cleared()); |
1893 current = | 1927 current = |
1894 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value()); | 1928 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value()); |
1895 } | 1929 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1928 bool IsWasmObject(Object* object) { | 1962 bool IsWasmObject(Object* object) { |
1929 if (!object->IsJSObject()) return false; | 1963 if (!object->IsJSObject()) return false; |
1930 | 1964 |
1931 JSObject* obj = JSObject::cast(object); | 1965 JSObject* obj = JSObject::cast(object); |
1932 Isolate* isolate = obj->GetIsolate(); | 1966 Isolate* isolate = obj->GetIsolate(); |
1933 if (obj->GetInternalFieldCount() != kWasmModuleInternalFieldCount) { | 1967 if (obj->GetInternalFieldCount() != kWasmModuleInternalFieldCount) { |
1934 return false; | 1968 return false; |
1935 } | 1969 } |
1936 | 1970 |
1937 Object* mem = obj->GetInternalField(kWasmMemArrayBuffer); | 1971 Object* mem = obj->GetInternalField(kWasmMemArrayBuffer); |
1938 if (obj->GetInternalField(kWasmModuleCodeTable)->IsFixedArray() && | 1972 if (!obj->GetInternalField(kWasmModuleCodeTable)->IsFixedArray() || |
1939 (mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) && | 1973 !(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) || |
1940 obj->GetInternalField(kWasmFunctionNamesArray)->IsByteArray()) { | 1974 !obj->GetInternalField(kWasmFunctionNamesArray)->IsByteArray() || |
1941 Object* debug_bytes = obj->GetInternalField(kWasmModuleBytesString); | 1975 !WasmCompiledModule::IsWasmCompiledModule( |
1942 if (!debug_bytes->IsUndefined(isolate)) { | 1976 obj->GetInternalField(kWasmCompiledModule))) { |
1943 if (!debug_bytes->IsSeqOneByteString()) { | 1977 return false; |
1944 return false; | |
1945 } | |
1946 DisallowHeapAllocation no_gc; | |
1947 SeqOneByteString* bytes = SeqOneByteString::cast(debug_bytes); | |
1948 if (bytes->length() < 4) return false; | |
1949 if (memcmp(bytes->GetChars(), "\0asm", 4)) return false; | |
1950 // All checks passed. | |
1951 } | |
1952 return true; | |
1953 } | 1978 } |
1954 return false; | 1979 |
| 1980 // All checks passed. |
| 1981 return true; |
1955 } | 1982 } |
1956 | 1983 |
1957 SeqOneByteString* GetWasmBytes(JSObject* wasm) { | 1984 SeqOneByteString* GetWasmBytes(JSObject* wasm) { |
1958 return SeqOneByteString::cast(wasm->GetInternalField(kWasmModuleBytesString)); | 1985 return SeqOneByteString::cast(wasm->GetInternalField(kWasmModuleBytesString)); |
1959 } | 1986 } |
1960 | 1987 |
1961 Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm) { | 1988 Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm) { |
1962 Handle<Object> info(wasm->GetInternalField(kWasmDebugInfo), | 1989 Handle<Object> info(wasm->GetInternalField(kWasmDebugInfo), |
1963 wasm->GetIsolate()); | 1990 wasm->GetIsolate()); |
1964 if (!info->IsUndefined(wasm->GetIsolate())) | 1991 if (!info->IsUndefined(wasm->GetIsolate())) |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2224 WasmCompiledModule* compiled_module = | 2251 WasmCompiledModule* compiled_module = |
2225 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); | 2252 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); |
2226 CHECK(compiled_module->has_weak_module_object()); | 2253 CHECK(compiled_module->has_weak_module_object()); |
2227 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); | 2254 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); |
2228 } | 2255 } |
2229 | 2256 |
2230 } // namespace testing | 2257 } // namespace testing |
2231 } // namespace wasm | 2258 } // namespace wasm |
2232 } // namespace internal | 2259 } // namespace internal |
2233 } // namespace v8 | 2260 } // namespace v8 |
OLD | NEW |