Chromium Code Reviews| 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 |
| 11 #include "src/simulator.h" | 11 #include "src/simulator.h" |
| 12 | 12 |
| 13 #include "src/wasm/ast-decoder.h" | 13 #include "src/wasm/ast-decoder.h" |
| 14 #include "src/wasm/module-decoder.h" | 14 #include "src/wasm/module-decoder.h" |
| 15 #include "src/wasm/wasm-debug.h" | |
| 15 #include "src/wasm/wasm-function-name-table.h" | 16 #include "src/wasm/wasm-function-name-table.h" |
| 16 #include "src/wasm/wasm-module.h" | 17 #include "src/wasm/wasm-module.h" |
| 17 #include "src/wasm/wasm-result.h" | 18 #include "src/wasm/wasm-result.h" |
| 18 | 19 |
| 19 #include "src/compiler/wasm-compiler.h" | 20 #include "src/compiler/wasm-compiler.h" |
| 20 | 21 |
| 21 namespace v8 { | 22 namespace v8 { |
| 22 namespace internal { | 23 namespace internal { |
| 23 namespace wasm { | 24 namespace wasm { |
| 24 | 25 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 } | 199 } |
| 199 if (modified) { | 200 if (modified) { |
| 200 Assembler::FlushICache(isolate_, code->instruction_start(), | 201 Assembler::FlushICache(isolate_, code->instruction_start(), |
| 201 code->instruction_size()); | 202 code->instruction_size()); |
| 202 } | 203 } |
| 203 } | 204 } |
| 204 }; | 205 }; |
| 205 | 206 |
| 206 namespace { | 207 namespace { |
| 207 // Internal constants for the layout of the module object. | 208 // Internal constants for the layout of the module object. |
| 208 const int kWasmModuleInternalFieldCount = 5; | |
| 209 const int kWasmModuleFunctionTable = 0; | 209 const int kWasmModuleFunctionTable = 0; |
| 210 const int kWasmModuleCodeTable = 1; | 210 const int kWasmModuleCodeTable = 1; |
| 211 const int kWasmMemArrayBuffer = 2; | 211 const int kWasmMemArrayBuffer = 2; |
| 212 const int kWasmGlobalsArrayBuffer = 3; | 212 const int kWasmGlobalsArrayBuffer = 3; |
| 213 // TODO(clemensh): Remove function name array, extract names from module bytes. | |
|
ahaas
2016/06/16 12:55:09
Will you have time to do this? In not, I think you
clemensh
2016/06/16 15:59:50
If needed, I will do this at the very end for all
| |
| 213 const int kWasmFunctionNamesArray = 4; | 214 const int kWasmFunctionNamesArray = 4; |
| 215 const int kWasmModuleBytesString = 5; | |
| 216 const int kWasmDebugInfo = 6; | |
| 217 const int kWasmModuleInternalFieldCount = 7; | |
| 214 | 218 |
| 215 void LoadDataSegments(const WasmModule* module, byte* mem_addr, | 219 void LoadDataSegments(const WasmModule* module, byte* mem_addr, |
| 216 size_t mem_size) { | 220 size_t mem_size) { |
| 217 for (const WasmDataSegment& segment : module->data_segments) { | 221 for (const WasmDataSegment& segment : module->data_segments) { |
| 218 if (!segment.init) continue; | 222 if (!segment.init) continue; |
| 219 if (!segment.source_size) continue; | 223 if (!segment.source_size) continue; |
| 220 CHECK_LT(segment.dest_addr, mem_size); | 224 CHECK_LT(segment.dest_addr, mem_size); |
| 221 CHECK_LE(segment.source_size, mem_size); | 225 CHECK_LE(segment.source_size, mem_size); |
| 222 CHECK_LE(segment.dest_addr + segment.source_size, mem_size); | 226 CHECK_LE(segment.dest_addr + segment.source_size, mem_size); |
| 223 byte* addr = mem_addr + segment.dest_addr; | 227 byte* addr = mem_addr + segment.dest_addr; |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 694 //------------------------------------------------------------------------- | 698 //------------------------------------------------------------------------- |
| 695 Handle<Map> map = factory->NewMap( | 699 Handle<Map> map = factory->NewMap( |
| 696 JS_OBJECT_TYPE, | 700 JS_OBJECT_TYPE, |
| 697 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); | 701 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); |
| 698 WasmModuleInstance instance(this); | 702 WasmModuleInstance instance(this); |
| 699 instance.context = isolate->native_context(); | 703 instance.context = isolate->native_context(); |
| 700 instance.js_object = factory->NewJSObjectFromMap(map, TENURED); | 704 instance.js_object = factory->NewJSObjectFromMap(map, TENURED); |
| 701 Handle<FixedArray> code_table = | 705 Handle<FixedArray> code_table = |
| 702 factory->NewFixedArray(static_cast<int>(functions.size()), TENURED); | 706 factory->NewFixedArray(static_cast<int>(functions.size()), TENURED); |
| 703 instance.js_object->SetInternalField(kWasmModuleCodeTable, *code_table); | 707 instance.js_object->SetInternalField(kWasmModuleCodeTable, *code_table); |
| 708 int module_bytes_len = static_cast<int>(instance.module->module_end - | |
| 709 instance.module->module_start); | |
| 710 DCHECK_EQ(instance.module->module_end - instance.module->module_start, | |
|
ahaas
2016/06/16 12:55:09
I don't think that this DCHECK is necessary. I wou
clemensh
2016/06/16 15:59:50
This is to check for int-overflows. I refactored t
| |
| 711 module_bytes_len); | |
| 712 Vector<const uint8_t> module_bytes_vec(instance.module->module_start, | |
| 713 module_bytes_len); | |
| 714 Handle<String> module_bytes_string = | |
| 715 factory->NewStringFromOneByte(module_bytes_vec, TENURED) | |
| 716 .ToHandleChecked(); | |
| 717 instance.js_object->SetInternalField(kWasmModuleBytesString, | |
| 718 *module_bytes_string); | |
| 704 | 719 |
| 705 //------------------------------------------------------------------------- | 720 //------------------------------------------------------------------------- |
| 706 // Allocate and initialize the linear memory. | 721 // Allocate and initialize the linear memory. |
| 707 //------------------------------------------------------------------------- | 722 //------------------------------------------------------------------------- |
| 708 isolate->counters()->wasm_min_mem_pages_count()->AddSample( | 723 isolate->counters()->wasm_min_mem_pages_count()->AddSample( |
| 709 instance.module->min_mem_pages); | 724 instance.module->min_mem_pages); |
| 710 isolate->counters()->wasm_max_mem_pages_count()->AddSample( | 725 isolate->counters()->wasm_max_mem_pages_count()->AddSample( |
| 711 instance.module->max_mem_pages); | 726 instance.module->max_mem_pages); |
| 712 if (memory.is_null()) { | 727 if (memory.is_null()) { |
| 713 if (!AllocateMemory(&thrower, isolate, &instance)) { | 728 if (!AllocateMemory(&thrower, isolate, &instance)) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 836 //------------------------------------------------------------------------- | 851 //------------------------------------------------------------------------- |
| 837 // Attach the function name table. | 852 // Attach the function name table. |
| 838 //------------------------------------------------------------------------- | 853 //------------------------------------------------------------------------- |
| 839 Handle<ByteArray> function_name_table = | 854 Handle<ByteArray> function_name_table = |
| 840 BuildFunctionNamesTable(isolate, module_env.module); | 855 BuildFunctionNamesTable(isolate, module_env.module); |
| 841 instance.js_object->SetInternalField(kWasmFunctionNamesArray, | 856 instance.js_object->SetInternalField(kWasmFunctionNamesArray, |
| 842 *function_name_table); | 857 *function_name_table); |
| 843 | 858 |
| 844 code_stats.Report(); | 859 code_stats.Report(); |
| 845 | 860 |
| 861 if (isolate->debug()->is_active()) { | |
| 862 // Trigger creation of the debug info, this will inform the debugger about | |
| 863 // the new module. | |
| 864 wasm::GetDebugInfo(*instance.js_object); | |
|
ahaas
2016/06/16 12:55:09
In GetDebugInfo you access the internal field kWas
clemensh
2016/06/16 15:59:50
Internal fields are auto-initialized to undefined.
| |
| 865 } | |
| 866 | |
| 846 // Run the start function if one was specified. | 867 // Run the start function if one was specified. |
| 847 if (this->start_function_index >= 0) { | 868 if (this->start_function_index >= 0) { |
| 848 HandleScope scope(isolate); | 869 HandleScope scope(isolate); |
| 849 uint32_t index = static_cast<uint32_t>(this->start_function_index); | 870 uint32_t index = static_cast<uint32_t>(this->start_function_index); |
| 850 Handle<String> name = isolate->factory()->NewStringFromStaticChars("start"); | 871 Handle<String> name = isolate->factory()->NewStringFromStaticChars("start"); |
| 851 Handle<Code> code = instance.function_code[index]; | 872 Handle<Code> code = instance.function_code[index]; |
| 852 Handle<JSFunction> jsfunc = compiler::CompileJSToWasmWrapper( | 873 Handle<JSFunction> jsfunc = compiler::CompileJSToWasmWrapper( |
| 853 isolate, &module_env, name, code, instance.js_object, index); | 874 isolate, &module_env, name, code, instance.js_object, index); |
| 854 | 875 |
| 855 // Call the JS function. | 876 // Call the JS function. |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1003 Handle<String> GetWasmFunctionName(Isolate* isolate, Handle<Object> wasm, | 1024 Handle<String> GetWasmFunctionName(Isolate* isolate, Handle<Object> wasm, |
| 1004 uint32_t func_index) { | 1025 uint32_t func_index) { |
| 1005 Handle<Object> name_or_null = | 1026 Handle<Object> name_or_null = |
| 1006 GetWasmFunctionNameOrNull(isolate, wasm, func_index); | 1027 GetWasmFunctionNameOrNull(isolate, wasm, func_index); |
| 1007 if (!name_or_null->IsNull(isolate)) { | 1028 if (!name_or_null->IsNull(isolate)) { |
| 1008 return Handle<String>::cast(name_or_null); | 1029 return Handle<String>::cast(name_or_null); |
| 1009 } | 1030 } |
| 1010 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); | 1031 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); |
| 1011 } | 1032 } |
| 1012 | 1033 |
| 1013 bool IsWasmObject(Handle<JSObject> object) { | 1034 bool IsWasmObject(Object* object) { |
| 1014 // TODO(clemensh): Check wasm byte header once we store a copy of the bytes. | 1035 if (!object->IsJSObject()) return false; |
| 1015 return object->GetInternalFieldCount() == kWasmModuleInternalFieldCount && | 1036 JSObject* obj = JSObject::cast(object); |
| 1016 object->GetInternalField(kWasmModuleCodeTable)->IsFixedArray() && | 1037 if (obj->GetInternalFieldCount() != kWasmModuleInternalFieldCount || |
| 1017 object->GetInternalField(kWasmMemArrayBuffer)->IsJSArrayBuffer() && | 1038 !obj->GetInternalField(kWasmModuleCodeTable)->IsFixedArray() || |
| 1018 object->GetInternalField(kWasmFunctionNamesArray)->IsByteArray(); | 1039 !obj->GetInternalField(kWasmMemArrayBuffer)->IsJSArrayBuffer() || |
| 1040 !obj->GetInternalField(kWasmFunctionNamesArray)->IsByteArray() || | |
| 1041 !obj->GetInternalField(kWasmModuleBytesString)->IsSeqOneByteString()) { | |
| 1042 return false; | |
| 1043 } | |
| 1044 DisallowHeapAllocation no_gc; | |
| 1045 SeqOneByteString* bytes = | |
| 1046 SeqOneByteString::cast(obj->GetInternalField(kWasmModuleBytesString)); | |
| 1047 if (bytes->length() < 4) return false; | |
| 1048 if (memcmp(bytes->GetChars(), "\0asm", 4)) return false; | |
| 1049 | |
| 1050 // All checks passed. | |
| 1051 return true; | |
| 1052 } | |
| 1053 | |
| 1054 SeqOneByteString* GetWasmBytes(JSObject* wasm) { | |
| 1055 return SeqOneByteString::cast(wasm->GetInternalField(kWasmModuleBytesString)); | |
| 1056 } | |
| 1057 | |
| 1058 WasmDebugInfo* GetDebugInfo(JSObject* wasm) { | |
| 1059 Object* info = wasm->GetInternalField(kWasmDebugInfo); | |
| 1060 if (!info->IsUndefined(wasm->GetIsolate())) return WasmDebugInfo::cast(info); | |
| 1061 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(handle(wasm)); | |
| 1062 wasm->SetInternalField(kWasmDebugInfo, *new_info); | |
| 1063 return *new_info; | |
| 1019 } | 1064 } |
| 1020 | 1065 |
| 1021 } // namespace wasm | 1066 } // namespace wasm |
| 1022 } // namespace internal | 1067 } // namespace internal |
| 1023 } // namespace v8 | 1068 } // namespace v8 |
| OLD | NEW |