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/compiler/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" |
6 | 6 |
7 #include "src/isolate-inl.h" | 7 #include "src/isolate-inl.h" |
8 | 8 |
9 #include "src/base/platform/elapsed-timer.h" | 9 #include "src/base/platform/elapsed-timer.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
870 op = m->RoundUint64ToFloat64(); | 870 op = m->RoundUint64ToFloat64(); |
871 break; | 871 break; |
872 case wasm::kExprI64SConvertF32: | 872 case wasm::kExprI64SConvertF32: |
873 return BuildI64SConvertF32(input, position); | 873 return BuildI64SConvertF32(input, position); |
874 case wasm::kExprI64SConvertF64: | 874 case wasm::kExprI64SConvertF64: |
875 return BuildI64SConvertF64(input, position); | 875 return BuildI64SConvertF64(input, position); |
876 case wasm::kExprI64UConvertF32: | 876 case wasm::kExprI64UConvertF32: |
877 return BuildI64UConvertF32(input, position); | 877 return BuildI64UConvertF32(input, position); |
878 case wasm::kExprI64UConvertF64: | 878 case wasm::kExprI64UConvertF64: |
879 return BuildI64UConvertF64(input, position); | 879 return BuildI64UConvertF64(input, position); |
880 case wasm::kExprGrowMemory: | |
881 return BuildGrowMemory(input); | |
880 case wasm::kExprI32AsmjsLoadMem8S: | 882 case wasm::kExprI32AsmjsLoadMem8S: |
881 return BuildAsmjsLoadMem(MachineType::Int8(), input); | 883 return BuildAsmjsLoadMem(MachineType::Int8(), input); |
882 case wasm::kExprI32AsmjsLoadMem8U: | 884 case wasm::kExprI32AsmjsLoadMem8U: |
883 return BuildAsmjsLoadMem(MachineType::Uint8(), input); | 885 return BuildAsmjsLoadMem(MachineType::Uint8(), input); |
884 case wasm::kExprI32AsmjsLoadMem16S: | 886 case wasm::kExprI32AsmjsLoadMem16S: |
885 return BuildAsmjsLoadMem(MachineType::Int16(), input); | 887 return BuildAsmjsLoadMem(MachineType::Int16(), input); |
886 case wasm::kExprI32AsmjsLoadMem16U: | 888 case wasm::kExprI32AsmjsLoadMem16U: |
887 return BuildAsmjsLoadMem(MachineType::Uint16(), input); | 889 return BuildAsmjsLoadMem(MachineType::Uint16(), input); |
888 case wasm::kExprI32AsmjsLoadMem: | 890 case wasm::kExprI32AsmjsLoadMem: |
889 return BuildAsmjsLoadMem(MachineType::Int32(), input); | 891 return BuildAsmjsLoadMem(MachineType::Int32(), input); |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1598 trap_->ZeroCheck32(wasm::kTrapFloatUnrepresentable, | 1600 trap_->ZeroCheck32(wasm::kTrapFloatUnrepresentable, |
1599 BuildCCall(sig_builder.Build(), args), position); | 1601 BuildCCall(sig_builder.Build(), args), position); |
1600 const Operator* load_op = jsgraph()->machine()->Load(result_type); | 1602 const Operator* load_op = jsgraph()->machine()->Load(result_type); |
1601 Node* load = | 1603 Node* load = |
1602 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), | 1604 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), |
1603 *effect_, *control_); | 1605 *effect_, *control_); |
1604 *effect_ = load; | 1606 *effect_ = load; |
1605 return load; | 1607 return load; |
1606 } | 1608 } |
1607 | 1609 |
1610 Node* WasmGraphBuilder::BuildGrowMemory(Node* input) { | |
1611 Runtime::FunctionId f = Runtime::kWasmGrowMemory; | |
1612 const Runtime::Function* fun = Runtime::FunctionForId(f); | |
1613 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( | |
1614 jsgraph()->zone(), f, fun->nargs, Operator::kNoProperties, | |
1615 CallDescriptor::kNoFlags); | |
1616 Node** control_ptr = control_; | |
1617 Node** effect_ptr = effect_; | |
1618 wasm::ModuleEnv* module = module_; | |
1619 *control_ptr = graph()->NewNode(jsgraph()->common()->Merge(1), *control_ptr); | |
1620 *effect_ptr = graph()->NewNode(jsgraph()->common()->EffectPhi(1), *effect_ptr, | |
1621 *control_ptr); | |
1622 input = BuildChangeInt32ToTagged(input); | |
1623 Node* inputs[] = {jsgraph()->CEntryStubConstant(fun->result_size), // C entry | |
1624 input, jsgraph()->Constant(module->instance->js_object), | |
ahaas
2016/06/14 13:03:13
Use HeapConstant(module->instance->js_object) inst
gdeepti
2016/06/23 16:57:02
Done.
| |
1625 jsgraph()->ExternalConstant( | |
1626 ExternalReference(f, jsgraph()->isolate())), // ref | |
1627 jsgraph()->Int32Constant(fun->nargs), // arity | |
1628 jsgraph()->Constant(module->instance->context), // context | |
ahaas
2016/06/14 13:03:13
Use HeapConstant(module->instance->context) instea
gdeepti
2016/06/23 16:57:02
Done.
| |
1629 *effect_ptr, | |
1630 *control_ptr}; | |
1631 Node* node = graph()->NewNode(jsgraph()->common()->Call(desc), | |
1632 static_cast<int>(arraysize(inputs)), inputs); | |
1633 *control_ptr = node; | |
1634 *effect_ptr = node; | |
1635 node = BuildChangeTaggedToFloat64(node); | |
1636 node = graph()->NewNode(jsgraph()->machine()->ChangeFloat64ToInt32(), node); | |
1637 return node; | |
1638 } | |
1639 | |
1608 Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right, | 1640 Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right, |
1609 wasm::WasmCodePosition position) { | 1641 wasm::WasmCodePosition position) { |
1610 MachineOperatorBuilder* m = jsgraph()->machine(); | 1642 MachineOperatorBuilder* m = jsgraph()->machine(); |
1611 trap_->ZeroCheck32(wasm::kTrapDivByZero, right, position); | 1643 trap_->ZeroCheck32(wasm::kTrapDivByZero, right, position); |
1612 Node* before = *control_; | 1644 Node* before = *control_; |
1613 Node* denom_is_m1; | 1645 Node* denom_is_m1; |
1614 Node* denom_is_not_m1; | 1646 Node* denom_is_not_m1; |
1615 Branch( | 1647 Branch( |
1616 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), | 1648 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), |
1617 &denom_is_m1, &denom_is_not_m1); | 1649 &denom_is_m1, &denom_is_not_m1); |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2535 return jsgraph()->RelocatableIntPtrConstant( | 2567 return jsgraph()->RelocatableIntPtrConstant( |
2536 reinterpret_cast<uintptr_t>(module_->instance->mem_start + offset), | 2568 reinterpret_cast<uintptr_t>(module_->instance->mem_start + offset), |
2537 RelocInfo::WASM_MEMORY_REFERENCE); | 2569 RelocInfo::WASM_MEMORY_REFERENCE); |
2538 } | 2570 } |
2539 } | 2571 } |
2540 | 2572 |
2541 Node* WasmGraphBuilder::MemSize(uint32_t offset) { | 2573 Node* WasmGraphBuilder::MemSize(uint32_t offset) { |
2542 DCHECK(module_ && module_->instance); | 2574 DCHECK(module_ && module_->instance); |
2543 uint32_t size = static_cast<uint32_t>(module_->instance->mem_size); | 2575 uint32_t size = static_cast<uint32_t>(module_->instance->mem_size); |
2544 if (offset == 0) { | 2576 if (offset == 0) { |
2545 if (!mem_size_) mem_size_ = jsgraph()->Int32Constant(size); | 2577 if (!mem_size_) |
2578 mem_size_ = jsgraph()->RelocatableInt32Constant( | |
2579 size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE); | |
2546 return mem_size_; | 2580 return mem_size_; |
2547 } else { | 2581 } else { |
2548 return jsgraph()->Int32Constant(size + offset); | 2582 return jsgraph()->RelocatableInt32Constant( |
2583 size + offset, RelocInfo::WASM_MEMORY_SIZE_REFERENCE); | |
2549 } | 2584 } |
2550 } | 2585 } |
2551 | 2586 |
2552 Node* WasmGraphBuilder::FunctionTable() { | 2587 Node* WasmGraphBuilder::FunctionTable() { |
2553 DCHECK(module_ && module_->instance && | 2588 DCHECK(module_ && module_->instance && |
2554 !module_->instance->function_table.is_null()); | 2589 !module_->instance->function_table.is_null()); |
2555 if (!function_table_) { | 2590 if (!function_table_) { |
2556 function_table_ = HeapConstant(module_->instance->function_table); | 2591 function_table_ = HeapConstant(module_->instance->function_table); |
2557 } | 2592 } |
2558 return function_table_; | 2593 return function_table_; |
(...skipping 26 matching lines...) Expand all Loading... | |
2585 return node; | 2620 return node; |
2586 } | 2621 } |
2587 | 2622 |
2588 void WasmGraphBuilder::BoundsCheckMem(MachineType memtype, Node* index, | 2623 void WasmGraphBuilder::BoundsCheckMem(MachineType memtype, Node* index, |
2589 uint32_t offset, | 2624 uint32_t offset, |
2590 wasm::WasmCodePosition position) { | 2625 wasm::WasmCodePosition position) { |
2591 DCHECK(module_ && module_->instance); | 2626 DCHECK(module_ && module_->instance); |
2592 size_t size = module_->instance->mem_size; | 2627 size_t size = module_->instance->mem_size; |
2593 byte memsize = wasm::WasmOpcodes::MemSize(memtype); | 2628 byte memsize = wasm::WasmOpcodes::MemSize(memtype); |
2594 | 2629 |
2630 // Check against the effective size. | |
2631 size_t effective_size; | |
2595 if (offset >= size || (static_cast<uint64_t>(offset) + memsize) > size) { | 2632 if (offset >= size || (static_cast<uint64_t>(offset) + memsize) > size) { |
2596 // The access will always throw (unless memory is grown). | 2633 effective_size = 0; |
2597 Node* cond = jsgraph()->Int32Constant(0); | 2634 } else { |
2598 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position); | 2635 effective_size = size - offset - memsize + 1; |
2599 return; | |
2600 } | 2636 } |
2601 | |
2602 // Check against the effective size. | |
2603 size_t effective_size = size - offset - memsize; | |
2604 CHECK(effective_size <= kMaxUInt32); | 2637 CHECK(effective_size <= kMaxUInt32); |
2605 | 2638 |
2606 Uint32Matcher m(index); | 2639 Uint32Matcher m(index); |
2607 if (m.HasValue()) { | 2640 if (m.HasValue()) { |
2608 uint32_t value = m.Value(); | 2641 uint32_t value = m.Value(); |
2609 if (value <= effective_size) { | 2642 if (value < effective_size) { |
2610 // The bounds check will always succeed. | 2643 // The bounds check will always succeed. |
2611 return; | 2644 return; |
2612 } | 2645 } |
2613 } | 2646 } |
2614 | 2647 |
2615 Node* cond = graph()->NewNode( | 2648 Node* cond = graph()->NewNode(jsgraph()->machine()->Uint32LessThan(), index, |
2616 jsgraph()->machine()->Uint32LessThanOrEqual(), index, | 2649 jsgraph()->RelocatableInt32Constant( |
2617 jsgraph()->Int32Constant(static_cast<uint32_t>(effective_size))); | 2650 static_cast<uint32_t>(effective_size), |
2651 RelocInfo::WASM_MEMORY_SIZE_REFERENCE)); | |
2618 | 2652 |
2619 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position); | 2653 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position); |
2620 } | 2654 } |
2621 | 2655 |
2622 MachineType WasmGraphBuilder::GetTypeForUnalignedAccess(uint32_t alignment, | 2656 MachineType WasmGraphBuilder::GetTypeForUnalignedAccess(uint32_t alignment, |
2623 bool signExtend) { | 2657 bool signExtend) { |
2624 switch (alignment) { | 2658 switch (alignment) { |
2625 case 0: | 2659 case 0: |
2626 return signExtend ? MachineType::Int8() : MachineType::Uint8(); | 2660 return signExtend ? MachineType::Int8() : MachineType::Uint8(); |
2627 case 1: | 2661 case 1: |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3297 function_->code_start_offset), | 3331 function_->code_start_offset), |
3298 compile_ms); | 3332 compile_ms); |
3299 } | 3333 } |
3300 | 3334 |
3301 return code; | 3335 return code; |
3302 } | 3336 } |
3303 | 3337 |
3304 } // namespace compiler | 3338 } // namespace compiler |
3305 } // namespace internal | 3339 } // namespace internal |
3306 } // namespace v8 | 3340 } // namespace v8 |
OLD | NEW |