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/asmjs/asm-js.h" | 5 #include "src/asmjs/asm-js.h" |
6 | 6 |
7 #include "src/api-natives.h" | 7 #include "src/api-natives.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/asmjs/asm-typer.h" | 9 #include "src/asmjs/asm-typer.h" |
10 #include "src/asmjs/asm-wasm-builder.h" | 10 #include "src/asmjs/asm-wasm-builder.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "src/wasm/wasm-result.h" | 24 #include "src/wasm/wasm-result.h" |
25 | 25 |
26 typedef uint8_t byte; | 26 typedef uint8_t byte; |
27 | 27 |
28 using v8::internal::wasm::ErrorThrower; | 28 using v8::internal::wasm::ErrorThrower; |
29 | 29 |
30 namespace v8 { | 30 namespace v8 { |
31 namespace internal { | 31 namespace internal { |
32 | 32 |
33 namespace { | 33 namespace { |
| 34 enum WasmDataEntries { |
| 35 kWasmDataCompiledModule, |
| 36 kWasmDataForeignGlobals, |
| 37 kWasmDataUsesArray, |
| 38 kWasmDataScript, |
| 39 kWasmDataScriptPosition, |
| 40 kWasmDataEntryCount, |
| 41 }; |
| 42 |
34 Handle<i::Object> StdlibMathMember(i::Isolate* isolate, | 43 Handle<i::Object> StdlibMathMember(i::Isolate* isolate, |
35 Handle<JSReceiver> stdlib, | 44 Handle<JSReceiver> stdlib, |
36 Handle<Name> name) { | 45 Handle<Name> name) { |
37 if (stdlib.is_null()) { | 46 if (stdlib.is_null()) { |
38 return Handle<i::Object>(); | 47 return Handle<i::Object>(); |
39 } | 48 } |
40 Handle<i::Name> math_name( | 49 Handle<i::Name> math_name( |
41 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("Math"))); | 50 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("Math"))); |
42 MaybeHandle<i::Object> maybe_math = i::Object::GetProperty(stdlib, math_name); | 51 MaybeHandle<i::Object> maybe_math = i::Object::GetProperty(stdlib, math_name); |
43 if (maybe_math.is_null()) { | 52 if (maybe_math.is_null()) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 STDLIB_MATH_CONST(SQRT1_2, 0.7071067811865476) | 153 STDLIB_MATH_CONST(SQRT1_2, 0.7071067811865476) |
145 STDLIB_MATH_CONST(SQRT2, 1.4142135623730951) | 154 STDLIB_MATH_CONST(SQRT2, 1.4142135623730951) |
146 #undef STDLIB_MATH_CONST | 155 #undef STDLIB_MATH_CONST |
147 default: { UNREACHABLE(); } | 156 default: { UNREACHABLE(); } |
148 } | 157 } |
149 return false; | 158 return false; |
150 } | 159 } |
151 | 160 |
152 } // namespace | 161 } // namespace |
153 | 162 |
154 MaybeHandle<FixedArray> AsmJs::ConvertAsmToWasm(ParseInfo* info) { | 163 MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(ParseInfo* info) { |
155 ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion"); | 164 ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion"); |
| 165 base::ElapsedTimer asm_wasm_timer; |
| 166 asm_wasm_timer.Start(); |
156 wasm::AsmWasmBuilder builder(info->isolate(), info->zone(), | 167 wasm::AsmWasmBuilder builder(info->isolate(), info->zone(), |
157 info->ast_value_factory(), info->script(), | 168 info->ast_value_factory(), info->script(), |
158 info->literal()); | 169 info->literal()); |
159 Handle<FixedArray> foreign_globals; | 170 Handle<FixedArray> foreign_globals; |
160 auto asm_wasm_result = builder.Run(&foreign_globals); | 171 auto asm_wasm_result = builder.Run(&foreign_globals); |
161 if (!asm_wasm_result.success) { | 172 if (!asm_wasm_result.success) { |
162 DCHECK(!info->isolate()->has_pending_exception()); | 173 DCHECK(!info->isolate()->has_pending_exception()); |
163 MessageHandler::ReportMessage(info->isolate(), | 174 MessageHandler::ReportMessage(info->isolate(), |
164 builder.typer()->message_location(), | 175 builder.typer()->message_location(), |
165 builder.typer()->error_message()); | 176 builder.typer()->error_message()); |
166 return MaybeHandle<FixedArray>(); | 177 return MaybeHandle<FixedArray>(); |
167 } | 178 } |
| 179 double asm_wasm_time = asm_wasm_timer.Elapsed().InMillisecondsF(); |
| 180 |
168 wasm::ZoneBuffer* module = asm_wasm_result.module_bytes; | 181 wasm::ZoneBuffer* module = asm_wasm_result.module_bytes; |
169 wasm::ZoneBuffer* asm_offsets = asm_wasm_result.asm_offset_table; | 182 wasm::ZoneBuffer* asm_offsets = asm_wasm_result.asm_offset_table; |
170 | 183 |
| 184 base::ElapsedTimer compile_timer; |
| 185 compile_timer.Start(); |
171 MaybeHandle<JSObject> compiled = wasm::CreateModuleObjectFromBytes( | 186 MaybeHandle<JSObject> compiled = wasm::CreateModuleObjectFromBytes( |
172 info->isolate(), module->begin(), module->end(), &thrower, | 187 info->isolate(), module->begin(), module->end(), &thrower, |
173 internal::wasm::kAsmJsOrigin, info->script(), asm_offsets->begin(), | 188 internal::wasm::kAsmJsOrigin, info->script(), asm_offsets->begin(), |
174 asm_offsets->end()); | 189 asm_offsets->end()); |
175 DCHECK(!compiled.is_null()); | 190 DCHECK(!compiled.is_null()); |
| 191 double compile_time = compile_timer.Elapsed().InMillisecondsF(); |
176 | 192 |
177 wasm::AsmTyper::StdlibSet uses = builder.typer()->StdlibUses(); | 193 wasm::AsmTyper::StdlibSet uses = builder.typer()->StdlibUses(); |
178 Handle<FixedArray> uses_array = | 194 Handle<FixedArray> uses_array = |
179 info->isolate()->factory()->NewFixedArray(static_cast<int>(uses.size())); | 195 info->isolate()->factory()->NewFixedArray(static_cast<int>(uses.size())); |
180 int count = 0; | 196 int count = 0; |
181 for (auto i : uses) { | 197 for (auto i : uses) { |
182 uses_array->set(count++, Smi::FromInt(i)); | 198 uses_array->set(count++, Smi::FromInt(i)); |
183 } | 199 } |
184 | 200 |
185 Handle<FixedArray> result = info->isolate()->factory()->NewFixedArray(3); | 201 Handle<FixedArray> result = |
186 result->set(0, *compiled.ToHandleChecked()); | 202 info->isolate()->factory()->NewFixedArray(kWasmDataEntryCount); |
187 result->set(1, *foreign_globals); | 203 result->set(kWasmDataCompiledModule, *compiled.ToHandleChecked()); |
188 result->set(2, *uses_array); | 204 result->set(kWasmDataForeignGlobals, *foreign_globals); |
| 205 result->set(kWasmDataUsesArray, *uses_array); |
| 206 result->set(kWasmDataScript, *info->script()); |
| 207 result->set(kWasmDataScriptPosition, |
| 208 Smi::FromInt(info->literal()->position())); |
| 209 |
| 210 MessageLocation location(info->script(), info->literal()->position(), |
| 211 info->literal()->position()); |
| 212 char text[100]; |
| 213 int length = base::OS::SNPrintF(text, arraysize(text), |
| 214 "asm->wasm: %0.3f ms, compile: %0.3f ms", |
| 215 asm_wasm_time, compile_time); |
| 216 DCHECK_NE(-1, length); |
| 217 USE(length); |
| 218 Handle<String> stext(info->isolate()->factory()->InternalizeUtf8String(text)); |
| 219 Handle<JSMessageObject> message = MessageHandler::MakeMessageObject( |
| 220 info->isolate(), MessageTemplate::kAsmJsCompiled, &location, stext, |
| 221 Handle<JSArray>::null()); |
| 222 message->set_error_level(v8::Isolate::kMessageInfo); |
| 223 MessageHandler::ReportMessage(info->isolate(), &location, message); |
| 224 |
189 return result; | 225 return result; |
190 } | 226 } |
191 | 227 |
192 bool AsmJs::IsStdlibValid(i::Isolate* isolate, Handle<FixedArray> wasm_data, | 228 bool AsmJs::IsStdlibValid(i::Isolate* isolate, Handle<FixedArray> wasm_data, |
193 Handle<JSReceiver> stdlib) { | 229 Handle<JSReceiver> stdlib) { |
194 i::Handle<i::FixedArray> uses(i::FixedArray::cast(wasm_data->get(2))); | 230 i::Handle<i::FixedArray> uses( |
| 231 i::FixedArray::cast(wasm_data->get(kWasmDataUsesArray))); |
195 for (int i = 0; i < uses->length(); ++i) { | 232 for (int i = 0; i < uses->length(); ++i) { |
196 if (!IsStdlibMemberValid(isolate, stdlib, | 233 if (!IsStdlibMemberValid(isolate, stdlib, |
197 uses->GetValueChecked<i::Object>(isolate, i))) { | 234 uses->GetValueChecked<i::Object>(isolate, i))) { |
198 return false; | 235 return false; |
199 } | 236 } |
200 } | 237 } |
201 return true; | 238 return true; |
202 } | 239 } |
203 | 240 |
204 MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate, | 241 MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate, |
205 Handle<FixedArray> wasm_data, | 242 Handle<FixedArray> wasm_data, |
206 Handle<JSArrayBuffer> memory, | 243 Handle<JSArrayBuffer> memory, |
207 Handle<JSReceiver> foreign) { | 244 Handle<JSReceiver> foreign) { |
208 i::Handle<i::JSObject> module(i::JSObject::cast(wasm_data->get(0))); | 245 base::ElapsedTimer instantiate_timer; |
| 246 instantiate_timer.Start(); |
| 247 i::Handle<i::JSObject> module( |
| 248 i::JSObject::cast(wasm_data->get(kWasmDataCompiledModule))); |
209 i::Handle<i::FixedArray> foreign_globals( | 249 i::Handle<i::FixedArray> foreign_globals( |
210 i::FixedArray::cast(wasm_data->get(1))); | 250 i::FixedArray::cast(wasm_data->get(kWasmDataForeignGlobals))); |
211 | 251 |
212 ErrorThrower thrower(isolate, "Asm.js -> WebAssembly instantiation"); | 252 ErrorThrower thrower(isolate, "Asm.js -> WebAssembly instantiation"); |
213 | 253 |
214 i::MaybeHandle<i::JSObject> maybe_module_object = | 254 i::MaybeHandle<i::JSObject> maybe_module_object = |
215 i::wasm::WasmModule::Instantiate(isolate, &thrower, module, foreign, | 255 i::wasm::WasmModule::Instantiate(isolate, &thrower, module, foreign, |
216 memory); | 256 memory); |
217 if (maybe_module_object.is_null()) { | 257 if (maybe_module_object.is_null()) { |
218 return MaybeHandle<Object>(); | 258 return MaybeHandle<Object>(); |
219 } | 259 } |
220 | 260 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 | 292 |
253 i::Handle<i::Name> single_function_name( | 293 i::Handle<i::Name> single_function_name( |
254 isolate->factory()->InternalizeUtf8String( | 294 isolate->factory()->InternalizeUtf8String( |
255 wasm::AsmWasmBuilder::single_function_name)); | 295 wasm::AsmWasmBuilder::single_function_name)); |
256 i::MaybeHandle<i::Object> single_function = | 296 i::MaybeHandle<i::Object> single_function = |
257 i::Object::GetProperty(module_object, single_function_name); | 297 i::Object::GetProperty(module_object, single_function_name); |
258 if (!single_function.is_null() && | 298 if (!single_function.is_null() && |
259 !single_function.ToHandleChecked()->IsUndefined(isolate)) { | 299 !single_function.ToHandleChecked()->IsUndefined(isolate)) { |
260 return single_function; | 300 return single_function; |
261 } | 301 } |
| 302 |
| 303 i::Handle<i::Script> script(i::Script::cast(wasm_data->get(kWasmDataScript))); |
| 304 int32_t position = 0; |
| 305 if (!wasm_data->get(kWasmDataScriptPosition)->ToInt32(&position)) { |
| 306 UNREACHABLE(); |
| 307 } |
| 308 MessageLocation location(script, position, position); |
| 309 char text[50]; |
| 310 int length = |
| 311 base::OS::SNPrintF(text, arraysize(text), "%0.3f ms", |
| 312 instantiate_timer.Elapsed().InMillisecondsF()); |
| 313 DCHECK_NE(-1, length); |
| 314 USE(length); |
| 315 Handle<String> stext(isolate->factory()->InternalizeUtf8String(text)); |
| 316 Handle<JSMessageObject> message = MessageHandler::MakeMessageObject( |
| 317 isolate, MessageTemplate::kAsmJsInstantiated, &location, stext, |
| 318 Handle<JSArray>::null()); |
| 319 message->set_error_level(v8::Isolate::kMessageInfo); |
| 320 MessageHandler::ReportMessage(isolate, &location, message); |
| 321 |
262 return module_object; | 322 return module_object; |
263 } | 323 } |
264 | 324 |
265 } // namespace internal | 325 } // namespace internal |
266 } // namespace v8 | 326 } // namespace v8 |
OLD | NEW |