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

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

Issue 2186593002: Add faster, but unsafe version of LoadInternalField. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Refactor LoadInternalField and its unchecked counterpart Created 4 years, 4 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/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-stub-assembler.h" 8 #include "src/code-stub-assembler.h"
9 #include "src/code-stubs.h" // For CallApiCallbackStub. 9 #include "src/code-stubs.h" // For CallApiCallbackStub.
10 #include "src/handles-inl.h" 10 #include "src/handles-inl.h"
(...skipping 25 matching lines...) Expand all
36 CHECK_EQ(kBuilding, state_); 36 CHECK_EQ(kBuilding, state_);
37 37
38 // For JS functions, the receiver is parameter 0. 38 // For JS functions, the receiver is parameter 0.
39 return FromRaw(assembler_->Parameter(0)); 39 return FromRaw(assembler_->Parameter(0));
40 } 40 }
41 41
42 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadInternalField( 42 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadInternalField(
43 ValueId value, int field_no) { 43 ValueId value, int field_no) {
44 CHECK_EQ(kBuilding, state_); 44 CHECK_EQ(kBuilding, state_);
45 45
46 // Determine the 'value' object's instance type.
47 Node* object_map = assembler_->LoadObjectField(
48 FromId(value), Internals::kHeapObjectMapOffset, MachineType::Pointer());
49 Node* instance_type = assembler_->WordAnd(
50 assembler_->LoadObjectField(object_map,
51 Internals::kMapInstanceTypeAndBitFieldOffset,
52 MachineType::Uint16()),
53 assembler_->IntPtrConstant(0xff));
54
55 // Check whether we have a proper JSObject.
56 CodeStubAssembler::Variable result(assembler_.get(), 46 CodeStubAssembler::Variable result(assembler_.get(),
57 MachineRepresentation::kTagged); 47 MachineRepresentation::kTagged);
58 CodeStubAssembler::Label is_jsobject(assembler_.get()); 48 LabelId is_not_jsobject = MakeLabel();
59 CodeStubAssembler::Label maybe_api_object(assembler_.get());
60 CodeStubAssembler::Label is_not_jsobject(assembler_.get());
61 CodeStubAssembler::Label merge(assembler_.get(), &result); 49 CodeStubAssembler::Label merge(assembler_.get(), &result);
62 assembler_->Branch(
63 assembler_->WordEqual(
64 instance_type, assembler_->IntPtrConstant(Internals::kJSObjectType)),
65 &is_jsobject, &maybe_api_object);
66 50
67 // JSObject? Then load the internal field field_no. 51 CheckIsJSObjectOrJump(value, is_not_jsobject);
68 assembler_->Bind(&is_jsobject); 52
69 Node* internal_field = assembler_->LoadObjectField( 53 Node* internal_field = assembler_->LoadObjectField(
70 FromId(value), JSObject::kHeaderSize + kPointerSize * field_no, 54 FromId(value), JSObject::kHeaderSize + kPointerSize * field_no,
71 MachineType::Pointer()); 55 MachineType::Pointer());
56
72 result.Bind(internal_field); 57 result.Bind(internal_field);
73 assembler_->Goto(&merge); 58 assembler_->Goto(&merge);
74 59
75 assembler_->Bind(&maybe_api_object); 60 // Return null, mimicking the C++ counterpart.
76 assembler_->Branch( 61 SetLabel(is_not_jsobject);
77 assembler_->WordEqual(instance_type, assembler_->IntPtrConstant( 62 result.Bind(assembler_->NullConstant());
78 Internals::kJSApiObjectType)),
79 &is_jsobject, &is_not_jsobject);
80
81 // No JSObject? Return undefined.
82 // TODO(vogelheim): Check whether this is the appropriate action, or whether
83 // the method should take a label instead.
84 assembler_->Bind(&is_not_jsobject);
85 Node* fail_value = assembler_->UndefinedConstant();
86 result.Bind(fail_value);
87 assembler_->Goto(&merge); 63 assembler_->Goto(&merge);
88 64
89 // Return. 65 // Return.
90 assembler_->Bind(&merge); 66 assembler_->Bind(&merge);
91 return FromRaw(result.value()); 67 return FromRaw(result.value());
92 } 68 }
93 69
70 FastAccessorAssembler::ValueId
71 FastAccessorAssembler::LoadInternalFieldUnchecked(ValueId value, int field_no) {
72 CHECK_EQ(kBuilding, state_);
73
74 // Defensive debug checks.
75 if (FLAG_debug_code) {
76 LabelId is_jsobject = MakeLabel();
77 LabelId is_not_jsobject = MakeLabel();
78 CheckIsJSObjectOrJump(value, is_not_jsobject);
79 assembler_->Goto(FromId(is_jsobject));
80
81 SetLabel(is_not_jsobject);
82 // Deliberately crash.
vogelheim 2016/08/08 11:47:22 Hmm. Actually, we force a debug break (which termi
Alfonso 2016/08/08 13:03:28 Acknowledged.
83 assembler_->DebugBreak();
84 assembler_->Goto(FromId(is_jsobject));
85
86 SetLabel(is_jsobject);
87 }
88
89 Node* result = assembler_->LoadObjectField(
90 FromId(value), JSObject::kHeaderSize + kPointerSize * field_no,
91 MachineType::Pointer());
92
93 return FromRaw(result);
94 }
95
94 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadValue(ValueId value, 96 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadValue(ValueId value,
95 int offset) { 97 int offset) {
96 CHECK_EQ(kBuilding, state_); 98 CHECK_EQ(kBuilding, state_);
97 return FromRaw(assembler_->LoadBufferObject(FromId(value), offset, 99 return FromRaw(assembler_->LoadBufferObject(FromId(value), offset,
98 MachineType::IntPtr())); 100 MachineType::IntPtr()));
99 } 101 }
100 102
101 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadObject(ValueId value, 103 FastAccessorAssembler::ValueId FastAccessorAssembler::LoadObject(ValueId value,
102 int offset) { 104 int offset) {
103 CHECK_EQ(kBuilding, state_); 105 CHECK_EQ(kBuilding, state_);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 assembler_->Branch( 157 assembler_->Branch(
156 assembler_->WordEqual(FromId(value_id), assembler_->IntPtrConstant(0)), 158 assembler_->WordEqual(FromId(value_id), assembler_->IntPtrConstant(0)),
157 FromId(label_id), &pass); 159 FromId(label_id), &pass);
158 assembler_->Bind(&pass); 160 assembler_->Bind(&pass);
159 } 161 }
160 162
161 FastAccessorAssembler::ValueId FastAccessorAssembler::Call( 163 FastAccessorAssembler::ValueId FastAccessorAssembler::Call(
162 FunctionCallback callback_function, ValueId arg) { 164 FunctionCallback callback_function, ValueId arg) {
163 CHECK_EQ(kBuilding, state_); 165 CHECK_EQ(kBuilding, state_);
164 166
167 CodeStubAssembler::Label deferred(assembler_.get(),
vogelheim 2016/08/08 11:47:22 This is a good change, but unrelated to what the C
Alfonso 2016/08/08 13:03:28 Reverting this, even if is the logical thing to do
168 compiler::CodeAssembler::Label::kDeferred);
169 assembler_->Goto(&deferred);
170 assembler_->Bind(&deferred);
171
165 // Wrap the FunctionCallback in an ExternalReference. 172 // Wrap the FunctionCallback in an ExternalReference.
166 ApiFunction callback_api_function(FUNCTION_ADDR(callback_function)); 173 ApiFunction callback_api_function(FUNCTION_ADDR(callback_function));
167 ExternalReference callback(&callback_api_function, 174 ExternalReference callback(&callback_api_function,
168 ExternalReference::DIRECT_API_CALL, isolate()); 175 ExternalReference::DIRECT_API_CALL, isolate());
169 176
170 // Create & call API callback via stub. 177 // Create & call API callback via stub.
171 CallApiCallbackStub stub(isolate(), 1, true, true); 178 CallApiCallbackStub stub(isolate(), 1, true, true);
172 DCHECK_EQ(5, stub.GetCallInterfaceDescriptor().GetParameterCount()); 179 DCHECK_EQ(5, stub.GetCallInterfaceDescriptor().GetParameterCount());
173 DCHECK_EQ(1, stub.GetCallInterfaceDescriptor().GetStackParameterCount()); 180 DCHECK_EQ(1, stub.GetCallInterfaceDescriptor().GetStackParameterCount());
174 // TODO(vogelheim): There is currently no clean way to retrieve the context 181 // TODO(vogelheim): There is currently no clean way to retrieve the context
(...skipping 11 matching lines...) Expand all
186 assembler_->UndefinedConstant(), /* call_data (undefined) */ 193 assembler_->UndefinedConstant(), /* call_data (undefined) */
187 assembler_->Parameter(0), /* receiver (same as holder in this case) */ 194 assembler_->Parameter(0), /* receiver (same as holder in this case) */
188 assembler_->ExternalConstant(callback), /* API callback function */ 195 assembler_->ExternalConstant(callback), /* API callback function */
189 196
190 // JS arguments, on stack: 197 // JS arguments, on stack:
191 FromId(arg)); 198 FromId(arg));
192 199
193 return FromRaw(call); 200 return FromRaw(call);
194 } 201 }
195 202
203 void FastAccessorAssembler::CheckIsJSObjectOrJump(ValueId value_id,
204 LabelId label_id) {
205 CHECK_EQ(kBuilding, state_);
206
207 // Determine the 'value' object's instance type.
208 Node* object_map = assembler_->LoadObjectField(
209 FromId(value_id), Internals::kHeapObjectMapOffset,
210 MachineType::Pointer());
211
212 Node* instance_type = assembler_->WordAnd(
213 assembler_->LoadObjectField(object_map,
214 Internals::kMapInstanceTypeAndBitFieldOffset,
215 MachineType::Uint16()),
216 assembler_->IntPtrConstant(0xff));
217
218 CodeStubAssembler::Label is_jsobject(assembler_.get());
219
220 // Check whether we have a proper JSObject.
221 assembler_->GotoIf(
222 assembler_->WordEqual(
223 instance_type, assembler_->IntPtrConstant(Internals::kJSObjectType)),
224 &is_jsobject);
225
226 // JSApiObject?.
227 assembler_->GotoUnless(
228 assembler_->WordEqual(instance_type, assembler_->IntPtrConstant(
229 Internals::kJSApiObjectType)),
230 FromId(label_id));
231
232 // Continue.
233 assembler_->Goto(&is_jsobject);
234 assembler_->Bind(&is_jsobject);
235 }
236
196 MaybeHandle<Code> FastAccessorAssembler::Build() { 237 MaybeHandle<Code> FastAccessorAssembler::Build() {
197 CHECK_EQ(kBuilding, state_); 238 CHECK_EQ(kBuilding, state_);
198 Handle<Code> code = assembler_->GenerateCode(); 239 Handle<Code> code = assembler_->GenerateCode();
199 state_ = !code.is_null() ? kBuilt : kError; 240 state_ = !code.is_null() ? kBuilt : kError;
200 Clear(); 241 Clear();
201 return code; 242 return code;
202 } 243 }
203 244
204 FastAccessorAssembler::ValueId FastAccessorAssembler::FromRaw(Node* node) { 245 FastAccessorAssembler::ValueId FastAccessorAssembler::FromRaw(Node* node) {
205 nodes_.push_back(node); 246 nodes_.push_back(node);
(...skipping 23 matching lines...) Expand all
229 void FastAccessorAssembler::Clear() { 270 void FastAccessorAssembler::Clear() {
230 for (auto label : labels_) { 271 for (auto label : labels_) {
231 delete label; 272 delete label;
232 } 273 }
233 nodes_.clear(); 274 nodes_.clear();
234 labels_.clear(); 275 labels_.clear();
235 } 276 }
236 277
237 } // namespace internal 278 } // namespace internal
238 } // namespace v8 279 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698