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

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

Issue 1866873002: [wasm] Adding metrics for Asm/Wasm. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 4 years, 8 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/macro-assembler.h" 5 #include "src/macro-assembler.h"
6 #include "src/objects.h" 6 #include "src/objects.h"
7 #include "src/v8.h" 7 #include "src/v8.h"
8 8
9 #include "src/simulator.h" 9 #include "src/simulator.h"
10 10
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 } 375 }
376 376
377 // Instantiates a wasm module as a JSObject. 377 // Instantiates a wasm module as a JSObject.
378 // * allocates a backing store of {mem_size} bytes. 378 // * allocates a backing store of {mem_size} bytes.
379 // * installs a named property "memory" for that buffer if exported 379 // * installs a named property "memory" for that buffer if exported
380 // * installs named properties on the object for exported functions 380 // * installs named properties on the object for exported functions
381 // * compiles wasm code to machine code 381 // * compiles wasm code to machine code
382 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, 382 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
383 Handle<JSObject> ffi, 383 Handle<JSObject> ffi,
384 Handle<JSArrayBuffer> memory) { 384 Handle<JSArrayBuffer> memory) {
385 HistogramTimerScope wasm_instantiate_time_scope(
386 isolate->counters()->wasm_instantiate_time());
385 this->shared_isolate = isolate; // TODO(titzer): have a real shared isolate. 387 this->shared_isolate = isolate; // TODO(titzer): have a real shared isolate.
386 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); 388 ErrorThrower thrower(isolate, "WasmModule::Instantiate()");
387 Factory* factory = isolate->factory(); 389 Factory* factory = isolate->factory();
388 390
389 //------------------------------------------------------------------------- 391 //-------------------------------------------------------------------------
390 // Allocate the instance and its JS counterpart. 392 // Allocate the instance and its JS counterpart.
391 //------------------------------------------------------------------------- 393 //-------------------------------------------------------------------------
392 Handle<Map> map = factory->NewMap( 394 Handle<Map> map = factory->NewMap(
393 JS_OBJECT_TYPE, 395 JS_OBJECT_TYPE,
394 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 396 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
395 WasmModuleInstance instance(this); 397 WasmModuleInstance instance(this);
396 instance.context = isolate->native_context(); 398 instance.context = isolate->native_context();
397 instance.js_object = factory->NewJSObjectFromMap(map, TENURED); 399 instance.js_object = factory->NewJSObjectFromMap(map, TENURED);
398 Handle<FixedArray> code_table = 400 Handle<FixedArray> code_table =
399 factory->NewFixedArray(static_cast<int>(functions.size()), TENURED); 401 factory->NewFixedArray(static_cast<int>(functions.size()), TENURED);
400 instance.js_object->SetInternalField(kWasmModuleCodeTable, *code_table); 402 instance.js_object->SetInternalField(kWasmModuleCodeTable, *code_table);
401 403
402 //------------------------------------------------------------------------- 404 //-------------------------------------------------------------------------
403 // Allocate and initialize the linear memory. 405 // Allocate and initialize the linear memory.
404 //------------------------------------------------------------------------- 406 //-------------------------------------------------------------------------
407 isolate->counters()->wasm_min_mem_pages_count()->AddSample(
408 instance.module->min_mem_pages);
409 isolate->counters()->wasm_max_mem_pages_count()->AddSample(
410 instance.module->max_mem_pages);
405 if (memory.is_null()) { 411 if (memory.is_null()) {
406 if (!AllocateMemory(&thrower, isolate, &instance)) { 412 if (!AllocateMemory(&thrower, isolate, &instance)) {
407 return MaybeHandle<JSObject>(); 413 return MaybeHandle<JSObject>();
408 } 414 }
409 } else { 415 } else {
410 SetMemory(&instance, memory); 416 SetMemory(&instance, memory);
411 } 417 }
412 instance.js_object->SetInternalField(kWasmMemArrayBuffer, 418 instance.js_object->SetInternalField(kWasmMemArrayBuffer,
413 *instance.mem_buffer); 419 *instance.mem_buffer);
414 LoadDataSegments(this, instance.mem_start, instance.mem_size); 420 LoadDataSegments(this, instance.mem_start, instance.mem_size);
415 421
416 //------------------------------------------------------------------------- 422 //-------------------------------------------------------------------------
417 // Allocate the globals area if necessary. 423 // Allocate the globals area if necessary.
418 //------------------------------------------------------------------------- 424 //-------------------------------------------------------------------------
419 if (!AllocateGlobals(&thrower, isolate, &instance)) { 425 if (!AllocateGlobals(&thrower, isolate, &instance)) {
420 return MaybeHandle<JSObject>(); 426 return MaybeHandle<JSObject>();
421 } 427 }
422 if (!instance.globals_buffer.is_null()) { 428 if (!instance.globals_buffer.is_null()) {
423 instance.js_object->SetInternalField(kWasmGlobalsArrayBuffer, 429 instance.js_object->SetInternalField(kWasmGlobalsArrayBuffer,
424 *instance.globals_buffer); 430 *instance.globals_buffer);
425 } 431 }
426 432
433 HistogramTimerScope wasm_compile_time_scope(
434 isolate->counters()->wasm_compile_time());
435
427 //------------------------------------------------------------------------- 436 //-------------------------------------------------------------------------
428 // Compile wrappers to imported functions. 437 // Compile wrappers to imported functions.
429 //------------------------------------------------------------------------- 438 //-------------------------------------------------------------------------
430 uint32_t index = 0; 439 uint32_t index = 0;
431 instance.function_table = BuildFunctionTable(isolate, this); 440 instance.function_table = BuildFunctionTable(isolate, this);
432 WasmLinker linker(isolate, functions.size()); 441 WasmLinker linker(isolate, functions.size());
433 ModuleEnv module_env; 442 ModuleEnv module_env;
434 module_env.module = this; 443 module_env.module = this;
435 module_env.instance = &instance; 444 module_env.instance = &instance;
436 module_env.linker = &linker; 445 module_env.linker = &linker;
(...skipping 13 matching lines...) Expand all
450 isolate, &module_env, function.ToHandleChecked(), import.sig, 459 isolate, &module_env, function.ToHandleChecked(), import.sig,
451 module_name, function_name); 460 module_name, function_name);
452 instance.import_code.push_back(code); 461 instance.import_code.push_back(code);
453 index++; 462 index++;
454 } 463 }
455 } 464 }
456 465
457 //------------------------------------------------------------------------- 466 //-------------------------------------------------------------------------
458 // Compile all functions in the module. 467 // Compile all functions in the module.
459 //------------------------------------------------------------------------- 468 //-------------------------------------------------------------------------
469 {
470 isolate->counters()->wasm_functions_per_module()->AddSample(
471 static_cast<int>(functions.size()));
460 472
461 // First pass: compile each function and initialize the code table. 473 // First pass: compile each function and initialize the code table.
462 index = FLAG_skip_compiling_wasm_funcs; 474 index = FLAG_skip_compiling_wasm_funcs;
463 while (index < functions.size()) { 475 while (index < functions.size()) {
464 const WasmFunction& func = functions[index]; 476 const WasmFunction& func = functions[index];
465 if (thrower.error()) break; 477 if (thrower.error()) break;
466 DCHECK_EQ(index, func.func_index); 478 DCHECK_EQ(index, func.func_index);
467 479
468 WasmName str = GetName(func.name_offset, func.name_length); 480 WasmName str = GetName(func.name_offset, func.name_length);
469 WasmName str_null = {nullptr, 0}; 481 WasmName str_null = {nullptr, 0};
470 Handle<String> name = factory->InternalizeUtf8String( 482 Handle<String> name = factory->InternalizeUtf8String(
471 Vector<const char>(str.name, str.length)); 483 Vector<const char>(str.name, str.length));
472 Handle<Code> code = Handle<Code>::null(); 484 Handle<Code> code = Handle<Code>::null();
473 Handle<JSFunction> function = Handle<JSFunction>::null(); 485 Handle<JSFunction> function = Handle<JSFunction>::null();
474 if (func.external) { 486 if (func.external) {
475 // Lookup external function in FFI object. 487 // Lookup external function in FFI object.
476 MaybeHandle<JSFunction> function = 488 MaybeHandle<JSFunction> function =
477 LookupFunction(thrower, factory, ffi, index, str, str_null); 489 LookupFunction(thrower, factory, ffi, index, str, str_null);
478 if (function.is_null()) return MaybeHandle<JSObject>(); 490 if (function.is_null()) return MaybeHandle<JSObject>();
479 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, 491 code = compiler::CompileWasmToJSWrapper(isolate, &module_env,
480 function.ToHandleChecked(), 492 function.ToHandleChecked(),
481 func.sig, str, str_null); 493 func.sig, str, str_null);
482 } else { 494 } else {
483 // Compile the function. 495 // Compile the function.
484 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func); 496 code =
485 if (code.is_null()) { 497 compiler::CompileWasmFunction(thrower, isolate, &module_env, func);
486 thrower.Error("Compilation of #%d:%.*s failed.", index, str.length, 498 if (code.is_null()) {
487 str.name); 499 thrower.Error("Compilation of #%d:%.*s failed.", index, str.length,
488 return MaybeHandle<JSObject>(); 500 str.name);
501 return MaybeHandle<JSObject>();
502 }
503 if (func.exported) {
504 function = compiler::CompileJSToWasmWrapper(
505 isolate, &module_env, name, code, instance.js_object, index);
506 }
507 }
508 if (!code.is_null()) {
509 // Install the code into the linker table.
510 linker.Finish(index, code);
511 code_table->set(index, *code);
489 } 512 }
490 if (func.exported) { 513 if (func.exported) {
491 function = compiler::CompileJSToWasmWrapper( 514 // Exported functions are installed as read-only properties on the
492 isolate, &module_env, name, code, instance.js_object, index); 515 // module.
516 JSObject::AddProperty(instance.js_object, name, function, READ_ONLY);
493 } 517 }
494 } 518 index++;
495 if (!code.is_null()) {
496 // Install the code into the linker table.
497 linker.Finish(index, code);
498 code_table->set(index, *code);
499 }
500 if (func.exported) {
501 // Exported functions are installed as read-only properties on the module.
502 JSObject::AddProperty(instance.js_object, name, function, READ_ONLY);
503 }
504 index++;
505 }
506
507 // Second pass: patch all direct call sites.
508 linker.Link(instance.function_table, this->function_table);
509 instance.js_object->SetInternalField(kWasmModuleFunctionTable,
510 Smi::FromInt(0));
511
512 //-------------------------------------------------------------------------
513 // Create and populate the exports object.
514 //-------------------------------------------------------------------------
515 if (export_table.size() > 0 || mem_export) {
516 index = 0;
517 // Create the "exports" object.
518 Handle<JSFunction> object_function = Handle<JSFunction>(
519 isolate->native_context()->object_function(), isolate);
520 Handle<JSObject> exports_object =
521 factory->NewJSObject(object_function, TENURED);
522 Handle<String> exports_name = factory->InternalizeUtf8String("exports");
523 JSObject::AddProperty(instance.js_object, exports_name, exports_object,
524 READ_ONLY);
525
526 // Compile wrappers and add them to the exports object.
527 for (const WasmExport& exp : export_table) {
528 if (thrower.error()) break;
529 WasmName str = GetName(exp.name_offset, exp.name_length);
530 Handle<String> name = factory->InternalizeUtf8String(
531 Vector<const char>(str.name, str.length));
532 Handle<Code> code = linker.GetFunctionCode(exp.func_index);
533 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper(
534 isolate, &module_env, name, code, instance.js_object, exp.func_index);
535 JSObject::AddProperty(exports_object, name, function, READ_ONLY);
536 } 519 }
537 520
538 if (mem_export) { 521 // Second pass: patch all direct call sites.
539 // Export the memory as a named property. 522 linker.Link(instance.function_table, this->function_table);
540 Handle<String> name = factory->InternalizeUtf8String("memory"); 523 instance.js_object->SetInternalField(kWasmModuleFunctionTable,
541 JSObject::AddProperty(exports_object, name, instance.mem_buffer, 524 Smi::FromInt(0));
525
526 //-------------------------------------------------------------------------
527 // Create and populate the exports object.
528 //-------------------------------------------------------------------------
529 if (export_table.size() > 0 || mem_export) {
530 index = 0;
531 // Create the "exports" object.
532 Handle<JSFunction> object_function = Handle<JSFunction>(
533 isolate->native_context()->object_function(), isolate);
534 Handle<JSObject> exports_object =
535 factory->NewJSObject(object_function, TENURED);
536 Handle<String> exports_name = factory->InternalizeUtf8String("exports");
537 JSObject::AddProperty(instance.js_object, exports_name, exports_object,
542 READ_ONLY); 538 READ_ONLY);
539
540 // Compile wrappers and add them to the exports object.
541 for (const WasmExport& exp : export_table) {
542 if (thrower.error()) break;
543 WasmName str = GetName(exp.name_offset, exp.name_length);
544 Handle<String> name = factory->InternalizeUtf8String(
545 Vector<const char>(str.name, str.length));
546 Handle<Code> code = linker.GetFunctionCode(exp.func_index);
547 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper(
548 isolate, &module_env, name, code, instance.js_object,
549 exp.func_index);
550 JSObject::AddProperty(exports_object, name, function, READ_ONLY);
551 }
552
553 if (mem_export) {
554 // Export the memory as a named property.
555 Handle<String> name = factory->InternalizeUtf8String("memory");
556 JSObject::AddProperty(exports_object, name, instance.mem_buffer,
557 READ_ONLY);
558 }
543 } 559 }
544 } 560 }
545 561
546 // Run the start function if one was specified. 562 // Run the start function if one was specified.
547 if (this->start_function_index >= 0) { 563 if (this->start_function_index >= 0) {
548 HandleScope scope(isolate); 564 HandleScope scope(isolate);
549 uint32_t index = static_cast<uint32_t>(this->start_function_index); 565 uint32_t index = static_cast<uint32_t>(this->start_function_index);
550 Handle<String> name = isolate->factory()->NewStringFromStaticChars("start"); 566 Handle<String> name = isolate->factory()->NewStringFromStaticChars("start");
551 Handle<Code> code = linker.GetFunctionCode(index); 567 Handle<Code> code = linker.GetFunctionCode(index);
552 Handle<JSFunction> jsfunc = compiler::CompileJSToWasmWrapper( 568 Handle<JSFunction> jsfunc = compiler::CompileJSToWasmWrapper(
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 } 705 }
690 if (result->IsHeapNumber()) { 706 if (result->IsHeapNumber()) {
691 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); 707 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
692 } 708 }
693 thrower.Error("WASM.compileRun() failed: Return value should be number"); 709 thrower.Error("WASM.compileRun() failed: Return value should be number");
694 return -1; 710 return -1;
695 } 711 }
696 } // namespace wasm 712 } // namespace wasm
697 } // namespace internal 713 } // namespace internal
698 } // namespace v8 714 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698