| 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 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 os.write(name.start(), name.length()); | 659 os.write(name.start(), name.length()); |
| 660 } else { | 660 } else { |
| 661 os << "+" << pair.function_->func_index; | 661 os << "+" << pair.function_->func_index; |
| 662 } | 662 } |
| 663 } else { | 663 } else { |
| 664 os << "?"; | 664 os << "?"; |
| 665 } | 665 } |
| 666 return os; | 666 return os; |
| 667 } | 667 } |
| 668 | 668 |
| 669 Object* wasm::GetOwningWasmInstance(Code* code) { | 669 WasmInstanceObject* wasm::GetOwningWasmInstance(Code* code) { |
| 670 DCHECK(code->kind() == Code::WASM_FUNCTION); | 670 DCHECK(code->kind() == Code::WASM_FUNCTION); |
| 671 DisallowHeapAllocation no_gc; | 671 DisallowHeapAllocation no_gc; |
| 672 FixedArray* deopt_data = code->deoptimization_data(); | 672 FixedArray* deopt_data = code->deoptimization_data(); |
| 673 DCHECK_NOT_NULL(deopt_data); | 673 DCHECK_NOT_NULL(deopt_data); |
| 674 DCHECK(deopt_data->length() == 2); | 674 DCHECK(deopt_data->length() == 2); |
| 675 Object* weak_link = deopt_data->get(0); | 675 Object* weak_link = deopt_data->get(0); |
| 676 if (!weak_link->IsWeakCell()) return nullptr; | 676 if (!weak_link->IsWeakCell()) return nullptr; |
| 677 WeakCell* cell = WeakCell::cast(weak_link); | 677 WeakCell* cell = WeakCell::cast(weak_link); |
| 678 return cell->value(); | 678 if (!cell->value()) return nullptr; |
| 679 return WasmInstanceObject::cast(cell->value()); |
| 679 } | 680 } |
| 680 | 681 |
| 681 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, | 682 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, |
| 682 int func_index) { | 683 int func_index) { |
| 683 return GetFunctionOffsetAndLength(compiled_module, func_index).first; | 684 return GetFunctionOffsetAndLength(compiled_module, func_index).first; |
| 684 } | 685 } |
| 685 | 686 |
| 686 bool wasm::GetPositionInfo(Handle<WasmCompiledModule> compiled_module, | 687 bool wasm::GetPositionInfo(Handle<WasmCompiledModule> compiled_module, |
| 687 uint32_t position, Script::PositionInfo* info) { | 688 uint32_t position, Script::PositionInfo* info) { |
| 688 std::vector<WasmFunction>& functions = compiled_module->module()->functions; | 689 std::vector<WasmFunction>& functions = compiled_module->module()->functions; |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 WasmInstanceBuilder(Isolate* isolate, ErrorThrower* thrower, | 952 WasmInstanceBuilder(Isolate* isolate, ErrorThrower* thrower, |
| 952 Handle<JSObject> module_object, Handle<JSReceiver> ffi, | 953 Handle<JSObject> module_object, Handle<JSReceiver> ffi, |
| 953 Handle<JSArrayBuffer> memory) | 954 Handle<JSArrayBuffer> memory) |
| 954 : isolate_(isolate), | 955 : isolate_(isolate), |
| 955 thrower_(thrower), | 956 thrower_(thrower), |
| 956 module_object_(module_object), | 957 module_object_(module_object), |
| 957 ffi_(ffi), | 958 ffi_(ffi), |
| 958 memory_(memory) {} | 959 memory_(memory) {} |
| 959 | 960 |
| 960 // Build an instance, in all of its glory. | 961 // Build an instance, in all of its glory. |
| 961 MaybeHandle<JSObject> Build() { | 962 MaybeHandle<WasmInstanceObject> Build() { |
| 962 MaybeHandle<JSObject> nothing; | 963 MaybeHandle<WasmInstanceObject> nothing; |
| 963 HistogramTimerScope wasm_instantiate_module_time_scope( | 964 HistogramTimerScope wasm_instantiate_module_time_scope( |
| 964 isolate_->counters()->wasm_instantiate_module_time()); | 965 isolate_->counters()->wasm_instantiate_module_time()); |
| 965 Factory* factory = isolate_->factory(); | 966 Factory* factory = isolate_->factory(); |
| 966 | 967 |
| 967 //-------------------------------------------------------------------------- | 968 //-------------------------------------------------------------------------- |
| 968 // Reuse the compiled module (if no owner), otherwise clone. | 969 // Reuse the compiled module (if no owner), otherwise clone. |
| 969 //-------------------------------------------------------------------------- | 970 //-------------------------------------------------------------------------- |
| 970 Handle<FixedArray> code_table; | 971 Handle<FixedArray> code_table; |
| 971 Handle<FixedArray> old_code_table; | 972 Handle<FixedArray> old_code_table; |
| 972 MaybeHandle<WasmInstanceObject> owner; | 973 MaybeHandle<WasmInstanceObject> owner; |
| (...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1826 code, Handle<Object>(old_function_tables->get(j), isolate_), | 1827 code, Handle<Object>(old_function_tables->get(j), isolate_), |
| 1827 Handle<Object>(new_function_tables->get(j), isolate_)); | 1828 Handle<Object>(new_function_tables->get(j), isolate_)); |
| 1828 } | 1829 } |
| 1829 } | 1830 } |
| 1830 compiled_module_->set_function_tables(new_function_tables); | 1831 compiled_module_->set_function_tables(new_function_tables); |
| 1831 } | 1832 } |
| 1832 }; | 1833 }; |
| 1833 | 1834 |
| 1834 // Instantiates a WASM module, creating a WebAssembly.Instance from a | 1835 // Instantiates a WASM module, creating a WebAssembly.Instance from a |
| 1835 // WebAssembly.Module. | 1836 // WebAssembly.Module. |
| 1836 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, | 1837 MaybeHandle<WasmInstanceObject> WasmModule::Instantiate( |
| 1837 ErrorThrower* thrower, | 1838 Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module, |
| 1838 Handle<JSObject> wasm_module, | 1839 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) { |
| 1839 Handle<JSReceiver> ffi, | |
| 1840 Handle<JSArrayBuffer> memory) { | |
| 1841 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); | 1840 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); |
| 1842 return builder.Build(); | 1841 return builder.Build(); |
| 1843 } | 1842 } |
| 1844 | 1843 |
| 1845 Handle<String> wasm::GetWasmFunctionName(Isolate* isolate, | 1844 Handle<String> wasm::GetWasmFunctionName(Isolate* isolate, |
| 1846 Handle<Object> instance_or_undef, | 1845 Handle<Object> instance_or_undef, |
| 1847 uint32_t func_index) { | 1846 uint32_t func_index) { |
| 1848 if (!instance_or_undef->IsUndefined(isolate)) { | 1847 if (!instance_or_undef->IsUndefined(isolate)) { |
| 1849 Handle<WasmCompiledModule> compiled_module( | 1848 Handle<WasmCompiledModule> compiled_module( |
| 1850 Handle<WasmInstanceObject>::cast(instance_or_undef) | 1849 Handle<WasmInstanceObject>::cast(instance_or_undef) |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 ModuleOrigin origin) { | 1992 ModuleOrigin origin) { |
| 1994 ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin); | 1993 ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin); |
| 1995 if (result.val) { | 1994 if (result.val) { |
| 1996 delete result.val; | 1995 delete result.val; |
| 1997 } else { | 1996 } else { |
| 1998 DCHECK(!result.ok()); | 1997 DCHECK(!result.ok()); |
| 1999 } | 1998 } |
| 2000 return result.ok(); | 1999 return result.ok(); |
| 2001 } | 2000 } |
| 2002 | 2001 |
| 2003 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(Isolate* isolate, | 2002 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory( |
| 2004 Handle<JSObject> object) { | 2003 Isolate* isolate, Handle<WasmInstanceObject> instance) { |
| 2005 auto instance = Handle<WasmInstanceObject>::cast(object); | |
| 2006 if (instance->has_memory_buffer()) { | 2004 if (instance->has_memory_buffer()) { |
| 2007 return Handle<JSArrayBuffer>(instance->get_memory_buffer(), isolate); | 2005 return Handle<JSArrayBuffer>(instance->get_memory_buffer(), isolate); |
| 2008 } | 2006 } |
| 2009 return MaybeHandle<JSArrayBuffer>(); | 2007 return MaybeHandle<JSArrayBuffer>(); |
| 2010 } | 2008 } |
| 2011 | 2009 |
| 2012 void SetInstanceMemory(Handle<JSObject> object, JSArrayBuffer* buffer) { | 2010 void SetInstanceMemory(Handle<WasmInstanceObject> instance, |
| 2011 JSArrayBuffer* buffer) { |
| 2013 DisallowHeapAllocation no_gc; | 2012 DisallowHeapAllocation no_gc; |
| 2014 auto instance = Handle<WasmInstanceObject>::cast(object); | |
| 2015 instance->set_memory_buffer(buffer); | 2013 instance->set_memory_buffer(buffer); |
| 2016 instance->get_compiled_module()->set_ptr_to_memory(buffer); | 2014 instance->get_compiled_module()->set_ptr_to_memory(buffer); |
| 2017 } | 2015 } |
| 2018 | 2016 |
| 2019 int32_t wasm::GetInstanceMemorySize(Isolate* isolate, | 2017 int32_t wasm::GetInstanceMemorySize(Isolate* isolate, |
| 2020 Handle<JSObject> instance) { | 2018 Handle<WasmInstanceObject> instance) { |
| 2021 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = | 2019 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = |
| 2022 GetInstanceMemory(isolate, instance); | 2020 GetInstanceMemory(isolate, instance); |
| 2023 Handle<JSArrayBuffer> buffer; | 2021 Handle<JSArrayBuffer> buffer; |
| 2024 if (!maybe_mem_buffer.ToHandle(&buffer)) { | 2022 if (!maybe_mem_buffer.ToHandle(&buffer)) { |
| 2025 return 0; | 2023 return 0; |
| 2026 } else { | 2024 } else { |
| 2027 return buffer->byte_length()->Number() / WasmModule::kPageSize; | 2025 return buffer->byte_length()->Number() / WasmModule::kPageSize; |
| 2028 } | 2026 } |
| 2029 } | 2027 } |
| 2030 | 2028 |
| 2031 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, | 2029 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, |
| 2032 Handle<WasmInstanceObject> instance) { | 2030 Handle<WasmInstanceObject> instance) { |
| 2033 if (instance->has_memory_object()) { | 2031 if (instance->has_memory_object()) { |
| 2034 Handle<WasmMemoryObject> memory_object(instance->get_memory_object(), | 2032 Handle<WasmMemoryObject> memory_object(instance->get_memory_object(), |
| 2035 isolate); | 2033 isolate); |
| 2036 | 2034 |
| 2037 int maximum = memory_object->maximum_pages(); | 2035 int maximum = memory_object->maximum_pages(); |
| 2038 if (maximum > 0) return static_cast<uint32_t>(maximum); | 2036 if (maximum > 0) return static_cast<uint32_t>(maximum); |
| 2039 } | 2037 } |
| 2040 uint32_t compiled_max_pages = | 2038 uint32_t compiled_max_pages = |
| 2041 instance->get_compiled_module()->max_mem_pages(); | 2039 instance->get_compiled_module()->max_mem_pages(); |
| 2042 isolate->counters()->wasm_max_mem_pages_count()->AddSample( | 2040 isolate->counters()->wasm_max_mem_pages_count()->AddSample( |
| 2043 compiled_max_pages); | 2041 compiled_max_pages); |
| 2044 if (compiled_max_pages != 0) return compiled_max_pages; | 2042 if (compiled_max_pages != 0) return compiled_max_pages; |
| 2045 return WasmModule::kV8MaxPages; | 2043 return WasmModule::kV8MaxPages; |
| 2046 } | 2044 } |
| 2047 | 2045 |
| 2048 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> object, | 2046 int32_t wasm::GrowInstanceMemory(Isolate* isolate, |
| 2047 Handle<WasmInstanceObject> instance, |
| 2049 uint32_t pages) { | 2048 uint32_t pages) { |
| 2050 if (!IsWasmInstance(*object)) return -1; | |
| 2051 auto instance = Handle<WasmInstanceObject>::cast(object); | |
| 2052 if (pages == 0) return GetInstanceMemorySize(isolate, instance); | 2049 if (pages == 0) return GetInstanceMemorySize(isolate, instance); |
| 2053 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); | 2050 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); |
| 2054 | 2051 |
| 2055 Address old_mem_start = nullptr; | 2052 Address old_mem_start = nullptr; |
| 2056 uint32_t old_size = 0, new_size = 0; | 2053 uint32_t old_size = 0, new_size = 0; |
| 2057 | 2054 |
| 2058 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = | 2055 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = |
| 2059 GetInstanceMemory(isolate, instance); | 2056 GetInstanceMemory(isolate, instance); |
| 2060 Handle<JSArrayBuffer> old_buffer; | 2057 Handle<JSArrayBuffer> old_buffer; |
| 2061 if (!maybe_mem_buffer.ToHandle(&old_buffer) || | 2058 if (!maybe_mem_buffer.ToHandle(&old_buffer) || |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2091 old_size, new_size); | 2088 old_size, new_size); |
| 2092 if (instance->has_memory_object()) { | 2089 if (instance->has_memory_object()) { |
| 2093 instance->get_memory_object()->set_buffer(*buffer); | 2090 instance->get_memory_object()->set_buffer(*buffer); |
| 2094 } | 2091 } |
| 2095 | 2092 |
| 2096 DCHECK(old_size % WasmModule::kPageSize == 0); | 2093 DCHECK(old_size % WasmModule::kPageSize == 0); |
| 2097 return (old_size / WasmModule::kPageSize); | 2094 return (old_size / WasmModule::kPageSize); |
| 2098 } | 2095 } |
| 2099 | 2096 |
| 2100 void testing::ValidateInstancesChain(Isolate* isolate, | 2097 void testing::ValidateInstancesChain(Isolate* isolate, |
| 2101 Handle<JSObject> wasm_module, | 2098 Handle<WasmModuleObject> module_obj, |
| 2102 int instance_count) { | 2099 int instance_count) { |
| 2103 CHECK_GE(instance_count, 0); | 2100 CHECK_GE(instance_count, 0); |
| 2104 DisallowHeapAllocation no_gc; | 2101 DisallowHeapAllocation no_gc; |
| 2105 WasmCompiledModule* compiled_module = | 2102 WasmCompiledModule* compiled_module = module_obj->get_compiled_module(); |
| 2106 WasmCompiledModule::cast(wasm_module->GetInternalField(0)); | |
| 2107 CHECK_EQ(JSObject::cast(compiled_module->ptr_to_weak_wasm_module()->value()), | 2103 CHECK_EQ(JSObject::cast(compiled_module->ptr_to_weak_wasm_module()->value()), |
| 2108 *wasm_module); | 2104 *module_obj); |
| 2109 Object* prev = nullptr; | 2105 Object* prev = nullptr; |
| 2110 int found_instances = compiled_module->has_weak_owning_instance() ? 1 : 0; | 2106 int found_instances = compiled_module->has_weak_owning_instance() ? 1 : 0; |
| 2111 WasmCompiledModule* current_instance = compiled_module; | 2107 WasmCompiledModule* current_instance = compiled_module; |
| 2112 while (current_instance->has_weak_next_instance()) { | 2108 while (current_instance->has_weak_next_instance()) { |
| 2113 CHECK((prev == nullptr && !current_instance->has_weak_prev_instance()) || | 2109 CHECK((prev == nullptr && !current_instance->has_weak_prev_instance()) || |
| 2114 current_instance->ptr_to_weak_prev_instance()->value() == prev); | 2110 current_instance->ptr_to_weak_prev_instance()->value() == prev); |
| 2115 CHECK_EQ(current_instance->ptr_to_weak_wasm_module()->value(), | 2111 CHECK_EQ(current_instance->ptr_to_weak_wasm_module()->value(), *module_obj); |
| 2116 *wasm_module); | |
| 2117 CHECK(IsWasmInstance( | 2112 CHECK(IsWasmInstance( |
| 2118 current_instance->ptr_to_weak_owning_instance()->value())); | 2113 current_instance->ptr_to_weak_owning_instance()->value())); |
| 2119 prev = current_instance; | 2114 prev = current_instance; |
| 2120 current_instance = WasmCompiledModule::cast( | 2115 current_instance = WasmCompiledModule::cast( |
| 2121 current_instance->ptr_to_weak_next_instance()->value()); | 2116 current_instance->ptr_to_weak_next_instance()->value()); |
| 2122 ++found_instances; | 2117 ++found_instances; |
| 2123 CHECK_LE(found_instances, instance_count); | 2118 CHECK_LE(found_instances, instance_count); |
| 2124 } | 2119 } |
| 2125 CHECK_EQ(found_instances, instance_count); | 2120 CHECK_EQ(found_instances, instance_count); |
| 2126 } | 2121 } |
| 2127 | 2122 |
| 2128 void testing::ValidateModuleState(Isolate* isolate, | 2123 void testing::ValidateModuleState(Isolate* isolate, |
| 2129 Handle<JSObject> wasm_module) { | 2124 Handle<WasmModuleObject> module_obj) { |
| 2130 DisallowHeapAllocation no_gc; | 2125 DisallowHeapAllocation no_gc; |
| 2131 WasmCompiledModule* compiled_module = | 2126 WasmCompiledModule* compiled_module = module_obj->get_compiled_module(); |
| 2132 WasmCompiledModule::cast(wasm_module->GetInternalField(0)); | |
| 2133 CHECK(compiled_module->has_weak_wasm_module()); | 2127 CHECK(compiled_module->has_weak_wasm_module()); |
| 2134 CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *wasm_module); | 2128 CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *module_obj); |
| 2135 CHECK(!compiled_module->has_weak_prev_instance()); | 2129 CHECK(!compiled_module->has_weak_prev_instance()); |
| 2136 CHECK(!compiled_module->has_weak_next_instance()); | 2130 CHECK(!compiled_module->has_weak_next_instance()); |
| 2137 CHECK(!compiled_module->has_weak_owning_instance()); | 2131 CHECK(!compiled_module->has_weak_owning_instance()); |
| 2138 } | 2132 } |
| 2139 | 2133 |
| 2140 void testing::ValidateOrphanedInstance(Isolate* isolate, | 2134 void testing::ValidateOrphanedInstance(Isolate* isolate, |
| 2141 Handle<JSObject> object) { | 2135 Handle<WasmInstanceObject> instance) { |
| 2142 DisallowHeapAllocation no_gc; | 2136 DisallowHeapAllocation no_gc; |
| 2143 WasmInstanceObject* instance = WasmInstanceObject::cast(*object); | |
| 2144 WasmCompiledModule* compiled_module = instance->get_compiled_module(); | 2137 WasmCompiledModule* compiled_module = instance->get_compiled_module(); |
| 2145 CHECK(compiled_module->has_weak_wasm_module()); | 2138 CHECK(compiled_module->has_weak_wasm_module()); |
| 2146 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared()); | 2139 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared()); |
| 2147 } | 2140 } |
| 2148 | 2141 |
| 2149 void WasmCompiledModule::RecreateModuleWrapper(Isolate* isolate, | 2142 void WasmCompiledModule::RecreateModuleWrapper(Isolate* isolate, |
| 2150 Handle<FixedArray> array) { | 2143 Handle<FixedArray> array) { |
| 2151 Handle<WasmCompiledModule> compiled_module( | 2144 Handle<WasmCompiledModule> compiled_module( |
| 2152 reinterpret_cast<WasmCompiledModule*>(*array), isolate); | 2145 reinterpret_cast<WasmCompiledModule*>(*array), isolate); |
| 2153 | 2146 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2179 MaybeHandle<String> WasmCompiledModule::GetFunctionName( | 2172 MaybeHandle<String> WasmCompiledModule::GetFunctionName( |
| 2180 Handle<WasmCompiledModule> compiled_module, uint32_t func_index) { | 2173 Handle<WasmCompiledModule> compiled_module, uint32_t func_index) { |
| 2181 DCHECK_LT(func_index, compiled_module->module()->functions.size()); | 2174 DCHECK_LT(func_index, compiled_module->module()->functions.size()); |
| 2182 WasmFunction& function = compiled_module->module()->functions[func_index]; | 2175 WasmFunction& function = compiled_module->module()->functions[func_index]; |
| 2183 Isolate* isolate = compiled_module->GetIsolate(); | 2176 Isolate* isolate = compiled_module->GetIsolate(); |
| 2184 MaybeHandle<String> string = ExtractStringFromModuleBytes( | 2177 MaybeHandle<String> string = ExtractStringFromModuleBytes( |
| 2185 isolate, compiled_module, function.name_offset, function.name_length); | 2178 isolate, compiled_module, function.name_offset, function.name_length); |
| 2186 if (!string.is_null()) return string.ToHandleChecked(); | 2179 if (!string.is_null()) return string.ToHandleChecked(); |
| 2187 return {}; | 2180 return {}; |
| 2188 } | 2181 } |
| OLD | NEW |