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

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

Issue 1764723002: [wasm] Remove TableSwitch and replace with br_table. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months 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
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/base/platform/elapsed-timer.h" 5 #include "src/base/platform/elapsed-timer.h"
6 #include "src/signature.h" 6 #include "src/signature.h"
7 7
8 #include "src/bit-vector.h" 8 #include "src/bit-vector.h"
9 #include "src/flags.h" 9 #include "src/flags.h"
10 #include "src/handles.h" 10 #include "src/handles.h"
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 inline bool Validate(const byte* pc, BreakDepthOperand& operand, 188 inline bool Validate(const byte* pc, BreakDepthOperand& operand,
189 ZoneVector<Block>& blocks) { 189 ZoneVector<Block>& blocks) {
190 if (operand.depth < blocks.size()) { 190 if (operand.depth < blocks.size()) {
191 operand.target = &blocks[blocks.size() - operand.depth - 1]; 191 operand.target = &blocks[blocks.size() - operand.depth - 1];
192 return true; 192 return true;
193 } 193 }
194 error(pc, pc + 1, "invalid break depth"); 194 error(pc, pc + 1, "invalid break depth");
195 return false; 195 return false;
196 } 196 }
197 197
198 bool Validate(const byte* pc, TableSwitchOperand& operand, 198 bool Validate(const byte* pc, BranchTableOperand& operand,
199 size_t block_depth) { 199 size_t block_depth) {
200 if (operand.table_count == 0) { 200 if (operand.table_count == 0) {
201 error(pc, "tableswitch with 0 entries"); 201 error(pc, "br_table with 0 entries");
202 return false; 202 return false;
203 } 203 }
204 // Verify table. 204 // Verify table.
205 for (uint32_t i = 0; i < operand.table_count; i++) { 205 for (uint32_t i = 0; i < operand.table_count; i++) {
206 uint16_t target = operand.read_entry(this, i); 206 uint16_t target = operand.read_entry(this, i);
207 if (target >= 0x8000) { 207 if (target >= block_depth) {
208 size_t depth = target - 0x8000; 208 error(operand.table + i * 2, "improper branch in br_table");
209 if (depth > block_depth) { 209 return false;
210 error(operand.table + i * 2, "improper branch in tableswitch");
211 return false;
212 }
213 } else {
214 if (target >= operand.case_count) {
215 error(operand.table + i * 2, "invalid case target in tableswitch");
216 return false;
217 }
218 } 210 }
219 } 211 }
220 return true; 212 return true;
221 } 213 }
222 214
223 int OpcodeArity(const byte* pc) { 215 int OpcodeArity(const byte* pc) {
224 #define DECLARE_ARITY(name, ...) \ 216 #define DECLARE_ARITY(name, ...) \
225 static const LocalType kTypes_##name[] = {__VA_ARGS__}; \ 217 static const LocalType kTypes_##name[] = {__VA_ARGS__}; \
226 static const int kArity_##name = \ 218 static const int kArity_##name = \
227 static_cast<int>(arraysize(kTypes_##name) - 1); 219 static_cast<int>(arraysize(kTypes_##name) - 1);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 } 265 }
274 case kExprCallImport: { 266 case kExprCallImport: {
275 ImportIndexOperand operand(this, pc); 267 ImportIndexOperand operand(this, pc);
276 return static_cast<int>( 268 return static_cast<int>(
277 function_env_->module->GetImportSignature(operand.index) 269 function_env_->module->GetImportSignature(operand.index)
278 ->parameter_count()); 270 ->parameter_count());
279 } 271 }
280 case kExprReturn: { 272 case kExprReturn: {
281 return static_cast<int>(function_env_->sig->return_count()); 273 return static_cast<int>(function_env_->sig->return_count());
282 } 274 }
283 case kExprTableSwitch: { 275 case kExprBrTable: {
284 TableSwitchOperand operand(this, pc); 276 return 1;
285 return 1 + operand.case_count;
286 } 277 }
287 278
288 #define DECLARE_OPCODE_CASE(name, opcode, sig) \ 279 #define DECLARE_OPCODE_CASE(name, opcode, sig) \
289 case kExpr##name: \ 280 case kExpr##name: \
290 return kArity_##sig; 281 return kArity_##sig;
291 282
292 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) 283 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
293 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE) 284 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
294 FOREACH_MISC_MEM_OPCODE(DECLARE_OPCODE_CASE) 285 FOREACH_MISC_MEM_OPCODE(DECLARE_OPCODE_CASE)
295 FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE) 286 FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 case kExprCallImport: { 327 case kExprCallImport: {
337 ImportIndexOperand operand(this, pc); 328 ImportIndexOperand operand(this, pc);
338 return 1 + operand.length; 329 return 1 + operand.length;
339 } 330 }
340 331
341 case kExprSetLocal: 332 case kExprSetLocal:
342 case kExprGetLocal: { 333 case kExprGetLocal: {
343 LocalIndexOperand operand(this, pc); 334 LocalIndexOperand operand(this, pc);
344 return 1 + operand.length; 335 return 1 + operand.length;
345 } 336 }
346 case kExprTableSwitch: { 337 case kExprBrTable: {
347 TableSwitchOperand operand(this, pc); 338 BranchTableOperand operand(this, pc);
348 return 1 + operand.length; 339 return 1 + operand.length;
349 } 340 }
350 case kExprI8Const: 341 case kExprI8Const:
351 return 2; 342 return 2;
352 case kExprI32Const: 343 case kExprI32Const:
353 case kExprF32Const: 344 case kExprF32Const:
354 return 5; 345 return 5;
355 case kExprI64Const: 346 case kExprI64Const:
356 case kExprF64Const: 347 case kExprF64Const:
357 return 9; 348 return 9;
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 break; 639 break;
649 } 640 }
650 case kExprBrIf: { 641 case kExprBrIf: {
651 BreakDepthOperand operand(this, pc_); 642 BreakDepthOperand operand(this, pc_);
652 if (Validate(pc_, operand, blocks_)) { 643 if (Validate(pc_, operand, blocks_)) {
653 Shift(kAstStmt, 2); 644 Shift(kAstStmt, 2);
654 } 645 }
655 len = 1 + operand.length; 646 len = 1 + operand.length;
656 break; 647 break;
657 } 648 }
658 case kExprTableSwitch: { 649 case kExprBrTable: {
659 TableSwitchOperand operand(this, pc_); 650 BranchTableOperand operand(this, pc_);
660 if (Validate(pc_, operand, blocks_.size())) { 651 if (Validate(pc_, operand, blocks_.size())) {
661 Shift(kAstEnd, 1 + operand.case_count); 652 Shift(kAstEnd, 1);
662 } 653 }
663 len = 1 + operand.length; 654 len = 1 + operand.length;
664 break; 655 break;
665 } 656 }
666 case kExprReturn: { 657 case kExprReturn: {
667 int count = static_cast<int>(function_env_->sig->return_count()); 658 int count = static_cast<int>(function_env_->sig->return_count());
668 if (count == 0) { 659 if (count == 0) {
669 BUILD(Return, 0, builder_->Buffer(0)); 660 BUILD(Return, 0, builder_->Buffer(0));
670 ssa_env_->Kill(); 661 ssa_env_->Kill();
671 Leaf(kAstEnd); 662 Leaf(kAstEnd);
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 SsaEnv* fenv = ssa_env_; 1027 SsaEnv* fenv = ssa_env_;
1037 SsaEnv* tenv = Split(fenv); 1028 SsaEnv* tenv = Split(fenv);
1038 BUILD(Branch, p->tree->children[1]->node, &tenv->control, 1029 BUILD(Branch, p->tree->children[1]->node, &tenv->control,
1039 &fenv->control); 1030 &fenv->control);
1040 ssa_env_ = tenv; 1031 ssa_env_ = tenv;
1041 ReduceBreakToExprBlock(p, operand.target, p->tree->children[0]); 1032 ReduceBreakToExprBlock(p, operand.target, p->tree->children[0]);
1042 ssa_env_ = fenv; 1033 ssa_env_ = fenv;
1043 } 1034 }
1044 break; 1035 break;
1045 } 1036 }
1046 case kExprTableSwitch: { 1037 case kExprBrTable: {
1047 if (p->index == 1) { 1038 if (p->index == 1) {
1048 // Switch key finished. 1039 // Switch key finished.
1049 TypeCheckLast(p, kAstI32); 1040 TypeCheckLast(p, kAstI32);
1050 if (failed()) break; 1041 if (failed()) break;
1051 1042
1052 TableSwitchOperand operand(this, p->pc()); 1043 BranchTableOperand operand(this, p->pc());
1053 DCHECK(Validate(p->pc(), operand, blocks_.size())); 1044 DCHECK(Validate(p->pc(), operand, blocks_.size()));
1054 1045
1055 // Build the switch only if it has more than just a default target. 1046 // Build a switch only if it has more than just a default target.
1056 bool build_switch = operand.table_count > 1; 1047 bool build_switch = operand.table_count > 1;
1057 TFNode* sw = nullptr; 1048 TFNode* sw = nullptr;
1058 if (build_switch) 1049 if (build_switch) {
1059 sw = BUILD(Switch, operand.table_count, p->last()->node); 1050 sw = BUILD(Switch, operand.table_count, p->last()->node);
1060
1061 // Allocate environments for each case.
1062 SsaEnv** case_envs = zone_->NewArray<SsaEnv*>(operand.case_count);
1063 for (uint32_t i = 0; i < operand.case_count; i++) {
1064 case_envs[i] = UnreachableEnv();
1065 } 1051 }
1066 1052
1067 ifs_.push_back({nullptr, nullptr, case_envs}); 1053 // Process the targets of the break table.
1068 SsaEnv* break_env = ssa_env_; 1054 SsaEnv* prev = ssa_env_;
1069 PushBlock(break_env); 1055 SsaEnv* copy = Steal(prev);
1070 SsaEnv* copy = Steal(break_env);
1071 ssa_env_ = copy;
1072
1073 // Build the environments for each case based on the table.
1074 for (uint32_t i = 0; i < operand.table_count; i++) { 1056 for (uint32_t i = 0; i < operand.table_count; i++) {
1075 uint16_t target = operand.read_entry(this, i); 1057 uint16_t target = operand.read_entry(this, i);
1076 SsaEnv* env = copy; 1058 SsaEnv* env = copy;
1077 if (build_switch) { 1059 if (build_switch) {
1078 env = Split(env); 1060 ssa_env_ = env = Split(env);
1079 env->control = (i == operand.table_count - 1) 1061 env->control = (i == operand.table_count - 1)
1080 ? BUILD(IfDefault, sw) 1062 ? BUILD(IfDefault, sw)
1081 : BUILD(IfValue, i, sw); 1063 : BUILD(IfValue, i, sw);
1082 } 1064 }
1083 if (target >= 0x8000) { 1065 SsaEnv* tenv = blocks_[blocks_.size() - target - 1].ssa_env;
1084 // Targets an outer block. 1066 Goto(env, tenv);
1085 int depth = target - 0x8000;
1086 SsaEnv* tenv = blocks_[blocks_.size() - depth - 1].ssa_env;
1087 Goto(env, tenv);
1088 } else {
1089 // Targets a case.
1090 Goto(env, case_envs[target]);
1091 }
1092 } 1067 }
1093 } 1068 ssa_env_ = prev;
1094
1095 if (p->done()) {
1096 // Last case. Fall through to the end.
1097 Block* block = &blocks_.back();
1098 if (p->index > 1) ReduceBreakToExprBlock(p, block);
1099 SsaEnv* next = block->ssa_env;
1100 blocks_.pop_back();
1101 ifs_.pop_back();
1102 SetEnv("switch:end", next);
1103 } else {
1104 // Interior case. Maybe fall through to the next case.
1105 SsaEnv* next = ifs_.back().case_envs[p->index - 1];
1106 if (p->index > 1 && ssa_env_->go()) Goto(ssa_env_, next);
1107 SetEnv("switch:case", next);
1108 } 1069 }
1109 break; 1070 break;
1110 } 1071 }
1111 case kExprReturn: { 1072 case kExprReturn: {
1112 TypeCheckLast(p, function_env_->sig->GetReturn(p->index - 1)); 1073 TypeCheckLast(p, function_env_->sig->GetReturn(p->index - 1));
1113 if (p->done()) { 1074 if (p->done()) {
1114 if (build()) { 1075 if (build()) {
1115 int count = p->tree->count; 1076 int count = p->tree->count;
1116 TFNode** buffer = builder_->Buffer(count); 1077 TFNode** buffer = builder_->Buffer(count);
1117 for (int i = 0; i < count; i++) { 1078 for (int i = 0; i < count; i++) {
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1705 1666
1706 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, FunctionEnv* env, 1667 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, FunctionEnv* env,
1707 const byte* start, const byte* end) { 1668 const byte* start, const byte* end) {
1708 LoopAssignmentAnalyzer analyzer(zone, env); 1669 LoopAssignmentAnalyzer analyzer(zone, env);
1709 return analyzer.Analyze(start, end); 1670 return analyzer.Analyze(start, end);
1710 } 1671 }
1711 1672
1712 } // namespace wasm 1673 } // namespace wasm
1713 } // namespace internal 1674 } // namespace internal
1714 } // namespace v8 1675 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698