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

Side by Side Diff: src/compiler/fast-accessor-assembler.cc

Issue 1474543004: Implement Fast Accessor Builder (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review feedback. Created 5 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
OLDNEW
(Empty)
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/fast-accessor-assembler.h"
6
7 #include "src/base/logging.h"
8 #include "src/compiler/graph.h"
9 #include "src/compiler/linkage.h"
10 #include "src/compiler/pipeline.h"
11 #include "src/compiler/raw-machine-assembler.h"
12 #include "src/compiler/schedule.h"
13 #include "src/compiler/verifier.h"
14 #include "src/handles-inl.h"
15 #include "src/objects.h" // For FAA::GetInternalField impl.
16
17 namespace v8 {
18 namespace internal {
19 namespace compiler {
20
21 FastAccessorAssembler::FastAccessorAssembler(Isolate* isolate)
22 : zone_(),
23 assembler_(new RawMachineAssembler(
24 isolate, new (zone()) Graph(zone()),
25 Linkage::GetJSCallDescriptor(&zone_, false, 1,
26 CallDescriptor::kNoFlags))),
27 state_(kBuilding) {}
28
29
30 FastAccessorAssembler::~FastAccessorAssembler() {}
31
32
33 FastAccessorAssembler::ValueId FastAccessorAssembler::IntegerConstant(
34 int const_value) {
35 CHECK_EQ(kBuilding, state_);
36 return FromRaw(assembler_->NumberConstant(const_value));
37 }
38
39
40 FastAccessorAssembler::ValueId FastAccessorAssembler::GetReceiver() {
41 CHECK_EQ(kBuilding, state_);
42
43 // For JS call descriptor, the receiver is parameter 0. If we use other
44 // call descriptors, this may or may not hold. So let's check.
45 CHECK(assembler_->call_descriptor()->IsJSFunctionCall());
46 return FromRaw(assembler_->Parameter(0));
47 }
48
49
50 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadInternalField(
51 ValueId value, int field_no) {
52 CHECK_EQ(kBuilding, state_);
53 // Determine the 'value' object's instance type.
54 auto object_map =
Michael Starzinger 2015/12/03 13:36:18 nit: The return type should be "Node*" here AFAICT
vogelheim 2015/12/04 09:33:00 Done.
55 assembler_->Load(kMachPtr, FromId(value),
56 assembler_->IntPtrConstant(
57 Internals::kHeapObjectMapOffset - kHeapObjectTag));
58 auto instance_type = assembler_->WordAnd(
59 assembler_->Load(
60 kMachUint16, object_map,
61 assembler_->IntPtrConstant(
62 Internals::kMapInstanceTypeAndBitFieldOffset - kHeapObjectTag)),
63 assembler_->IntPtrConstant(0xff));
64
65 // Check whether we have a proper JSObject.
66 RawMachineLabel is_jsobject, is_not_jsobject, merge;
67 assembler_->Branch(
68 assembler_->WordEqual(
69 instance_type, assembler_->IntPtrConstant(Internals::kJSObjectType)),
70 &is_jsobject, &is_not_jsobject);
71
72 // JSObject? Then load the internal field field_no.
73 assembler_->Bind(&is_jsobject);
74 auto internal_field = assembler_->Load(
75 kMachPtr, FromId(value),
76 assembler_->IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag +
77 kPointerSize * field_no));
78 assembler_->Goto(&merge);
79
80 // No JSObject? Return undefined.
81 assembler_->Bind(&is_not_jsobject);
82 auto fail_value = assembler_->UndefinedConstant();
83 assembler_->Goto(&merge);
84
85 // Return.
86 assembler_->Bind(&merge);
87 auto phi = assembler_->Phi(kMachAnyTagged, internal_field, fail_value);
88 return FromRaw(phi);
89 }
90
91
92 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadValue(
93 FastAccessorAssembler::ValueId value, int offset) {
94 CHECK_EQ(kBuilding, state_);
95 return FromRaw(assembler_->Load(kMachIntPtr, FromId(value),
96 assembler_->IntPtrConstant(offset)));
97 }
98
99
100 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadObject(
101 FastAccessorAssembler::ValueId value, int offset) {
102 CHECK_EQ(kBuilding, state_);
103 return FromRaw(assembler_->Load(
104 kMachAnyTagged, assembler_->Load(kMachPtr, FromId(value),
105 assembler_->IntPtrConstant(offset))));
106 }
107
108
109 void FastAccessorAssembler::ReturnValue(ValueId value) {
110 CHECK_EQ(kBuilding, state_);
111 assembler_->Return(FromId(value));
112 }
113
114
115 void FastAccessorAssembler::CheckFlagSetOrReturnNull(
116 FastAccessorAssembler::ValueId value, int mask) {
117 CHECK_EQ(kBuilding, state_);
118 RawMachineLabel pass, fail;
119 assembler_->Branch(
120 assembler_->Word32Equal(
121 assembler_->Word32And(FromId(value), assembler_->Int32Constant(mask)),
122 assembler_->Int32Constant(0)),
123 &pass, &fail);
124 assembler_->Bind(&fail);
125 assembler_->Return(assembler_->NullConstant());
126 assembler_->Bind(&pass);
127 }
128
129
130 void FastAccessorAssembler::CheckNotZeroOrReturnNull(ValueId value) {
131 CHECK_EQ(kBuilding, state_);
132 RawMachineLabel is_null, not_null;
133 assembler_->Branch(
134 assembler_->IntPtrEqual(FromId(value), assembler_->IntPtrConstant(0)),
135 &is_null, &not_null);
136 assembler_->Bind(&is_null);
137 assembler_->Return(assembler_->NullConstant());
138 assembler_->Bind(&not_null);
139 }
140
141
142 FastAccessorAssembler::LabelId FastAccessorAssembler::MakeLabel() {
143 CHECK_EQ(kBuilding, state_);
144 RawMachineLabel* label =
145 new (zone()->New(sizeof(RawMachineLabel))) RawMachineLabel;
146 return FromRaw(label);
147 }
148
149
150 void FastAccessorAssembler::SetLabel(LabelId label_id) {
151 CHECK_EQ(kBuilding, state_);
152 assembler_->Bind(FromId(label_id));
153 }
154
155
156 void FastAccessorAssembler::CheckNotZeroOrJump(ValueId value_id,
157 LabelId label_id) {
158 CHECK_EQ(kBuilding, state_);
159 RawMachineLabel pass;
160 assembler_->Branch(
161 assembler_->IntPtrEqual(FromId(value_id), assembler_->IntPtrConstant(0)),
162 &pass, FromId(label_id));
163 assembler_->Bind(&pass);
164 }
165
166
167 MaybeHandle<Code> FastAccessorAssembler::Build() {
168 CHECK_EQ(kBuilding, state_);
169
170 // Cleanup: We no longer need this.
171 nodes_.clear();
172 labels_.clear();
173
174 // Export the schedule and call the compiler.
175 CompilationInfo info("FastAccessorAssembler", assembler_->isolate(), zone());
176 Schedule* schedule = assembler_->Export();
177
178 // TODO(vogelheim): Pipeline should have a dedicated entry point for this
179 // assembler.
180 MaybeHandle<Code> code = Pipeline::GenerateCodeForTesting(
181 &info, assembler_->call_descriptor(), assembler_->graph(), schedule);
182
183 // Update state & return.
184 state_ = !code.is_null() ? kBuilt : kError;
185 return code;
186 }
187
188
189 FastAccessorAssembler::ValueId FastAccessorAssembler::FromRaw(Node* node) {
190 nodes_.push_back(node);
191 ValueId value = {nodes_.size() - 1};
192 return value;
193 }
194
195
196 FastAccessorAssembler::LabelId FastAccessorAssembler::FromRaw(
197 RawMachineLabel* label) {
198 labels_.push_back(label);
199 LabelId label_id = {labels_.size() - 1};
200 return label_id;
201 }
202
203
204 Node* FastAccessorAssembler::FromId(
205 FastAccessorAssembler::ValueId value) const {
Michael Starzinger 2015/12/03 13:36:18 nit: Just "ValueId" without the namespace prefix s
vogelheim 2015/12/04 09:33:00 Done.
206 CHECK_LT(value.value_id, nodes_.size());
207 CHECK_NOT_NULL(nodes_.at(value.value_id));
208 return nodes_.at(value.value_id);
209 }
210
211
212 RawMachineLabel* FastAccessorAssembler::FromId(
213 FastAccessorAssembler::LabelId label) const {
Michael Starzinger 2015/12/03 13:36:18 Likewise.
vogelheim 2015/12/04 09:33:00 Done.
214 CHECK_LT(label.label_id, labels_.size());
215 CHECK_NOT_NULL(labels_.at(label.label_id));
216 return labels_.at(label.label_id);
217 }
218
219
220 } // namespace compiler
221 } // namespace internal
222 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698