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

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

Powered by Google App Engine
This is Rietveld 408576698