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

Side by Side Diff: src/code-stub-assembler.h

Issue 2497243002: [stubs] Port builtin for Array.push fast-case from Crankshaft to TF (Closed)
Patch Set: Cleanup Created 4 years, 1 month 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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #ifndef V8_CODE_STUB_ASSEMBLER_H_ 5 #ifndef V8_CODE_STUB_ASSEMBLER_H_
6 #define V8_CODE_STUB_ASSEMBLER_H_ 6 #define V8_CODE_STUB_ASSEMBLER_H_
7 7
8 #include <functional> 8 #include <functional>
9 9
10 #include "src/compiler/code-assembler.h" 10 #include "src/compiler/code-assembler.h"
11 #include "src/globals.h" 11 #include "src/globals.h"
12 #include "src/objects.h" 12 #include "src/objects.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 class CallInterfaceDescriptor; 17 class CallInterfaceDescriptor;
18 class CodeStubArguments;
18 class StatsCounter; 19 class StatsCounter;
19 class StubCache; 20 class StubCache;
20 21
21 enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol }; 22 enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
22 23
23 #define HEAP_CONSTANT_LIST(V) \ 24 #define HEAP_CONSTANT_LIST(V) \
24 V(BooleanMap, BooleanMap) \ 25 V(BooleanMap, BooleanMap) \
25 V(CodeMap, CodeMap) \ 26 V(CodeMap, CodeMap) \
26 V(empty_string, EmptyString) \ 27 V(empty_string, EmptyString) \
27 V(EmptyFixedArray, EmptyFixedArray) \ 28 V(EmptyFixedArray, EmptyFixedArray) \
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 // On 32-bit platforms, there is a slight performance advantage to doing all 63 // On 32-bit platforms, there is a slight performance advantage to doing all
63 // of the array offset/index arithmetic with SMIs, since it's possible 64 // of the array offset/index arithmetic with SMIs, since it's possible
64 // to save a few tag/untag operations without paying an extra expense when 65 // to save a few tag/untag operations without paying an extra expense when
65 // calculating array offset (the smi math can be folded away) and there are 66 // calculating array offset (the smi math can be folded away) and there are
66 // fewer live ranges. Thus only convert indices to untagged value on 64-bit 67 // fewer live ranges. Thus only convert indices to untagged value on 64-bit
67 // platforms. 68 // platforms.
68 ParameterMode OptimalParameterMode() const { 69 ParameterMode OptimalParameterMode() const {
69 return Is64() ? INTPTR_PARAMETERS : SMI_PARAMETERS; 70 return Is64() ? INTPTR_PARAMETERS : SMI_PARAMETERS;
70 } 71 }
71 72
73 MachineRepresentation OptimalParameterRepresentation() const {
74 return OptimalParameterMode() == INTPTR_PARAMETERS
75 ? MachineType::PointerRepresentation()
76 : MachineRepresentation::kTaggedSigned;
77 }
78
72 compiler::Node* UntagParameter(compiler::Node* value, ParameterMode mode) { 79 compiler::Node* UntagParameter(compiler::Node* value, ParameterMode mode) {
73 if (mode != SMI_PARAMETERS) value = SmiUntag(value); 80 if (mode != SMI_PARAMETERS) value = SmiUntag(value);
74 return value; 81 return value;
75 } 82 }
76 83
77 compiler::Node* TagParameter(compiler::Node* value, ParameterMode mode) { 84 compiler::Node* TagParameter(compiler::Node* value, ParameterMode mode) {
78 if (mode != SMI_PARAMETERS) value = SmiTag(value); 85 if (mode != SMI_PARAMETERS) value = SmiTag(value);
79 return value; 86 return value;
80 } 87 }
81 88
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 compiler::Node* SmiMod(compiler::Node* a, compiler::Node* b); 142 compiler::Node* SmiMod(compiler::Node* a, compiler::Node* b);
136 // Computes a * b for Smi inputs a and b; result is not necessarily a Smi. 143 // Computes a * b for Smi inputs a and b; result is not necessarily a Smi.
137 compiler::Node* SmiMul(compiler::Node* a, compiler::Node* b); 144 compiler::Node* SmiMul(compiler::Node* a, compiler::Node* b);
138 compiler::Node* SmiOr(compiler::Node* a, compiler::Node* b) { 145 compiler::Node* SmiOr(compiler::Node* a, compiler::Node* b) {
139 return BitcastWordToTaggedSigned( 146 return BitcastWordToTaggedSigned(
140 WordOr(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); 147 WordOr(BitcastTaggedToWord(a), BitcastTaggedToWord(b)));
141 } 148 }
142 149
143 // Smi | HeapNumber operations. 150 // Smi | HeapNumber operations.
144 compiler::Node* NumberInc(compiler::Node* value); 151 compiler::Node* NumberInc(compiler::Node* value);
152 void GotoIfNotNumber(compiler::Node* value, Label* is_not_number);
Jakob Kummerow 2016/11/23 17:17:06 nit: when you rebase, please drop all the "compile
danno 2016/11/29 14:39:59 Done.
153 void GotoIfNumber(compiler::Node* value, Label* is_number);
145 154
146 // Allocate an object of the given size. 155 // Allocate an object of the given size.
147 compiler::Node* Allocate(compiler::Node* size, AllocationFlags flags = kNone); 156 compiler::Node* Allocate(compiler::Node* size, AllocationFlags flags = kNone);
148 compiler::Node* Allocate(int size, AllocationFlags flags = kNone); 157 compiler::Node* Allocate(int size, AllocationFlags flags = kNone);
149 compiler::Node* InnerAllocate(compiler::Node* previous, int offset); 158 compiler::Node* InnerAllocate(compiler::Node* previous, int offset);
150 compiler::Node* InnerAllocate(compiler::Node* previous, 159 compiler::Node* InnerAllocate(compiler::Node* previous,
151 compiler::Node* offset); 160 compiler::Node* offset);
152 compiler::Node* IsRegularHeapObjectSize(compiler::Node* size); 161 compiler::Node* IsRegularHeapObjectSize(compiler::Node* size);
153 162
154 typedef std::function<compiler::Node*()> ConditionBody; 163 typedef std::function<compiler::Node*()> ConditionBody;
155 void Assert(ConditionBody condition_body, const char* string = nullptr, 164 void Assert(ConditionBody condition_body, const char* string = nullptr,
156 const char* file = nullptr, int line = 0); 165 const char* file = nullptr, int line = 0);
157 166
158 // Check a value for smi-ness 167 // Check a value for smi-ness
159 compiler::Node* TaggedIsSmi(compiler::Node* a); 168 compiler::Node* TaggedIsSmi(compiler::Node* a);
169 compiler::Node* TaggedIsNotSmi(compiler::Node* a);
160 // Check that the value is a non-negative smi. 170 // Check that the value is a non-negative smi.
161 compiler::Node* WordIsPositiveSmi(compiler::Node* a); 171 compiler::Node* WordIsPositiveSmi(compiler::Node* a);
162 // Check that a word has a word-aligned address. 172 // Check that a word has a word-aligned address.
163 compiler::Node* WordIsWordAligned(compiler::Node* word); 173 compiler::Node* WordIsWordAligned(compiler::Node* word);
164 compiler::Node* WordIsPowerOfTwo(compiler::Node* value); 174 compiler::Node* WordIsPowerOfTwo(compiler::Node* value);
165 175
166 void BranchIfSmiEqual(compiler::Node* a, compiler::Node* b, Label* if_true, 176 void BranchIfSmiEqual(compiler::Node* a, compiler::Node* b, Label* if_true,
167 Label* if_false) { 177 Label* if_false) {
168 Branch(SmiEqual(a, b), if_true, if_false); 178 Branch(SmiEqual(a, b), if_true, if_false);
169 } 179 }
(...skipping 24 matching lines...) Expand all
194 void BranchIfSimd128Equal(compiler::Node* lhs, compiler::Node* rhs, 204 void BranchIfSimd128Equal(compiler::Node* lhs, compiler::Node* rhs,
195 Label* if_equal, Label* if_notequal) { 205 Label* if_equal, Label* if_notequal) {
196 BranchIfSimd128Equal(lhs, LoadMap(lhs), rhs, LoadMap(rhs), if_equal, 206 BranchIfSimd128Equal(lhs, LoadMap(lhs), rhs, LoadMap(rhs), if_equal,
197 if_notequal); 207 if_notequal);
198 } 208 }
199 209
200 void BranchIfJSReceiver(compiler::Node* object, Label* if_true, 210 void BranchIfJSReceiver(compiler::Node* object, Label* if_true,
201 Label* if_false); 211 Label* if_false);
202 void BranchIfJSObject(compiler::Node* object, Label* if_true, 212 void BranchIfJSObject(compiler::Node* object, Label* if_true,
203 Label* if_false); 213 Label* if_false);
214
215 enum class FastJSArrayAccessMode { INBOUNDS_READ, ANY_ACCESS };
216
204 void BranchIfFastJSArray(compiler::Node* object, compiler::Node* context, 217 void BranchIfFastJSArray(compiler::Node* object, compiler::Node* context,
205 Label* if_true, Label* if_false); 218 FastJSArrayAccessMode mode, Label* if_true,
219 Label* if_false);
206 220
207 // Load value from current frame by given offset in bytes. 221 // Load value from current frame by given offset in bytes.
208 compiler::Node* LoadFromFrame(int offset, 222 compiler::Node* LoadFromFrame(int offset,
209 MachineType rep = MachineType::AnyTagged()); 223 MachineType rep = MachineType::AnyTagged());
210 // Load value from current parent frame by given offset in bytes. 224 // Load value from current parent frame by given offset in bytes.
211 compiler::Node* LoadFromParentFrame( 225 compiler::Node* LoadFromParentFrame(
212 int offset, MachineType rep = MachineType::AnyTagged()); 226 int offset, MachineType rep = MachineType::AnyTagged());
213 227
214 // Load an object pointer from a buffer that isn't in the heap. 228 // Load an object pointer from a buffer that isn't in the heap.
215 compiler::Node* LoadBufferObject(compiler::Node* buffer, int offset, 229 compiler::Node* LoadBufferObject(compiler::Node* buffer, int offset,
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 379
366 compiler::Node* StoreFixedArrayElement( 380 compiler::Node* StoreFixedArrayElement(
367 compiler::Node* object, compiler::Node* index, compiler::Node* value, 381 compiler::Node* object, compiler::Node* index, compiler::Node* value,
368 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER, 382 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
369 ParameterMode parameter_mode = INTEGER_PARAMETERS); 383 ParameterMode parameter_mode = INTEGER_PARAMETERS);
370 384
371 compiler::Node* StoreFixedDoubleArrayElement( 385 compiler::Node* StoreFixedDoubleArrayElement(
372 compiler::Node* object, compiler::Node* index, compiler::Node* value, 386 compiler::Node* object, compiler::Node* index, compiler::Node* value,
373 ParameterMode parameter_mode = INTEGER_PARAMETERS); 387 ParameterMode parameter_mode = INTEGER_PARAMETERS);
374 388
389 compiler::Node* BuildAppendJSArray(ElementsKind kind, compiler::Node* context,
390 compiler::Node* array,
391 CodeStubArguments& args,
392 Variable& arg_index, Label* bailout);
393
375 void StoreFieldsNoWriteBarrier(compiler::Node* start_address, 394 void StoreFieldsNoWriteBarrier(compiler::Node* start_address,
376 compiler::Node* end_address, 395 compiler::Node* end_address,
377 compiler::Node* value); 396 compiler::Node* value);
378 397
379 // Allocate a HeapNumber without initializing its value. 398 // Allocate a HeapNumber without initializing its value.
380 compiler::Node* AllocateHeapNumber(MutableMode mode = IMMUTABLE); 399 compiler::Node* AllocateHeapNumber(MutableMode mode = IMMUTABLE);
381 // Allocate a HeapNumber with a specific value. 400 // Allocate a HeapNumber with a specific value.
382 compiler::Node* AllocateHeapNumberWithValue(compiler::Node* value, 401 compiler::Node* AllocateHeapNumberWithValue(compiler::Node* value,
383 MutableMode mode = IMMUTABLE); 402 MutableMode mode = IMMUTABLE);
384 // Allocate a SeqOneByteString with the given length. 403 // Allocate a SeqOneByteString with the given length.
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 compiler::Node* value); 594 compiler::Node* value);
576 compiler::Node* TruncateTaggedToWord32(compiler::Node* context, 595 compiler::Node* TruncateTaggedToWord32(compiler::Node* context,
577 compiler::Node* value); 596 compiler::Node* value);
578 // Truncate the floating point value of a HeapNumber to an Int32. 597 // Truncate the floating point value of a HeapNumber to an Int32.
579 compiler::Node* TruncateHeapNumberValueToWord32(compiler::Node* object); 598 compiler::Node* TruncateHeapNumberValueToWord32(compiler::Node* object);
580 599
581 // Conversions. 600 // Conversions.
582 compiler::Node* ChangeFloat64ToTagged(compiler::Node* value); 601 compiler::Node* ChangeFloat64ToTagged(compiler::Node* value);
583 compiler::Node* ChangeInt32ToTagged(compiler::Node* value); 602 compiler::Node* ChangeInt32ToTagged(compiler::Node* value);
584 compiler::Node* ChangeUint32ToTagged(compiler::Node* value); 603 compiler::Node* ChangeUint32ToTagged(compiler::Node* value);
604 compiler::Node* ChangeNumberToFloat64(compiler::Node* value);
585 605
586 // Type conversions. 606 // Type conversions.
587 // Throws a TypeError for {method_name} if {value} is not coercible to Object, 607 // Throws a TypeError for {method_name} if {value} is not coercible to Object,
588 // or returns the {value} converted to a String otherwise. 608 // or returns the {value} converted to a String otherwise.
589 compiler::Node* ToThisString(compiler::Node* context, compiler::Node* value, 609 compiler::Node* ToThisString(compiler::Node* context, compiler::Node* value,
590 char const* method_name); 610 char const* method_name);
591 // Throws a TypeError for {method_name} if {value} is neither of the given 611 // Throws a TypeError for {method_name} if {value} is neither of the given
592 // {primitive_type} nor a JSValue wrapping a value of {primitive_type}, or 612 // {primitive_type} nor a JSValue wrapping a value of {primitive_type}, or
593 // returns the {value} (or wrapped value) otherwise. 613 // returns the {value} (or wrapped value) otherwise.
594 compiler::Node* ToThisValue(compiler::Node* context, compiler::Node* value, 614 compiler::Node* ToThisValue(compiler::Node* context, compiler::Node* value,
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 template <typename T> 755 template <typename T>
736 compiler::Node* IsSetWord(compiler::Node* word) { 756 compiler::Node* IsSetWord(compiler::Node* word) {
737 return WordNotEqual(WordAnd(word, IntPtrConstant(T::kMask)), 757 return WordNotEqual(WordAnd(word, IntPtrConstant(T::kMask)),
738 IntPtrConstant(0)); 758 IntPtrConstant(0));
739 } 759 }
740 760
741 void SetCounter(StatsCounter* counter, int value); 761 void SetCounter(StatsCounter* counter, int value);
742 void IncrementCounter(StatsCounter* counter, int delta); 762 void IncrementCounter(StatsCounter* counter, int delta);
743 void DecrementCounter(StatsCounter* counter, int delta); 763 void DecrementCounter(StatsCounter* counter, int delta);
744 764
765 void Increment(Variable& variable, int value = 1,
766 ParameterMode mode = INTPTR_PARAMETERS);
767
745 // Generates "if (false) goto label" code. Useful for marking a label as 768 // Generates "if (false) goto label" code. Useful for marking a label as
746 // "live" to avoid assertion failures during graph building. In the resulting 769 // "live" to avoid assertion failures during graph building. In the resulting
747 // code this check will be eliminated. 770 // code this check will be eliminated.
748 void Use(Label* label); 771 void Use(Label* label);
749 772
750 // Various building blocks for stubs doing property lookups. 773 // Various building blocks for stubs doing property lookups.
751 void TryToName(compiler::Node* key, Label* if_keyisindex, Variable* var_index, 774 void TryToName(compiler::Node* key, Label* if_keyisindex, Variable* var_index,
752 Label* if_keyisunique, Label* if_bailout); 775 Label* if_keyisunique, Label* if_bailout);
753 776
754 // Calculates array index for given dictionary entry and entry field. 777 // Calculates array index for given dictionary entry and entry field.
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 }; 1265 };
1243 1266
1244 class CodeStubArguments { 1267 class CodeStubArguments {
1245 public: 1268 public:
1246 // |argc| specifies the number of arguments passed to the builtin excluding 1269 // |argc| specifies the number of arguments passed to the builtin excluding
1247 // the receiver. 1270 // the receiver.
1248 CodeStubArguments(CodeStubAssembler* assembler, compiler::Node* argc, 1271 CodeStubArguments(CodeStubAssembler* assembler, compiler::Node* argc,
1249 CodeStubAssembler::ParameterMode mode = 1272 CodeStubAssembler::ParameterMode mode =
1250 CodeStubAssembler::INTPTR_PARAMETERS); 1273 CodeStubAssembler::INTPTR_PARAMETERS);
1251 1274
1252 compiler::Node* GetReceiver(); 1275 compiler::Node* GetReceiver() const;
1253 1276
1254 // |index| is zero-based and does not include the receiver 1277 // |index| is zero-based and does not include the receiver
1255 compiler::Node* AtIndex(compiler::Node* index, 1278 compiler::Node* AtIndex(compiler::Node* index,
1256 CodeStubAssembler::ParameterMode mode = 1279 CodeStubAssembler::ParameterMode mode =
1257 CodeStubAssembler::INTPTR_PARAMETERS); 1280 CodeStubAssembler::INTPTR_PARAMETERS) const;
1258 1281
1259 compiler::Node* AtIndex(int index); 1282 compiler::Node* AtIndex(int index) const;
1283
1284 compiler::Node* GetLength() const { return argc_; }
1260 1285
1261 typedef std::function<void(CodeStubAssembler* assembler, compiler::Node* arg)> 1286 typedef std::function<void(CodeStubAssembler* assembler, compiler::Node* arg)>
1262 ForEachBodyFunction; 1287 ForEachBodyFunction;
1263 1288
1264 // Iteration doesn't include the receiver. |first| and |last| are zero-based. 1289 // Iteration doesn't include the receiver. |first| and |last| are zero-based.
1265 void ForEach(ForEachBodyFunction body, compiler::Node* first = nullptr, 1290 void ForEach(ForEachBodyFunction body, compiler::Node* first = nullptr,
1266 compiler::Node* last = nullptr, 1291 compiler::Node* last = nullptr,
1267 CodeStubAssembler::ParameterMode mode = 1292 CodeStubAssembler::ParameterMode mode =
1268 CodeStubAssembler::INTPTR_PARAMETERS) { 1293 CodeStubAssembler::INTPTR_PARAMETERS) {
1269 CodeStubAssembler::VariableList list(0, assembler_->zone()); 1294 CodeStubAssembler::VariableList list(0, assembler_->zone());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 } 1327 }
1303 #else 1328 #else
1304 #define CSA_SLOW_ASSERT(csa, x) ((void)0) 1329 #define CSA_SLOW_ASSERT(csa, x) ((void)0)
1305 #endif 1330 #endif
1306 1331
1307 DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags); 1332 DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags);
1308 1333
1309 } // namespace internal 1334 } // namespace internal
1310 } // namespace v8 1335 } // namespace v8
1311 #endif // V8_CODE_STUB_ASSEMBLER_H_ 1336 #endif // V8_CODE_STUB_ASSEMBLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698