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 <memory> | 5 #include <memory> |
6 | 6 |
7 #include "src/base/atomic-utils.h" | 7 #include "src/base/atomic-utils.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 | 9 |
10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 // Install the code into the linker table. | 432 // Install the code into the linker table. |
433 functions[i] = code; | 433 functions[i] = code; |
434 } | 434 } |
435 } | 435 } |
436 | 436 |
437 void PatchDirectCalls(Handle<FixedArray> old_functions, | 437 void PatchDirectCalls(Handle<FixedArray> old_functions, |
438 Handle<FixedArray> new_functions, int start) { | 438 Handle<FixedArray> new_functions, int start) { |
439 DCHECK_EQ(new_functions->length(), old_functions->length()); | 439 DCHECK_EQ(new_functions->length(), old_functions->length()); |
440 | 440 |
441 DisallowHeapAllocation no_gc; | 441 DisallowHeapAllocation no_gc; |
442 std::map<Code*, Code*> old_to_new_code; | 442 std::map<Code*, HeapObject*> old_to_new_code; |
443 for (int i = 0; i < new_functions->length(); ++i) { | 443 for (int i = 0; i < new_functions->length(); ++i) { |
444 old_to_new_code.insert(std::make_pair(Code::cast(old_functions->get(i)), | 444 old_to_new_code.insert( |
445 Code::cast(new_functions->get(i)))); | 445 std::make_pair(Code::cast(old_functions->get(i)), |
| 446 HeapObject::cast(new_functions->get(i)))); |
446 } | 447 } |
447 int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); | 448 int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
448 AllowDeferredHandleDereference embedding_raw_address; | 449 AllowDeferredHandleDereference embedding_raw_address; |
449 for (int i = start; i < new_functions->length(); ++i) { | 450 for (int i = start; i < new_functions->length(); ++i) { |
450 Code* wasm_function = Code::cast(new_functions->get(i)); | 451 Code* wasm_function = Code::cast(new_functions->get(i)); |
451 for (RelocIterator it(wasm_function, mode_mask); !it.done(); it.next()) { | 452 for (RelocIterator it(wasm_function, mode_mask); !it.done(); it.next()) { |
452 Code* old_code = | 453 Code* old_code = |
453 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); | 454 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); |
454 if (old_code->kind() == Code::WASM_TO_JS_FUNCTION || | 455 if (old_code->kind() == Code::WASM_TO_JS_FUNCTION || |
455 old_code->kind() == Code::WASM_FUNCTION) { | 456 old_code->kind() == Code::WASM_FUNCTION) { |
456 auto found = old_to_new_code.find(old_code); | 457 auto found = old_to_new_code.find(old_code); |
457 DCHECK(found != old_to_new_code.end()); | 458 DCHECK(found != old_to_new_code.end()); |
458 Code* new_code = found->second; | 459 HeapObject* new_code = found->second; |
459 if (new_code != old_code) { | 460 if (new_code != old_code) { |
460 it.rinfo()->set_target_address(new_code->instruction_start(), | 461 if (new_code->IsCode()) { |
461 UPDATE_WRITE_BARRIER, | 462 it.rinfo()->set_target_address( |
462 SKIP_ICACHE_FLUSH); | 463 Code::cast(new_code)->instruction_start(), UPDATE_WRITE_BARRIER, |
| 464 SKIP_ICACHE_FLUSH); |
| 465 } else { |
| 466 DCHECK(new_code->IsForeign()); |
| 467 it.rinfo()->set_target_address( |
| 468 ExternalReference(Foreign::cast(new_code)->foreign_address(), |
| 469 it.rinfo()->isolate(), |
| 470 ExternalReference::BUILTIN_FP_FP_CALL) |
| 471 .address(), |
| 472 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH); |
| 473 } |
463 } | 474 } |
464 } | 475 } |
465 } | 476 } |
466 } | 477 } |
467 } | 478 } |
468 | 479 |
469 static void ResetCompiledModule(Isolate* isolate, JSObject* owner, | 480 static void ResetCompiledModule(Isolate* isolate, JSObject* owner, |
470 WasmCompiledModule* compiled_module) { | 481 WasmCompiledModule* compiled_module) { |
471 TRACE("Resetting %d\n", compiled_module->instance_id()); | 482 TRACE("Resetting %d\n", compiled_module->instance_id()); |
472 Object* undefined = *isolate->factory()->undefined_value(); | 483 Object* undefined = *isolate->factory()->undefined_value(); |
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 | 1387 |
1377 switch (import.kind) { | 1388 switch (import.kind) { |
1378 case kExternalFunction: { | 1389 case kExternalFunction: { |
1379 // Function imports must be callable. | 1390 // Function imports must be callable. |
1380 Handle<Object> function = result.ToHandleChecked(); | 1391 Handle<Object> function = result.ToHandleChecked(); |
1381 if (!function->IsCallable()) { | 1392 if (!function->IsCallable()) { |
1382 ReportFFIError("function import requires a callable", index, | 1393 ReportFFIError("function import requires a callable", index, |
1383 module_name, function_name); | 1394 module_name, function_name); |
1384 return -1; | 1395 return -1; |
1385 } | 1396 } |
1386 | 1397 Handle<JSReceiver> function_as_receiver = |
1387 Handle<Code> import_wrapper = CompileImportWrapper( | 1398 Handle<JSReceiver>::cast(function); |
1388 index, import, Handle<JSReceiver>::cast(function), module_name, | 1399 Handle<String> native_variant_key = |
1389 function_name); | 1400 isolate_->factory()->InternalizeUtf8String("native_variant"); |
1390 code_table->set(num_imported_functions, *import_wrapper); | 1401 MaybeHandle<Object> maybeObj = |
1391 RecordStats(isolate_, *import_wrapper); | 1402 JSReceiver::GetProperty(function_as_receiver, native_variant_key); |
| 1403 Handle<Object> native_variant; |
| 1404 if (maybeObj.ToHandle(&native_variant) && |
| 1405 native_variant->IsJSObject()) { |
| 1406 Handle<Foreign> foreign(Foreign::cast( |
| 1407 JSObject::cast(*native_variant)->GetInternalField(0))); |
| 1408 code_table->set(num_imported_functions, *foreign); |
| 1409 } else { |
| 1410 Handle<Code> import_wrapper = |
| 1411 CompileImportWrapper(index, import, function_as_receiver, |
| 1412 module_name, function_name); |
| 1413 code_table->set(num_imported_functions, *import_wrapper); |
| 1414 RecordStats(isolate_, *import_wrapper); |
| 1415 } |
1392 num_imported_functions++; | 1416 num_imported_functions++; |
1393 break; | 1417 break; |
1394 } | 1418 } |
1395 case kExternalTable: | 1419 case kExternalTable: |
1396 // TODO(titzer): Table imports must be a WebAssembly.Table. | 1420 // TODO(titzer): Table imports must be a WebAssembly.Table. |
1397 break; | 1421 break; |
1398 case kExternalMemory: { | 1422 case kExternalMemory: { |
1399 Handle<Object> object = result.ToHandleChecked(); | 1423 Handle<Object> object = result.ToHandleChecked(); |
1400 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) { | 1424 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) { |
1401 ReportFFIError("memory import must be a WebAssembly.Memory object", | 1425 ReportFFIError("memory import must be a WebAssembly.Memory object", |
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1981 CHECK_NOT_NULL(result.val); | 2005 CHECK_NOT_NULL(result.val); |
1982 module = const_cast<WasmModule*>(result.val); | 2006 module = const_cast<WasmModule*>(result.val); |
1983 } | 2007 } |
1984 | 2008 |
1985 Handle<WasmModuleWrapper> module_wrapper = | 2009 Handle<WasmModuleWrapper> module_wrapper = |
1986 WasmModuleWrapper::New(isolate, module); | 2010 WasmModuleWrapper::New(isolate, module); |
1987 | 2011 |
1988 compiled_module->set_module_wrapper(module_wrapper); | 2012 compiled_module->set_module_wrapper(module_wrapper); |
1989 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); | 2013 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); |
1990 } | 2014 } |
OLD | NEW |