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

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

Issue 2887193002: Create a thread safe version of StatsCounters and use. (Closed)
Patch Set: fix nits of mtrofin 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/isolate.cc ('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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 } while (false) 49 } while (false)
50 50
51 namespace { 51 namespace {
52 52
53 static const int kInvalidSigIndex = -1; 53 static const int kInvalidSigIndex = -1;
54 54
55 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) { 55 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) {
56 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset; 56 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset;
57 } 57 }
58 58
59 static void RecordStats(Isolate* isolate, Code* code, bool is_sync) { 59 static void RecordStats(Code* code, Counters* counters) {
60 if (is_sync) { 60 counters->wasm_generated_code_size()->Increment(code->body_size());
61 // TODO(karlschimpf): Make this work when asynchronous. 61 counters->wasm_reloc_size()->Increment(code->relocation_info()->length());
62 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 62 }
63 isolate->counters()->wasm_generated_code_size()->Increment( 63
64 code->body_size()); 64 static void RecordStats(Handle<FixedArray> functions, Counters* counters) {
65 isolate->counters()->wasm_reloc_size()->Increment( 65 DisallowHeapAllocation no_gc;
66 code->relocation_info()->length()); 66 for (int i = 0; i < functions->length(); ++i) {
67 RecordStats(Code::cast(functions->get(i)), counters);
67 } 68 }
68 } 69 }
69 70
70 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions,
71 bool is_sync) {
72 DisallowHeapAllocation no_gc;
73 for (int i = 0; i < functions->length(); ++i) {
74 RecordStats(isolate, Code::cast(functions->get(i)), is_sync);
75 }
76 }
77
78 void* TryAllocateBackingStore(Isolate* isolate, size_t size, 71 void* TryAllocateBackingStore(Isolate* isolate, size_t size,
79 bool enable_guard_regions, void*& allocation_base, 72 bool enable_guard_regions, void*& allocation_base,
80 size_t& allocation_length) { 73 size_t& allocation_length) {
81 // 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
82 // 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
83 // 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
84 // weren't any. 77 // weren't any.
85 if (enable_guard_regions && kGuardRegionsSupported) { 78 if (enable_guard_regions && kGuardRegionsSupported) {
86 // 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
87 // pages yet. 80 // pages yet.
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 class CompilationHelper { 324 class CompilationHelper {
332 public: 325 public:
333 // The compilation helper takes ownership of the {WasmModule}. 326 // The compilation helper takes ownership of the {WasmModule}.
334 // In {CompileToModuleObject}, it will transfer ownership to the generated 327 // In {CompileToModuleObject}, it will transfer ownership to the generated
335 // {WasmModuleWrapper}. If this method is not called, ownership may be 328 // {WasmModuleWrapper}. If this method is not called, ownership may be
336 // reclaimed by explicitely releasing the {module_} field. 329 // reclaimed by explicitely releasing the {module_} field.
337 CompilationHelper(Isolate* isolate, std::unique_ptr<WasmModule> module, 330 CompilationHelper(Isolate* isolate, std::unique_ptr<WasmModule> module,
338 bool is_sync) 331 bool is_sync)
339 : isolate_(isolate), 332 : isolate_(isolate),
340 module_(std::move(module)), 333 module_(std::move(module)),
334 counters_shared_(isolate->counters_shared()),
341 is_sync_(is_sync), 335 is_sync_(is_sync),
342 executed_units_(isolate->random_number_generator()) {} 336 executed_units_(isolate->random_number_generator()) {
337 counters_ = counters_shared_.get();
338 }
343 339
344 // The actual runnable task that performs compilations in the background. 340 // The actual runnable task that performs compilations in the background.
345 class CompilationTask : public CancelableTask { 341 class CompilationTask : public CancelableTask {
346 public: 342 public:
347 CompilationHelper* helper_; 343 CompilationHelper* helper_;
348 explicit CompilationTask(CompilationHelper* helper) 344 explicit CompilationTask(CompilationHelper* helper)
349 : CancelableTask(helper->isolate_), helper_(helper) {} 345 : CancelableTask(helper->isolate_), helper_(helper) {}
350 346
351 void RunInternal() override { 347 void RunInternal() override {
352 while (helper_->FetchAndExecuteCompilationUnit()) { 348 while (helper_->FetchAndExecuteCompilationUnit()) {
353 } 349 }
354 helper_->module_->pending_tasks.get()->Signal(); 350 helper_->module_->pending_tasks.get()->Signal();
355 } 351 }
356 }; 352 };
357 353
358 Isolate* isolate_; 354 Isolate* isolate_;
359 std::unique_ptr<WasmModule> module_; 355 std::unique_ptr<WasmModule> module_;
356 std::shared_ptr<Counters> counters_shared_;
357 Counters* counters_;
Clemens Hammacher 2017/06/02 13:08:50 Why is this field needed? {counters_shared_.get()}
kschimpf 2017/06/02 15:01:02 I was confusing the assignment operator with the g
kschimpf 2017/06/02 17:06:27 Fixed in CL https://codereview.chromium.org/291995
360 bool is_sync_; 358 bool is_sync_;
361 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> 359 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>>
362 compilation_units_; 360 compilation_units_;
363 CodeGenerationSchedule executed_units_; 361 CodeGenerationSchedule executed_units_;
364 base::Mutex result_mutex_; 362 base::Mutex result_mutex_;
365 base::AtomicNumber<size_t> next_unit_; 363 base::AtomicNumber<size_t> next_unit_;
366 size_t num_background_tasks_ = 0; 364 size_t num_background_tasks_ = 0;
367 // This flag should only be set while holding result_mutex_. 365 // This flag should only be set while holding result_mutex_.
368 bool finisher_is_running_ = false; 366 bool finisher_is_running_ = false;
369 367
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 // (lazy) compilation time. 681 // (lazy) compilation time.
684 ValidateSequentially(&module_env, thrower); 682 ValidateSequentially(&module_env, thrower);
685 } 683 }
686 if (thrower->error()) return {}; 684 if (thrower->error()) return {};
687 685
688 // At this point, compilation has completed. Update the code table. 686 // At this point, compilation has completed. Update the code table.
689 for (size_t i = FLAG_skip_compiling_wasm_funcs; 687 for (size_t i = FLAG_skip_compiling_wasm_funcs;
690 i < temp_instance->function_code.size(); ++i) { 688 i < temp_instance->function_code.size(); ++i) {
691 Code* code = *temp_instance->function_code[i]; 689 Code* code = *temp_instance->function_code[i];
692 code_table->set(static_cast<int>(i), code); 690 code_table->set(static_cast<int>(i), code);
693 RecordStats(isolate_, code, is_sync_); 691 RecordStats(code, counters_);
694 } 692 }
695 693
696 // Create heap objects for script, module bytes and asm.js offset table to 694 // Create heap objects for script, module bytes and asm.js offset table to
697 // be stored in the shared module data. 695 // be stored in the shared module data.
698 Handle<Script> script; 696 Handle<Script> script;
699 Handle<ByteArray> asm_js_offset_table; 697 Handle<ByteArray> asm_js_offset_table;
700 if (asm_js_script.is_null()) { 698 if (asm_js_script.is_null()) {
701 script = CreateWasmScript(isolate_, wire_bytes); 699 script = CreateWasmScript(isolate_, wire_bytes);
702 } else { 700 } else {
703 script = asm_js_script; 701 script = asm_js_script;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 for (auto exp : module->export_table) { 749 for (auto exp : module->export_table) {
752 if (exp.kind != kExternalFunction) continue; 750 if (exp.kind != kExternalFunction) continue;
753 Handle<Code> wasm_code = EnsureExportedLazyDeoptData( 751 Handle<Code> wasm_code = EnsureExportedLazyDeoptData(
754 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index); 752 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index);
755 Handle<Code> wrapper_code = 753 Handle<Code> wrapper_code =
756 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(isolate_, module, 754 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(isolate_, module,
757 wasm_code, exp.index); 755 wasm_code, exp.index);
758 int export_index = 756 int export_index =
759 static_cast<int>(module->functions.size() + func_index); 757 static_cast<int>(module->functions.size() + func_index);
760 code_table->set(export_index, *wrapper_code); 758 code_table->set(export_index, *wrapper_code);
761 RecordStats(isolate_, *wrapper_code, is_sync_); 759 RecordStats(*wrapper_code, counters_);
762 func_index++; 760 func_index++;
763 } 761 }
764 762
765 return WasmModuleObject::New(isolate_, compiled_module); 763 return WasmModuleObject::New(isolate_, compiled_module);
766 } 764 }
767 }; 765 };
768 766
769 static void MemoryInstanceFinalizer(Isolate* isolate, 767 static void MemoryInstanceFinalizer(Isolate* isolate,
770 WasmInstanceObject* instance) { 768 WasmInstanceObject* instance) {
771 DisallowHeapAllocation no_gc; 769 DisallowHeapAllocation no_gc;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 int ExtractDirectCallIndex(wasm::Decoder& decoder, const byte* pc) { 903 int ExtractDirectCallIndex(wasm::Decoder& decoder, const byte* pc) {
906 DCHECK_EQ(static_cast<int>(kExprCallFunction), static_cast<int>(*pc)); 904 DCHECK_EQ(static_cast<int>(kExprCallFunction), static_cast<int>(*pc));
907 // Read the leb128 encoded u32 value (up to 5 bytes starting at pc + 1). 905 // Read the leb128 encoded u32 value (up to 5 bytes starting at pc + 1).
908 decoder.Reset(pc + 1, pc + 6); 906 decoder.Reset(pc + 1, pc + 6);
909 uint32_t call_idx = decoder.consume_u32v("call index"); 907 uint32_t call_idx = decoder.consume_u32v("call index");
910 DCHECK(decoder.ok()); 908 DCHECK(decoder.ok());
911 DCHECK_GE(kMaxInt, call_idx); 909 DCHECK_GE(kMaxInt, call_idx);
912 return static_cast<int>(call_idx); 910 return static_cast<int>(call_idx);
913 } 911 }
914 912
915 void RecordLazyCodeStats(Isolate* isolate, Code* code) { 913 void RecordLazyCodeStats(Code* code, Counters* counters) {
916 isolate->counters()->wasm_lazily_compiled_functions()->Increment(); 914 counters->wasm_lazily_compiled_functions()->Increment();
917 isolate->counters()->wasm_generated_code_size()->Increment(code->body_size()); 915 counters->wasm_generated_code_size()->Increment(code->body_size());
918 isolate->counters()->wasm_reloc_size()->Increment( 916 counters->wasm_reloc_size()->Increment(code->relocation_info()->length());
919 code->relocation_info()->length());
920 } 917 }
921 918
922 } // namespace 919 } // namespace
923 920
924 Handle<JSArrayBuffer> wasm::SetupArrayBuffer(Isolate* isolate, 921 Handle<JSArrayBuffer> wasm::SetupArrayBuffer(Isolate* isolate,
925 void* allocation_base, 922 void* allocation_base,
926 size_t allocation_length, 923 size_t allocation_length,
927 void* backing_store, size_t size, 924 void* backing_store, size_t size,
928 bool is_external, 925 bool is_external,
929 bool enable_guard_regions) { 926 bool enable_guard_regions) {
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule}, 1141 // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule},
1145 // etc. 1142 // etc.
1146 class InstantiationHelper { 1143 class InstantiationHelper {
1147 public: 1144 public:
1148 InstantiationHelper(Isolate* isolate, ErrorThrower* thrower, 1145 InstantiationHelper(Isolate* isolate, ErrorThrower* thrower,
1149 Handle<WasmModuleObject> module_object, 1146 Handle<WasmModuleObject> module_object,
1150 MaybeHandle<JSReceiver> ffi, 1147 MaybeHandle<JSReceiver> ffi,
1151 MaybeHandle<JSArrayBuffer> memory) 1148 MaybeHandle<JSArrayBuffer> memory)
1152 : isolate_(isolate), 1149 : isolate_(isolate),
1153 module_(module_object->compiled_module()->module()), 1150 module_(module_object->compiled_module()->module()),
1151 counters_shared_(isolate->counters_shared()),
1154 thrower_(thrower), 1152 thrower_(thrower),
1155 module_object_(module_object), 1153 module_object_(module_object),
1156 ffi_(ffi.is_null() ? Handle<JSReceiver>::null() 1154 ffi_(ffi.is_null() ? Handle<JSReceiver>::null()
1157 : ffi.ToHandleChecked()), 1155 : ffi.ToHandleChecked()),
1158 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null() 1156 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null()
1159 : memory.ToHandleChecked()) {} 1157 : memory.ToHandleChecked()) {
1158 counters_ = counters_shared_.get();
1159 }
1160 1160
1161 // Build an instance, in all of its glory. 1161 // Build an instance, in all of its glory.
1162 MaybeHandle<WasmInstanceObject> Build() { 1162 MaybeHandle<WasmInstanceObject> Build() {
1163 // Check that an imports argument was provided, if the module requires it. 1163 // Check that an imports argument was provided, if the module requires it.
1164 // No point in continuing otherwise. 1164 // No point in continuing otherwise.
1165 if (!module_->import_table.empty() && ffi_.is_null()) { 1165 if (!module_->import_table.empty() && ffi_.is_null()) {
1166 thrower_->TypeError( 1166 thrower_->TypeError(
1167 "Imports argument must be present and must be an object"); 1167 "Imports argument must be present and must be an object");
1168 return {}; 1168 return {};
1169 } 1169 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 case Code::JS_TO_WASM_FUNCTION: 1239 case Code::JS_TO_WASM_FUNCTION:
1240 case Code::WASM_FUNCTION: { 1240 case Code::WASM_FUNCTION: {
1241 Handle<Code> code = factory->CopyCode(orig_code); 1241 Handle<Code> code = factory->CopyCode(orig_code);
1242 code_table->set(i, *code); 1242 code_table->set(i, *code);
1243 break; 1243 break;
1244 } 1244 }
1245 default: 1245 default:
1246 UNREACHABLE(); 1246 UNREACHABLE();
1247 } 1247 }
1248 } 1248 }
1249 RecordStats(isolate_, code_table, is_sync_); 1249 RecordStats(code_table, counters_);
1250 } else { 1250 } else {
1251 // There was no owner, so we can reuse the original. 1251 // There was no owner, so we can reuse the original.
1252 compiled_module_ = original; 1252 compiled_module_ = original;
1253 old_code_table = 1253 old_code_table =
1254 factory->CopyFixedArray(compiled_module_->code_table()); 1254 factory->CopyFixedArray(compiled_module_->code_table());
1255 code_table = compiled_module_->code_table(); 1255 code_table = compiled_module_->code_table();
1256 TRACE("Reusing existing instance %d\n", 1256 TRACE("Reusing existing instance %d\n",
1257 compiled_module_->instance_id()); 1257 compiled_module_->instance_id());
1258 } 1258 }
1259 compiled_module_->set_native_context(isolate_->native_context()); 1259 compiled_module_->set_native_context(isolate_->native_context());
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 int start_index = module_->start_function_index; 1516 int start_index = module_->start_function_index;
1517 Handle<Code> startup_code = EnsureExportedLazyDeoptData( 1517 Handle<Code> startup_code = EnsureExportedLazyDeoptData(
1518 isolate_, instance, code_table, start_index); 1518 isolate_, instance, code_table, start_index);
1519 FunctionSig* sig = module_->functions[start_index].sig; 1519 FunctionSig* sig = module_->functions[start_index].sig;
1520 Handle<Code> wrapper_code = 1520 Handle<Code> wrapper_code =
1521 js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( 1521 js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper(
1522 isolate_, module_, startup_code, start_index); 1522 isolate_, module_, startup_code, start_index);
1523 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( 1523 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New(
1524 isolate_, instance, MaybeHandle<String>(), start_index, 1524 isolate_, instance, MaybeHandle<String>(), start_index,
1525 static_cast<int>(sig->parameter_count()), wrapper_code); 1525 static_cast<int>(sig->parameter_count()), wrapper_code);
1526 RecordStats(isolate_, *startup_code, is_sync_); 1526 RecordStats(*startup_code, counters_);
1527 // Call the JS function. 1527 // Call the JS function.
1528 Handle<Object> undefined = factory->undefined_value(); 1528 Handle<Object> undefined = factory->undefined_value();
1529 MaybeHandle<Object> retval = 1529 MaybeHandle<Object> retval =
1530 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); 1530 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr);
1531 1531
1532 if (retval.is_null()) { 1532 if (retval.is_null()) {
1533 DCHECK(isolate_->has_pending_exception()); 1533 DCHECK(isolate_->has_pending_exception());
1534 isolate_->OptionalRescheduleException(false); 1534 isolate_->OptionalRescheduleException(false);
1535 // It's unfortunate that the new instance is already linked in the 1535 // It's unfortunate that the new instance is already linked in the
1536 // chain. However, we need to set up everything before executing the 1536 // chain. However, we need to set up everything before executing the
(...skipping 13 matching lines...) Expand all
1550 // Represents the initialized state of a table. 1550 // Represents the initialized state of a table.
1551 struct TableInstance { 1551 struct TableInstance {
1552 Handle<WasmTableObject> table_object; // WebAssembly.Table instance 1552 Handle<WasmTableObject> table_object; // WebAssembly.Table instance
1553 Handle<FixedArray> js_wrappers; // JSFunctions exported 1553 Handle<FixedArray> js_wrappers; // JSFunctions exported
1554 Handle<FixedArray> function_table; // internal code array 1554 Handle<FixedArray> function_table; // internal code array
1555 Handle<FixedArray> signature_table; // internal sig array 1555 Handle<FixedArray> signature_table; // internal sig array
1556 }; 1556 };
1557 1557
1558 Isolate* isolate_; 1558 Isolate* isolate_;
1559 WasmModule* const module_; 1559 WasmModule* const module_;
1560 constexpr static bool is_sync_ = true; 1560 std::shared_ptr<Counters> counters_shared_;
1561 Counters* counters_;
Clemens Hammacher 2017/06/02 13:08:50 Same here.
kschimpf 2017/06/02 17:06:28 Fixed in CL https://codereview.chromium.org/291995
1561 ErrorThrower* thrower_; 1562 ErrorThrower* thrower_;
1562 Handle<WasmModuleObject> module_object_; 1563 Handle<WasmModuleObject> module_object_;
1563 Handle<JSReceiver> ffi_; // TODO(titzer): Use MaybeHandle 1564 Handle<JSReceiver> ffi_; // TODO(titzer): Use MaybeHandle
1564 Handle<JSArrayBuffer> memory_; // TODO(titzer): Use MaybeHandle 1565 Handle<JSArrayBuffer> memory_; // TODO(titzer): Use MaybeHandle
1565 Handle<JSArrayBuffer> globals_; 1566 Handle<JSArrayBuffer> globals_;
1566 Handle<WasmCompiledModule> compiled_module_; 1567 Handle<WasmCompiledModule> compiled_module_;
1567 std::vector<TableInstance> table_instances_; 1568 std::vector<TableInstance> table_instances_;
1568 std::vector<Handle<JSFunction>> js_wrappers_; 1569 std::vector<Handle<JSFunction>> js_wrappers_;
1569 JSToWasmWrapperCache js_to_wasm_cache_; 1570 JSToWasmWrapperCache js_to_wasm_cache_;
1570 1571
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 isolate_, index, module_->functions[import.index].sig, 1761 isolate_, index, module_->functions[import.index].sig,
1761 Handle<JSReceiver>::cast(value), module_name, import_name, 1762 Handle<JSReceiver>::cast(value), module_name, import_name,
1762 module_->get_origin()); 1763 module_->get_origin());
1763 if (import_wrapper.is_null()) { 1764 if (import_wrapper.is_null()) {
1764 ReportLinkError( 1765 ReportLinkError(
1765 "imported function does not match the expected type", index, 1766 "imported function does not match the expected type", index,
1766 module_name, import_name); 1767 module_name, import_name);
1767 return -1; 1768 return -1;
1768 } 1769 }
1769 code_table->set(num_imported_functions, *import_wrapper); 1770 code_table->set(num_imported_functions, *import_wrapper);
1770 RecordStats(isolate_, *import_wrapper, is_sync_); 1771 RecordStats(*import_wrapper, counters_);
1771 num_imported_functions++; 1772 num_imported_functions++;
1772 break; 1773 break;
1773 } 1774 }
1774 case kExternalTable: { 1775 case kExternalTable: {
1775 if (!WasmJs::IsWasmTableObject(isolate_, value)) { 1776 if (!WasmJs::IsWasmTableObject(isolate_, value)) {
1776 ReportLinkError("table import requires a WebAssembly.Table", index, 1777 ReportLinkError("table import requires a WebAssembly.Table", index,
1777 module_name, import_name); 1778 module_name, import_name);
1778 return -1; 1779 return -1;
1779 } 1780 }
1780 WasmIndirectFunctionTable& table = 1781 WasmIndirectFunctionTable& table =
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after
2733 // e.g. when we synchronizing tasks or when we delete the AyncCompileJob. 2734 // e.g. when we synchronizing tasks or when we delete the AyncCompileJob.
2734 class AsyncCompileJob { 2735 class AsyncCompileJob {
2735 // TODO(ahaas): Fix https://bugs.chromium.org/p/v8/issues/detail?id=6263 to 2736 // TODO(ahaas): Fix https://bugs.chromium.org/p/v8/issues/detail?id=6263 to
2736 // make sure that d8 does not shut down before the AsyncCompileJob is 2737 // make sure that d8 does not shut down before the AsyncCompileJob is
2737 // finished. 2738 // finished.
2738 public: 2739 public:
2739 explicit AsyncCompileJob(Isolate* isolate, std::unique_ptr<byte[]> bytes_copy, 2740 explicit AsyncCompileJob(Isolate* isolate, std::unique_ptr<byte[]> bytes_copy,
2740 size_t length, Handle<Context> context, 2741 size_t length, Handle<Context> context,
2741 Handle<JSPromise> promise) 2742 Handle<JSPromise> promise)
2742 : isolate_(isolate), 2743 : isolate_(isolate),
2744 counters_shared_(isolate->counters_shared()),
2743 bytes_copy_(std::move(bytes_copy)), 2745 bytes_copy_(std::move(bytes_copy)),
2744 wire_bytes_(bytes_copy_.get(), bytes_copy_.get() + length) { 2746 wire_bytes_(bytes_copy_.get(), bytes_copy_.get() + length) {
2745 // The handles for the context and promise must be deferred. 2747 // The handles for the context and promise must be deferred.
2746 DeferredHandleScope deferred(isolate); 2748 DeferredHandleScope deferred(isolate);
2747 context_ = Handle<Context>(*context); 2749 context_ = Handle<Context>(*context);
2748 module_promise_ = Handle<JSPromise>(*promise); 2750 module_promise_ = Handle<JSPromise>(*promise);
2749 deferred_handles_.push_back(deferred.Detach()); 2751 deferred_handles_.push_back(deferred.Detach());
2752 counters_ = counters_shared_.get();
2750 } 2753 }
2751 2754
2752 void Start() { 2755 void Start() {
2753 DoAsync<DecodeModule>(); // -- 2756 DoAsync<DecodeModule>(); // --
2754 } 2757 }
2755 2758
2756 ~AsyncCompileJob() { 2759 ~AsyncCompileJob() {
2757 for (auto d : deferred_handles_) delete d; 2760 for (auto d : deferred_handles_) delete d;
2758 } 2761 }
2759 2762
2760 private: 2763 private:
2761 Isolate* isolate_; 2764 Isolate* isolate_;
2765 std::shared_ptr<Counters> counters_shared_;
2766 Counters* counters_;
2762 std::unique_ptr<byte[]> bytes_copy_; 2767 std::unique_ptr<byte[]> bytes_copy_;
2763 ModuleWireBytes wire_bytes_; 2768 ModuleWireBytes wire_bytes_;
2764 Handle<Context> context_; 2769 Handle<Context> context_;
2765 Handle<JSPromise> module_promise_; 2770 Handle<JSPromise> module_promise_;
2766 std::unique_ptr<CompilationHelper> helper_; 2771 std::unique_ptr<CompilationHelper> helper_;
2767 std::unique_ptr<ModuleBytesEnv> module_bytes_env_; 2772 std::unique_ptr<ModuleBytesEnv> module_bytes_env_;
2768 2773
2769 bool failed_ = false; 2774 bool failed_ = false;
2770 std::vector<DeferredHandles*> deferred_handles_; 2775 std::vector<DeferredHandles*> deferred_handles_;
2771 Handle<WasmModuleObject> module_object_; 2776 Handle<WasmModuleObject> module_object_;
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
3118 }; 3123 };
3119 3124
3120 //========================================================================== 3125 //==========================================================================
3121 // Step 5b (sync): Finish heap-allocated data structures. 3126 // Step 5b (sync): Finish heap-allocated data structures.
3122 //========================================================================== 3127 //==========================================================================
3123 class FinishCompile : public SyncCompileTask { 3128 class FinishCompile : public SyncCompileTask {
3124 void RunImpl() override { 3129 void RunImpl() override {
3125 TRACE_COMPILE("(5b) Finish compile...\n"); 3130 TRACE_COMPILE("(5b) Finish compile...\n");
3126 HandleScope scope(job_->isolate_); 3131 HandleScope scope(job_->isolate_);
3127 // At this point, compilation has completed. Update the code table. 3132 // At this point, compilation has completed. Update the code table.
3128 constexpr bool is_sync = true;
3129 for (size_t i = FLAG_skip_compiling_wasm_funcs; 3133 for (size_t i = FLAG_skip_compiling_wasm_funcs;
3130 i < job_->temp_instance_->function_code.size(); ++i) { 3134 i < job_->temp_instance_->function_code.size(); ++i) {
3131 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i))); 3135 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i)));
3132 RecordStats(job_->isolate_, code, !is_sync); 3136 RecordStats(code, job_->counters_);
3133 } 3137 }
3134 3138
3135 // Create heap objects for script and module bytes to be stored in the 3139 // Create heap objects for script and module bytes to be stored in the
3136 // shared module data. Asm.js is not compiled asynchronously. 3140 // shared module data. Asm.js is not compiled asynchronously.
3137 Handle<Script> script = 3141 Handle<Script> script =
3138 CreateWasmScript(job_->isolate_, job_->wire_bytes_); 3142 CreateWasmScript(job_->isolate_, job_->wire_bytes_);
3139 Handle<ByteArray> asm_js_offset_table; 3143 Handle<ByteArray> asm_js_offset_table;
3140 // TODO(wasm): Improve efficiency of storing module wire bytes. 3144 // TODO(wasm): Improve efficiency of storing module wire bytes.
3141 // 1. Only store relevant sections, not function bodies 3145 // 1. Only store relevant sections, not function bodies
3142 // 2. Don't make a second copy of the bytes here; reuse the copy made 3146 // 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
3188 //========================================================================== 3192 //==========================================================================
3189 // Step 6 (sync): Compile JS->WASM wrappers. 3193 // Step 6 (sync): Compile JS->WASM wrappers.
3190 //========================================================================== 3194 //==========================================================================
3191 class CompileWrappers : public SyncCompileTask { 3195 class CompileWrappers : public SyncCompileTask {
3192 void RunImpl() override { 3196 void RunImpl() override {
3193 TRACE_COMPILE("(6) Compile wrappers...\n"); 3197 TRACE_COMPILE("(6) Compile wrappers...\n");
3194 // Compile JS->WASM wrappers for exported functions. 3198 // Compile JS->WASM wrappers for exported functions.
3195 HandleScope scope(job_->isolate_); 3199 HandleScope scope(job_->isolate_);
3196 JSToWasmWrapperCache js_to_wasm_cache; 3200 JSToWasmWrapperCache js_to_wasm_cache;
3197 int func_index = 0; 3201 int func_index = 0;
3198 constexpr bool is_sync = true;
3199 WasmModule* module = job_->compiled_module_->module(); 3202 WasmModule* module = job_->compiled_module_->module();
3200 for (auto exp : module->export_table) { 3203 for (auto exp : module->export_table) {
3201 if (exp.kind != kExternalFunction) continue; 3204 if (exp.kind != kExternalFunction) continue;
3202 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)), 3205 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)),
3203 job_->isolate_); 3206 job_->isolate_);
3204 Handle<Code> wrapper_code = 3207 Handle<Code> wrapper_code =
3205 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper( 3208 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(
3206 job_->isolate_, module, wasm_code, exp.index); 3209 job_->isolate_, module, wasm_code, exp.index);
3207 int export_index = 3210 int export_index =
3208 static_cast<int>(module->functions.size() + func_index); 3211 static_cast<int>(module->functions.size() + func_index);
3209 job_->code_table_->set(export_index, *wrapper_code); 3212 job_->code_table_->set(export_index, *wrapper_code);
3210 RecordStats(job_->isolate_, *wrapper_code, !is_sync); 3213 RecordStats(*wrapper_code, job_->counters_);
3211 func_index++; 3214 func_index++;
3212 } 3215 }
3213 3216
3214 job_->DoSync<FinishModule>(); 3217 job_->DoSync<FinishModule>();
3215 } 3218 }
3216 }; 3219 };
3217 3220
3218 //========================================================================== 3221 //==========================================================================
3219 // Step 7 (sync): Finish the module and resolve the promise. 3222 // Step 7 (sync): Finish the module and resolve the promise.
3220 //========================================================================== 3223 //==========================================================================
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3324 // do the patching redundantly. 3327 // do the patching redundantly.
3325 Handle<FixedArray> new_deopt_data = 3328 Handle<FixedArray> new_deopt_data =
3326 isolate->factory()->CopyFixedArrayUpTo(exp_deopt_data, 2, TENURED); 3329 isolate->factory()->CopyFixedArrayUpTo(exp_deopt_data, 2, TENURED);
3327 lazy_compile_code->set_deoptimization_data(*new_deopt_data); 3330 lazy_compile_code->set_deoptimization_data(*new_deopt_data);
3328 } 3331 }
3329 3332
3330 return compiled_code; 3333 return compiled_code;
3331 } 3334 }
3332 3335
3333 void LazyCompilationOrchestrator::CompileFunction( 3336 void LazyCompilationOrchestrator::CompileFunction(
3334 Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index) { 3337 Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index,
3338 Counters* counters) {
3335 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), 3339 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(),
3336 isolate); 3340 isolate);
3337 if (Code::cast(compiled_module->code_table()->get(func_index))->kind() == 3341 if (Code::cast(compiled_module->code_table()->get(func_index))->kind() ==
3338 Code::WASM_FUNCTION) { 3342 Code::WASM_FUNCTION) {
3339 return; 3343 return;
3340 } 3344 }
3341 3345
3342 size_t num_function_tables = 3346 size_t num_function_tables =
3343 compiled_module->module()->function_tables.size(); 3347 compiled_module->module()->function_tables.size();
3344 // Store a vector of handles to be embedded in the generated code. 3348 // Store a vector of handles to be embedded in the generated code.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3412 DCHECK_IMPLIES(mem_size == 0, mem_start == nullptr); 3416 DCHECK_IMPLIES(mem_size == 0, mem_start == nullptr);
3413 if (mem_size > 0) { 3417 if (mem_size > 0) {
3414 code_specialization.RelocateMemoryReferences(nullptr, 0, mem_start, 3418 code_specialization.RelocateMemoryReferences(nullptr, 0, mem_start,
3415 mem_size); 3419 mem_size);
3416 } 3420 }
3417 } 3421 }
3418 code_specialization.RelocateDirectCalls(instance); 3422 code_specialization.RelocateDirectCalls(instance);
3419 code_specialization.ApplyToWasmCode(*code, SKIP_ICACHE_FLUSH); 3423 code_specialization.ApplyToWasmCode(*code, SKIP_ICACHE_FLUSH);
3420 Assembler::FlushICache(isolate, code->instruction_start(), 3424 Assembler::FlushICache(isolate, code->instruction_start(),
3421 code->instruction_size()); 3425 code->instruction_size());
3422 RecordLazyCodeStats(isolate, *code); 3426 RecordLazyCodeStats(*code, counters);
3423 } 3427 }
3424 3428
3425 Handle<Code> LazyCompilationOrchestrator::CompileLazy( 3429 Handle<Code> LazyCompilationOrchestrator::CompileLazy(
3426 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, 3430 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller,
3427 int call_offset, int exported_func_index, bool patch_caller) { 3431 int call_offset, int exported_func_index, bool patch_caller) {
3428 struct NonCompiledFunction { 3432 struct NonCompiledFunction {
3429 int offset; 3433 int offset;
3430 int func_index; 3434 int func_index;
3431 }; 3435 };
3436 std::shared_ptr<Counters> counters_shared = isolate->counters_shared();
3437 Counters* counters = counters_shared.get();
3432 std::vector<NonCompiledFunction> non_compiled_functions; 3438 std::vector<NonCompiledFunction> non_compiled_functions;
3433 int func_to_return_idx = exported_func_index; 3439 int func_to_return_idx = exported_func_index;
3434 wasm::Decoder decoder(nullptr, nullptr); 3440 wasm::Decoder decoder(nullptr, nullptr);
3435 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION; 3441 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION;
3436 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), 3442 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(),
3437 isolate); 3443 isolate);
3438 3444
3439 if (is_js_to_wasm) { 3445 if (is_js_to_wasm) {
3440 non_compiled_functions.push_back({0, exported_func_index}); 3446 non_compiled_functions.push_back({0, exported_func_index});
3441 } else if (patch_caller) { 3447 } else if (patch_caller) {
(...skipping 24 matching lines...) Expand all
3466 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); 3472 ExtractDirectCallIndex(decoder, func_bytes + byte_pos);
3467 non_compiled_functions.push_back({offset, called_func_index}); 3473 non_compiled_functions.push_back({offset, called_func_index});
3468 // Call offset one instruction after the call. Remember the last called 3474 // Call offset one instruction after the call. Remember the last called
3469 // function before that offset. 3475 // function before that offset.
3470 if (offset < call_offset) func_to_return_idx = called_func_index; 3476 if (offset < call_offset) func_to_return_idx = called_func_index;
3471 } 3477 }
3472 } 3478 }
3473 3479
3474 // TODO(clemensh): compile all functions in non_compiled_functions in 3480 // TODO(clemensh): compile all functions in non_compiled_functions in
3475 // background, wait for func_to_return_idx. 3481 // background, wait for func_to_return_idx.
3476 CompileFunction(isolate, instance, func_to_return_idx); 3482 CompileFunction(isolate, instance, func_to_return_idx, counters);
3477 3483
3478 if (is_js_to_wasm || patch_caller) { 3484 if (is_js_to_wasm || patch_caller) {
3479 DisallowHeapAllocation no_gc; 3485 DisallowHeapAllocation no_gc;
3480 // Now patch the code object with all functions which are now compiled. 3486 // Now patch the code object with all functions which are now compiled.
3481 int idx = 0; 3487 int idx = 0;
3482 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done(); 3488 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done();
3483 it.next()) { 3489 it.next()) {
3484 Code* callee = 3490 Code* callee =
3485 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); 3491 Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
3486 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue; 3492 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue;
(...skipping 22 matching lines...) Expand all
3509 callee_compiled->instruction_start()); 3515 callee_compiled->instruction_start());
3510 } 3516 }
3511 DCHECK_EQ(non_compiled_functions.size(), idx); 3517 DCHECK_EQ(non_compiled_functions.size(), idx);
3512 } 3518 }
3513 3519
3514 Code* ret = 3520 Code* ret =
3515 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); 3521 Code::cast(compiled_module->code_table()->get(func_to_return_idx));
3516 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); 3522 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind());
3517 return handle(ret, isolate); 3523 return handle(ret, isolate);
3518 } 3524 }
OLDNEW
« src/isolate.cc ('K') | « src/wasm/wasm-module.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698