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