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

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

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