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

Side by Side Diff: test/cctest/wasm/wasm-run-utils.h

Issue 2551053002: [wasm] Always provide a wasm instance object at runtime (Closed)
Patch Set: Rebase 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 | « test/cctest/wasm/test-wasm-trap-position.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #ifndef WASM_RUN_UTILS_H 5 #ifndef WASM_RUN_UTILS_H
6 #define WASM_RUN_UTILS_H 6 #define WASM_RUN_UTILS_H
7 7
8 #include <setjmp.h> 8 #include <setjmp.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 #include <stdlib.h> 10 #include <stdlib.h>
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 ModuleBytesEnv(&module_, &instance_, 84 ModuleBytesEnv(&module_, &instance_,
85 Vector<const byte>::empty()), 85 Vector<const byte>::empty()),
86 zone->allocator()) 86 zone->allocator())
87 : nullptr) { 87 : nullptr) {
88 instance->module = &module_; 88 instance->module = &module_;
89 instance->globals_start = global_data; 89 instance->globals_start = global_data;
90 module_.globals_size = kMaxGlobalsSize; 90 module_.globals_size = kMaxGlobalsSize;
91 instance->mem_start = nullptr; 91 instance->mem_start = nullptr;
92 instance->mem_size = 0; 92 instance->mem_size = 0;
93 memset(global_data, 0, sizeof(global_data)); 93 memset(global_data, 0, sizeof(global_data));
94 instance_object_ = InitInstanceObject();
94 } 95 }
95 96
96 ~TestingModule() { 97 ~TestingModule() {
97 if (instance->mem_start) { 98 if (instance->mem_start) {
98 free(instance->mem_start); 99 free(instance->mem_start);
99 } 100 }
100 if (interpreter_) delete interpreter_; 101 if (interpreter_) delete interpreter_;
101 } 102 }
102 103
103 void ChangeOriginToAsmjs() { module_.origin = kAsmJsOrigin; } 104 void ChangeOriginToAsmjs() { module_.origin = kAsmJsOrigin; }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 174
174 // Pseudo-randomly intialize the memory. 175 // Pseudo-randomly intialize the memory.
175 void RandomizeMemory(unsigned int seed = 88) { 176 void RandomizeMemory(unsigned int seed = 88) {
176 byte* raw = raw_mem_start<byte>(); 177 byte* raw = raw_mem_start<byte>();
177 byte* end = raw_mem_end<byte>(); 178 byte* end = raw_mem_end<byte>();
178 v8::base::RandomNumberGenerator rng; 179 v8::base::RandomNumberGenerator rng;
179 rng.SetSeed(seed); 180 rng.SetSeed(seed);
180 rng.NextBytes(raw, end - raw); 181 rng.NextBytes(raw, end - raw);
181 } 182 }
182 183
183 uint32_t AddFunction(FunctionSig* sig, Handle<Code> code) { 184 uint32_t AddFunction(FunctionSig* sig, Handle<Code> code, const char* name) {
184 if (module->functions.size() == 0) { 185 if (module->functions.size() == 0) {
185 // TODO(titzer): Reserving space here to avoid the underlying WasmFunction 186 // TODO(titzer): Reserving space here to avoid the underlying WasmFunction
186 // structs from moving. 187 // structs from moving.
187 module_.functions.reserve(kMaxFunctions); 188 module_.functions.reserve(kMaxFunctions);
188 } 189 }
189 uint32_t index = static_cast<uint32_t>(module->functions.size()); 190 uint32_t index = static_cast<uint32_t>(module->functions.size());
190 module_.functions.push_back({sig, index, 0, 0, 0, 0, 0, false, false}); 191 module_.functions.push_back({sig, index, 0, 0, 0, 0, 0, false, false});
192 if (name) {
193 Vector<const byte> name_vec = Vector<const byte>::cast(CStrVector(name));
194 module_.functions.back().name_offset = AddBytes(name_vec);
195 module_.functions.back().name_length = name_vec.length();
196 }
191 instance->function_code.push_back(code); 197 instance->function_code.push_back(code);
192 if (interpreter_) { 198 if (interpreter_) {
193 const WasmFunction* function = &module->functions.back(); 199 const WasmFunction* function = &module->functions.back();
194 int interpreter_index = interpreter_->AddFunctionForTesting(function); 200 int interpreter_index = interpreter_->AddFunctionForTesting(function);
195 CHECK_EQ(index, static_cast<uint32_t>(interpreter_index)); 201 CHECK_EQ(index, static_cast<uint32_t>(interpreter_index));
196 } 202 }
197 DCHECK_LT(index, kMaxFunctions); // limited for testing. 203 DCHECK_LT(index, kMaxFunctions); // limited for testing.
198 return index; 204 return index;
199 } 205 }
200 206
201 uint32_t AddJsFunction(FunctionSig* sig, const char* source) { 207 uint32_t AddJsFunction(FunctionSig* sig, const char* source) {
202 Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle( 208 Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
203 *v8::Local<v8::Function>::Cast(CompileRun(source)))); 209 *v8::Local<v8::Function>::Cast(CompileRun(source))));
204 uint32_t index = AddFunction(sig, Handle<Code>::null()); 210 uint32_t index = AddFunction(sig, Handle<Code>::null(), nullptr);
205 Handle<Code> code = CompileWasmToJSWrapper( 211 Handle<Code> code = CompileWasmToJSWrapper(
206 isolate_, jsfunc, sig, index, Handle<String>::null(), 212 isolate_, jsfunc, sig, index, Handle<String>::null(),
207 Handle<String>::null(), module->origin); 213 Handle<String>::null(), module->origin);
208 instance->function_code[index] = code; 214 instance->function_code[index] = code;
209 return index; 215 return index;
210 } 216 }
211 217
212 Handle<JSFunction> WrapCode(uint32_t index) { 218 Handle<JSFunction> WrapCode(uint32_t index) {
213 // Wrap the code so it can be called as a JS function. 219 // Wrap the code so it can be called as a JS function.
214 Handle<WasmInstanceObject> instance_obj(0, isolate_); 220 Handle<WasmInstanceObject> instance_obj(0, isolate_);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 *instance->function_code[function.func_index]); 264 *instance->function_code[function.func_index]);
259 } 265 }
260 } 266 }
261 } 267 }
262 268
263 WasmFunction* GetFunctionAt(int index) { return &module_.functions[index]; } 269 WasmFunction* GetFunctionAt(int index) { return &module_.functions[index]; }
264 270
265 WasmInterpreter* interpreter() { return interpreter_; } 271 WasmInterpreter* interpreter() { return interpreter_; }
266 WasmExecutionMode execution_mode() { return execution_mode_; } 272 WasmExecutionMode execution_mode() { return execution_mode_; }
267 Isolate* isolate() { return isolate_; } 273 Isolate* isolate() { return isolate_; }
274 Handle<WasmInstanceObject> instance_object() { return instance_object_; }
268 275
269 private: 276 private:
270 WasmExecutionMode execution_mode_; 277 WasmExecutionMode execution_mode_;
271 WasmModule module_; 278 WasmModule module_;
272 WasmInstance instance_; 279 WasmInstance instance_;
273 Isolate* isolate_; 280 Isolate* isolate_;
274 uint32_t global_offset; 281 uint32_t global_offset;
275 V8_ALIGNED(8) byte global_data[kMaxGlobalsSize]; // preallocated global data. 282 V8_ALIGNED(8) byte global_data[kMaxGlobalsSize]; // preallocated global data.
276 WasmInterpreter* interpreter_; 283 WasmInterpreter* interpreter_;
284 Handle<WasmInstanceObject> instance_object_;
277 285
278 const WasmGlobal* AddGlobal(LocalType type) { 286 const WasmGlobal* AddGlobal(LocalType type) {
279 byte size = WasmOpcodes::MemSize(WasmOpcodes::MachineTypeFor(type)); 287 byte size = WasmOpcodes::MemSize(WasmOpcodes::MachineTypeFor(type));
280 global_offset = (global_offset + size - 1) & ~(size - 1); // align 288 global_offset = (global_offset + size - 1) & ~(size - 1); // align
281 module_.globals.push_back( 289 module_.globals.push_back(
282 {type, true, WasmInitExpr(), global_offset, false, false}); 290 {type, true, WasmInitExpr(), global_offset, false, false});
283 global_offset += size; 291 global_offset += size;
284 // limit number of globals. 292 // limit number of globals.
285 CHECK_LT(global_offset, kMaxGlobalsSize); 293 CHECK_LT(global_offset, kMaxGlobalsSize);
286 return &module->globals.back(); 294 return &module->globals.back();
287 } 295 }
296
297 uint32_t AddBytes(Vector<const byte> bytes) {
298 Handle<SeqOneByteString> old_bytes =
299 instance_object_->get_compiled_module()->module_bytes();
300 uint32_t old_size = static_cast<uint32_t>(old_bytes->length());
301 ScopedVector<byte> new_bytes(old_size + bytes.length());
302 memcpy(new_bytes.start(), old_bytes->GetChars(), old_size);
303 memcpy(new_bytes.start() + old_size, bytes.start(), bytes.length());
304 Handle<SeqOneByteString> new_bytes_str = Handle<SeqOneByteString>::cast(
305 isolate_->factory()->NewStringFromOneByte(new_bytes).ToHandleChecked());
306 instance_object_->get_compiled_module()->set_module_bytes(new_bytes_str);
307 return old_size;
308 }
309
310 Handle<WasmInstanceObject> InitInstanceObject() {
311 Handle<Managed<wasm::WasmModule>> module_wrapper =
312 Managed<wasm::WasmModule>::New(isolate_, &module_, false);
313 Handle<WasmCompiledModule> compiled_module =
314 WasmCompiledModule::New(isolate_, module_wrapper);
315 // Minimally initialize the compiled module such that IsWasmCompiledModule
316 // passes.
317 // If tests need more (correct) information, add it later.
318 compiled_module->set_min_mem_pages(0);
319 compiled_module->set_max_mem_pages(Smi::kMaxValue);
320 Handle<SeqOneByteString> empty_string = Handle<SeqOneByteString>::cast(
321 isolate_->factory()->NewStringFromOneByte({}).ToHandleChecked());
322 compiled_module->set_module_bytes(empty_string);
323 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module));
324 return WasmInstanceObject::New(isolate_, compiled_module);
325 }
288 }; 326 };
289 327
290 inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module, 328 inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module,
291 FunctionSig* sig, 329 FunctionSig* sig,
292 SourcePositionTable* source_position_table, 330 SourcePositionTable* source_position_table,
293 const byte* start, const byte* end) { 331 const byte* start, const byte* end) {
294 compiler::WasmGraphBuilder builder(zone, jsgraph, sig, source_position_table); 332 compiler::WasmGraphBuilder builder(zone, jsgraph, sig, source_position_table);
295 DecodeResult result = 333 DecodeResult result =
296 BuildTFGraph(zone->allocator(), &builder, module, sig, start, end); 334 BuildTFGraph(zone->allocator(), &builder, module, sig, start, end);
297 if (result.failed()) { 335 if (result.failed()) {
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 DCHECK_EQ(index, result); 517 DCHECK_EQ(index, result);
480 return result; 518 return result;
481 } 519 }
482 520
483 void SetSigIndex(int sig_index) { function_->sig_index = sig_index; } 521 void SetSigIndex(int sig_index) { function_->sig_index = sig_index; }
484 522
485 private: 523 private:
486 friend class WasmRunnerBase; 524 friend class WasmRunnerBase;
487 525
488 explicit WasmFunctionCompiler(Zone* zone, FunctionSig* sig, 526 explicit WasmFunctionCompiler(Zone* zone, FunctionSig* sig,
489 TestingModule* module) 527 TestingModule* module, const char* name)
490 : GraphAndBuilders(zone), 528 : GraphAndBuilders(zone),
491 jsgraph(module->isolate(), this->graph(), this->common(), nullptr, 529 jsgraph(module->isolate(), this->graph(), this->common(), nullptr,
492 nullptr, this->machine()), 530 nullptr, this->machine()),
493 sig(sig), 531 sig(sig),
494 descriptor_(nullptr), 532 descriptor_(nullptr),
495 testing_module_(module), 533 testing_module_(module),
496 local_decls(zone, sig), 534 local_decls(zone, sig),
497 source_position_table_(this->graph()), 535 source_position_table_(this->graph()),
498 interpreter_(module->interpreter()) { 536 interpreter_(module->interpreter()) {
499 // Get a new function from the testing module. 537 // Get a new function from the testing module.
500 int index = module->AddFunction(sig, Handle<Code>::null()); 538 int index = module->AddFunction(sig, Handle<Code>::null(), name);
501 function_ = testing_module_->GetFunctionAt(index); 539 function_ = testing_module_->GetFunctionAt(index);
502 } 540 }
503 541
504 Handle<Code> Compile() { 542 Handle<Code> Compile() {
505 CallDescriptor* desc = descriptor(); 543 CallDescriptor* desc = descriptor();
506 if (kPointerSize == 4) { 544 if (kPointerSize == 4) {
507 desc = testing_module_->GetI32WasmCallDescriptor(this->zone(), desc); 545 desc = testing_module_->GetI32WasmCallDescriptor(this->zone(), desc);
508 } 546 }
509 CompilationInfo info(CStrVector("wasm"), this->isolate(), this->zone(), 547 CompilationInfo info(CStrVector("wasm"), this->isolate(), this->zone(),
510 Code::ComputeFlags(Code::WASM_FUNCTION)); 548 Code::ComputeFlags(Code::WASM_FUNCTION));
511 std::unique_ptr<CompilationJob> job(Pipeline::NewWasmCompilationJob( 549 std::unique_ptr<CompilationJob> job(Pipeline::NewWasmCompilationJob(
512 &info, &jsgraph, desc, &source_position_table_, nullptr)); 550 &info, &jsgraph, desc, &source_position_table_, nullptr));
513 if (job->ExecuteJob() != CompilationJob::SUCCEEDED || 551 if (job->ExecuteJob() != CompilationJob::SUCCEEDED ||
514 job->FinalizeJob() != CompilationJob::SUCCEEDED) 552 job->FinalizeJob() != CompilationJob::SUCCEEDED)
515 return Handle<Code>::null(); 553 return Handle<Code>::null();
516 554
517 Handle<Code> code = info.code(); 555 Handle<Code> code = info.code();
518 556
519 // Length is always 2, since usually <wasm_obj, func_index> is stored in 557 // Deopt data holds <WeakCell<wasm_instance>, func_index>.
520 // the deopt data. Here, we only store the function index.
521 DCHECK(code->deoptimization_data() == nullptr || 558 DCHECK(code->deoptimization_data() == nullptr ||
522 code->deoptimization_data()->length() == 0); 559 code->deoptimization_data()->length() == 0);
523 Handle<FixedArray> deopt_data = 560 Handle<FixedArray> deopt_data =
524 isolate()->factory()->NewFixedArray(2, TENURED); 561 isolate()->factory()->NewFixedArray(2, TENURED);
562 Handle<Object> weak_instance =
563 isolate()->factory()->NewWeakCell(testing_module_->instance_object());
564 deopt_data->set(0, *weak_instance);
525 deopt_data->set(1, Smi::FromInt(static_cast<int>(function_index()))); 565 deopt_data->set(1, Smi::FromInt(static_cast<int>(function_index())));
526 deopt_data->set_length(2); 566 deopt_data->set_length(2);
527 code->set_deoptimization_data(*deopt_data); 567 code->set_deoptimization_data(*deopt_data);
528 568
529 #ifdef ENABLE_DISASSEMBLER 569 #ifdef ENABLE_DISASSEMBLER
530 if (FLAG_print_opt_code) { 570 if (FLAG_print_opt_code) {
531 OFStream os(stdout); 571 OFStream os(stdout);
532 code->Disassemble("wasm code", os); 572 code->Disassemble("wasm code", os);
533 } 573 }
534 #endif 574 #endif
(...skipping 27 matching lines...) Expand all
562 // more than once. 602 // more than once.
563 void Build(const byte* start, const byte* end) { 603 void Build(const byte* start, const byte* end) {
564 CHECK(!compiled_); 604 CHECK(!compiled_);
565 compiled_ = true; 605 compiled_ = true;
566 functions_[0]->Build(start, end); 606 functions_[0]->Build(start, end);
567 } 607 }
568 608
569 // Resets the state for building the next function. 609 // Resets the state for building the next function.
570 // The main function called will always be the first function. 610 // The main function called will always be the first function.
571 template <typename ReturnType, typename... ParamTypes> 611 template <typename ReturnType, typename... ParamTypes>
572 WasmFunctionCompiler& NewFunction() { 612 WasmFunctionCompiler& NewFunction(const char* name = nullptr) {
573 return NewFunction(CreateSig<ReturnType, ParamTypes...>()); 613 return NewFunction(CreateSig<ReturnType, ParamTypes...>(), name);
574 } 614 }
575 615
576 // Resets the state for building the next function. 616 // Resets the state for building the next function.
577 // The main function called will be the last generated function. 617 // The main function called will be the last generated function.
578 // Returns the index of the previously built function. 618 // Returns the index of the previously built function.
579 WasmFunctionCompiler& NewFunction(FunctionSig* sig) { 619 WasmFunctionCompiler& NewFunction(FunctionSig* sig,
580 functions_.emplace_back(new WasmFunctionCompiler(&zone_, sig, &module_)); 620 const char* name = nullptr) {
621 functions_.emplace_back(
622 new WasmFunctionCompiler(&zone_, sig, &module_, name));
581 return *functions_.back(); 623 return *functions_.back();
582 } 624 }
583 625
584 byte AllocateLocal(LocalType type) { 626 byte AllocateLocal(LocalType type) {
585 return functions_[0]->AllocateLocal(type); 627 return functions_[0]->AllocateLocal(type);
586 } 628 }
587 629
588 WasmFunction* function() { return functions_[0]->function_; } 630 WasmFunction* function() { return functions_[0]->function_; }
589 WasmInterpreter* interpreter() { return functions_[0]->interpreter_; } 631 WasmInterpreter* interpreter() { return functions_[0]->interpreter_; }
590 bool possible_nondeterminism() { return possible_nondeterminism_; } 632 bool possible_nondeterminism() { return possible_nondeterminism_; }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 686
645 public: 687 public:
646 // This field has to be static. Otherwise, gcc complains about the using in 688 // This field has to be static. Otherwise, gcc complains about the using in
647 // the lambda context below. 689 // the lambda context below.
648 static jmp_buf jump_buffer; 690 static jmp_buf jump_buffer;
649 }; 691 };
650 692
651 template <typename ReturnType, typename... ParamTypes> 693 template <typename ReturnType, typename... ParamTypes>
652 class WasmRunner : public WasmRunnerBase { 694 class WasmRunner : public WasmRunnerBase {
653 public: 695 public:
654 explicit WasmRunner(WasmExecutionMode execution_mode) 696 explicit WasmRunner(WasmExecutionMode execution_mode,
697 const char* main_fn_name = "main")
655 : WasmRunnerBase(execution_mode, sizeof...(ParamTypes)) { 698 : WasmRunnerBase(execution_mode, sizeof...(ParamTypes)) {
656 NewFunction<ReturnType, ParamTypes...>(); 699 NewFunction<ReturnType, ParamTypes...>(main_fn_name);
657 if (!interpret()) { 700 if (!interpret()) {
658 wrapper_.Init<ReturnType, ParamTypes...>(functions_[0]->descriptor()); 701 wrapper_.Init<ReturnType, ParamTypes...>(functions_[0]->descriptor());
659 } 702 }
660 } 703 }
661 704
662 ReturnType Call(ParamTypes... p) { 705 ReturnType Call(ParamTypes... p) {
663 DCHECK(compiled_); 706 DCHECK(compiled_);
664 if (interpret()) return CallInterpreter(p...); 707 if (interpret()) return CallInterpreter(p...);
665 708
666 // Use setjmp/longjmp to deal with traps in WebAssembly code. 709 // Use setjmp/longjmp to deal with traps in WebAssembly code.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 void RunWasm_##name(WasmExecutionMode execution_mode) 783 void RunWasm_##name(WasmExecutionMode execution_mode)
741 784
742 #define WASM_EXEC_COMPILED_TEST(name) \ 785 #define WASM_EXEC_COMPILED_TEST(name) \
743 void RunWasm_##name(WasmExecutionMode execution_mode); \ 786 void RunWasm_##name(WasmExecutionMode execution_mode); \
744 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ 787 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \
745 void RunWasm_##name(WasmExecutionMode execution_mode) 788 void RunWasm_##name(WasmExecutionMode execution_mode)
746 789
747 } // namespace 790 } // namespace
748 791
749 #endif 792 #endif
OLDNEW
« no previous file with comments | « test/cctest/wasm/test-wasm-trap-position.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698