| 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 } | 179 } |
| 180 #endif | 180 #endif |
| 181 | 181 |
| 182 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | 182 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
| 183 JSArrayBuffer::Setup(buffer, isolate, false, memory, static_cast<int>(size)); | 183 JSArrayBuffer::Setup(buffer, isolate, false, memory, static_cast<int>(size)); |
| 184 buffer->set_is_neuterable(false); | 184 buffer->set_is_neuterable(false); |
| 185 return buffer; | 185 return buffer; |
| 186 } | 186 } |
| 187 | 187 |
| 188 void RelocateInstanceCode(Handle<JSObject> instance, Address old_start, | 188 void RelocateInstanceCode(Handle<JSObject> instance, Address old_start, |
| 189 Address start, uint32_t prev_size, | 189 Address new_start, uint32_t old_size, |
| 190 uint32_t new_size) { | 190 uint32_t new_size) { |
| 191 Handle<FixedArray> functions = Handle<FixedArray>( | 191 Handle<FixedArray> functions = Handle<FixedArray>( |
| 192 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); | 192 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); |
| 193 for (int i = 0; i < functions->length(); ++i) { | 193 for (int i = 0; i < functions->length(); ++i) { |
| 194 Handle<Code> function = Handle<Code>(Code::cast(functions->get(i))); | 194 Handle<Code> function = Handle<Code>(Code::cast(functions->get(i))); |
| 195 AllowDeferredHandleDereference embedding_raw_address; | 195 AllowDeferredHandleDereference embedding_raw_address; |
| 196 int mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE) | | 196 int mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE) | |
| 197 (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE); | 197 (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE) | |
| 198 (1 << RelocInfo::WASM_MEMTYPE_SIZE_REFERENCE); |
| 199 byte memtype_size; |
| 198 for (RelocIterator it(*function, mask); !it.done(); it.next()) { | 200 for (RelocIterator it(*function, mask); !it.done(); it.next()) { |
| 199 it.rinfo()->update_wasm_memory_reference(old_start, start, prev_size, | 201 RelocInfo::Mode mode = it.rinfo()->rmode(); |
| 200 new_size); | 202 if (RelocInfo::IsWasmMemtypeSizeReference(mode)) { |
| 203 DCHECK(old_size == 0); |
| 204 memtype_size = it.rinfo()->wasm_memtype_size_reference(); |
| 205 } else if (RelocInfo::IsWasmMemoryReference(mode) || |
| 206 (RelocInfo::IsWasmMemorySizeReference(mode) && old_size)) { |
| 207 it.rinfo()->update_wasm_memory_reference(old_start, new_start, old_size, |
| 208 new_size); |
| 209 } else if (RelocInfo::IsWasmMemorySizeReference(mode)) { |
| 210 // memtype_size is only populated when old_size = 0, stashed value |
| 211 // should only be used when growing from 0 memory to calculate that last |
| 212 // legal address and cleared after. |
| 213 if (old_size == 0 && memtype_size != 0) { |
| 214 it.rinfo()->update_wasm_memory_reference( |
| 215 old_start, new_start, old_size, (new_size - memtype_size + 1)); |
| 216 memtype_size = 0; |
| 217 } |
| 218 } else { |
| 219 UNREACHABLE(); |
| 220 } |
| 201 } | 221 } |
| 202 } | 222 } |
| 203 } | 223 } |
| 204 | 224 |
| 205 void RelocateGlobals(Handle<JSObject> instance, Address old_start, | 225 void RelocateGlobals(Handle<JSObject> instance, Address old_start, |
| 206 Address globals_start) { | 226 Address globals_start) { |
| 207 Handle<FixedArray> functions = Handle<FixedArray>( | 227 Handle<FixedArray> functions = Handle<FixedArray>( |
| 208 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); | 228 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); |
| 209 uint32_t function_count = static_cast<uint32_t>(functions->length()); | 229 uint32_t function_count = static_cast<uint32_t>(functions->length()); |
| 210 for (uint32_t i = 0; i < function_count; ++i) { | 230 for (uint32_t i = 0; i < function_count; ++i) { |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 Address globals_start = | 639 Address globals_start = |
| 620 GetGlobalStartAddressFromCodeTemplate(undefined, owner); | 640 GetGlobalStartAddressFromCodeTemplate(undefined, owner); |
| 621 | 641 |
| 622 if (old_mem_size > 0) { | 642 if (old_mem_size > 0) { |
| 623 CHECK_NE(mem_start, undefined); | 643 CHECK_NE(mem_start, undefined); |
| 624 old_mem_address = | 644 old_mem_address = |
| 625 static_cast<Address>(JSArrayBuffer::cast(mem_start)->backing_store()); | 645 static_cast<Address>(JSArrayBuffer::cast(mem_start)->backing_store()); |
| 626 } | 646 } |
| 627 int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_REFERENCE) | | 647 int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_REFERENCE) | |
| 628 RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_SIZE_REFERENCE) | | 648 RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_SIZE_REFERENCE) | |
| 649 RelocInfo::ModeMask(RelocInfo::WASM_MEMTYPE_SIZE_REFERENCE) | |
| 629 RelocInfo::ModeMask(RelocInfo::WASM_GLOBAL_REFERENCE); | 650 RelocInfo::ModeMask(RelocInfo::WASM_GLOBAL_REFERENCE); |
| 630 | 651 |
| 631 Object* fct_obj = compiled_module->ptr_to_code_table(); | 652 Object* fct_obj = compiled_module->ptr_to_code_table(); |
| 632 if (fct_obj != nullptr && fct_obj != undefined && | 653 if (fct_obj != nullptr && fct_obj != undefined && |
| 633 (old_mem_size > 0 || globals_start != nullptr)) { | 654 (old_mem_size > 0 || globals_start != nullptr)) { |
| 634 FixedArray* functions = FixedArray::cast(fct_obj); | 655 FixedArray* functions = FixedArray::cast(fct_obj); |
| 635 for (int i = 0; i < functions->length(); ++i) { | 656 for (int i = 0; i < functions->length(); ++i) { |
| 636 Code* code = Code::cast(functions->get(i)); | 657 Code* code = Code::cast(functions->get(i)); |
| 637 bool changed = false; | 658 bool changed = false; |
| 638 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { | 659 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { |
| (...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2040 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> wasm) { | 2061 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> wasm) { |
| 2041 Handle<Object> info(wasm->GetInternalField(kWasmDebugInfo), | 2062 Handle<Object> info(wasm->GetInternalField(kWasmDebugInfo), |
| 2042 wasm->GetIsolate()); | 2063 wasm->GetIsolate()); |
| 2043 if (!info->IsUndefined(wasm->GetIsolate())) | 2064 if (!info->IsUndefined(wasm->GetIsolate())) |
| 2044 return Handle<WasmDebugInfo>::cast(info); | 2065 return Handle<WasmDebugInfo>::cast(info); |
| 2045 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(wasm); | 2066 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(wasm); |
| 2046 wasm->SetInternalField(kWasmDebugInfo, *new_info); | 2067 wasm->SetInternalField(kWasmDebugInfo, *new_info); |
| 2047 return new_info; | 2068 return new_info; |
| 2048 } | 2069 } |
| 2049 | 2070 |
| 2050 bool wasm::UpdateWasmModuleMemory(Handle<JSObject> object, Address old_start, | |
| 2051 Address new_start, uint32_t old_size, | |
| 2052 uint32_t new_size) { | |
| 2053 DisallowHeapAllocation no_allocation; | |
| 2054 if (!IsWasmObject(*object)) { | |
| 2055 return false; | |
| 2056 } | |
| 2057 | |
| 2058 // Get code table associated with the module js_object | |
| 2059 Object* obj = object->GetInternalField(kWasmModuleCodeTable); | |
| 2060 Handle<FixedArray> code_table(FixedArray::cast(obj)); | |
| 2061 | |
| 2062 // Iterate through the code objects in the code table and update relocation | |
| 2063 // information | |
| 2064 for (int i = 0; i < code_table->length(); ++i) { | |
| 2065 obj = code_table->get(i); | |
| 2066 Handle<Code> code(Code::cast(obj)); | |
| 2067 | |
| 2068 int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_REFERENCE) | | |
| 2069 RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_SIZE_REFERENCE); | |
| 2070 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { | |
| 2071 RelocInfo::Mode mode = it.rinfo()->rmode(); | |
| 2072 if (RelocInfo::IsWasmMemoryReference(mode) || | |
| 2073 RelocInfo::IsWasmMemorySizeReference(mode)) { | |
| 2074 it.rinfo()->update_wasm_memory_reference(old_start, new_start, old_size, | |
| 2075 new_size); | |
| 2076 } | |
| 2077 } | |
| 2078 } | |
| 2079 return true; | |
| 2080 } | |
| 2081 | |
| 2082 Handle<FixedArray> wasm::BuildFunctionTable(Isolate* isolate, uint32_t index, | 2071 Handle<FixedArray> wasm::BuildFunctionTable(Isolate* isolate, uint32_t index, |
| 2083 const WasmModule* module) { | 2072 const WasmModule* module) { |
| 2084 const WasmIndirectFunctionTable* table = &module->function_tables[index]; | 2073 const WasmIndirectFunctionTable* table = &module->function_tables[index]; |
| 2085 DCHECK_EQ(table->size, table->values.size()); | 2074 DCHECK_EQ(table->size, table->values.size()); |
| 2086 DCHECK_GE(table->max_size, table->size); | 2075 DCHECK_GE(table->max_size, table->size); |
| 2087 Handle<FixedArray> values = | 2076 Handle<FixedArray> values = |
| 2088 isolate->factory()->NewFixedArray(2 * table->max_size, TENURED); | 2077 isolate->factory()->NewFixedArray(2 * table->max_size, TENURED); |
| 2089 for (uint32_t i = 0; i < table->size; ++i) { | 2078 for (uint32_t i = 0; i < table->size; ++i) { |
| 2090 const WasmFunction* function = &module->functions[table->values[i]]; | 2079 const WasmFunction* function = &module->functions[table->values[i]]; |
| 2091 int32_t index = table->map.Find(function->sig); | 2080 int32_t index = table->map.Find(function->sig); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2227 Handle<JSArrayBuffer> buffer; | 2216 Handle<JSArrayBuffer> buffer; |
| 2228 if (!maybe_mem_buffer.ToHandle(&buffer)) { | 2217 if (!maybe_mem_buffer.ToHandle(&buffer)) { |
| 2229 return 0; | 2218 return 0; |
| 2230 } else { | 2219 } else { |
| 2231 return buffer->byte_length()->Number() / WasmModule::kPageSize; | 2220 return buffer->byte_length()->Number() / WasmModule::kPageSize; |
| 2232 } | 2221 } |
| 2233 } | 2222 } |
| 2234 | 2223 |
| 2235 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, | 2224 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, |
| 2236 uint32_t pages) { | 2225 uint32_t pages) { |
| 2237 if (pages == 0) { | 2226 if (!IsWasmObject(*instance)) return -1; |
| 2238 return GetInstanceMemorySize(isolate, instance); | 2227 if (pages == 0) return GetInstanceMemorySize(isolate, instance); |
| 2239 } | |
| 2240 Address old_mem_start = nullptr; | 2228 Address old_mem_start = nullptr; |
| 2241 uint32_t old_size = 0, new_size = 0; | 2229 uint32_t old_size = 0, new_size = 0; |
| 2242 | 2230 |
| 2243 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = | 2231 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = |
| 2244 GetInstanceMemory(isolate, instance); | 2232 GetInstanceMemory(isolate, instance); |
| 2245 Handle<JSArrayBuffer> old_buffer; | 2233 Handle<JSArrayBuffer> old_buffer; |
| 2246 if (!maybe_mem_buffer.ToHandle(&old_buffer)) { | 2234 if (!maybe_mem_buffer.ToHandle(&old_buffer)) { |
| 2247 // If module object does not have linear memory associated with it, | 2235 // If module object does not have linear memory associated with it, |
| 2248 // Allocate new array buffer of given size. | 2236 // Allocate new array buffer of given size. |
| 2249 // TODO(gdeepti): Fix bounds check to take into account size of memtype. | 2237 // TODO(gdeepti): Fix bounds check to take into account size of memtype. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2266 WasmModule::kMaxMemPages * WasmModule::kPageSize <= new_size) { | 2254 WasmModule::kMaxMemPages * WasmModule::kPageSize <= new_size) { |
| 2267 return -1; | 2255 return -1; |
| 2268 } | 2256 } |
| 2269 Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); | 2257 Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); |
| 2270 if (buffer.is_null()) return -1; | 2258 if (buffer.is_null()) return -1; |
| 2271 Address new_mem_start = static_cast<Address>(buffer->backing_store()); | 2259 Address new_mem_start = static_cast<Address>(buffer->backing_store()); |
| 2272 if (old_size != 0) { | 2260 if (old_size != 0) { |
| 2273 memcpy(new_mem_start, old_mem_start, old_size); | 2261 memcpy(new_mem_start, old_mem_start, old_size); |
| 2274 } | 2262 } |
| 2275 SetInstanceMemory(instance, *buffer); | 2263 SetInstanceMemory(instance, *buffer); |
| 2276 if (!UpdateWasmModuleMemory(instance, old_mem_start, new_mem_start, old_size, | 2264 RelocateInstanceCode(instance, old_mem_start, new_mem_start, old_size, |
| 2277 new_size)) { | 2265 new_size); |
| 2278 return -1; | |
| 2279 } | |
| 2280 DCHECK(old_size % WasmModule::kPageSize == 0); | 2266 DCHECK(old_size % WasmModule::kPageSize == 0); |
| 2281 return (old_size / WasmModule::kPageSize); | 2267 return (old_size / WasmModule::kPageSize); |
| 2282 } | 2268 } |
| 2283 | 2269 |
| 2284 void testing::ValidateInstancesChain(Isolate* isolate, | 2270 void testing::ValidateInstancesChain(Isolate* isolate, |
| 2285 Handle<JSObject> module_obj, | 2271 Handle<JSObject> module_obj, |
| 2286 int instance_count) { | 2272 int instance_count) { |
| 2287 CHECK_GE(instance_count, 0); | 2273 CHECK_GE(instance_count, 0); |
| 2288 DisallowHeapAllocation no_gc; | 2274 DisallowHeapAllocation no_gc; |
| 2289 WasmCompiledModule* compiled_module = | 2275 WasmCompiledModule* compiled_module = |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2323 } | 2309 } |
| 2324 | 2310 |
| 2325 void testing::ValidateOrphanedInstance(Isolate* isolate, | 2311 void testing::ValidateOrphanedInstance(Isolate* isolate, |
| 2326 Handle<JSObject> instance) { | 2312 Handle<JSObject> instance) { |
| 2327 DisallowHeapAllocation no_gc; | 2313 DisallowHeapAllocation no_gc; |
| 2328 CHECK(IsWasmObject(*instance)); | 2314 CHECK(IsWasmObject(*instance)); |
| 2329 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); | 2315 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); |
| 2330 CHECK(compiled_module->has_weak_module_object()); | 2316 CHECK(compiled_module->has_weak_module_object()); |
| 2331 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); | 2317 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); |
| 2332 } | 2318 } |
| OLD | NEW |