Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(835)

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2416543002: [wasm] Fix bounds check for zero initial memory. (Closed)
Patch Set: Add aTODO Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698