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 <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
10 | 10 |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 return jsgraph()->Int32Constant(value); | 467 return jsgraph()->Int32Constant(value); |
468 } | 468 } |
469 | 469 |
470 Node* WasmGraphBuilder::Int64Constant(int64_t value) { | 470 Node* WasmGraphBuilder::Int64Constant(int64_t value) { |
471 return jsgraph()->Int64Constant(value); | 471 return jsgraph()->Int64Constant(value); |
472 } | 472 } |
473 | 473 |
474 void WasmGraphBuilder::StackCheck(wasm::WasmCodePosition position, | 474 void WasmGraphBuilder::StackCheck(wasm::WasmCodePosition position, |
475 Node** effect, Node** control) { | 475 Node** effect, Node** control) { |
476 if (FLAG_wasm_no_stack_checks) return; | 476 if (FLAG_wasm_no_stack_checks) return; |
477 if (effect == nullptr) { | |
478 effect = effect_; | |
479 } | |
480 if (control == nullptr) { | |
481 control = control_; | |
482 } | |
483 // We do not generate stack checks for cctests. | 477 // We do not generate stack checks for cctests. |
484 if (module_ && !module_->instance->context.is_null()) { | 478 if (!module_ || module_->instance->context.is_null()) return; |
485 Node* limit = graph()->NewNode( | 479 if (effect == nullptr) effect = effect_; |
486 jsgraph()->machine()->Load(MachineType::Pointer()), | 480 if (control == nullptr) control = control_; |
487 jsgraph()->ExternalConstant( | |
488 ExternalReference::address_of_stack_limit(jsgraph()->isolate())), | |
489 jsgraph()->IntPtrConstant(0), *effect, *control); | |
490 Node* pointer = graph()->NewNode(jsgraph()->machine()->LoadStackPointer()); | |
491 | 481 |
492 Node* check = | 482 Node* limit = graph()->NewNode( |
493 graph()->NewNode(jsgraph()->machine()->UintLessThan(), limit, pointer); | 483 jsgraph()->machine()->Load(MachineType::Pointer()), |
| 484 jsgraph()->ExternalConstant( |
| 485 ExternalReference::address_of_stack_limit(jsgraph()->isolate())), |
| 486 jsgraph()->IntPtrConstant(0), *effect, *control); |
| 487 Node* pointer = graph()->NewNode(jsgraph()->machine()->LoadStackPointer()); |
494 | 488 |
495 Diamond stack_check(graph(), jsgraph()->common(), check, BranchHint::kTrue); | 489 Node* check = |
496 stack_check.Chain(*control); | 490 graph()->NewNode(jsgraph()->machine()->UintLessThan(), limit, pointer); |
497 Node* effect_true = *effect; | |
498 | 491 |
499 // Generate a call to the runtime if there is a stack check failure. | 492 Diamond stack_check(graph(), jsgraph()->common(), check, BranchHint::kTrue); |
500 Node* call = BuildCallToRuntime(Runtime::kStackGuard, jsgraph(), | 493 stack_check.Chain(*control); |
501 module_->instance->context, nullptr, 0, | 494 Node* effect_true = *effect; |
502 effect, stack_check.if_false); | |
503 SetSourcePosition(call, position); | |
504 | 495 |
505 Node* ephi = graph()->NewNode(jsgraph()->common()->EffectPhi(2), | 496 Handle<Code> code = jsgraph()->isolate()->builtins()->WasmStackGuard(); |
506 effect_true, call, stack_check.merge); | 497 CallInterfaceDescriptor idesc = |
| 498 WasmStackGuardDescriptor(jsgraph()->isolate()); |
| 499 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 500 jsgraph()->isolate(), jsgraph()->zone(), idesc, 0, |
| 501 CallDescriptor::kNoFlags, Operator::kNoProperties); |
| 502 Node* stub_code = jsgraph()->HeapConstant(code); |
507 | 503 |
508 *control = stack_check.merge; | 504 Node* context = jsgraph()->SmiConstant(0); |
509 *effect = ephi; | 505 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), stub_code, |
510 } | 506 context, *effect, stack_check.if_false); |
| 507 |
| 508 SetSourcePosition(call, position); |
| 509 |
| 510 Node* ephi = graph()->NewNode(jsgraph()->common()->EffectPhi(2), effect_true, |
| 511 call, stack_check.merge); |
| 512 |
| 513 *control = stack_check.merge; |
| 514 *effect = ephi; |
511 } | 515 } |
512 | 516 |
513 Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, Node* right, | 517 Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, Node* right, |
514 wasm::WasmCodePosition position) { | 518 wasm::WasmCodePosition position) { |
515 const Operator* op; | 519 const Operator* op; |
516 MachineOperatorBuilder* m = jsgraph()->machine(); | 520 MachineOperatorBuilder* m = jsgraph()->machine(); |
517 switch (opcode) { | 521 switch (opcode) { |
518 case wasm::kExprI32Add: | 522 case wasm::kExprI32Add: |
519 op = m->Int32Add(); | 523 op = m->Int32Add(); |
520 break; | 524 break; |
(...skipping 2476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2997 | 3001 |
2998 // We are passing the raw arg_buffer here. To the GC and other parts, it looks | 3002 // We are passing the raw arg_buffer here. To the GC and other parts, it looks |
2999 // like a Smi (lowest bit not set). In the runtime function however, don't | 3003 // like a Smi (lowest bit not set). In the runtime function however, don't |
3000 // call Smi::value on it, but just cast it to a byte pointer. | 3004 // call Smi::value on it, but just cast it to a byte pointer. |
3001 Node* parameters[] = { | 3005 Node* parameters[] = { |
3002 jsgraph()->HeapConstant(instance), // wasm instance | 3006 jsgraph()->HeapConstant(instance), // wasm instance |
3003 jsgraph()->SmiConstant(function_index), // function index | 3007 jsgraph()->SmiConstant(function_index), // function index |
3004 arg_buffer, // argument buffer | 3008 arg_buffer, // argument buffer |
3005 }; | 3009 }; |
3006 BuildCallToRuntime(Runtime::kWasmRunInterpreter, jsgraph(), | 3010 BuildCallToRuntime(Runtime::kWasmRunInterpreter, jsgraph(), |
3007 jsgraph()->isolate()->native_context(), parameters, | 3011 instance->compiled_module()->native_context(), parameters, |
3008 arraysize(parameters), effect_, *control_); | 3012 arraysize(parameters), effect_, *control_); |
3009 | 3013 |
3010 // Read back the return value. | 3014 // Read back the return value. |
3011 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && | 3015 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && |
3012 sig->GetReturn() == wasm::kWasmI64) { | 3016 sig->GetReturn() == wasm::kWasmI64) { |
3013 MachineType load_rep = wasm::WasmOpcodes::MachineTypeFor(wasm::kWasmI32); | 3017 MachineType load_rep = wasm::WasmOpcodes::MachineTypeFor(wasm::kWasmI32); |
3014 Node* lower = | 3018 Node* lower = |
3015 graph()->NewNode(jsgraph()->machine()->Load(load_rep), arg_buffer, | 3019 graph()->NewNode(jsgraph()->machine()->Load(load_rep), arg_buffer, |
3016 Int32Constant(0), *effect_, *control_); | 3020 Int32Constant(0), *effect_, *control_); |
3017 Node* upper = | 3021 Node* upper = |
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4134 function_->code_start_offset), | 4138 function_->code_start_offset), |
4135 compile_ms); | 4139 compile_ms); |
4136 } | 4140 } |
4137 | 4141 |
4138 return code; | 4142 return code; |
4139 } | 4143 } |
4140 | 4144 |
4141 } // namespace compiler | 4145 } // namespace compiler |
4142 } // namespace internal | 4146 } // namespace internal |
4143 } // namespace v8 | 4147 } // namespace v8 |
OLD | NEW |