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 "src/base/atomic-utils.h" | 5 #include "src/base/atomic-utils.h" |
6 #include "src/macro-assembler.h" | 6 #include "src/macro-assembler.h" |
7 #include "src/objects.h" | 7 #include "src/objects.h" |
8 #include "src/property-descriptor.h" | 8 #include "src/property-descriptor.h" |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 CHECK_LE(segment.source_size, mem_size); | 137 CHECK_LE(segment.source_size, mem_size); |
138 CHECK_LE(segment.dest_addr + segment.source_size, mem_size); | 138 CHECK_LE(segment.dest_addr + segment.source_size, mem_size); |
139 byte* addr = mem_addr + segment.dest_addr; | 139 byte* addr = mem_addr + segment.dest_addr; |
140 memcpy(addr, module->module_start + segment.source_offset, | 140 memcpy(addr, module->module_start + segment.source_offset, |
141 segment.source_size); | 141 segment.source_size); |
142 } | 142 } |
143 } | 143 } |
144 | 144 |
145 Handle<FixedArray> BuildFunctionTable(Isolate* isolate, | 145 Handle<FixedArray> BuildFunctionTable(Isolate* isolate, |
146 const WasmModule* module) { | 146 const WasmModule* module) { |
147 if (module->function_table.size() == 0) { | 147 // Compute the size of the indirect function table |
148 uint32_t table_size = module->FunctionTableSize(); | |
149 if (table_size == 0) { | |
148 return Handle<FixedArray>::null(); | 150 return Handle<FixedArray>::null(); |
149 } | 151 } |
150 int table_size = static_cast<int>(module->function_table.size()); | 152 |
151 Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size); | 153 Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size); |
152 for (int i = 0; i < table_size; i++) { | 154 for (uint32_t i = 0; |
155 i < static_cast<uint32_t>(module->function_table.size()); | |
ritesht
2016/06/21 23:16:33
I have to cast this as the "set" function requires
| |
156 ++i) { | |
153 const WasmFunction* function = | 157 const WasmFunction* function = |
154 &module->functions[module->function_table[i]]; | 158 &module->functions[module->function_table[i]]; |
155 fixed->set(i, Smi::FromInt(function->sig_index)); | 159 fixed->set(i, Smi::FromInt(function->sig_index)); |
156 } | 160 } |
157 return fixed; | 161 return fixed; |
158 } | 162 } |
159 | 163 |
160 Handle<JSArrayBuffer> NewArrayBuffer(Isolate* isolate, size_t size, | 164 Handle<JSArrayBuffer> NewArrayBuffer(Isolate* isolate, size_t size, |
161 byte** backing_store) { | 165 byte** backing_store) { |
162 *backing_store = nullptr; | 166 *backing_store = nullptr; |
163 if (size > (WasmModule::kMaxMemPages * WasmModule::kPageSize)) { | 167 if (size > (WasmModule::kMaxMemPages * WasmModule::kPageSize)) { |
164 // TODO(titzer): lift restriction on maximum memory allocated here. | 168 // TODO(titzer): lift restriction on maximum memory allocated here. |
165 return Handle<JSArrayBuffer>::null(); | 169 return Handle<JSArrayBuffer>::null(); |
166 } | 170 } |
167 void* memory = isolate->array_buffer_allocator()->Allocate(size); | 171 void* memory = isolate->array_buffer_allocator()->Allocate(size); |
168 if (memory == nullptr) { | 172 if (memory == nullptr) { |
169 return Handle<JSArrayBuffer>::null(); | 173 return Handle<JSArrayBuffer>::null(); |
170 } | 174 } |
171 | 175 |
172 *backing_store = reinterpret_cast<byte*>(memory); | 176 *backing_store = reinterpret_cast<byte*>(memory); |
173 | 177 |
174 #if DEBUG | 178 #if DEBUG |
175 // Double check the API allocator actually zero-initialized the memory. | 179 // Double check the API allocator actually zero-initialized the memory. |
176 byte* bytes = reinterpret_cast<byte*>(*backing_store); | 180 byte* bytes = reinterpret_cast<byte*>(*backing_store); |
177 for (size_t i = 0; i < size; i++) { | 181 for (size_t i = 0; i < size; ++i) { |
178 DCHECK_EQ(0, bytes[i]); | 182 DCHECK_EQ(0, bytes[i]); |
179 } | 183 } |
180 #endif | 184 #endif |
181 | 185 |
182 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | 186 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
183 JSArrayBuffer::Setup(buffer, isolate, false, memory, static_cast<int>(size)); | 187 JSArrayBuffer::Setup(buffer, isolate, false, memory, static_cast<int>(size)); |
184 buffer->set_is_neuterable(false); | 188 buffer->set_is_neuterable(false); |
185 return buffer; | 189 return buffer; |
186 } | 190 } |
187 | 191 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
303 modified = true; | 307 modified = true; |
304 } | 308 } |
305 } | 309 } |
306 } | 310 } |
307 } | 311 } |
308 return modified; | 312 return modified; |
309 } | 313 } |
310 | 314 |
311 void LinkModuleFunctions(Isolate* isolate, | 315 void LinkModuleFunctions(Isolate* isolate, |
312 std::vector<Handle<Code>>& functions) { | 316 std::vector<Handle<Code>>& functions) { |
313 for (size_t i = 0; i < functions.size(); i++) { | 317 for (size_t i = 0; i < functions.size(); ++i) { |
314 Handle<Code> code = functions[i]; | 318 Handle<Code> code = functions[i]; |
315 bool modified = LinkFunction(code, functions, Code::WASM_FUNCTION); | 319 bool modified = LinkFunction(code, functions, Code::WASM_FUNCTION); |
316 if (modified) { | 320 if (modified) { |
317 Assembler::FlushICache(isolate, code->instruction_start(), | 321 Assembler::FlushICache(isolate, code->instruction_start(), |
318 code->instruction_size()); | 322 code->instruction_size()); |
319 } | 323 } |
320 } | 324 } |
321 } | 325 } |
322 | 326 |
323 void LinkImports(Isolate* isolate, std::vector<Handle<Code>>& functions, | 327 void LinkImports(Isolate* isolate, std::vector<Handle<Code>>& functions, |
(...skipping 11 matching lines...) Expand all Loading... | |
335 } // namespace | 339 } // namespace |
336 | 340 |
337 WasmModule::WasmModule() | 341 WasmModule::WasmModule() |
338 : module_start(nullptr), | 342 : module_start(nullptr), |
339 module_end(nullptr), | 343 module_end(nullptr), |
340 min_mem_pages(0), | 344 min_mem_pages(0), |
341 max_mem_pages(0), | 345 max_mem_pages(0), |
342 mem_export(false), | 346 mem_export(false), |
343 mem_external(false), | 347 mem_external(false), |
344 start_function_index(-1), | 348 start_function_index(-1), |
345 origin(kWasmOrigin) {} | 349 origin(kWasmOrigin), |
350 globals_size(0), | |
351 indirect_table_size(0) {} | |
346 | 352 |
347 static MaybeHandle<JSFunction> ReportFFIError(ErrorThrower& thrower, | 353 static MaybeHandle<JSFunction> ReportFFIError(ErrorThrower& thrower, |
348 const char* error, uint32_t index, | 354 const char* error, uint32_t index, |
349 wasm::WasmName module_name, | 355 wasm::WasmName module_name, |
350 wasm::WasmName function_name) { | 356 wasm::WasmName function_name) { |
351 if (!function_name.is_empty()) { | 357 if (!function_name.is_empty()) { |
352 thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", | 358 thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", |
353 index, module_name.length(), module_name.start(), | 359 index, module_name.length(), module_name.start(), |
354 function_name.length(), function_name.start(), error); | 360 function_name.length(), function_name.start(), error); |
355 } else { | 361 } else { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
507 instance->import_code[index] = code; | 513 instance->import_code[index] = code; |
508 } | 514 } |
509 } | 515 } |
510 return true; | 516 return true; |
511 } | 517 } |
512 | 518 |
513 void InitializeParallelCompilation( | 519 void InitializeParallelCompilation( |
514 Isolate* isolate, const std::vector<WasmFunction>& functions, | 520 Isolate* isolate, const std::vector<WasmFunction>& functions, |
515 std::vector<compiler::WasmCompilationUnit*>& compilation_units, | 521 std::vector<compiler::WasmCompilationUnit*>& compilation_units, |
516 ModuleEnv& module_env, ErrorThrower& thrower) { | 522 ModuleEnv& module_env, ErrorThrower& thrower) { |
517 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); i++) { | 523 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) { |
518 compilation_units[i] = new compiler::WasmCompilationUnit( | 524 compilation_units[i] = new compiler::WasmCompilationUnit( |
519 &thrower, isolate, &module_env, &functions[i], i); | 525 &thrower, isolate, &module_env, &functions[i], i); |
520 } | 526 } |
521 } | 527 } |
522 | 528 |
523 uint32_t* StartCompilationTasks( | 529 uint32_t* StartCompilationTasks( |
524 Isolate* isolate, | 530 Isolate* isolate, |
525 std::vector<compiler::WasmCompilationUnit*>& compilation_units, | 531 std::vector<compiler::WasmCompilationUnit*>& compilation_units, |
526 std::queue<compiler::WasmCompilationUnit*>& executed_units, | 532 std::queue<compiler::WasmCompilationUnit*>& executed_units, |
527 const base::SmartPointer<base::Semaphore>& pending_tasks, | 533 const base::SmartPointer<base::Semaphore>& pending_tasks, |
528 base::Mutex& result_mutex, base::AtomicNumber<size_t>& next_unit) { | 534 base::Mutex& result_mutex, base::AtomicNumber<size_t>& next_unit) { |
529 const size_t num_tasks = | 535 const size_t num_tasks = |
530 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), | 536 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), |
531 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()); | 537 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()); |
532 uint32_t* task_ids = new uint32_t[num_tasks]; | 538 uint32_t* task_ids = new uint32_t[num_tasks]; |
533 for (size_t i = 0; i < num_tasks; i++) { | 539 for (size_t i = 0; i < num_tasks; ++i) { |
534 WasmCompilationTask* task = | 540 WasmCompilationTask* task = |
535 new WasmCompilationTask(isolate, &compilation_units, &executed_units, | 541 new WasmCompilationTask(isolate, &compilation_units, &executed_units, |
536 pending_tasks.get(), &result_mutex, &next_unit); | 542 pending_tasks.get(), &result_mutex, &next_unit); |
537 task_ids[i] = task->id(); | 543 task_ids[i] = task->id(); |
538 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 544 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
539 task, v8::Platform::kShortRunningTask); | 545 task, v8::Platform::kShortRunningTask); |
540 } | 546 } |
541 return task_ids; | 547 return task_ids; |
542 } | 548 } |
543 | 549 |
544 void WaitForCompilationTasks( | 550 void WaitForCompilationTasks( |
545 Isolate* isolate, uint32_t* task_ids, | 551 Isolate* isolate, uint32_t* task_ids, |
546 const base::SmartPointer<base::Semaphore>& pending_tasks) { | 552 const base::SmartPointer<base::Semaphore>& pending_tasks) { |
547 const size_t num_tasks = | 553 const size_t num_tasks = |
548 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), | 554 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), |
549 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()); | 555 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()); |
550 for (size_t i = 0; i < num_tasks; i++) { | 556 for (size_t i = 0; i < num_tasks; ++i) { |
551 // If the task has not started yet, then we abort it. Otherwise we wait for | 557 // If the task has not started yet, then we abort it. Otherwise we wait for |
552 // it to finish. | 558 // it to finish. |
553 if (!isolate->cancelable_task_manager()->TryAbort(task_ids[i])) { | 559 if (!isolate->cancelable_task_manager()->TryAbort(task_ids[i])) { |
554 pending_tasks->Wait(); | 560 pending_tasks->Wait(); |
555 } | 561 } |
556 } | 562 } |
557 } | 563 } |
558 | 564 |
559 void FinishCompilationUnits( | 565 void FinishCompilationUnits( |
560 std::queue<compiler::WasmCompilationUnit*>& executed_units, | 566 std::queue<compiler::WasmCompilationUnit*>& executed_units, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
639 // Finish the compilation of the remaining compilation units. | 645 // Finish the compilation of the remaining compilation units. |
640 FinishCompilationUnits(executed_units, functions, result_mutex); | 646 FinishCompilationUnits(executed_units, functions, result_mutex); |
641 } | 647 } |
642 | 648 |
643 void CompileSequentially(Isolate* isolate, const WasmModule* module, | 649 void CompileSequentially(Isolate* isolate, const WasmModule* module, |
644 std::vector<Handle<Code>>& functions, | 650 std::vector<Handle<Code>>& functions, |
645 ErrorThrower* thrower, ModuleEnv* module_env) { | 651 ErrorThrower* thrower, ModuleEnv* module_env) { |
646 DCHECK(!thrower->error()); | 652 DCHECK(!thrower->error()); |
647 | 653 |
648 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; | 654 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; |
649 i < module->functions.size(); i++) { | 655 i < module->functions.size(); ++i) { |
650 const WasmFunction& func = module->functions[i]; | 656 const WasmFunction& func = module->functions[i]; |
651 | 657 |
652 DCHECK_EQ(i, func.func_index); | 658 DCHECK_EQ(i, func.func_index); |
653 WasmName str = module->GetName(func.name_offset, func.name_length); | 659 WasmName str = module->GetName(func.name_offset, func.name_length); |
654 Handle<Code> code = Handle<Code>::null(); | 660 Handle<Code> code = Handle<Code>::null(); |
655 // Compile the function. | 661 // Compile the function. |
656 code = compiler::WasmCompilationUnit::CompileWasmFunction( | 662 code = compiler::WasmCompilationUnit::CompileWasmFunction( |
657 thrower, isolate, module_env, &func); | 663 thrower, isolate, module_env, &func); |
658 if (code.is_null()) { | 664 if (code.is_null()) { |
659 thrower->Error("Compilation of #%d:%.*s failed.", i, str.length(), | 665 thrower->Error("Compilation of #%d:%.*s failed.", i, str.length(), |
660 str.start()); | 666 str.start()); |
661 break; | 667 break; |
662 } | 668 } |
663 // Install the code into the linker table. | 669 // Install the code into the linker table. |
664 functions[i] = code; | 670 functions[i] = code; |
665 } | 671 } |
666 } | 672 } |
667 | 673 |
668 void PopulateFunctionTable(WasmModuleInstance* instance) { | 674 void PopulateFunctionTable(WasmModuleInstance* instance) { |
669 if (!instance->function_table.is_null()) { | 675 if (!instance->function_table.is_null()) { |
670 int table_size = static_cast<int>(instance->module->function_table.size()); | 676 uint32_t table_size = instance->module->FunctionTableSize(); |
671 DCHECK_EQ(instance->function_table->length(), table_size * 2); | 677 DCHECK_EQ(table_size * 2, instance->function_table->length()); |
672 for (int i = 0; i < table_size; i++) { | 678 uint32_t populated_table_size = |
673 instance->function_table->set( | 679 static_cast<uint32_t>(instance->module->function_table.size()); |
674 i + table_size, | 680 for (uint32_t i = 0; i < populated_table_size; ++i) { |
675 *instance->function_code[instance->module->function_table[i]]); | 681 instance->function_table->set( |
682 i + table_size, | |
683 *instance->function_code[instance->module->function_table[i]]); | |
676 } | 684 } |
677 } | 685 } |
678 } | 686 } |
679 } // namespace | 687 } // namespace |
680 | 688 |
681 void SetDeoptimizationData(Factory* factory, Handle<JSObject> js_object, | 689 void SetDeoptimizationData(Factory* factory, Handle<JSObject> js_object, |
682 std::vector<Handle<Code>>& functions) { | 690 std::vector<Handle<Code>>& functions) { |
683 for (size_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) { | 691 for (size_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) { |
684 Handle<Code> code = functions[i]; | 692 Handle<Code> code = functions[i]; |
685 DCHECK(code->deoptimization_data() == nullptr || | 693 DCHECK(code->deoptimization_data() == nullptr || |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1115 Object* info = wasm->GetInternalField(kWasmDebugInfo); | 1123 Object* info = wasm->GetInternalField(kWasmDebugInfo); |
1116 if (!info->IsUndefined(wasm->GetIsolate())) return WasmDebugInfo::cast(info); | 1124 if (!info->IsUndefined(wasm->GetIsolate())) return WasmDebugInfo::cast(info); |
1117 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(handle(wasm)); | 1125 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(handle(wasm)); |
1118 wasm->SetInternalField(kWasmDebugInfo, *new_info); | 1126 wasm->SetInternalField(kWasmDebugInfo, *new_info); |
1119 return *new_info; | 1127 return *new_info; |
1120 } | 1128 } |
1121 | 1129 |
1122 } // namespace wasm | 1130 } // namespace wasm |
1123 } // namespace internal | 1131 } // namespace internal |
1124 } // namespace v8 | 1132 } // namespace v8 |
OLD | NEW |