Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(385)

Side by Side Diff: src/wasm/module-decoder.cc

Issue 2540133002: [wasm] Remove raw byte pointers from WasmModule (Closed)
Patch Set: Address comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/module-decoder.h ('k') | src/wasm/wasm-interpreter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/flags.h" 9 #include "src/flags.h"
10 #include "src/macro-assembler.h" 10 #include "src/macro-assembler.h"
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 if (limit_ < start_) { 182 if (limit_ < start_) {
183 error(start_, "end is less than start"); 183 error(start_, "end is less than start");
184 limit_ = start_; 184 limit_ = start_;
185 } 185 }
186 } 186 }
187 187
188 virtual void onFirstError() { 188 virtual void onFirstError() {
189 pc_ = limit_; // On error, terminate section decoding loop. 189 pc_ = limit_; // On error, terminate section decoding loop.
190 } 190 }
191 191
192 static void DumpModule(WasmModule* module, const ModuleResult& result) { 192 void DumpModule(const ModuleResult& result) {
193 std::string path; 193 std::string path;
194 if (FLAG_dump_wasm_module_path) { 194 if (FLAG_dump_wasm_module_path) {
195 path = FLAG_dump_wasm_module_path; 195 path = FLAG_dump_wasm_module_path;
196 if (path.size() && 196 if (path.size() &&
197 !base::OS::isDirectorySeparator(path[path.size() - 1])) { 197 !base::OS::isDirectorySeparator(path[path.size() - 1])) {
198 path += base::OS::DirectorySeparator(); 198 path += base::OS::DirectorySeparator();
199 } 199 }
200 } 200 }
201 // File are named `HASH.{ok,failed}.wasm`. 201 // File are named `HASH.{ok,failed}.wasm`.
202 size_t hash = base::hash_range(module->module_start, module->module_end); 202 size_t hash = base::hash_range(start_, limit_);
203 char buf[32] = {'\0'}; 203 char buf[32] = {'\0'};
204 #if V8_OS_WIN && _MSC_VER < 1900 204 #if V8_OS_WIN && _MSC_VER < 1900
205 #define snprintf sprintf_s 205 #define snprintf sprintf_s
206 #endif 206 #endif
207 snprintf(buf, sizeof(buf) - 1, "%016zx.%s.wasm", hash, 207 snprintf(buf, sizeof(buf) - 1, "%016zx.%s.wasm", hash,
208 result.ok() ? "ok" : "failed"); 208 result.ok() ? "ok" : "failed");
209 std::string name(buf); 209 std::string name(buf);
210 if (FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb")) { 210 if (FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb")) {
211 fwrite(module->module_start, module->module_end - module->module_start, 1, 211 fwrite(start_, limit_ - start_, 1, wasm_file);
212 wasm_file);
213 fclose(wasm_file); 212 fclose(wasm_file);
214 } 213 }
215 } 214 }
216 215
217 // Decodes an entire module. 216 // Decodes an entire module.
218 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { 217 ModuleResult DecodeModule(bool verify_functions = true) {
219 pc_ = start_; 218 pc_ = start_;
220 module->module_start = start_; 219 WasmModule* module = new WasmModule(module_zone);
221 module->module_end = limit_;
222 module->min_mem_pages = 0; 220 module->min_mem_pages = 0;
223 module->max_mem_pages = 0; 221 module->max_mem_pages = 0;
224 module->mem_export = false; 222 module->mem_export = false;
225 module->origin = origin_; 223 module->origin = origin_;
226 224
227 const byte* pos = pc_; 225 const byte* pos = pc_;
228 uint32_t magic_word = consume_u32("wasm magic"); 226 uint32_t magic_word = consume_u32("wasm magic");
229 #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff 227 #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff
230 if (magic_word != kWasmMagic) { 228 if (magic_word != kWasmMagic) {
231 error(pos, pos, 229 error(pos, pos,
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 error(pos, pos, "function body count %u mismatch (%u expected)", 578 error(pos, pos, "function body count %u mismatch (%u expected)",
581 functions_count, module->num_declared_functions); 579 functions_count, module->num_declared_functions);
582 } 580 }
583 for (uint32_t i = 0; ok() && i < functions_count; ++i) { 581 for (uint32_t i = 0; ok() && i < functions_count; ++i) {
584 WasmFunction* function = 582 WasmFunction* function =
585 &module->functions[i + module->num_imported_functions]; 583 &module->functions[i + module->num_imported_functions];
586 uint32_t size = consume_u32v("body size"); 584 uint32_t size = consume_u32v("body size");
587 function->code_start_offset = pc_offset(); 585 function->code_start_offset = pc_offset();
588 function->code_end_offset = pc_offset() + size; 586 function->code_end_offset = pc_offset() + size;
589 if (verify_functions) { 587 if (verify_functions) {
590 ModuleEnv module_env; 588 ModuleBytesEnv module_env(module, nullptr,
591 module_env.module = module; 589 ModuleWireBytes(start_, limit_));
592 module_env.origin = module->origin;
593
594 VerifyFunctionBody(i + module->num_imported_functions, &module_env, 590 VerifyFunctionBody(i + module->num_imported_functions, &module_env,
595 function); 591 function);
596 } 592 }
597 consume_bytes(size, "function body"); 593 consume_bytes(size, "function body");
598 } 594 }
599 section_iter.advance(); 595 section_iter.advance();
600 } 596 }
601 597
602 // ===== Data section ==================================================== 598 // ===== Data section ====================================================
603 if (section_iter.section_code() == kDataSectionCode) { 599 if (section_iter.section_code() == kDataSectionCode) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 } 645 }
650 646
651 if (ok()) { 647 if (ok()) {
652 CalculateGlobalOffsets(module); 648 CalculateGlobalOffsets(module);
653 } 649 }
654 const WasmModule* finished_module = module; 650 const WasmModule* finished_module = module;
655 ModuleResult result = toResult(finished_module); 651 ModuleResult result = toResult(finished_module);
656 if (verify_functions && result.ok()) { 652 if (verify_functions && result.ok()) {
657 result.MoveFrom(result_); // Copy error code and location. 653 result.MoveFrom(result_); // Copy error code and location.
658 } 654 }
659 if (FLAG_dump_wasm_module) DumpModule(module, result); 655 if (FLAG_dump_wasm_module) DumpModule(result);
660 return result; 656 return result;
661 } 657 }
662 658
663 uint32_t SafeReserve(uint32_t count) { 659 uint32_t SafeReserve(uint32_t count) {
664 // Avoid OOM by only reserving up to a certain size. 660 // Avoid OOM by only reserving up to a certain size.
665 const uint32_t kMaxReserve = 20000; 661 const uint32_t kMaxReserve = 20000;
666 return count < kMaxReserve ? count : kMaxReserve; 662 return count < kMaxReserve ? count : kMaxReserve;
667 } 663 }
668 664
669 // Decodes a single anonymous function starting at {start_}. 665 // Decodes a single anonymous function starting at {start_}.
670 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, 666 FunctionResult DecodeSingleFunction(ModuleBytesEnv* module_env,
671 WasmFunction* function) { 667 WasmFunction* function) {
672 pc_ = start_; 668 pc_ = start_;
673 function->sig = consume_sig(); // read signature 669 function->sig = consume_sig(); // read signature
674 function->name_offset = 0; // ---- name 670 function->name_offset = 0; // ---- name
675 function->name_length = 0; // ---- name length 671 function->name_length = 0; // ---- name length
676 function->code_start_offset = off(pc_); // ---- code start 672 function->code_start_offset = off(pc_); // ---- code start
677 function->code_end_offset = off(limit_); // ---- code end 673 function->code_end_offset = off(limit_); // ---- code end
678 674
679 if (ok()) VerifyFunctionBody(0, module_env, function); 675 if (ok()) VerifyFunctionBody(0, module_env, function);
680 676
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 byte size = 768 byte size =
773 WasmOpcodes::MemSize(WasmOpcodes::MachineTypeFor(global.type)); 769 WasmOpcodes::MemSize(WasmOpcodes::MachineTypeFor(global.type));
774 offset = (offset + size - 1) & ~(size - 1); // align 770 offset = (offset + size - 1) & ~(size - 1); // align
775 global.offset = offset; 771 global.offset = offset;
776 offset += size; 772 offset += size;
777 } 773 }
778 module->globals_size = offset; 774 module->globals_size = offset;
779 } 775 }
780 776
781 // Verifies the body (code) of a given function. 777 // Verifies the body (code) of a given function.
782 void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv, 778 void VerifyFunctionBody(uint32_t func_num, ModuleBytesEnv* menv,
783 WasmFunction* function) { 779 WasmFunction* function) {
784 if (FLAG_trace_wasm_decoder || FLAG_trace_wasm_decode_time) { 780 if (FLAG_trace_wasm_decoder || FLAG_trace_wasm_decode_time) {
785 OFStream os(stdout); 781 OFStream os(stdout);
786 os << "Verifying WASM function " << WasmFunctionName(function, menv) 782 os << "Verifying WASM function " << WasmFunctionName(function, menv)
787 << std::endl; 783 << std::endl;
788 } 784 }
789 FunctionBody body = {menv, function->sig, start_, 785 FunctionBody body = {menv, function->sig, start_,
790 start_ + function->code_start_offset, 786 start_ + function->code_start_offset,
791 start_ + function->code_end_offset}; 787 start_ + function->code_end_offset};
792 DecodeResult result = VerifyWasmCode(module_zone->allocator(), body); 788 DecodeResult result = VerifyWasmCode(module_zone->allocator(), body);
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 isolate->counters()->wasm_decode_module_time()); 1109 isolate->counters()->wasm_decode_module_time());
1114 size_t size = module_end - module_start; 1110 size_t size = module_end - module_start;
1115 if (module_start > module_end) return ModuleError("start > end"); 1111 if (module_start > module_end) return ModuleError("start > end");
1116 if (size >= kMaxModuleSize) return ModuleError("size > maximum module size"); 1112 if (size >= kMaxModuleSize) return ModuleError("size > maximum module size");
1117 // TODO(bradnelson): Improve histogram handling of size_t. 1113 // TODO(bradnelson): Improve histogram handling of size_t.
1118 isolate->counters()->wasm_module_size_bytes()->AddSample( 1114 isolate->counters()->wasm_module_size_bytes()->AddSample(
1119 static_cast<int>(size)); 1115 static_cast<int>(size));
1120 // Signatures are stored in zone memory, which have the same lifetime 1116 // Signatures are stored in zone memory, which have the same lifetime
1121 // as the {module}. 1117 // as the {module}.
1122 Zone* zone = new Zone(isolate->allocator(), ZONE_NAME); 1118 Zone* zone = new Zone(isolate->allocator(), ZONE_NAME);
1123 WasmModule* module = new WasmModule(zone, module_start);
1124 ModuleDecoder decoder(zone, module_start, module_end, origin); 1119 ModuleDecoder decoder(zone, module_start, module_end, origin);
1125 ModuleResult result = decoder.DecodeModule(module, verify_functions); 1120 ModuleResult result = decoder.DecodeModule(verify_functions);
1126 // TODO(bradnelson): Improve histogram handling of size_t. 1121 // TODO(bradnelson): Improve histogram handling of size_t.
1127 // TODO(titzer): this isn't accurate, since it doesn't count the data 1122 // TODO(titzer): this isn't accurate, since it doesn't count the data
1128 // allocated on the C++ heap. 1123 // allocated on the C++ heap.
1129 // https://bugs.chromium.org/p/chromium/issues/detail?id=657320 1124 // https://bugs.chromium.org/p/chromium/issues/detail?id=657320
1130 isolate->counters()->wasm_decode_module_peak_memory_bytes()->AddSample( 1125 isolate->counters()->wasm_decode_module_peak_memory_bytes()->AddSample(
1131 static_cast<int>(zone->allocation_size())); 1126 static_cast<int>(zone->allocation_size()));
1132 return result; 1127 return result;
1133 } 1128 }
1134 1129
1135 FunctionSig* DecodeWasmSignatureForTesting(Zone* zone, const byte* start, 1130 FunctionSig* DecodeWasmSignatureForTesting(Zone* zone, const byte* start,
1136 const byte* end) { 1131 const byte* end) {
1137 ModuleDecoder decoder(zone, start, end, kWasmOrigin); 1132 ModuleDecoder decoder(zone, start, end, kWasmOrigin);
1138 return decoder.DecodeFunctionSignature(start); 1133 return decoder.DecodeFunctionSignature(start);
1139 } 1134 }
1140 1135
1141 WasmInitExpr DecodeWasmInitExprForTesting(const byte* start, const byte* end) { 1136 WasmInitExpr DecodeWasmInitExprForTesting(const byte* start, const byte* end) {
1142 AccountingAllocator allocator; 1137 AccountingAllocator allocator;
1143 Zone zone(&allocator, ZONE_NAME); 1138 Zone zone(&allocator, ZONE_NAME);
1144 ModuleDecoder decoder(&zone, start, end, kWasmOrigin); 1139 ModuleDecoder decoder(&zone, start, end, kWasmOrigin);
1145 return decoder.DecodeInitExpr(start); 1140 return decoder.DecodeInitExpr(start);
1146 } 1141 }
1147 1142
1148 FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone, 1143 FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone,
1149 ModuleEnv* module_env, 1144 ModuleBytesEnv* module_env,
1150 const byte* function_start, 1145 const byte* function_start,
1151 const byte* function_end) { 1146 const byte* function_end) {
1152 HistogramTimerScope wasm_decode_function_time_scope( 1147 HistogramTimerScope wasm_decode_function_time_scope(
1153 isolate->counters()->wasm_decode_function_time()); 1148 isolate->counters()->wasm_decode_function_time());
1154 size_t size = function_end - function_start; 1149 size_t size = function_end - function_start;
1155 if (function_start > function_end) return FunctionError("start > end"); 1150 if (function_start > function_end) return FunctionError("start > end");
1156 if (size > kMaxFunctionSize) 1151 if (size > kMaxFunctionSize)
1157 return FunctionError("size > maximum function size"); 1152 return FunctionError("size > maximum function size");
1158 isolate->counters()->wasm_function_size_bytes()->AddSample( 1153 isolate->counters()->wasm_function_size_bytes()->AddSample(
1159 static_cast<int>(size)); 1154 static_cast<int>(size));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1231 table.push_back(std::move(func_asm_offsets)); 1226 table.push_back(std::move(func_asm_offsets));
1232 } 1227 }
1233 if (decoder.more()) decoder.error("unexpected additional bytes"); 1228 if (decoder.more()) decoder.error("unexpected additional bytes");
1234 1229
1235 return decoder.toResult(std::move(table)); 1230 return decoder.toResult(std::move(table));
1236 } 1231 }
1237 1232
1238 } // namespace wasm 1233 } // namespace wasm
1239 } // namespace internal 1234 } // namespace internal
1240 } // namespace v8 1235 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/module-decoder.h ('k') | src/wasm/wasm-interpreter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698