| 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/wasm/module-decoder.h" | 5 #include "src/wasm/module-decoder.h" |
| 6 | 6 |
| 7 #include "src/base/functional.h" | 7 #include "src/base/functional.h" |
| 8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
| 9 #include "src/base/template-utils.h" | 9 #include "src/base/template-utils.h" |
| 10 #include "src/counters.h" | 10 #include "src/counters.h" |
| (...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1204 // FunctionSig stores the return types first. | 1204 // FunctionSig stores the return types first. |
| 1205 ValueType* buffer = zone->NewArray<ValueType>(param_count + return_count); | 1205 ValueType* buffer = zone->NewArray<ValueType>(param_count + return_count); |
| 1206 uint32_t b = 0; | 1206 uint32_t b = 0; |
| 1207 for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i]; | 1207 for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i]; |
| 1208 for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i]; | 1208 for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i]; |
| 1209 | 1209 |
| 1210 return new (zone) FunctionSig(return_count, param_count, buffer); | 1210 return new (zone) FunctionSig(return_count, param_count, buffer); |
| 1211 } | 1211 } |
| 1212 }; | 1212 }; |
| 1213 | 1213 |
| 1214 ModuleResult DecodeWasmModuleInternal(Isolate* isolate, | 1214 } // namespace |
| 1215 const byte* module_start, | 1215 |
| 1216 const byte* module_end, | 1216 ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start, |
| 1217 bool verify_functions, | 1217 const byte* module_end, bool verify_functions, |
| 1218 ModuleOrigin origin, bool is_sync) { | 1218 ModuleOrigin origin, Counters* counters, |
| 1219 bool is_sync) { |
| 1220 auto counter = origin == kWasmOrigin |
| 1221 ? counters->wasm_decode_wasm_module_time() |
| 1222 : counters->wasm_decode_asm_module_time(); |
| 1223 TimedHistogramScope wasm_decode_module_time_scope(counter); |
| 1219 size_t size = module_end - module_start; | 1224 size_t size = module_end - module_start; |
| 1220 if (module_start > module_end) return ModuleResult::Error("start > end"); | 1225 if (module_start > module_end) return ModuleResult::Error("start > end"); |
| 1221 if (size >= kV8MaxWasmModuleSize) | 1226 if (size >= kV8MaxWasmModuleSize) |
| 1222 return ModuleResult::Error("size > maximum module size: %zu", size); | 1227 return ModuleResult::Error("size > maximum module size: %zu", size); |
| 1223 // TODO(bradnelson): Improve histogram handling of size_t. | 1228 // TODO(bradnelson): Improve histogram handling of size_t. |
| 1224 if (is_sync) { | 1229 if (is_sync) { |
| 1225 // TODO(karlschimpf): Make this work when asynchronous. | 1230 // TODO(karlschimpf): Make this work when asynchronous. |
| 1226 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | 1231 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 |
| 1227 auto counter = origin == kWasmOrigin | 1232 auto counter = origin == kWasmOrigin |
| 1228 ? isolate->counters()->wasm_wasm_module_size_bytes() | 1233 ? counters->wasm_wasm_module_size_bytes() |
| 1229 : isolate->counters()->wasm_asm_module_size_bytes(); | 1234 : counters->wasm_asm_module_size_bytes(); |
| 1230 counter->AddSample(static_cast<int>(size)); | 1235 counter->AddSample(static_cast<int>(size)); |
| 1231 } | 1236 } |
| 1232 // Signatures are stored in zone memory, which have the same lifetime | 1237 // Signatures are stored in zone memory, which have the same lifetime |
| 1233 // as the {module}. | 1238 // as the {module}. |
| 1234 ModuleDecoder decoder(module_start, module_end, origin); | 1239 ModuleDecoder decoder(module_start, module_end, origin); |
| 1235 ModuleResult result = decoder.DecodeModule(isolate, verify_functions); | 1240 ModuleResult result = decoder.DecodeModule(isolate, verify_functions); |
| 1236 // TODO(bradnelson): Improve histogram handling of size_t. | 1241 // TODO(bradnelson): Improve histogram handling of size_t. |
| 1237 // TODO(titzer): this isn't accurate, since it doesn't count the data | 1242 // TODO(titzer): this isn't accurate, since it doesn't count the data |
| 1238 // allocated on the C++ heap. | 1243 // allocated on the C++ heap. |
| 1239 // https://bugs.chromium.org/p/chromium/issues/detail?id=657320 | 1244 // https://bugs.chromium.org/p/chromium/issues/detail?id=657320 |
| 1240 if (is_sync && result.ok()) { | 1245 if (is_sync && result.ok()) { |
| 1241 // TODO(karlschimpf): Make this work when asynchronous. | 1246 // TODO(karlschimpf): Make this work when asynchronous. |
| 1242 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | 1247 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 |
| 1243 auto counter = | 1248 auto counter = origin == kWasmOrigin |
| 1244 origin == kWasmOrigin | 1249 ? counters->wasm_decode_wasm_module_peak_memory_bytes() |
| 1245 ? isolate->counters()->wasm_decode_wasm_module_peak_memory_bytes() | 1250 : counters->wasm_decode_asm_module_peak_memory_bytes(); |
| 1246 : isolate->counters()->wasm_decode_asm_module_peak_memory_bytes(); | |
| 1247 counter->AddSample( | 1251 counter->AddSample( |
| 1248 static_cast<int>(result.val->signature_zone->allocation_size())); | 1252 static_cast<int>(result.val->signature_zone->allocation_size())); |
| 1249 } | 1253 } |
| 1250 return result; | 1254 return result; |
| 1251 } | 1255 } |
| 1252 | 1256 |
| 1253 } // namespace | 1257 ModuleResult SyncDecodeWasmModule(Isolate* isolate, const byte* module_start, |
| 1258 const byte* module_end, bool verify_functions, |
| 1259 ModuleOrigin origin) { |
| 1260 return DecodeWasmModule(isolate, module_start, module_end, verify_functions, |
| 1261 origin, isolate->counters(), true); |
| 1262 } |
| 1254 | 1263 |
| 1255 ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start, | 1264 ModuleResult AsyncDecodeWasmModule(Isolate* isolate, const byte* module_start, |
| 1256 const byte* module_end, bool verify_functions, | 1265 const byte* module_end, |
| 1257 ModuleOrigin origin, bool is_sync) { | 1266 bool verify_functions, ModuleOrigin origin, |
| 1258 if (is_sync) { | 1267 Counters* async_counters) { |
| 1259 // TODO(karlschimpf): Make this work when asynchronous. | 1268 return DecodeWasmModule(isolate, module_start, module_end, verify_functions, |
| 1260 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | 1269 origin, async_counters, false); |
| 1261 auto counter = origin == kWasmOrigin | |
| 1262 ? isolate->counters()->wasm_decode_wasm_module_time() | |
| 1263 : isolate->counters()->wasm_decode_asm_module_time(); | |
| 1264 HistogramTimerScope wasm_decode_module_time_scope(counter); | |
| 1265 return DecodeWasmModuleInternal(isolate, module_start, module_end, | |
| 1266 verify_functions, origin, true); | |
| 1267 } | |
| 1268 return DecodeWasmModuleInternal(isolate, module_start, module_end, | |
| 1269 verify_functions, origin, false); | |
| 1270 } | 1270 } |
| 1271 | 1271 |
| 1272 FunctionSig* DecodeWasmSignatureForTesting(Zone* zone, const byte* start, | 1272 FunctionSig* DecodeWasmSignatureForTesting(Zone* zone, const byte* start, |
| 1273 const byte* end) { | 1273 const byte* end) { |
| 1274 ModuleDecoder decoder(start, end, kWasmOrigin); | 1274 ModuleDecoder decoder(start, end, kWasmOrigin); |
| 1275 return decoder.DecodeFunctionSignature(zone, start); | 1275 return decoder.DecodeFunctionSignature(zone, start); |
| 1276 } | 1276 } |
| 1277 | 1277 |
| 1278 WasmInitExpr DecodeWasmInitExprForTesting(const byte* start, const byte* end) { | 1278 WasmInitExpr DecodeWasmInitExprForTesting(const byte* start, const byte* end) { |
| 1279 AccountingAllocator allocator; | 1279 AccountingAllocator allocator; |
| 1280 ModuleDecoder decoder(start, end, kWasmOrigin); | 1280 ModuleDecoder decoder(start, end, kWasmOrigin); |
| 1281 return decoder.DecodeInitExpr(start); | 1281 return decoder.DecodeInitExpr(start); |
| 1282 } | 1282 } |
| 1283 | 1283 |
| 1284 namespace { | 1284 namespace { |
| 1285 | 1285 |
| 1286 FunctionResult DecodeWasmFunctionInternal(Isolate* isolate, Zone* zone, | 1286 FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone, |
| 1287 ModuleBytesEnv* module_env, | 1287 ModuleBytesEnv* module_env, |
| 1288 const byte* function_start, | 1288 const byte* function_start, |
| 1289 const byte* function_end, | 1289 const byte* function_end, Counters* counters, |
| 1290 bool is_sync) { | 1290 bool is_sync) { |
| 1291 size_t size = function_end - function_start; | 1291 size_t size = function_end - function_start; |
| 1292 bool is_wasm = module_env->module_env.is_wasm(); |
| 1293 auto size_counter = is_wasm ? counters->wasm_wasm_function_size_bytes() |
| 1294 : counters->wasm_asm_function_size_bytes(); |
| 1295 size_counter->AddSample(static_cast<int>(size)); |
| 1296 auto time_counter = is_wasm ? counters->wasm_decode_wasm_function_time() |
| 1297 : counters->wasm_decode_asm_function_time(); |
| 1298 TimedHistogramScope wasm_decode_function_time_scope(time_counter); |
| 1292 if (function_start > function_end) | 1299 if (function_start > function_end) |
| 1293 return FunctionResult::Error("start > end"); | 1300 return FunctionResult::Error("start > end"); |
| 1294 if (size > kV8MaxWasmFunctionSize) | 1301 if (size > kV8MaxWasmFunctionSize) |
| 1295 return FunctionResult::Error("size > maximum function size: %zu", size); | 1302 return FunctionResult::Error("size > maximum function size: %zu", size); |
| 1296 if (is_sync) { | |
| 1297 // TODO(karlschimpf): Make this work when asynchronous. | |
| 1298 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | |
| 1299 bool is_wasm = module_env->module_env.is_wasm(); | |
| 1300 (is_wasm ? isolate->counters()->wasm_wasm_function_size_bytes() | |
| 1301 : isolate->counters()->wasm_asm_function_size_bytes()) | |
| 1302 ->AddSample(static_cast<int>(size)); | |
| 1303 } | |
| 1304 ModuleDecoder decoder(function_start, function_end, kWasmOrigin); | 1303 ModuleDecoder decoder(function_start, function_end, kWasmOrigin); |
| 1305 return decoder.DecodeSingleFunction(zone, module_env, | 1304 return decoder.DecodeSingleFunction(zone, module_env, |
| 1306 base::make_unique<WasmFunction>()); | 1305 base::make_unique<WasmFunction>()); |
| 1307 } | 1306 } |
| 1308 | 1307 |
| 1309 } // namespace | 1308 } // namespace |
| 1310 | 1309 |
| 1311 FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone, | 1310 FunctionResult SyncDecodeWasmFunction(Isolate* isolate, Zone* zone, |
| 1312 ModuleBytesEnv* module_env, | 1311 ModuleBytesEnv* module_env, |
| 1313 const byte* function_start, | 1312 const byte* function_start, |
| 1314 const byte* function_end, bool is_sync) { | 1313 const byte* function_end) { |
| 1315 if (is_sync) { | 1314 return DecodeWasmFunction(isolate, zone, module_env, function_start, |
| 1316 // TODO(karlschimpf): Make this work when asynchronous. | 1315 function_end, isolate->counters(), true); |
| 1317 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | 1316 } |
| 1318 size_t size = function_end - function_start; | 1317 |
| 1319 bool is_wasm = module_env->module_env.is_wasm(); | 1318 FunctionResult AsyncDecodeWasmFunction(Isolate* isolate, Zone* zone, |
| 1320 auto size_counter = | 1319 ModuleBytesEnv* module_env, |
| 1321 is_wasm ? isolate->counters()->wasm_wasm_function_size_bytes() | 1320 const byte* function_start, |
| 1322 : isolate->counters()->wasm_asm_function_size_bytes(); | 1321 const byte* function_end, |
| 1323 size_counter->AddSample(static_cast<int>(size)); | 1322 Counters* async_counters) { |
| 1324 auto time_counter = | 1323 return DecodeWasmFunction(isolate, zone, module_env, function_start, |
| 1325 is_wasm ? isolate->counters()->wasm_decode_wasm_function_time() | 1324 function_end, async_counters, false); |
| 1326 : isolate->counters()->wasm_decode_asm_function_time(); | |
| 1327 HistogramTimerScope wasm_decode_function_time_scope(time_counter); | |
| 1328 return DecodeWasmFunctionInternal(isolate, zone, module_env, function_start, | |
| 1329 function_end, true); | |
| 1330 } | |
| 1331 return DecodeWasmFunctionInternal(isolate, zone, module_env, function_start, | |
| 1332 function_end, false); | |
| 1333 } | 1325 } |
| 1334 | 1326 |
| 1335 AsmJsOffsetsResult DecodeAsmJsOffsets(const byte* tables_start, | 1327 AsmJsOffsetsResult DecodeAsmJsOffsets(const byte* tables_start, |
| 1336 const byte* tables_end) { | 1328 const byte* tables_end) { |
| 1337 AsmJsOffsets table; | 1329 AsmJsOffsets table; |
| 1338 | 1330 |
| 1339 Decoder decoder(tables_start, tables_end); | 1331 Decoder decoder(tables_start, tables_end); |
| 1340 uint32_t functions_count = decoder.consume_u32v("functions count"); | 1332 uint32_t functions_count = decoder.consume_u32v("functions count"); |
| 1341 // Reserve space for the entries, taking care of invalid input. | 1333 // Reserve space for the entries, taking care of invalid input. |
| 1342 if (functions_count < static_cast<unsigned>(tables_end - tables_start)) { | 1334 if (functions_count < static_cast<unsigned>(tables_end - tables_start)) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 {name_offset, name_length}, | 1401 {name_offset, name_length}, |
| 1410 {payload_offset, payload_length}}); | 1402 {payload_offset, payload_length}}); |
| 1411 } | 1403 } |
| 1412 | 1404 |
| 1413 return result; | 1405 return result; |
| 1414 } | 1406 } |
| 1415 | 1407 |
| 1416 } // namespace wasm | 1408 } // namespace wasm |
| 1417 } // namespace internal | 1409 } // namespace internal |
| 1418 } // namespace v8 | 1410 } // namespace v8 |
| OLD | NEW |