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

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

Issue 2887193002: Create a thread safe version of StatsCounters and use. (Closed)
Patch Set: Clean up nits. Created 3 years, 7 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
« src/counters.h ('K') | « src/wasm/wasm-module.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <functional> 5 #include <functional>
6 #include <memory> 6 #include <memory>
7 7
8 #include "src/asmjs/asm-js.h" 8 #include "src/asmjs/asm-js.h"
9 #include "src/assembler-inl.h" 9 #include "src/assembler-inl.h"
10 #include "src/base/atomic-utils.h" 10 #include "src/base/atomic-utils.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 } while (false) 48 } while (false)
49 49
50 namespace { 50 namespace {
51 51
52 static const int kInvalidSigIndex = -1; 52 static const int kInvalidSigIndex = -1;
53 53
54 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) { 54 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) {
55 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset; 55 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset;
56 } 56 }
57 57
58 static void RecordStats(Isolate* isolate, Code* code, bool is_sync) { 58 static void RecordStats(Isolate* isolate, Code* code, Counters* counters) {
59 if (is_sync) { 59 counters->wasm_generated_code_size()->Increment(code->body_size());
60 // TODO(karlschimpf): Make this work when asynchronous. 60 counters->wasm_reloc_size()->Increment(code->relocation_info()->length());
61 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 61 }
62 isolate->counters()->wasm_generated_code_size()->Increment( 62
63 code->body_size()); 63 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions,
64 isolate->counters()->wasm_reloc_size()->Increment( 64 Counters* counters) {
65 code->relocation_info()->length()); 65 DisallowHeapAllocation no_gc;
66 for (int i = 0; i < functions->length(); ++i) {
67 RecordStats(isolate, Code::cast(functions->get(i)), counters);
66 } 68 }
67 } 69 }
68 70
69 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions,
70 bool is_sync) {
71 DisallowHeapAllocation no_gc;
72 for (int i = 0; i < functions->length(); ++i) {
73 RecordStats(isolate, Code::cast(functions->get(i)), is_sync);
74 }
75 }
76
77 void* TryAllocateBackingStore(Isolate* isolate, size_t size, 71 void* TryAllocateBackingStore(Isolate* isolate, size_t size,
78 bool enable_guard_regions, void*& allocation_base, 72 bool enable_guard_regions, void*& allocation_base,
79 size_t& allocation_length) { 73 size_t& allocation_length) {
80 // TODO(eholk): Right now enable_guard_regions has no effect on 32-bit 74 // TODO(eholk): Right now enable_guard_regions has no effect on 32-bit
81 // systems. It may be safer to fail instead, given that other code might do 75 // systems. It may be safer to fail instead, given that other code might do
82 // things that would be unsafe if they expected guard pages where there 76 // things that would be unsafe if they expected guard pages where there
83 // weren't any. 77 // weren't any.
84 if (enable_guard_regions && kGuardRegionsSupported) { 78 if (enable_guard_regions && kGuardRegionsSupported) {
85 // TODO(eholk): On Windows we want to make sure we don't commit the guard 79 // TODO(eholk): On Windows we want to make sure we don't commit the guard
86 // pages yet. 80 // pages yet.
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 286
293 // A helper for compiling an entire module. 287 // A helper for compiling an entire module.
294 class CompilationHelper { 288 class CompilationHelper {
295 public: 289 public:
296 // The compilation helper takes ownership of the {WasmModule}. 290 // The compilation helper takes ownership of the {WasmModule}.
297 // In {CompileToModuleObject}, it will transfer ownership to the generated 291 // In {CompileToModuleObject}, it will transfer ownership to the generated
298 // {WasmModuleWrapper}. If this method is not called, ownership may be 292 // {WasmModuleWrapper}. If this method is not called, ownership may be
299 // reclaimed by explicitely releasing the {module_} field. 293 // reclaimed by explicitely releasing the {module_} field.
300 CompilationHelper(Isolate* isolate, std::unique_ptr<WasmModule> module, 294 CompilationHelper(Isolate* isolate, std::unique_ptr<WasmModule> module,
301 bool is_sync) 295 bool is_sync)
302 : isolate_(isolate), module_(std::move(module)), is_sync_(is_sync) {} 296 : isolate_(isolate),
297 module_(std::move(module)),
298 counters_shared_(isolate->counters_shared()),
299 is_sync_(is_sync) {
300 counters_ = counters_shared_.get();
301 }
303 302
304 // The actual runnable task that performs compilations in the background. 303 // The actual runnable task that performs compilations in the background.
305 class CompilationTask : public CancelableTask { 304 class CompilationTask : public CancelableTask {
306 public: 305 public:
307 CompilationHelper* helper_; 306 CompilationHelper* helper_;
308 explicit CompilationTask(CompilationHelper* helper) 307 explicit CompilationTask(CompilationHelper* helper)
309 : CancelableTask(helper->isolate_), helper_(helper) {} 308 : CancelableTask(helper->isolate_), helper_(helper) {}
310 309
311 void RunInternal() override { 310 void RunInternal() override {
312 while (helper_->FetchAndExecuteCompilationUnit()) { 311 while (helper_->FetchAndExecuteCompilationUnit()) {
313 } 312 }
314 helper_->module_->pending_tasks.get()->Signal(); 313 helper_->module_->pending_tasks.get()->Signal();
315 } 314 }
316 }; 315 };
317 316
318 Isolate* isolate_; 317 Isolate* isolate_;
319 std::unique_ptr<WasmModule> module_; 318 std::unique_ptr<WasmModule> module_;
319 std::shared_ptr<Counters> counters_shared_;
320 Counters* counters_;
320 bool is_sync_; 321 bool is_sync_;
321 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> 322 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>>
322 compilation_units_; 323 compilation_units_;
323 std::queue<std::unique_ptr<compiler::WasmCompilationUnit>> executed_units_; 324 std::queue<std::unique_ptr<compiler::WasmCompilationUnit>> executed_units_;
324 base::Mutex result_mutex_; 325 base::Mutex result_mutex_;
325 base::AtomicNumber<size_t> next_unit_; 326 base::AtomicNumber<size_t> next_unit_;
326 size_t num_background_tasks_ = 0; 327 size_t num_background_tasks_ = 0;
327 // This flag should only be set while holding result_mutex_. 328 // This flag should only be set while holding result_mutex_.
328 bool finisher_is_running_ = false; 329 bool finisher_is_running_ = false;
329 330
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 CompileSequentially(&module_env, temp_instance->function_code, thrower); 614 CompileSequentially(&module_env, temp_instance->function_code, thrower);
614 } 615 }
615 if (thrower->error()) return {}; 616 if (thrower->error()) return {};
616 } 617 }
617 618
618 // At this point, compilation has completed. Update the code table. 619 // At this point, compilation has completed. Update the code table.
619 for (size_t i = FLAG_skip_compiling_wasm_funcs; 620 for (size_t i = FLAG_skip_compiling_wasm_funcs;
620 i < temp_instance->function_code.size(); ++i) { 621 i < temp_instance->function_code.size(); ++i) {
621 Code* code = *temp_instance->function_code[i]; 622 Code* code = *temp_instance->function_code[i];
622 code_table->set(static_cast<int>(i), code); 623 code_table->set(static_cast<int>(i), code);
623 RecordStats(isolate_, code, is_sync_); 624 RecordStats(isolate_, code, counters_);
624 } 625 }
625 626
626 // Create heap objects for script, module bytes and asm.js offset table to 627 // Create heap objects for script, module bytes and asm.js offset table to
627 // be stored in the shared module data. 628 // be stored in the shared module data.
628 Handle<Script> script; 629 Handle<Script> script;
629 Handle<ByteArray> asm_js_offset_table; 630 Handle<ByteArray> asm_js_offset_table;
630 if (asm_js_script.is_null()) { 631 if (asm_js_script.is_null()) {
631 script = CreateWasmScript(isolate_, wire_bytes); 632 script = CreateWasmScript(isolate_, wire_bytes);
632 } else { 633 } else {
633 script = asm_js_script; 634 script = asm_js_script;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 for (auto exp : module->export_table) { 682 for (auto exp : module->export_table) {
682 if (exp.kind != kExternalFunction) continue; 683 if (exp.kind != kExternalFunction) continue;
683 Handle<Code> wasm_code = EnsureExportedLazyDeoptData( 684 Handle<Code> wasm_code = EnsureExportedLazyDeoptData(
684 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index); 685 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index);
685 Handle<Code> wrapper_code = 686 Handle<Code> wrapper_code =
686 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(isolate_, module, 687 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(isolate_, module,
687 wasm_code, exp.index); 688 wasm_code, exp.index);
688 int export_index = 689 int export_index =
689 static_cast<int>(module->functions.size() + func_index); 690 static_cast<int>(module->functions.size() + func_index);
690 code_table->set(export_index, *wrapper_code); 691 code_table->set(export_index, *wrapper_code);
691 RecordStats(isolate_, *wrapper_code, is_sync_); 692 RecordStats(isolate_, *wrapper_code, counters_);
692 func_index++; 693 func_index++;
693 } 694 }
694 695
695 return WasmModuleObject::New(isolate_, compiled_module); 696 return WasmModuleObject::New(isolate_, compiled_module);
696 } 697 }
697 }; 698 };
698 699
699 static void MemoryInstanceFinalizer(Isolate* isolate, 700 static void MemoryInstanceFinalizer(Isolate* isolate,
700 WasmInstanceObject* instance) { 701 WasmInstanceObject* instance) {
701 DisallowHeapAllocation no_gc; 702 DisallowHeapAllocation no_gc;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 int ExtractDirectCallIndex(wasm::Decoder& decoder, const byte* pc) { 836 int ExtractDirectCallIndex(wasm::Decoder& decoder, const byte* pc) {
836 DCHECK_EQ(static_cast<int>(kExprCallFunction), static_cast<int>(*pc)); 837 DCHECK_EQ(static_cast<int>(kExprCallFunction), static_cast<int>(*pc));
837 // Read the leb128 encoded u32 value (up to 5 bytes starting at pc + 1). 838 // Read the leb128 encoded u32 value (up to 5 bytes starting at pc + 1).
838 decoder.Reset(pc + 1, pc + 6); 839 decoder.Reset(pc + 1, pc + 6);
839 uint32_t call_idx = decoder.consume_u32v("call index"); 840 uint32_t call_idx = decoder.consume_u32v("call index");
840 DCHECK(decoder.ok()); 841 DCHECK(decoder.ok());
841 DCHECK_GE(kMaxInt, call_idx); 842 DCHECK_GE(kMaxInt, call_idx);
842 return static_cast<int>(call_idx); 843 return static_cast<int>(call_idx);
843 } 844 }
844 845
845 void RecordLazyCodeStats(Isolate* isolate, Code* code) { 846 void RecordLazyCodeStats(Isolate* isolate, Code* code, Counters* counters_) {
846 isolate->counters()->wasm_lazily_compiled_functions()->Increment(); 847 counters_->wasm_lazily_compiled_functions()->Increment();
847 isolate->counters()->wasm_generated_code_size()->Increment(code->body_size()); 848 counters_->wasm_generated_code_size()->Increment(code->body_size());
848 isolate->counters()->wasm_reloc_size()->Increment( 849 counters_->wasm_reloc_size()->Increment(code->relocation_info()->length());
849 code->relocation_info()->length());
850 } 850 }
851 851
852 } // namespace 852 } // namespace
853 853
854 Handle<JSArrayBuffer> wasm::SetupArrayBuffer(Isolate* isolate, 854 Handle<JSArrayBuffer> wasm::SetupArrayBuffer(Isolate* isolate,
855 void* allocation_base, 855 void* allocation_base,
856 size_t allocation_length, 856 size_t allocation_length,
857 void* backing_store, size_t size, 857 void* backing_store, size_t size,
858 bool is_external, 858 bool is_external,
859 bool enable_guard_regions) { 859 bool enable_guard_regions) {
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule}, 1074 // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule},
1075 // etc. 1075 // etc.
1076 class InstantiationHelper { 1076 class InstantiationHelper {
1077 public: 1077 public:
1078 InstantiationHelper(Isolate* isolate, ErrorThrower* thrower, 1078 InstantiationHelper(Isolate* isolate, ErrorThrower* thrower,
1079 Handle<WasmModuleObject> module_object, 1079 Handle<WasmModuleObject> module_object,
1080 MaybeHandle<JSReceiver> ffi, 1080 MaybeHandle<JSReceiver> ffi,
1081 MaybeHandle<JSArrayBuffer> memory) 1081 MaybeHandle<JSArrayBuffer> memory)
1082 : isolate_(isolate), 1082 : isolate_(isolate),
1083 module_(module_object->compiled_module()->module()), 1083 module_(module_object->compiled_module()->module()),
1084 counters_shared_(isolate->counters_shared()),
1084 thrower_(thrower), 1085 thrower_(thrower),
1085 module_object_(module_object), 1086 module_object_(module_object),
1086 ffi_(ffi.is_null() ? Handle<JSReceiver>::null() 1087 ffi_(ffi.is_null() ? Handle<JSReceiver>::null()
1087 : ffi.ToHandleChecked()), 1088 : ffi.ToHandleChecked()),
1088 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null() 1089 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null()
1089 : memory.ToHandleChecked()) {} 1090 : memory.ToHandleChecked()) {
1091 counters_ = counters_shared_.get();
1092 }
1090 1093
1091 // Build an instance, in all of its glory. 1094 // Build an instance, in all of its glory.
1092 MaybeHandle<WasmInstanceObject> Build() { 1095 MaybeHandle<WasmInstanceObject> Build() {
1093 // Check that an imports argument was provided, if the module requires it. 1096 // Check that an imports argument was provided, if the module requires it.
1094 // No point in continuing otherwise. 1097 // No point in continuing otherwise.
1095 if (!module_->import_table.empty() && ffi_.is_null()) { 1098 if (!module_->import_table.empty() && ffi_.is_null()) {
1096 thrower_->TypeError( 1099 thrower_->TypeError(
1097 "Imports argument must be present and must be an object"); 1100 "Imports argument must be present and must be an object");
1098 return {}; 1101 return {};
1099 } 1102 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 case Code::JS_TO_WASM_FUNCTION: 1172 case Code::JS_TO_WASM_FUNCTION:
1170 case Code::WASM_FUNCTION: { 1173 case Code::WASM_FUNCTION: {
1171 Handle<Code> code = factory->CopyCode(orig_code); 1174 Handle<Code> code = factory->CopyCode(orig_code);
1172 code_table->set(i, *code); 1175 code_table->set(i, *code);
1173 break; 1176 break;
1174 } 1177 }
1175 default: 1178 default:
1176 UNREACHABLE(); 1179 UNREACHABLE();
1177 } 1180 }
1178 } 1181 }
1179 RecordStats(isolate_, code_table, is_sync_); 1182 RecordStats(isolate_, code_table, counters_);
1180 } else { 1183 } else {
1181 // There was no owner, so we can reuse the original. 1184 // There was no owner, so we can reuse the original.
1182 compiled_module_ = original; 1185 compiled_module_ = original;
1183 old_code_table = 1186 old_code_table =
1184 factory->CopyFixedArray(compiled_module_->code_table()); 1187 factory->CopyFixedArray(compiled_module_->code_table());
1185 code_table = compiled_module_->code_table(); 1188 code_table = compiled_module_->code_table();
1186 TRACE("Reusing existing instance %d\n", 1189 TRACE("Reusing existing instance %d\n",
1187 compiled_module_->instance_id()); 1190 compiled_module_->instance_id());
1188 } 1191 }
1189 compiled_module_->set_native_context(isolate_->native_context()); 1192 compiled_module_->set_native_context(isolate_->native_context());
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 int start_index = module_->start_function_index; 1449 int start_index = module_->start_function_index;
1447 Handle<Code> startup_code = EnsureExportedLazyDeoptData( 1450 Handle<Code> startup_code = EnsureExportedLazyDeoptData(
1448 isolate_, instance, code_table, start_index); 1451 isolate_, instance, code_table, start_index);
1449 FunctionSig* sig = module_->functions[start_index].sig; 1452 FunctionSig* sig = module_->functions[start_index].sig;
1450 Handle<Code> wrapper_code = 1453 Handle<Code> wrapper_code =
1451 js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( 1454 js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper(
1452 isolate_, module_, startup_code, start_index); 1455 isolate_, module_, startup_code, start_index);
1453 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( 1456 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New(
1454 isolate_, instance, MaybeHandle<String>(), start_index, 1457 isolate_, instance, MaybeHandle<String>(), start_index,
1455 static_cast<int>(sig->parameter_count()), wrapper_code); 1458 static_cast<int>(sig->parameter_count()), wrapper_code);
1456 RecordStats(isolate_, *startup_code, is_sync_); 1459 RecordStats(isolate_, *startup_code, counters_);
1457 // Call the JS function. 1460 // Call the JS function.
1458 Handle<Object> undefined = factory->undefined_value(); 1461 Handle<Object> undefined = factory->undefined_value();
1459 MaybeHandle<Object> retval = 1462 MaybeHandle<Object> retval =
1460 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); 1463 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr);
1461 1464
1462 if (retval.is_null()) { 1465 if (retval.is_null()) {
1463 DCHECK(isolate_->has_pending_exception()); 1466 DCHECK(isolate_->has_pending_exception());
1464 isolate_->OptionalRescheduleException(false); 1467 isolate_->OptionalRescheduleException(false);
1465 // It's unfortunate that the new instance is already linked in the 1468 // It's unfortunate that the new instance is already linked in the
1466 // chain. However, we need to set up everything before executing the 1469 // chain. However, we need to set up everything before executing the
(...skipping 13 matching lines...) Expand all
1480 // Represents the initialized state of a table. 1483 // Represents the initialized state of a table.
1481 struct TableInstance { 1484 struct TableInstance {
1482 Handle<WasmTableObject> table_object; // WebAssembly.Table instance 1485 Handle<WasmTableObject> table_object; // WebAssembly.Table instance
1483 Handle<FixedArray> js_wrappers; // JSFunctions exported 1486 Handle<FixedArray> js_wrappers; // JSFunctions exported
1484 Handle<FixedArray> function_table; // internal code array 1487 Handle<FixedArray> function_table; // internal code array
1485 Handle<FixedArray> signature_table; // internal sig array 1488 Handle<FixedArray> signature_table; // internal sig array
1486 }; 1489 };
1487 1490
1488 Isolate* isolate_; 1491 Isolate* isolate_;
1489 WasmModule* const module_; 1492 WasmModule* const module_;
1490 constexpr static bool is_sync_ = true; 1493 std::shared_ptr<Counters> counters_shared_;
1494 Counters* counters_;
1491 ErrorThrower* thrower_; 1495 ErrorThrower* thrower_;
1492 Handle<WasmModuleObject> module_object_; 1496 Handle<WasmModuleObject> module_object_;
1493 Handle<JSReceiver> ffi_; // TODO(titzer): Use MaybeHandle 1497 Handle<JSReceiver> ffi_; // TODO(titzer): Use MaybeHandle
1494 Handle<JSArrayBuffer> memory_; // TODO(titzer): Use MaybeHandle 1498 Handle<JSArrayBuffer> memory_; // TODO(titzer): Use MaybeHandle
1495 Handle<JSArrayBuffer> globals_; 1499 Handle<JSArrayBuffer> globals_;
1496 Handle<WasmCompiledModule> compiled_module_; 1500 Handle<WasmCompiledModule> compiled_module_;
1497 std::vector<TableInstance> table_instances_; 1501 std::vector<TableInstance> table_instances_;
1498 std::vector<Handle<JSFunction>> js_wrappers_; 1502 std::vector<Handle<JSFunction>> js_wrappers_;
1499 JSToWasmWrapperCache js_to_wasm_cache_; 1503 JSToWasmWrapperCache js_to_wasm_cache_;
1500 1504
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 isolate_, index, module_->functions[import.index].sig, 1655 isolate_, index, module_->functions[import.index].sig,
1652 Handle<JSReceiver>::cast(value), module_name, import_name, 1656 Handle<JSReceiver>::cast(value), module_name, import_name,
1653 module_->get_origin()); 1657 module_->get_origin());
1654 if (import_wrapper.is_null()) { 1658 if (import_wrapper.is_null()) {
1655 ReportLinkError( 1659 ReportLinkError(
1656 "imported function does not match the expected type", index, 1660 "imported function does not match the expected type", index,
1657 module_name, import_name); 1661 module_name, import_name);
1658 return -1; 1662 return -1;
1659 } 1663 }
1660 code_table->set(num_imported_functions, *import_wrapper); 1664 code_table->set(num_imported_functions, *import_wrapper);
1661 RecordStats(isolate_, *import_wrapper, is_sync_); 1665 RecordStats(isolate_, *import_wrapper, counters_);
1662 num_imported_functions++; 1666 num_imported_functions++;
1663 break; 1667 break;
1664 } 1668 }
1665 case kExternalTable: { 1669 case kExternalTable: {
1666 if (!WasmJs::IsWasmTableObject(isolate_, value)) { 1670 if (!WasmJs::IsWasmTableObject(isolate_, value)) {
1667 ReportLinkError("table import requires a WebAssembly.Table", index, 1671 ReportLinkError("table import requires a WebAssembly.Table", index,
1668 module_name, import_name); 1672 module_name, import_name);
1669 return -1; 1673 return -1;
1670 } 1674 }
1671 WasmIndirectFunctionTable& table = 1675 WasmIndirectFunctionTable& table =
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 // e.g. when we synchronizing tasks or when we delete the AyncCompileJob. 2628 // e.g. when we synchronizing tasks or when we delete the AyncCompileJob.
2625 class AsyncCompileJob { 2629 class AsyncCompileJob {
2626 // TODO(ahaas): Fix https://bugs.chromium.org/p/v8/issues/detail?id=6263 to 2630 // TODO(ahaas): Fix https://bugs.chromium.org/p/v8/issues/detail?id=6263 to
2627 // make sure that d8 does not shut down before the AsyncCompileJob is 2631 // make sure that d8 does not shut down before the AsyncCompileJob is
2628 // finished. 2632 // finished.
2629 public: 2633 public:
2630 explicit AsyncCompileJob(Isolate* isolate, std::unique_ptr<byte[]> bytes_copy, 2634 explicit AsyncCompileJob(Isolate* isolate, std::unique_ptr<byte[]> bytes_copy,
2631 size_t length, Handle<Context> context, 2635 size_t length, Handle<Context> context,
2632 Handle<JSPromise> promise) 2636 Handle<JSPromise> promise)
2633 : isolate_(isolate), 2637 : isolate_(isolate),
2638 counters_shared_(isolate->counters_shared()),
2634 bytes_copy_(std::move(bytes_copy)), 2639 bytes_copy_(std::move(bytes_copy)),
2635 wire_bytes_(bytes_copy_.get(), bytes_copy_.get() + length) { 2640 wire_bytes_(bytes_copy_.get(), bytes_copy_.get() + length) {
2636 // The handles for the context and promise must be deferred. 2641 // The handles for the context and promise must be deferred.
2637 DeferredHandleScope deferred(isolate); 2642 DeferredHandleScope deferred(isolate);
2638 context_ = Handle<Context>(*context); 2643 context_ = Handle<Context>(*context);
2639 module_promise_ = Handle<JSPromise>(*promise); 2644 module_promise_ = Handle<JSPromise>(*promise);
2640 deferred_handles_.push_back(deferred.Detach()); 2645 deferred_handles_.push_back(deferred.Detach());
2646 counters_ = counters_shared_.get();
2641 } 2647 }
2642 2648
2643 void Start() { 2649 void Start() {
2644 DoAsync<DecodeModule>(); // -- 2650 DoAsync<DecodeModule>(); // --
2645 } 2651 }
2646 2652
2647 ~AsyncCompileJob() { 2653 ~AsyncCompileJob() {
2648 for (auto d : deferred_handles_) delete d; 2654 for (auto d : deferred_handles_) delete d;
2649 } 2655 }
2650 2656
2651 private: 2657 private:
2652 Isolate* isolate_; 2658 Isolate* isolate_;
2659 std::shared_ptr<Counters> counters_shared_;
2660 Counters* counters_;
2653 std::unique_ptr<byte[]> bytes_copy_; 2661 std::unique_ptr<byte[]> bytes_copy_;
2654 ModuleWireBytes wire_bytes_; 2662 ModuleWireBytes wire_bytes_;
2655 Handle<Context> context_; 2663 Handle<Context> context_;
2656 Handle<JSPromise> module_promise_; 2664 Handle<JSPromise> module_promise_;
2657 std::unique_ptr<CompilationHelper> helper_; 2665 std::unique_ptr<CompilationHelper> helper_;
2658 std::unique_ptr<ModuleBytesEnv> module_bytes_env_; 2666 std::unique_ptr<ModuleBytesEnv> module_bytes_env_;
2659 2667
2660 bool failed_ = false; 2668 bool failed_ = false;
2661 std::vector<DeferredHandles*> deferred_handles_; 2669 std::vector<DeferredHandles*> deferred_handles_;
2662 Handle<WasmModuleObject> module_object_; 2670 Handle<WasmModuleObject> module_object_;
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
3009 }; 3017 };
3010 3018
3011 //========================================================================== 3019 //==========================================================================
3012 // Step 5b (sync): Finish heap-allocated data structures. 3020 // Step 5b (sync): Finish heap-allocated data structures.
3013 //========================================================================== 3021 //==========================================================================
3014 class FinishCompile : public SyncCompileTask { 3022 class FinishCompile : public SyncCompileTask {
3015 void RunImpl() override { 3023 void RunImpl() override {
3016 TRACE_COMPILE("(5b) Finish compile...\n"); 3024 TRACE_COMPILE("(5b) Finish compile...\n");
3017 HandleScope scope(job_->isolate_); 3025 HandleScope scope(job_->isolate_);
3018 // At this point, compilation has completed. Update the code table. 3026 // At this point, compilation has completed. Update the code table.
3019 constexpr bool is_sync = true;
3020 for (size_t i = FLAG_skip_compiling_wasm_funcs; 3027 for (size_t i = FLAG_skip_compiling_wasm_funcs;
3021 i < job_->temp_instance_->function_code.size(); ++i) { 3028 i < job_->temp_instance_->function_code.size(); ++i) {
3022 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i))); 3029 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i)));
3023 RecordStats(job_->isolate_, code, !is_sync); 3030 RecordStats(job_->isolate_, code, job_->counters_);
3024 } 3031 }
3025 3032
3026 // Create heap objects for script and module bytes to be stored in the 3033 // Create heap objects for script and module bytes to be stored in the
3027 // shared module data. Asm.js is not compiled asynchronously. 3034 // shared module data. Asm.js is not compiled asynchronously.
3028 Handle<Script> script = 3035 Handle<Script> script =
3029 CreateWasmScript(job_->isolate_, job_->wire_bytes_); 3036 CreateWasmScript(job_->isolate_, job_->wire_bytes_);
3030 Handle<ByteArray> asm_js_offset_table; 3037 Handle<ByteArray> asm_js_offset_table;
3031 // TODO(wasm): Improve efficiency of storing module wire bytes. 3038 // TODO(wasm): Improve efficiency of storing module wire bytes.
3032 // 1. Only store relevant sections, not function bodies 3039 // 1. Only store relevant sections, not function bodies
3033 // 2. Don't make a second copy of the bytes here; reuse the copy made 3040 // 2. Don't make a second copy of the bytes here; reuse the copy made
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3079 //========================================================================== 3086 //==========================================================================
3080 // Step 6 (sync): Compile JS->WASM wrappers. 3087 // Step 6 (sync): Compile JS->WASM wrappers.
3081 //========================================================================== 3088 //==========================================================================
3082 class CompileWrappers : public SyncCompileTask { 3089 class CompileWrappers : public SyncCompileTask {
3083 void RunImpl() override { 3090 void RunImpl() override {
3084 TRACE_COMPILE("(6) Compile wrappers...\n"); 3091 TRACE_COMPILE("(6) Compile wrappers...\n");
3085 // Compile JS->WASM wrappers for exported functions. 3092 // Compile JS->WASM wrappers for exported functions.
3086 HandleScope scope(job_->isolate_); 3093 HandleScope scope(job_->isolate_);
3087 JSToWasmWrapperCache js_to_wasm_cache; 3094 JSToWasmWrapperCache js_to_wasm_cache;
3088 int func_index = 0; 3095 int func_index = 0;
3089 constexpr bool is_sync = true;
3090 WasmModule* module = job_->compiled_module_->module(); 3096 WasmModule* module = job_->compiled_module_->module();
3091 for (auto exp : module->export_table) { 3097 for (auto exp : module->export_table) {
3092 if (exp.kind != kExternalFunction) continue; 3098 if (exp.kind != kExternalFunction) continue;
3093 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)), 3099 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)),
3094 job_->isolate_); 3100 job_->isolate_);
3095 Handle<Code> wrapper_code = 3101 Handle<Code> wrapper_code =
3096 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper( 3102 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(
3097 job_->isolate_, module, wasm_code, exp.index); 3103 job_->isolate_, module, wasm_code, exp.index);
3098 int export_index = 3104 int export_index =
3099 static_cast<int>(module->functions.size() + func_index); 3105 static_cast<int>(module->functions.size() + func_index);
3100 job_->code_table_->set(export_index, *wrapper_code); 3106 job_->code_table_->set(export_index, *wrapper_code);
3101 RecordStats(job_->isolate_, *wrapper_code, !is_sync); 3107 RecordStats(job_->isolate_, *wrapper_code, job_->counters_);
3102 func_index++; 3108 func_index++;
3103 } 3109 }
3104 3110
3105 job_->DoSync<FinishModule>(); 3111 job_->DoSync<FinishModule>();
3106 } 3112 }
3107 }; 3113 };
3108 3114
3109 //========================================================================== 3115 //==========================================================================
3110 // Step 7 (sync): Finish the module and resolve the promise. 3116 // Step 7 (sync): Finish the module and resolve the promise.
3111 //========================================================================== 3117 //==========================================================================
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3215 // do the patching redundantly. 3221 // do the patching redundantly.
3216 Handle<FixedArray> new_deopt_data = 3222 Handle<FixedArray> new_deopt_data =
3217 isolate->factory()->CopyFixedArrayUpTo(exp_deopt_data, 2, TENURED); 3223 isolate->factory()->CopyFixedArrayUpTo(exp_deopt_data, 2, TENURED);
3218 lazy_compile_code->set_deoptimization_data(*new_deopt_data); 3224 lazy_compile_code->set_deoptimization_data(*new_deopt_data);
3219 } 3225 }
3220 3226
3221 return compiled_code; 3227 return compiled_code;
3222 } 3228 }
3223 3229
3224 void LazyCompilationOrchestrator::CompileFunction( 3230 void LazyCompilationOrchestrator::CompileFunction(
3225 Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index) { 3231 Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index,
3232 Counters* counters_) {
3226 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), 3233 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(),
3227 isolate); 3234 isolate);
3228 if (Code::cast(compiled_module->code_table()->get(func_index))->kind() == 3235 if (Code::cast(compiled_module->code_table()->get(func_index))->kind() ==
3229 Code::WASM_FUNCTION) { 3236 Code::WASM_FUNCTION) {
3230 return; 3237 return;
3231 } 3238 }
3232 3239
3233 size_t num_function_tables = 3240 size_t num_function_tables =
3234 compiled_module->module()->function_tables.size(); 3241 compiled_module->module()->function_tables.size();
3235 // Store a vector of handles to be embedded in the generated code. 3242 // Store a vector of handles to be embedded in the generated code.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3301 DCHECK_IMPLIES(mem_size == 0, mem_start == nullptr); 3308 DCHECK_IMPLIES(mem_size == 0, mem_start == nullptr);
3302 if (mem_size > 0) { 3309 if (mem_size > 0) {
3303 code_specialization.RelocateMemoryReferences(nullptr, 0, mem_start, 3310 code_specialization.RelocateMemoryReferences(nullptr, 0, mem_start,
3304 mem_size); 3311 mem_size);
3305 } 3312 }
3306 } 3313 }
3307 code_specialization.RelocateDirectCalls(instance); 3314 code_specialization.RelocateDirectCalls(instance);
3308 code_specialization.ApplyToWasmCode(*code, SKIP_ICACHE_FLUSH); 3315 code_specialization.ApplyToWasmCode(*code, SKIP_ICACHE_FLUSH);
3309 Assembler::FlushICache(isolate, code->instruction_start(), 3316 Assembler::FlushICache(isolate, code->instruction_start(),
3310 code->instruction_size()); 3317 code->instruction_size());
3311 RecordLazyCodeStats(isolate, *code); 3318 RecordLazyCodeStats(isolate, *code, counters_);
3312 } 3319 }
3313 3320
3314 Handle<Code> LazyCompilationOrchestrator::CompileLazy( 3321 Handle<Code> LazyCompilationOrchestrator::CompileLazy(
3315 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, 3322 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller,
3316 int call_offset, int exported_func_index, bool patch_caller) { 3323 int call_offset, int exported_func_index, bool patch_caller) {
3317 struct NonCompiledFunction { 3324 struct NonCompiledFunction {
3318 int offset; 3325 int offset;
3319 int func_index; 3326 int func_index;
3320 }; 3327 };
3328 std::shared_ptr<Counters> counters_shared = isolate->counters_shared();
3329 Counters* counters = counters_shared.get();
3321 std::vector<NonCompiledFunction> non_compiled_functions; 3330 std::vector<NonCompiledFunction> non_compiled_functions;
3322 int func_to_return_idx = exported_func_index; 3331 int func_to_return_idx = exported_func_index;
3323 wasm::Decoder decoder(nullptr, nullptr); 3332 wasm::Decoder decoder(nullptr, nullptr);
3324 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION; 3333 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION;
3325 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), 3334 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(),
3326 isolate); 3335 isolate);
3327 3336
3328 if (is_js_to_wasm) { 3337 if (is_js_to_wasm) {
3329 non_compiled_functions.push_back({0, exported_func_index}); 3338 non_compiled_functions.push_back({0, exported_func_index});
3330 } else if (patch_caller) { 3339 } else if (patch_caller) {
(...skipping 24 matching lines...) Expand all
3355 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); 3364 ExtractDirectCallIndex(decoder, func_bytes + byte_pos);
3356 non_compiled_functions.push_back({offset, called_func_index}); 3365 non_compiled_functions.push_back({offset, called_func_index});
3357 // Call offset one instruction after the call. Remember the last called 3366 // Call offset one instruction after the call. Remember the last called
3358 // function before that offset. 3367 // function before that offset.
3359 if (offset < call_offset) func_to_return_idx = called_func_index; 3368 if (offset < call_offset) func_to_return_idx = called_func_index;
3360 } 3369 }
3361 } 3370 }
3362 3371
3363 // TODO(clemensh): compile all functions in non_compiled_functions in 3372 // TODO(clemensh): compile all functions in non_compiled_functions in
3364 // background, wait for func_to_return_idx. 3373 // background, wait for func_to_return_idx.
3365 CompileFunction(isolate, instance, func_to_return_idx); 3374 CompileFunction(isolate, instance, func_to_return_idx, counters);
3366 3375
3367 if (is_js_to_wasm || patch_caller) { 3376 if (is_js_to_wasm || patch_caller) {
3368 DisallowHeapAllocation no_gc; 3377 DisallowHeapAllocation no_gc;
3369 // Now patch the code object with all functions which are now compiled. 3378 // Now patch the code object with all functions which are now compiled.
3370 int idx = 0; 3379 int idx = 0;
3371 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done(); 3380 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done();
3372 it.next()) { 3381 it.next()) {
3373 Code* callee = 3382 Code* callee =
3374 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); 3383 Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
3375 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue; 3384 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue;
(...skipping 22 matching lines...) Expand all
3398 callee_compiled->instruction_start()); 3407 callee_compiled->instruction_start());
3399 } 3408 }
3400 DCHECK_EQ(non_compiled_functions.size(), idx); 3409 DCHECK_EQ(non_compiled_functions.size(), idx);
3401 } 3410 }
3402 3411
3403 Code* ret = 3412 Code* ret =
3404 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); 3413 Code::cast(compiled_module->code_table()->get(func_to_return_idx));
3405 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); 3414 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind());
3406 return handle(ret, isolate); 3415 return handle(ret, isolate);
3407 } 3416 }
OLDNEW
« src/counters.h ('K') | « src/wasm/wasm-module.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698