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

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

Issue 1674633002: Move FastAccessorAssembler from RawMachineAssembler to CodeStubAssembler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase. Created 4 years, 10 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
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/fast-accessor-assembler.h" 5 #include "src/compiler/fast-accessor-assembler.h"
6 6
7 #include "src/base/logging.h" 7 #include "src/base/logging.h"
8 #include "src/code-stubs.h" // For CallApiFunctionStub. 8 #include "src/code-stubs.h" // For CallApiFunctionStub.
9 #include "src/compiler/graph.h" 9 #include "src/compiler/code-stub-assembler.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h" // For GetStubCallDescriptor
11 #include "src/compiler/pipeline.h"
12 #include "src/compiler/raw-machine-assembler.h"
13 #include "src/compiler/schedule.h"
14 #include "src/compiler/verifier.h"
15 #include "src/handles-inl.h" 11 #include "src/handles-inl.h"
16 #include "src/objects.h" // For FAA::GetInternalField impl. 12 #include "src/objects.h" // For FAA::GetInternalField impl.
17 13
18 namespace v8 { 14 namespace v8 {
19 namespace internal { 15 namespace internal {
20 namespace compiler { 16 namespace compiler {
21 17
22 FastAccessorAssembler::FastAccessorAssembler(Isolate* isolate) 18 FastAccessorAssembler::FastAccessorAssembler(Isolate* isolate)
23 : zone_(), 19 : zone_(),
24 assembler_(new RawMachineAssembler( 20 isolate_(isolate),
25 isolate, new (zone()) Graph(zone()), 21 assembler_(new CodeStubAssembler(isolate, zone(), 1,
26 Linkage::GetJSCallDescriptor(&zone_, false, 1, 22 Code::ComputeFlags(Code::STUB),
27 CallDescriptor::kNoFlags))), 23 "FastAccessorAssembler")),
28 state_(kBuilding) {} 24 state_(kBuilding) {}
29 25
30 26 FastAccessorAssembler::~FastAccessorAssembler() { Clear(); }
31 FastAccessorAssembler::~FastAccessorAssembler() {}
32
33 27
34 FastAccessorAssembler::ValueId FastAccessorAssembler::IntegerConstant( 28 FastAccessorAssembler::ValueId FastAccessorAssembler::IntegerConstant(
35 int const_value) { 29 int const_value) {
36 CHECK_EQ(kBuilding, state_); 30 CHECK_EQ(kBuilding, state_);
37 return FromRaw(assembler_->NumberConstant(const_value)); 31 return FromRaw(assembler_->NumberConstant(const_value));
38 } 32 }
39 33
40
41 FastAccessorAssembler::ValueId FastAccessorAssembler::GetReceiver() { 34 FastAccessorAssembler::ValueId FastAccessorAssembler::GetReceiver() {
42 CHECK_EQ(kBuilding, state_); 35 CHECK_EQ(kBuilding, state_);
43 36
44 // For JS call descriptor, the receiver is parameter 0. If we use other 37 // For JS functions, the receiver is parameter 0.
45 // call descriptors, this may or may not hold. So let's check.
46 CHECK(assembler_->call_descriptor()->IsJSFunctionCall());
47 return FromRaw(assembler_->Parameter(0)); 38 return FromRaw(assembler_->Parameter(0));
48 } 39 }
49 40
50
51 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadInternalField( 41 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadInternalField(
52 ValueId value, int field_no) { 42 ValueId value, int field_no) {
53 CHECK_EQ(kBuilding, state_); 43 CHECK_EQ(kBuilding, state_);
44
54 // Determine the 'value' object's instance type. 45 // Determine the 'value' object's instance type.
55 Node* object_map = 46 Node* object_map = assembler_->LoadObjectFieldTyped(
56 assembler_->Load(MachineType::Pointer(), FromId(value), 47 FromId(value), Internals::kHeapObjectMapOffset, MachineType::Pointer());
57 assembler_->IntPtrConstant(
58 Internals::kHeapObjectMapOffset - kHeapObjectTag));
59 Node* instance_type = assembler_->WordAnd( 48 Node* instance_type = assembler_->WordAnd(
60 assembler_->Load( 49 assembler_->LoadObjectFieldTyped(
61 MachineType::Uint16(), object_map, 50 object_map, Internals::kMapInstanceTypeAndBitFieldOffset,
62 assembler_->IntPtrConstant( 51 MachineType::Uint16()),
63 Internals::kMapInstanceTypeAndBitFieldOffset - kHeapObjectTag)),
64 assembler_->IntPtrConstant(0xff)); 52 assembler_->IntPtrConstant(0xff));
65 53
66 // Check whether we have a proper JSObject. 54 // Check whether we have a proper JSObject.
67 RawMachineLabel is_jsobject, is_not_jsobject, merge; 55 CodeStubAssembler::Variable result(assembler_.get(),
56 MachineRepresentation::kTagged);
57 CodeStubAssembler::Label is_jsobject(assembler_.get());
58 CodeStubAssembler::Label is_not_jsobject(assembler_.get());
59 CodeStubAssembler::Label merge(assembler_.get(), &result);
68 assembler_->Branch( 60 assembler_->Branch(
69 assembler_->WordEqual( 61 assembler_->WordEqual(
70 instance_type, assembler_->IntPtrConstant(Internals::kJSObjectType)), 62 instance_type, assembler_->IntPtrConstant(Internals::kJSObjectType)),
71 &is_jsobject, &is_not_jsobject); 63 &is_jsobject, &is_not_jsobject);
72 64
73 // JSObject? Then load the internal field field_no. 65 // JSObject? Then load the internal field field_no.
74 assembler_->Bind(&is_jsobject); 66 assembler_->Bind(&is_jsobject);
75 Node* internal_field = assembler_->Load( 67 Node* internal_field = assembler_->LoadObjectFieldTyped(
76 MachineType::Pointer(), FromId(value), 68 FromId(value), JSObject::kHeaderSize + kPointerSize * field_no,
77 assembler_->IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag + 69 MachineType::Pointer());
78 kPointerSize * field_no)); 70 result.Bind(internal_field);
79 assembler_->Goto(&merge); 71 assembler_->Goto(&merge);
80 72
81 // No JSObject? Return undefined. 73 // No JSObject? Return undefined.
82 // TODO(vogelheim): Check whether this is the appropriate action, or whether 74 // TODO(vogelheim): Check whether this is the appropriate action, or whether
83 // the method should take a label instead. 75 // the method should take a label instead.
84 assembler_->Bind(&is_not_jsobject); 76 assembler_->Bind(&is_not_jsobject);
85 Node* fail_value = assembler_->UndefinedConstant(); 77 Node* fail_value = assembler_->UndefinedConstant();
78 result.Bind(fail_value);
86 assembler_->Goto(&merge); 79 assembler_->Goto(&merge);
87 80
88 // Return. 81 // Return.
89 assembler_->Bind(&merge); 82 assembler_->Bind(&merge);
90 Node* phi = assembler_->Phi(MachineRepresentation::kTagged, internal_field, 83 return FromRaw(result.value());
91 fail_value);
92 return FromRaw(phi);
93 } 84 }
94 85
95
96 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadValue(ValueId value, 86 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadValue(ValueId value,
97 int offset) { 87 int offset) {
98 CHECK_EQ(kBuilding, state_); 88 CHECK_EQ(kBuilding, state_);
99 return FromRaw(assembler_->Load(MachineType::IntPtr(), FromId(value), 89 return FromRaw(assembler_->LoadNativeFieldTyped(FromId(value), offset,
100 assembler_->IntPtrConstant(offset))); 90 MachineType::IntPtr()));
101 } 91 }
102 92
103
104 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadObject(ValueId value, 93 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadObject(ValueId value,
105 int offset) { 94 int offset) {
106 CHECK_EQ(kBuilding, state_); 95 CHECK_EQ(kBuilding, state_);
107 return FromRaw( 96 return FromRaw(assembler_->LoadNativeFieldTyped(
108 assembler_->Load(MachineType::AnyTagged(), 97 assembler_->LoadNativeFieldTyped(FromId(value), offset,
109 assembler_->Load(MachineType::Pointer(), FromId(value), 98 MachineType::Pointer()),
110 assembler_->IntPtrConstant(offset)))); 99 0, MachineType::AnyTagged()));
111 } 100 }
112 101
113
114 void FastAccessorAssembler::ReturnValue(ValueId value) { 102 void FastAccessorAssembler::ReturnValue(ValueId value) {
115 CHECK_EQ(kBuilding, state_); 103 CHECK_EQ(kBuilding, state_);
116 assembler_->Return(FromId(value)); 104 assembler_->Return(FromId(value));
117 } 105 }
118 106
119
120 void FastAccessorAssembler::CheckFlagSetOrReturnNull(ValueId value, int mask) { 107 void FastAccessorAssembler::CheckFlagSetOrReturnNull(ValueId value, int mask) {
121 CHECK_EQ(kBuilding, state_); 108 CHECK_EQ(kBuilding, state_);
122 RawMachineLabel pass, fail; 109 CodeStubAssembler::Label pass(assembler_.get());
110 CodeStubAssembler::Label fail(assembler_.get());
123 assembler_->Branch( 111 assembler_->Branch(
124 assembler_->Word32Equal( 112 assembler_->Word32Equal(
125 assembler_->Word32And(FromId(value), assembler_->Int32Constant(mask)), 113 assembler_->Word32And(FromId(value), assembler_->Int32Constant(mask)),
126 assembler_->Int32Constant(0)), 114 assembler_->Int32Constant(0)),
127 &pass, &fail); 115 &pass, &fail);
128 assembler_->Bind(&fail); 116 assembler_->Bind(&fail);
129 assembler_->Return(assembler_->NullConstant()); 117 assembler_->Return(assembler_->NullConstant());
130 assembler_->Bind(&pass); 118 assembler_->Bind(&pass);
131 } 119 }
132 120
133
134 void FastAccessorAssembler::CheckNotZeroOrReturnNull(ValueId value) { 121 void FastAccessorAssembler::CheckNotZeroOrReturnNull(ValueId value) {
135 CHECK_EQ(kBuilding, state_); 122 CHECK_EQ(kBuilding, state_);
136 RawMachineLabel is_null, not_null; 123 CodeStubAssembler::Label is_null(assembler_.get());
124 CodeStubAssembler::Label not_null(assembler_.get());
137 assembler_->Branch( 125 assembler_->Branch(
138 assembler_->IntPtrEqual(FromId(value), assembler_->IntPtrConstant(0)), 126 assembler_->WordEqual(FromId(value), assembler_->IntPtrConstant(0)),
139 &is_null, &not_null); 127 &is_null, &not_null);
140 assembler_->Bind(&is_null); 128 assembler_->Bind(&is_null);
141 assembler_->Return(assembler_->NullConstant()); 129 assembler_->Return(assembler_->NullConstant());
142 assembler_->Bind(&not_null); 130 assembler_->Bind(&not_null);
143 } 131 }
144 132
145
146 FastAccessorAssembler::LabelId FastAccessorAssembler::MakeLabel() { 133 FastAccessorAssembler::LabelId FastAccessorAssembler::MakeLabel() {
147 CHECK_EQ(kBuilding, state_); 134 CHECK_EQ(kBuilding, state_);
148 RawMachineLabel* label = 135 return FromRaw(new CodeStubAssembler::Label(assembler_.get()));
149 new (zone()->New(sizeof(RawMachineLabel))) RawMachineLabel;
150 return FromRaw(label);
151 } 136 }
152 137
153
154 void FastAccessorAssembler::SetLabel(LabelId label_id) { 138 void FastAccessorAssembler::SetLabel(LabelId label_id) {
155 CHECK_EQ(kBuilding, state_); 139 CHECK_EQ(kBuilding, state_);
156 assembler_->Bind(FromId(label_id)); 140 assembler_->Bind(FromId(label_id));
157 } 141 }
158 142
159
160 void FastAccessorAssembler::CheckNotZeroOrJump(ValueId value_id, 143 void FastAccessorAssembler::CheckNotZeroOrJump(ValueId value_id,
161 LabelId label_id) { 144 LabelId label_id) {
162 CHECK_EQ(kBuilding, state_); 145 CHECK_EQ(kBuilding, state_);
163 RawMachineLabel pass; 146 CodeStubAssembler::Label pass(assembler_.get());
164 assembler_->Branch( 147 assembler_->Branch(
165 assembler_->IntPtrEqual(FromId(value_id), assembler_->IntPtrConstant(0)), 148 assembler_->WordEqual(FromId(value_id), assembler_->IntPtrConstant(0)),
166 &pass, FromId(label_id)); 149 &pass, FromId(label_id));
167 assembler_->Bind(&pass); 150 assembler_->Bind(&pass);
168 } 151 }
169 152
170 FastAccessorAssembler::ValueId FastAccessorAssembler::Call( 153 FastAccessorAssembler::ValueId FastAccessorAssembler::Call(
171 FunctionCallback callback_function, ValueId arg) { 154 FunctionCallback callback_function, ValueId arg) {
172 CHECK_EQ(kBuilding, state_); 155 CHECK_EQ(kBuilding, state_);
173 156
174 // Create API function stub. 157 // Create API function stub.
175 CallApiFunctionStub stub(assembler_->isolate(), true); 158 CallApiFunctionStub stub(isolate(), true);
176 159
177 // Wrap the FunctionCallback in an ExternalReference. 160 // Wrap the FunctionCallback in an ExternalReference.
178 ApiFunction callback_api_function(FUNCTION_ADDR(callback_function)); 161 ApiFunction callback_api_function(FUNCTION_ADDR(callback_function));
179 ExternalReference callback(&callback_api_function, 162 ExternalReference callback(&callback_api_function,
180 ExternalReference::DIRECT_API_CALL, 163 ExternalReference::DIRECT_API_CALL, isolate());
181 assembler_->isolate());
182 164
183 // The stub has 5 parameters, and kJSParam (here: 1) parameters to pass 165 // The stub has 5 parameters, and kJSParam (here: 1) parameters to pass
184 // through to the callback. 166 // through to the callback.
185 // See: ApiFunctionDescriptor::BuildCallInterfaceDescriptorFunctionType 167 // See: ApiFunctionDescriptor::BuildCallInterfaceDescriptorFunctionType
186 static const int kStackParam = 1; 168 static const int kStackParam = 1;
187 Node* args[] = { 169 Node* args[] = {
188 // Stub/register parameters: 170 // Stub/register parameters:
189 assembler_->Parameter(0), /* receiver (use accessor's) */ 171 assembler_->Parameter(0), /* receiver (use accessor's) */
190 assembler_->UndefinedConstant(), /* call_data (undefined) */ 172 assembler_->UndefinedConstant(), /* call_data (undefined) */
191 assembler_->NullConstant(), /* holder (null) */ 173 assembler_->NullConstant(), /* holder (null) */
192 assembler_->ExternalConstant(callback), /* API callback function */ 174 assembler_->ExternalConstant(callback), /* API callback function */
193 assembler_->IntPtrConstant(kStackParam), /* # JS arguments */ 175 assembler_->IntPtrConstant(kStackParam), /* # JS arguments */
194 176
195 // kStackParam stack parameter(s): 177 // kStackParam stack parameter(s):
196 FromId(arg), 178 FromId(arg),
197 179
198 // Context parameter. (See Linkage::GetStubCallDescriptor.) 180 // Context parameter. (See Linkage::GetStubCallDescriptor.)
199 assembler_->UndefinedConstant()}; 181 assembler_->UndefinedConstant()};
200 CHECK_EQ(5 + kStackParam + 1, arraysize(args)); 182 CHECK_EQ(5 + kStackParam + 1, arraysize(args));
201 183
202 Node* call = assembler_->CallN( 184 Node* call = assembler_->CallN(
203 Linkage::GetStubCallDescriptor( 185 Linkage::GetStubCallDescriptor(
204 assembler_->isolate(), zone(), stub.GetCallInterfaceDescriptor(), 186 isolate(), zone(), stub.GetCallInterfaceDescriptor(),
205 kStackParam + stub.GetStackParameterCount(), 187 kStackParam + stub.GetStackParameterCount(),
206 CallDescriptor::kNoFlags), 188 CallDescriptor::kNoFlags),
207 assembler_->HeapConstant(stub.GetCode()), args); 189 assembler_->HeapConstant(stub.GetCode()), args);
208 return FromRaw(call); 190 return FromRaw(call);
209 } 191 }
210 192
211 MaybeHandle<Code> FastAccessorAssembler::Build() { 193 MaybeHandle<Code> FastAccessorAssembler::Build() {
212 CHECK_EQ(kBuilding, state_); 194 CHECK_EQ(kBuilding, state_);
213 195 Handle<Code> code = assembler_->GenerateCode();
214 // Cleanup: We no longer need this.
215 nodes_.clear();
216 labels_.clear();
217
218 // Export the schedule and call the compiler.
219 Schedule* schedule = assembler_->Export();
220 Code::Flags flags = Code::ComputeFlags(Code::STUB);
221 MaybeHandle<Code> code = Pipeline::GenerateCodeForCodeStub(
222 assembler_->isolate(), assembler_->call_descriptor(), assembler_->graph(),
223 schedule, flags, "FastAccessorAssembler");
224
225 // Update state & return.
226 state_ = !code.is_null() ? kBuilt : kError; 196 state_ = !code.is_null() ? kBuilt : kError;
197 Clear();
227 return code; 198 return code;
228 } 199 }
229 200
230
231 FastAccessorAssembler::ValueId FastAccessorAssembler::FromRaw(Node* node) { 201 FastAccessorAssembler::ValueId FastAccessorAssembler::FromRaw(Node* node) {
232 nodes_.push_back(node); 202 nodes_.push_back(node);
233 ValueId value = {nodes_.size() - 1}; 203 ValueId value = {nodes_.size() - 1};
234 return value; 204 return value;
235 } 205 }
236 206
237
238 FastAccessorAssembler::LabelId FastAccessorAssembler::FromRaw( 207 FastAccessorAssembler::LabelId FastAccessorAssembler::FromRaw(
239 RawMachineLabel* label) { 208 CodeStubAssembler::Label* label) {
240 labels_.push_back(label); 209 labels_.push_back(label);
241 LabelId label_id = {labels_.size() - 1}; 210 LabelId label_id = {labels_.size() - 1};
242 return label_id; 211 return label_id;
243 } 212 }
244 213
245
246 Node* FastAccessorAssembler::FromId(ValueId value) const { 214 Node* FastAccessorAssembler::FromId(ValueId value) const {
247 CHECK_LT(value.value_id, nodes_.size()); 215 CHECK_LT(value.value_id, nodes_.size());
248 CHECK_NOT_NULL(nodes_.at(value.value_id)); 216 CHECK_NOT_NULL(nodes_.at(value.value_id));
249 return nodes_.at(value.value_id); 217 return nodes_.at(value.value_id);
250 } 218 }
251 219
252 220 CodeStubAssembler::Label* FastAccessorAssembler::FromId(LabelId label) const {
253 RawMachineLabel* FastAccessorAssembler::FromId(LabelId label) const {
254 CHECK_LT(label.label_id, labels_.size()); 221 CHECK_LT(label.label_id, labels_.size());
255 CHECK_NOT_NULL(labels_.at(label.label_id)); 222 CHECK_NOT_NULL(labels_.at(label.label_id));
256 return labels_.at(label.label_id); 223 return labels_.at(label.label_id);
257 } 224 }
258 225
226 void FastAccessorAssembler::Clear() {
227 for (auto label : labels_) {
228 delete label;
229 }
230 nodes_.clear();
231 labels_.clear();
232 }
259 233
260 } // namespace compiler 234 } // namespace compiler
261 } // namespace internal 235 } // namespace internal
262 } // namespace v8 236 } // namespace v8
OLDNEW
« src/compiler/fast-accessor-assembler.h ('K') | « src/compiler/fast-accessor-assembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698