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
3 // found in the LICENSE file.
4 
5 #include "src/compiler/js-frame-specialization.h"
6 
7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/linkage.h"
9 #include "src/frames-inl.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14 
Reduce(Node * node)15 Reduction JSFrameSpecialization::Reduce(Node* node) {
16   switch (node->opcode()) {
17     case IrOpcode::kOsrValue:
18       return ReduceOsrValue(node);
19     case IrOpcode::kOsrGuard:
20       return ReduceOsrGuard(node);
21     case IrOpcode::kParameter:
22       return ReduceParameter(node);
23     default:
24       break;
25   }
26   return NoChange();
27 }
28 
ReduceOsrValue(Node * node)29 Reduction JSFrameSpecialization::ReduceOsrValue(Node* node) {
30   DCHECK_EQ(IrOpcode::kOsrValue, node->opcode());
31   Handle<Object> value;
32   int index = OsrValueIndexOf(node->op());
33   int const parameters_count = frame()->ComputeParametersCount() + 1;
34   if (index == Linkage::kOsrContextSpillSlotIndex) {
35     value = handle(frame()->context(), isolate());
36   } else if (index >= parameters_count) {
37     value = handle(frame()->GetExpression(index - parameters_count), isolate());
38   } else {
39     // The OsrValue index 0 is the receiver.
40     value =
41         handle(index ? frame()->GetParameter(index - 1) : frame()->receiver(),
42                isolate());
43   }
44   return Replace(jsgraph()->Constant(value));
45 }
46 
ReduceOsrGuard(Node * node)47 Reduction JSFrameSpecialization::ReduceOsrGuard(Node* node) {
48   DCHECK_EQ(IrOpcode::kOsrGuard, node->opcode());
49   ReplaceWithValue(node, node->InputAt(0),
50                    NodeProperties::GetEffectInput(node));
51   return Changed(node);
52 }
53 
ReduceParameter(Node * node)54 Reduction JSFrameSpecialization::ReduceParameter(Node* node) {
55   DCHECK_EQ(IrOpcode::kParameter, node->opcode());
56   Handle<Object> value;
57   int const index = ParameterIndexOf(node->op());
58   int const parameters_count = frame()->ComputeParametersCount() + 1;
59   if (index == Linkage::kJSCallClosureParamIndex) {
60     // The Parameter index references the closure.
61     value = handle(frame()->function(), isolate());
62   } else if (index == Linkage::GetJSCallArgCountParamIndex(parameters_count)) {
63     // The Parameter index references the parameter count.
64     value = handle(Smi::FromInt(parameters_count - 1), isolate());
65   } else if (index == Linkage::GetJSCallContextParamIndex(parameters_count)) {
66     // The Parameter index references the context.
67     value = handle(frame()->context(), isolate());
68   } else {
69     // The Parameter index 0 is the receiver.
70     value =
71         handle(index ? frame()->GetParameter(index - 1) : frame()->receiver(),
72                isolate());
73   }
74   return Replace(jsgraph()->Constant(value));
75 }
76 
77 
isolate() const78 Isolate* JSFrameSpecialization::isolate() const { return jsgraph()->isolate(); }
79 
80 }  // namespace compiler
81 }  // namespace internal
82 }  // namespace v8
83