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 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 } | 829 } |
830 | 830 |
831 // Create the compiled module object, and populate with compiled functions | 831 // Create the compiled module object, and populate with compiled functions |
832 // and information needed at instantiation time. This object needs to be | 832 // and information needed at instantiation time. This object needs to be |
833 // serializable. Instantiation may occur off a deserialized version of this | 833 // serializable. Instantiation may occur off a deserialized version of this |
834 // object. | 834 // object. |
835 Handle<WasmCompiledModule> ret = | 835 Handle<WasmCompiledModule> ret = |
836 WasmCompiledModule::New(isolate, module_wrapper); | 836 WasmCompiledModule::New(isolate, module_wrapper); |
837 ret->set_code_table(code_table); | 837 ret->set_code_table(code_table); |
838 ret->set_min_mem_pages(min_mem_pages); | 838 ret->set_min_mem_pages(min_mem_pages); |
| 839 ret->set_max_mem_pages(max_mem_pages); |
839 if (function_table_count > 0) { | 840 if (function_table_count > 0) { |
840 ret->set_function_tables(function_tables); | 841 ret->set_function_tables(function_tables); |
841 ret->set_empty_function_tables(function_tables); | 842 ret->set_empty_function_tables(function_tables); |
842 } | 843 } |
843 | 844 |
844 // Compile JS->WASM wrappers for exported functions. | 845 // Compile JS->WASM wrappers for exported functions. |
845 int func_index = 0; | 846 int func_index = 0; |
846 for (auto exp : export_table) { | 847 for (auto exp : export_table) { |
847 if (exp.kind != kExternalFunction) continue; | 848 if (exp.kind != kExternalFunction) continue; |
848 Handle<Code> wasm_code = | 849 Handle<Code> wasm_code = |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 //-------------------------------------------------------------------------- | 1117 //-------------------------------------------------------------------------- |
1117 InitGlobals(); | 1118 InitGlobals(); |
1118 | 1119 |
1119 //-------------------------------------------------------------------------- | 1120 //-------------------------------------------------------------------------- |
1120 // Set up the memory for the new instance. | 1121 // Set up the memory for the new instance. |
1121 //-------------------------------------------------------------------------- | 1122 //-------------------------------------------------------------------------- |
1122 MaybeHandle<JSArrayBuffer> old_memory; | 1123 MaybeHandle<JSArrayBuffer> old_memory; |
1123 | 1124 |
1124 uint32_t min_mem_pages = module_->min_mem_pages; | 1125 uint32_t min_mem_pages = module_->min_mem_pages; |
1125 isolate_->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); | 1126 isolate_->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); |
1126 // TODO(wasm): re-enable counter for max_mem_pages when we use that field. | |
1127 | 1127 |
1128 if (!memory_.is_null()) { | 1128 if (!memory_.is_null()) { |
1129 // Set externally passed ArrayBuffer non neuterable. | 1129 // Set externally passed ArrayBuffer non neuterable. |
1130 memory_->set_is_neuterable(false); | 1130 memory_->set_is_neuterable(false); |
1131 } else if (min_mem_pages > 0) { | 1131 } else if (min_mem_pages > 0) { |
1132 memory_ = AllocateMemory(min_mem_pages); | 1132 memory_ = AllocateMemory(min_mem_pages); |
1133 if (memory_.is_null()) return nothing; // failed to allocate memory | 1133 if (memory_.is_null()) return nothing; // failed to allocate memory |
1134 } | 1134 } |
1135 | 1135 |
1136 if (!memory_.is_null()) { | 1136 if (!memory_.is_null()) { |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1669 case kExternalMemory: { | 1669 case kExternalMemory: { |
1670 // Export the memory as a WebAssembly.Memory object. | 1670 // Export the memory as a WebAssembly.Memory object. |
1671 Handle<Object> memory_object( | 1671 Handle<Object> memory_object( |
1672 instance->GetInternalField(kWasmMemObject), isolate_); | 1672 instance->GetInternalField(kWasmMemObject), isolate_); |
1673 if (memory_object->IsUndefined(isolate_)) { | 1673 if (memory_object->IsUndefined(isolate_)) { |
1674 // If there was no imported WebAssembly.Memory object, create one. | 1674 // If there was no imported WebAssembly.Memory object, create one. |
1675 Handle<JSArrayBuffer> buffer( | 1675 Handle<JSArrayBuffer> buffer( |
1676 JSArrayBuffer::cast( | 1676 JSArrayBuffer::cast( |
1677 instance->GetInternalField(kWasmMemArrayBuffer)), | 1677 instance->GetInternalField(kWasmMemArrayBuffer)), |
1678 isolate_); | 1678 isolate_); |
1679 memory_object = | 1679 memory_object = WasmJs::CreateWasmMemoryObject( |
1680 WasmJs::CreateWasmMemoryObject(isolate_, buffer, false, 0); | 1680 isolate_, buffer, (module_->max_mem_pages != 0), |
| 1681 module_->max_mem_pages); |
1681 instance->SetInternalField(kWasmMemObject, *memory_object); | 1682 instance->SetInternalField(kWasmMemObject, *memory_object); |
1682 } | 1683 } |
1683 | 1684 |
1684 desc.set_value(memory_object); | 1685 desc.set_value(memory_object); |
1685 break; | 1686 break; |
1686 } | 1687 } |
1687 case kExternalGlobal: { | 1688 case kExternalGlobal: { |
1688 // Export the value of the global variable as a number. | 1689 // Export the value of the global variable as a number. |
1689 WasmGlobal& global = module_->globals[exp.index]; | 1690 WasmGlobal& global = module_->globals[exp.index]; |
1690 double num = 0; | 1691 double num = 0; |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2094 GetInstanceMemory(isolate, instance); | 2095 GetInstanceMemory(isolate, instance); |
2095 Handle<JSArrayBuffer> buffer; | 2096 Handle<JSArrayBuffer> buffer; |
2096 if (!maybe_mem_buffer.ToHandle(&buffer)) { | 2097 if (!maybe_mem_buffer.ToHandle(&buffer)) { |
2097 return 0; | 2098 return 0; |
2098 } else { | 2099 } else { |
2099 return buffer->byte_length()->Number() / WasmModule::kPageSize; | 2100 return buffer->byte_length()->Number() / WasmModule::kPageSize; |
2100 } | 2101 } |
2101 } | 2102 } |
2102 | 2103 |
2103 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) { | 2104 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) { |
2104 uint32_t max_pages = WasmModule::kV8MaxPages; | |
2105 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), | 2105 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), |
2106 isolate); | 2106 isolate); |
2107 if (memory_object->IsUndefined(isolate)) return max_pages; | 2107 if (!memory_object->IsUndefined(isolate)) { |
2108 return WasmJs::GetWasmMemoryMaximumSize(isolate, memory_object); | 2108 uint32_t mem_obj_max = |
| 2109 WasmJs::GetWasmMemoryMaximumSize(isolate, memory_object); |
| 2110 if (mem_obj_max != 0) return mem_obj_max; |
| 2111 } |
| 2112 uint32_t compiled_max_pages = GetCompiledModule(*instance)->max_mem_pages(); |
| 2113 isolate->counters()->wasm_max_mem_pages_count()->AddSample( |
| 2114 compiled_max_pages); |
| 2115 if (compiled_max_pages != 0) return compiled_max_pages; |
| 2116 return WasmModule::kV8MaxPages; |
2109 } | 2117 } |
2110 | 2118 |
2111 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, | 2119 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, |
2112 uint32_t pages) { | 2120 uint32_t pages) { |
2113 if (!IsWasmInstance(*instance)) return -1; | 2121 if (!IsWasmInstance(*instance)) return -1; |
2114 if (pages == 0) return GetInstanceMemorySize(isolate, instance); | 2122 if (pages == 0) return GetInstanceMemorySize(isolate, instance); |
2115 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); | 2123 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); |
2116 if (WasmModule::kV8MaxPages < max_pages) return -1; | |
2117 | 2124 |
2118 Address old_mem_start = nullptr; | 2125 Address old_mem_start = nullptr; |
2119 uint32_t old_size = 0, new_size = 0; | 2126 uint32_t old_size = 0, new_size = 0; |
2120 | 2127 |
2121 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = | 2128 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = |
2122 GetInstanceMemory(isolate, instance); | 2129 GetInstanceMemory(isolate, instance); |
2123 Handle<JSArrayBuffer> old_buffer; | 2130 Handle<JSArrayBuffer> old_buffer; |
2124 if (!maybe_mem_buffer.ToHandle(&old_buffer) || | 2131 if (!maybe_mem_buffer.ToHandle(&old_buffer) || |
2125 old_buffer->backing_store() == nullptr) { | 2132 old_buffer->backing_store() == nullptr) { |
2126 // If module object does not have linear memory associated with it, | 2133 // If module object does not have linear memory associated with it, |
2127 // Allocate new array buffer of given size. | 2134 // Allocate new array buffer of given size. |
2128 new_size = pages * WasmModule::kPageSize; | 2135 new_size = pages * WasmModule::kPageSize; |
2129 if (max_pages < pages) return -1; | 2136 if (max_pages < pages) return -1; |
2130 } else { | 2137 } else { |
2131 old_mem_start = static_cast<Address>(old_buffer->backing_store()); | 2138 old_mem_start = static_cast<Address>(old_buffer->backing_store()); |
2132 old_size = old_buffer->byte_length()->Number(); | 2139 old_size = old_buffer->byte_length()->Number(); |
2133 // If the old memory was zero-sized, we should have been in the | 2140 // If the old memory was zero-sized, we should have been in the |
2134 // "undefined" case above. | 2141 // "undefined" case above. |
2135 DCHECK_NOT_NULL(old_mem_start); | 2142 DCHECK_NOT_NULL(old_mem_start); |
2136 DCHECK(old_size + pages * WasmModule::kPageSize <= | 2143 DCHECK(old_size + pages * WasmModule::kPageSize <= |
2137 std::numeric_limits<uint32_t>::max()); | 2144 std::numeric_limits<uint32_t>::max()); |
2138 new_size = old_size + pages * WasmModule::kPageSize; | 2145 new_size = old_size + pages * WasmModule::kPageSize; |
2139 } | 2146 } |
2140 | 2147 |
2141 if (new_size <= old_size || max_pages * WasmModule::kPageSize < new_size) { | 2148 if (new_size <= old_size || max_pages * WasmModule::kPageSize < new_size || |
| 2149 WasmModule::kV8MaxPages * WasmModule::kPageSize < new_size) { |
2142 return -1; | 2150 return -1; |
2143 } | 2151 } |
2144 Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); | 2152 Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); |
2145 if (buffer.is_null()) return -1; | 2153 if (buffer.is_null()) return -1; |
2146 Address new_mem_start = static_cast<Address>(buffer->backing_store()); | 2154 Address new_mem_start = static_cast<Address>(buffer->backing_store()); |
2147 if (old_size != 0) { | 2155 if (old_size != 0) { |
2148 memcpy(new_mem_start, old_mem_start, old_size); | 2156 memcpy(new_mem_start, old_mem_start, old_size); |
2149 } | 2157 } |
2150 SetInstanceMemory(instance, *buffer); | 2158 SetInstanceMemory(instance, *buffer); |
2151 Handle<FixedArray> code_table = GetCompiledModule(*instance)->code_table(); | 2159 Handle<FixedArray> code_table = GetCompiledModule(*instance)->code_table(); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 CHECK_NOT_NULL(result.val); | 2240 CHECK_NOT_NULL(result.val); |
2233 module = const_cast<WasmModule*>(result.val); | 2241 module = const_cast<WasmModule*>(result.val); |
2234 } | 2242 } |
2235 | 2243 |
2236 Handle<WasmModuleWrapper> module_wrapper = | 2244 Handle<WasmModuleWrapper> module_wrapper = |
2237 WasmModuleWrapper::New(isolate, module); | 2245 WasmModuleWrapper::New(isolate, module); |
2238 | 2246 |
2239 compiled_module->set_module_wrapper(module_wrapper); | 2247 compiled_module->set_module_wrapper(module_wrapper); |
2240 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); | 2248 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); |
2241 } | 2249 } |
OLD | NEW |