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

Side by Side Diff: src/compiler/wasm-compiler.cc

Issue 2731523005: [wasm] Lazy compilation for asm.js (Closed)
Patch Set: [wasm] Lazy compilation for asm.js Created 3 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
« no previous file with comments | « src/builtins/x64/builtins-x64.cc ('k') | src/counters.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/compiler/wasm-compiler.h" 5 #include "src/compiler/wasm-compiler.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/assembler-inl.h" 9 #include "src/assembler-inl.h"
10 #include "src/base/platform/elapsed-timer.h" 10 #include "src/base/platform/elapsed-timer.h"
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 } 173 }
174 174
175 // Add a check that traps if {node} is zero. 175 // Add a check that traps if {node} is zero.
176 Node* ZeroCheck64(wasm::TrapReason reason, Node* node, 176 Node* ZeroCheck64(wasm::TrapReason reason, Node* node,
177 wasm::WasmCodePosition position) { 177 wasm::WasmCodePosition position) {
178 return TrapIfEq64(reason, node, 0, position); 178 return TrapIfEq64(reason, node, 0, position);
179 } 179 }
180 180
181 Builtins::Name GetBuiltinIdForTrap(wasm::TrapReason reason) { 181 Builtins::Name GetBuiltinIdForTrap(wasm::TrapReason reason) {
182 bool in_cctest = 182 bool in_cctest =
183 !builder_->module_ || builder_->module_->instance->context.is_null(); 183 !builder_->module_ || (builder_->module_->instance &&
184 builder_->module_->instance->context.is_null());
184 if (in_cctest) { 185 if (in_cctest) {
185 // We use Builtins::builtin_count as a marker to tell the code generator 186 // We use Builtins::builtin_count as a marker to tell the code generator
186 // to generate a call to a testing c-function instead of a runtime 187 // to generate a call to a testing c-function instead of a runtime
187 // function. This code should only be called from a cctest. 188 // function. This code should only be called from a cctest.
188 return Builtins::builtin_count; 189 return Builtins::builtin_count;
189 } 190 }
190 191
191 switch (reason) { 192 switch (reason) {
192 #define TRAPREASON_TO_MESSAGE(name) \ 193 #define TRAPREASON_TO_MESSAGE(name) \
193 case wasm::k##name: \ 194 case wasm::k##name: \
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 } 481 }
481 482
482 Node* WasmGraphBuilder::Int64Constant(int64_t value) { 483 Node* WasmGraphBuilder::Int64Constant(int64_t value) {
483 return jsgraph()->Int64Constant(value); 484 return jsgraph()->Int64Constant(value);
484 } 485 }
485 486
486 void WasmGraphBuilder::StackCheck(wasm::WasmCodePosition position, 487 void WasmGraphBuilder::StackCheck(wasm::WasmCodePosition position,
487 Node** effect, Node** control) { 488 Node** effect, Node** control) {
488 if (FLAG_wasm_no_stack_checks) return; 489 if (FLAG_wasm_no_stack_checks) return;
489 // We do not generate stack checks for cctests. 490 // We do not generate stack checks for cctests.
490 if (!module_ || module_->instance->context.is_null()) return; 491 if (!module_ || (module_->instance && module_->instance->context.is_null()))
492 return;
491 if (effect == nullptr) effect = effect_; 493 if (effect == nullptr) effect = effect_;
492 if (control == nullptr) control = control_; 494 if (control == nullptr) control = control_;
493 495
494 Node* limit = graph()->NewNode( 496 Node* limit = graph()->NewNode(
495 jsgraph()->machine()->Load(MachineType::Pointer()), 497 jsgraph()->machine()->Load(MachineType::Pointer()),
496 jsgraph()->ExternalConstant( 498 jsgraph()->ExternalConstant(
497 ExternalReference::address_of_stack_limit(jsgraph()->isolate())), 499 ExternalReference::address_of_stack_limit(jsgraph()->isolate())),
498 jsgraph()->IntPtrConstant(0), *effect, *control); 500 jsgraph()->IntPtrConstant(0), *effect, *control);
499 Node* pointer = graph()->NewNode(jsgraph()->machine()->LoadStackPointer()); 501 Node* pointer = graph()->NewNode(jsgraph()->machine()->LoadStackPointer());
500 502
(...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1789 BuildCCall(sig_builder.Build(), args), position); 1791 BuildCCall(sig_builder.Build(), args), position);
1790 const Operator* load_op = jsgraph()->machine()->Load(result_type); 1792 const Operator* load_op = jsgraph()->machine()->Load(result_type);
1791 Node* load = 1793 Node* load =
1792 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), 1794 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0),
1793 *effect_, *control_); 1795 *effect_, *control_);
1794 *effect_ = load; 1796 *effect_ = load;
1795 return load; 1797 return load;
1796 } 1798 }
1797 1799
1798 Node* WasmGraphBuilder::GrowMemory(Node* input) { 1800 Node* WasmGraphBuilder::GrowMemory(Node* input) {
1801 // GrowMemory will not be called from asm.js, hence we cannot be in
1802 // lazy-compilation mode, hence the instance will be set.
1803 DCHECK_NOT_NULL(module_);
1804 DCHECK_NOT_NULL(module_->instance);
1805
1799 Diamond check_input_range( 1806 Diamond check_input_range(
1800 graph(), jsgraph()->common(), 1807 graph(), jsgraph()->common(),
1801 graph()->NewNode(jsgraph()->machine()->Uint32LessThanOrEqual(), input, 1808 graph()->NewNode(jsgraph()->machine()->Uint32LessThanOrEqual(), input,
1802 jsgraph()->Uint32Constant(FLAG_wasm_max_mem_pages)), 1809 jsgraph()->Uint32Constant(FLAG_wasm_max_mem_pages)),
1803 BranchHint::kTrue); 1810 BranchHint::kTrue);
1804 1811
1805 check_input_range.Chain(*control_); 1812 check_input_range.Chain(*control_);
1806 1813
1807 Node* parameters[] = {BuildChangeUint32ToSmi(input)}; 1814 Node* parameters[] = {BuildChangeUint32ToSmi(input)};
1808 Node* old_effect = *effect_; 1815 Node* old_effect = *effect_;
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
2279 } 2286 }
2280 } 2287 }
2281 return call; 2288 return call;
2282 } 2289 }
2283 2290
2284 Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, Node*** rets, 2291 Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, Node*** rets,
2285 wasm::WasmCodePosition position) { 2292 wasm::WasmCodePosition position) {
2286 DCHECK_NULL(args[0]); 2293 DCHECK_NULL(args[0]);
2287 2294
2288 // Add code object as constant. 2295 // Add code object as constant.
2289 Handle<Code> code = module_->GetFunctionCode(index); 2296 Handle<Code> code = module_->instance
2297 ? module_->GetFunctionCode(index)
2298 : jsgraph()->isolate()->builtins()->Illegal();
2290 DCHECK(!code.is_null()); 2299 DCHECK(!code.is_null());
2291 args[0] = HeapConstant(code); 2300 args[0] = HeapConstant(code);
2292 wasm::FunctionSig* sig = module_->GetFunctionSignature(index); 2301 wasm::FunctionSig* sig = module_->GetFunctionSignature(index);
2293 2302
2294 return BuildWasmCall(sig, args, rets, position); 2303 return BuildWasmCall(sig, args, rets, position);
2295 } 2304 }
2296 2305
2297 Node* WasmGraphBuilder::CallIndirect(uint32_t sig_index, Node** args, 2306 Node* WasmGraphBuilder::CallIndirect(uint32_t sig_index, Node** args,
2298 Node*** rets, 2307 Node*** rets,
2299 wasm::WasmCodePosition position) { 2308 wasm::WasmCodePosition position) {
2300 DCHECK_NOT_NULL(args[0]); 2309 DCHECK_NOT_NULL(args[0]);
2301 DCHECK(module_ && module_->instance); 2310 DCHECK_NOT_NULL(module_);
2302 2311
2303 // Assume only one table for now. 2312 // Assume only one table for now.
2304 uint32_t table_index = 0; 2313 uint32_t table_index = 0;
2305 wasm::FunctionSig* sig = module_->GetSignature(sig_index); 2314 wasm::FunctionSig* sig = module_->GetSignature(sig_index);
2306 2315
2307 DCHECK(module_->IsValidTable(table_index)); 2316 DCHECK(module_->IsValidTable(table_index));
2308 2317
2309 EnsureFunctionTableNodes(); 2318 EnsureFunctionTableNodes();
2310 MachineOperatorBuilder* machine = jsgraph()->machine(); 2319 MachineOperatorBuilder* machine = jsgraph()->machine();
2311 Node* key = args[0]; 2320 Node* key = args[0];
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after
3036 MachineType load_rep = 3045 MachineType load_rep =
3037 wasm::WasmOpcodes::MachineTypeFor(sig->GetReturn()); 3046 wasm::WasmOpcodes::MachineTypeFor(sig->GetReturn());
3038 val = graph()->NewNode(jsgraph()->machine()->Load(load_rep), arg_buffer, 3047 val = graph()->NewNode(jsgraph()->machine()->Load(load_rep), arg_buffer,
3039 Int32Constant(0), *effect_, *control_); 3048 Int32Constant(0), *effect_, *control_);
3040 } 3049 }
3041 Return(val); 3050 Return(val);
3042 } 3051 }
3043 } 3052 }
3044 3053
3045 Node* WasmGraphBuilder::MemBuffer(uint32_t offset) { 3054 Node* WasmGraphBuilder::MemBuffer(uint32_t offset) {
3046 DCHECK(module_ && module_->instance); 3055 DCHECK_NOT_NULL(module_);
3056 uintptr_t mem_start = reinterpret_cast<uintptr_t>(
3057 module_->instance ? module_->instance->mem_start : nullptr);
3047 if (offset == 0) { 3058 if (offset == 0) {
3048 if (!mem_buffer_) { 3059 if (!mem_buffer_) {
3049 mem_buffer_ = jsgraph()->RelocatableIntPtrConstant( 3060 mem_buffer_ = jsgraph()->RelocatableIntPtrConstant(
3050 reinterpret_cast<uintptr_t>(module_->instance->mem_start), 3061 mem_start, RelocInfo::WASM_MEMORY_REFERENCE);
3051 RelocInfo::WASM_MEMORY_REFERENCE);
3052 } 3062 }
3053 return mem_buffer_; 3063 return mem_buffer_;
3054 } else { 3064 } else {
3055 return jsgraph()->RelocatableIntPtrConstant( 3065 return jsgraph()->RelocatableIntPtrConstant(
3056 reinterpret_cast<uintptr_t>(module_->instance->mem_start + offset), 3066 mem_start + offset, RelocInfo::WASM_MEMORY_REFERENCE);
3057 RelocInfo::WASM_MEMORY_REFERENCE);
3058 } 3067 }
3059 } 3068 }
3060 3069
3061 Node* WasmGraphBuilder::CurrentMemoryPages() { 3070 Node* WasmGraphBuilder::CurrentMemoryPages() {
3071 // CurrentMemoryPages will not be called from asm.js, hence we cannot be in
3072 // lazy-compilation mode, hence the instance will be set.
3073 DCHECK_EQ(wasm::kWasmOrigin, module_->module->origin);
3074 DCHECK_NOT_NULL(module_);
3075 DCHECK_NOT_NULL(module_->instance);
3076
3062 Runtime::FunctionId function_id = Runtime::kWasmMemorySize; 3077 Runtime::FunctionId function_id = Runtime::kWasmMemorySize;
3063 const Runtime::Function* function = Runtime::FunctionForId(function_id); 3078 const Runtime::Function* function = Runtime::FunctionForId(function_id);
3064 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( 3079 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
3065 jsgraph()->zone(), function_id, function->nargs, Operator::kNoThrow, 3080 jsgraph()->zone(), function_id, function->nargs, Operator::kNoThrow,
3066 CallDescriptor::kNoFlags); 3081 CallDescriptor::kNoFlags);
3067 Node* inputs[] = { 3082 Node* inputs[] = {
3068 jsgraph()->CEntryStubConstant(function->result_size), // C entry 3083 jsgraph()->CEntryStubConstant(function->result_size), // C entry
3069 jsgraph()->ExternalConstant( 3084 jsgraph()->ExternalConstant(
3070 ExternalReference(function_id, jsgraph()->isolate())), // ref 3085 ExternalReference(function_id, jsgraph()->isolate())), // ref
3071 jsgraph()->Int32Constant(function->nargs), // arity 3086 jsgraph()->Int32Constant(function->nargs), // arity
(...skipping 13 matching lines...) Expand all
3085 DCHECK_NOT_NULL(module_); 3100 DCHECK_NOT_NULL(module_);
3086 if (mem_size_) return mem_size_; 3101 if (mem_size_) return mem_size_;
3087 uint32_t size = module_->instance ? module_->instance->mem_size : 0; 3102 uint32_t size = module_->instance ? module_->instance->mem_size : 0;
3088 mem_size_ = jsgraph()->RelocatableInt32Constant( 3103 mem_size_ = jsgraph()->RelocatableInt32Constant(
3089 size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE); 3104 size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
3090 return mem_size_; 3105 return mem_size_;
3091 } 3106 }
3092 3107
3093 void WasmGraphBuilder::EnsureFunctionTableNodes() { 3108 void WasmGraphBuilder::EnsureFunctionTableNodes() {
3094 if (function_tables_.size() > 0) return; 3109 if (function_tables_.size() > 0) return;
3095 size_t tables_size = module_->instance->function_tables.size(); 3110 size_t tables_size = module_->module->function_tables.size();
3096 DCHECK(tables_size == module_->instance->signature_tables.size()); 3111 if (module_->instance) {
3112 DCHECK_EQ(tables_size, module_->instance->function_tables.size());
3113 DCHECK_EQ(tables_size, module_->instance->signature_tables.size());
3114 }
3097 for (size_t i = 0; i < tables_size; ++i) { 3115 for (size_t i = 0; i < tables_size; ++i) {
3098 auto function_handle = module_->instance->function_tables[i]; 3116 auto function_handle = module_->GetFunctionTableObj(i);
3099 auto signature_handle = module_->instance->signature_tables[i]; 3117 auto signature_handle = module_->GetSignatureTableObj(i);
3100 DCHECK(!function_handle.is_null() && !signature_handle.is_null()); 3118 DCHECK(!function_handle.is_null() && !signature_handle.is_null());
3101 function_tables_.push_back(HeapConstant(function_handle)); 3119 function_tables_.push_back(HeapConstant(function_handle));
3102 signature_tables_.push_back(HeapConstant(signature_handle)); 3120 signature_tables_.push_back(HeapConstant(signature_handle));
3103 uint32_t table_size = module_->module->function_tables[i].min_size; 3121 uint32_t table_size = module_->module->function_tables[i].min_size;
3104 function_table_sizes_.push_back(jsgraph()->RelocatableInt32Constant( 3122 function_table_sizes_.push_back(jsgraph()->RelocatableInt32Constant(
3105 static_cast<uint32_t>(table_size), 3123 static_cast<uint32_t>(table_size),
3106 RelocInfo::WASM_FUNCTION_TABLE_SIZE_REFERENCE)); 3124 RelocInfo::WASM_FUNCTION_TABLE_SIZE_REFERENCE));
3107 } 3125 }
3108 } 3126 }
3109 3127
3110 Node* WasmGraphBuilder::GetGlobal(uint32_t index) { 3128 Node* WasmGraphBuilder::GetGlobal(uint32_t index) {
3111 MachineType mem_type = 3129 MachineType mem_type =
3112 wasm::WasmOpcodes::MachineTypeFor(module_->GetGlobalType(index)); 3130 wasm::WasmOpcodes::MachineTypeFor(module_->GetGlobalType(index));
3131 byte* globals_start =
3132 module_->instance ? module_->instance->globals_start : nullptr;
3133 uintptr_t global_addr = reinterpret_cast<uintptr_t>(
3134 globals_start + module_->module->globals[index].offset);
3113 Node* addr = jsgraph()->RelocatableIntPtrConstant( 3135 Node* addr = jsgraph()->RelocatableIntPtrConstant(
3114 reinterpret_cast<uintptr_t>(module_->instance->globals_start + 3136 global_addr, RelocInfo::WASM_GLOBAL_REFERENCE);
3115 module_->module->globals[index].offset),
3116 RelocInfo::WASM_GLOBAL_REFERENCE);
3117 const Operator* op = jsgraph()->machine()->Load(mem_type); 3137 const Operator* op = jsgraph()->machine()->Load(mem_type);
3118 Node* node = graph()->NewNode(op, addr, jsgraph()->Int32Constant(0), *effect_, 3138 Node* node = graph()->NewNode(op, addr, jsgraph()->Int32Constant(0), *effect_,
3119 *control_); 3139 *control_);
3120 *effect_ = node; 3140 *effect_ = node;
3121 return node; 3141 return node;
3122 } 3142 }
3123 3143
3124 Node* WasmGraphBuilder::SetGlobal(uint32_t index, Node* val) { 3144 Node* WasmGraphBuilder::SetGlobal(uint32_t index, Node* val) {
3125 MachineType mem_type = 3145 MachineType mem_type =
3126 wasm::WasmOpcodes::MachineTypeFor(module_->GetGlobalType(index)); 3146 wasm::WasmOpcodes::MachineTypeFor(module_->GetGlobalType(index));
3147 byte* globals_start =
3148 module_->instance ? module_->instance->globals_start : 0;
3127 Node* addr = jsgraph()->RelocatableIntPtrConstant( 3149 Node* addr = jsgraph()->RelocatableIntPtrConstant(
3128 reinterpret_cast<uintptr_t>(module_->instance->globals_start + 3150 reinterpret_cast<uintptr_t>(globals_start +
3129 module_->module->globals[index].offset), 3151 module_->module->globals[index].offset),
3130 RelocInfo::WASM_GLOBAL_REFERENCE); 3152 RelocInfo::WASM_GLOBAL_REFERENCE);
3131 const Operator* op = jsgraph()->machine()->Store( 3153 const Operator* op = jsgraph()->machine()->Store(
3132 StoreRepresentation(mem_type.representation(), kNoWriteBarrier)); 3154 StoreRepresentation(mem_type.representation(), kNoWriteBarrier));
3133 Node* node = graph()->NewNode(op, addr, jsgraph()->Int32Constant(0), val, 3155 Node* node = graph()->NewNode(op, addr, jsgraph()->Int32Constant(0), val,
3134 *effect_, *control_); 3156 *effect_, *control_);
3135 *effect_ = node; 3157 *effect_ = node;
3136 return node; 3158 return node;
3137 } 3159 }
3138 3160
(...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after
4235 wasm::ErrorThrower* thrower, Isolate* isolate, 4257 wasm::ErrorThrower* thrower, Isolate* isolate,
4236 wasm::ModuleBytesEnv* module_env, const wasm::WasmFunction* function) { 4258 wasm::ModuleBytesEnv* module_env, const wasm::WasmFunction* function) {
4237 WasmCompilationUnit unit(isolate, module_env, function); 4259 WasmCompilationUnit unit(isolate, module_env, function);
4238 unit.ExecuteCompilation(); 4260 unit.ExecuteCompilation();
4239 return unit.FinishCompilation(thrower); 4261 return unit.FinishCompilation(thrower);
4240 } 4262 }
4241 4263
4242 } // namespace compiler 4264 } // namespace compiler
4243 } // namespace internal 4265 } // namespace internal
4244 } // namespace v8 4266 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/x64/builtins-x64.cc ('k') | src/counters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698