OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |