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

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

Issue 2972803002: [wasm] Use WeakFixedArray for list of instances sharing a WasmMemoryObject. (Closed)
Patch Set: Rebase Created 3 years, 5 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 "src/wasm/wasm-objects.h" 5 #include "src/wasm/wasm-objects.h"
6 #include "src/utils.h" 6 #include "src/utils.h"
7 7
8 #include "src/assembler-inl.h" 8 #include "src/assembler-inl.h"
9 #include "src/base/iterator.h" 9 #include "src/base/iterator.h"
10 #include "src/compiler/wasm-compiler.h" 10 #include "src/compiler/wasm-compiler.h"
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 isolate->factory()->NewJSObject(memory_ctor, TENURED)); 322 isolate->factory()->NewJSObject(memory_ctor, TENURED));
323 if (buffer.is_null()) { 323 if (buffer.is_null()) {
324 const bool enable_guard_regions = EnableGuardRegions(); 324 const bool enable_guard_regions = EnableGuardRegions();
325 buffer = SetupArrayBuffer(isolate, nullptr, 0, nullptr, 0, false, 325 buffer = SetupArrayBuffer(isolate, nullptr, 0, nullptr, 0, false,
326 enable_guard_regions); 326 enable_guard_regions);
327 } 327 }
328 memory_obj->set_array_buffer(*buffer); 328 memory_obj->set_array_buffer(*buffer);
329 memory_obj->set_maximum_pages(maximum); 329 memory_obj->set_maximum_pages(maximum);
330 Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym()); 330 Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym());
331 Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check(); 331 Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check();
332 return Handle<WasmMemoryObject>::cast(memory_obj); 332
333 return memory_obj;
333 } 334 }
334 335
335 uint32_t WasmMemoryObject::current_pages() { 336 uint32_t WasmMemoryObject::current_pages() {
336 uint32_t byte_length; 337 uint32_t byte_length;
337 CHECK(array_buffer()->byte_length()->ToUint32(&byte_length)); 338 CHECK(array_buffer()->byte_length()->ToUint32(&byte_length));
338 return byte_length / wasm::WasmModule::kPageSize; 339 return byte_length / wasm::WasmModule::kPageSize;
339 } 340 }
340 341
341 void WasmMemoryObject::AddInstance(Isolate* isolate, 342 void WasmMemoryObject::AddInstance(Isolate* isolate,
343 Handle<WasmMemoryObject> memory,
342 Handle<WasmInstanceObject> instance) { 344 Handle<WasmInstanceObject> instance) {
343 Handle<WasmInstanceWrapper> instance_wrapper = 345 int unused = 0;
344 handle(instance->instance_wrapper()); 346 Handle<WeakFixedArray> old_instances =
345 if (has_instances_link()) { 347 memory->has_instances()
346 Handle<WasmInstanceWrapper> current_wrapper(instances_link()); 348 ? Handle<WeakFixedArray>(memory->instances(), isolate)
347 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*current_wrapper)); 349 : Handle<WeakFixedArray>::null();
348 DCHECK(!current_wrapper->has_previous()); 350 Handle<WeakFixedArray> new_instances =
349 instance_wrapper->set_next_wrapper(*current_wrapper); 351 WeakFixedArray::Add(old_instances, instance, &unused);
gdeepti 2017/07/06 17:42:55 Variable unused not needed here as WeakFixedArray:
titzer 2017/07/07 08:16:34 Good catch. Done.
350 current_wrapper->set_previous_wrapper(*instance_wrapper); 352 memory->set_instances(*new_instances);
353 }
354
355 void WasmMemoryObject::RemoveInstance(Isolate* isolate,
356 Handle<WasmMemoryObject> memory,
357 Handle<WasmInstanceObject> instance) {
358 if (memory->has_instances()) {
359 memory->instances()->Remove(instance);
351 } 360 }
352 set_instances_link(*instance_wrapper);
353 } 361 }
354 362
355 // static 363 // static
356 int32_t WasmMemoryObject::Grow(Isolate* isolate, 364 int32_t WasmMemoryObject::Grow(Isolate* isolate,
357 Handle<WasmMemoryObject> memory_object, 365 Handle<WasmMemoryObject> memory_object,
358 uint32_t pages) { 366 uint32_t pages) {
359 Handle<JSArrayBuffer> old_buffer(memory_object->array_buffer()); 367 Handle<JSArrayBuffer> old_buffer(memory_object->array_buffer());
368 Address old_mem_start = static_cast<Address>(old_buffer->backing_store());
360 uint32_t old_size = 0; 369 uint32_t old_size = 0;
361 CHECK(old_buffer->byte_length()->ToUint32(&old_size)); 370 CHECK(old_buffer->byte_length()->ToUint32(&old_size));
362 Handle<JSArrayBuffer> new_buffer; 371 Handle<JSArrayBuffer> new_buffer;
363 // Return current size if grow by 0. 372 // Return current size if grow by 0.
364 if (pages == 0) { 373 if (pages == 0) {
365 // Even for pages == 0, we need to attach a new JSArrayBuffer with the same 374 // Even for pages == 0, we need to attach a new JSArrayBuffer with the same
366 // backing store and neuter the old one to be spec compliant. 375 // backing store and neuter the old one to be spec compliant.
367 if (old_size != 0) { 376 if (old_size != 0) {
368 new_buffer = SetupArrayBuffer( 377 new_buffer = SetupArrayBuffer(
369 isolate, old_buffer->allocation_base(), 378 isolate, old_buffer->allocation_base(),
370 old_buffer->allocation_length(), old_buffer->backing_store(), 379 old_buffer->allocation_length(), old_buffer->backing_store(),
371 old_size, old_buffer->is_external(), old_buffer->has_guard_region()); 380 old_size, old_buffer->is_external(), old_buffer->has_guard_region());
372 memory_object->set_array_buffer(*new_buffer); 381 memory_object->set_array_buffer(*new_buffer);
373 } 382 }
374 DCHECK_EQ(0, old_size % WasmModule::kPageSize); 383 DCHECK_EQ(0, old_size % WasmModule::kPageSize);
375 return old_size / WasmModule::kPageSize; 384 return old_size / WasmModule::kPageSize;
376 } 385 }
377 if (!memory_object->has_instances_link()) { 386
378 // Memory object does not have an instance associated with it, just grow 387 uint32_t max_pages;
379 uint32_t max_pages; 388 if (memory_object->has_maximum_pages()) {
380 if (memory_object->has_maximum_pages()) { 389 max_pages = static_cast<uint32_t>(memory_object->maximum_pages());
381 max_pages = static_cast<uint32_t>(memory_object->maximum_pages()); 390 if (FLAG_wasm_max_mem_pages < max_pages) return -1;
382 if (FLAG_wasm_max_mem_pages < max_pages) return -1;
383 } else {
384 max_pages = FLAG_wasm_max_mem_pages;
385 }
386 new_buffer = GrowMemoryBuffer(isolate, old_buffer, pages, max_pages);
387 if (new_buffer.is_null()) return -1;
388 } else { 391 } else {
389 Handle<WasmInstanceWrapper> instance_wrapper( 392 max_pages = FLAG_wasm_max_mem_pages;
390 memory_object->instances_link()); 393 }
391 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); 394 new_buffer = GrowMemoryBuffer(isolate, old_buffer, pages, max_pages);
392 DCHECK(instance_wrapper->has_instance()); 395 if (new_buffer.is_null()) return -1;
393 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object();
394 DCHECK(instance->IsWasmInstanceObject());
395 uint32_t max_pages = instance->GetMaxMemoryPages();
396 396
397 // Grow memory object buffer and update instances associated with it. 397 if (memory_object->has_instances()) {
398 new_buffer = GrowMemoryBuffer(isolate, old_buffer, pages, max_pages); 398 Handle<WeakFixedArray> instances(memory_object->instances(), isolate);
399 if (new_buffer.is_null()) return -1; 399 for (int i = 0; i < instances->Length(); i++) {
400 DCHECK(!instance_wrapper->has_previous()); 400 Object* elem = instances->Get(i);
401 SetInstanceMemory(isolate, instance, new_buffer); 401 if (!elem->IsWasmInstanceObject()) continue;
gdeepti 2017/07/06 17:42:55 Just to confirm, this is to skip over empty slots?
titzer 2017/07/07 08:16:34 Acknowledged.
402 Address old_mem_start = static_cast<Address>(old_buffer->backing_store()); 402 Handle<WasmInstanceObject> instance(WasmInstanceObject::cast(elem),
403 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); 403 isolate);
404 while (instance_wrapper->has_next()) {
405 instance_wrapper = instance_wrapper->next_wrapper();
406 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
407 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object();
408 DCHECK(instance->IsWasmInstanceObject());
409 SetInstanceMemory(isolate, instance, new_buffer); 404 SetInstanceMemory(isolate, instance, new_buffer);
410 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); 405 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size);
gdeepti 2017/07/06 17:42:55 Nit: Move declaration of old_mem_start to be scope
titzer 2017/07/07 08:16:34 Done.
411 } 406 }
412 } 407 }
408
413 memory_object->set_array_buffer(*new_buffer); 409 memory_object->set_array_buffer(*new_buffer);
414 DCHECK_EQ(0, old_size % WasmModule::kPageSize); 410 DCHECK_EQ(0, old_size % WasmModule::kPageSize);
415 return old_size / WasmModule::kPageSize; 411 return old_size / WasmModule::kPageSize;
416 } 412 }
417 413
418 WasmModuleObject* WasmInstanceObject::module_object() { 414 WasmModuleObject* WasmInstanceObject::module_object() {
419 return *compiled_module()->wasm_module(); 415 return *compiled_module()->wasm_module();
420 } 416 }
421 417
422 WasmModule* WasmInstanceObject::module() { return compiled_module()->module(); } 418 WasmModule* WasmInstanceObject::module() { return compiled_module()->module(); }
(...skipping 13 matching lines...) Expand all
436 Handle<JSObject> instance_object = 432 Handle<JSObject> instance_object =
437 isolate->factory()->NewJSObject(instance_cons, TENURED); 433 isolate->factory()->NewJSObject(instance_cons, TENURED);
438 434
439 Handle<Symbol> instance_sym(isolate->native_context()->wasm_instance_sym()); 435 Handle<Symbol> instance_sym(isolate->native_context()->wasm_instance_sym());
440 Object::SetProperty(instance_object, instance_sym, instance_object, STRICT) 436 Object::SetProperty(instance_object, instance_sym, instance_object, STRICT)
441 .Check(); 437 .Check();
442 Handle<WasmInstanceObject> instance( 438 Handle<WasmInstanceObject> instance(
443 reinterpret_cast<WasmInstanceObject*>(*instance_object), isolate); 439 reinterpret_cast<WasmInstanceObject*>(*instance_object), isolate);
444 440
445 instance->set_compiled_module(*compiled_module); 441 instance->set_compiled_module(*compiled_module);
446 Handle<WasmInstanceWrapper> instance_wrapper =
447 WasmInstanceWrapper::New(isolate, instance);
448 instance->set_instance_wrapper(*instance_wrapper);
449 return instance; 442 return instance;
450 } 443 }
451 444
452 int32_t WasmInstanceObject::GetMemorySize() { 445 int32_t WasmInstanceObject::GetMemorySize() {
453 if (!has_memory_buffer()) return 0; 446 if (!has_memory_buffer()) return 0;
454 uint32_t bytes = memory_buffer()->byte_length()->Number(); 447 uint32_t bytes = memory_buffer()->byte_length()->Number();
455 DCHECK_EQ(0, bytes % WasmModule::kPageSize); 448 DCHECK_EQ(0, bytes % WasmModule::kPageSize);
456 return bytes / WasmModule::kPageSize; 449 return bytes / WasmModule::kPageSize;
457 } 450 }
458 451
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, 1387 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller,
1395 int offset, int func_index, bool patch_caller) { 1388 int offset, int func_index, bool patch_caller) {
1396 isolate->set_context(*instance->compiled_module()->native_context()); 1389 isolate->set_context(*instance->compiled_module()->native_context());
1397 Object* orch_obj = 1390 Object* orch_obj =
1398 instance->compiled_module()->shared()->lazy_compilation_orchestrator(); 1391 instance->compiled_module()->shared()->lazy_compilation_orchestrator();
1399 LazyCompilationOrchestrator* orch = 1392 LazyCompilationOrchestrator* orch =
1400 Managed<LazyCompilationOrchestrator>::cast(orch_obj)->get(); 1393 Managed<LazyCompilationOrchestrator>::cast(orch_obj)->get();
1401 return orch->CompileLazy(isolate, instance, caller, offset, func_index, 1394 return orch->CompileLazy(isolate, instance, caller, offset, func_index,
1402 patch_caller); 1395 patch_caller);
1403 } 1396 }
1404
1405 Handle<WasmInstanceWrapper> WasmInstanceWrapper::New(
1406 Isolate* isolate, Handle<WasmInstanceObject> instance) {
1407 Handle<FixedArray> array =
1408 isolate->factory()->NewFixedArray(kFieldCount, TENURED);
1409 Handle<WasmInstanceWrapper> instance_wrapper(
1410 reinterpret_cast<WasmInstanceWrapper*>(*array), isolate);
1411 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance);
1412 instance_wrapper->set(kWrapperInstanceObjectIndex, *cell);
1413 return instance_wrapper;
1414 }
1415
1416 bool WasmInstanceWrapper::IsWasmInstanceWrapper(Object* obj) {
1417 if (!obj->IsFixedArray()) return false;
1418 Handle<FixedArray> array = handle(FixedArray::cast(obj));
1419 if (array->length() != kFieldCount) return false;
1420 if (!array->get(kWrapperInstanceObjectIndex)->IsWeakCell()) return false;
1421 Isolate* isolate = array->GetIsolate();
1422 if (!array->get(kNextInstanceWrapperIndex)->IsUndefined(isolate) &&
1423 !array->get(kNextInstanceWrapperIndex)->IsFixedArray())
1424 return false;
1425 if (!array->get(kPreviousInstanceWrapperIndex)->IsUndefined(isolate) &&
1426 !array->get(kPreviousInstanceWrapperIndex)->IsFixedArray())
1427 return false;
1428 return true;
1429 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698