• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_X64_CODE_STUBS_X64_H_
29 #define V8_X64_CODE_STUBS_X64_H_
30 
31 #include "ic-inl.h"
32 #include "type-info.h"
33 
34 namespace v8 {
35 namespace internal {
36 
37 
38 // Compute a transcendental math function natively, or call the
39 // TranscendentalCache runtime function.
40 class TranscendentalCacheStub: public CodeStub {
41  public:
42   enum ArgumentType {
43     TAGGED = 0,
44     UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
45   };
46 
TranscendentalCacheStub(TranscendentalCache::Type type,ArgumentType argument_type)47   explicit TranscendentalCacheStub(TranscendentalCache::Type type,
48                                    ArgumentType argument_type)
49       : type_(type), argument_type_(argument_type) {}
50   void Generate(MacroAssembler* masm);
51  private:
52   TranscendentalCache::Type type_;
53   ArgumentType argument_type_;
54 
MajorKey()55   Major MajorKey() { return TranscendentalCache; }
MinorKey()56   int MinorKey() { return type_ | argument_type_; }
57   Runtime::FunctionId RuntimeFunction();
58   void GenerateOperation(MacroAssembler* masm);
59 };
60 
61 
62 class ToBooleanStub: public CodeStub {
63  public:
ToBooleanStub()64   ToBooleanStub() { }
65 
66   void Generate(MacroAssembler* masm);
67 
68  private:
MajorKey()69   Major MajorKey() { return ToBoolean; }
MinorKey()70   int MinorKey() { return 0; }
71 };
72 
73 
74 class TypeRecordingBinaryOpStub: public CodeStub {
75  public:
TypeRecordingBinaryOpStub(Token::Value op,OverwriteMode mode)76   TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode)
77       : op_(op),
78         mode_(mode),
79         operands_type_(TRBinaryOpIC::UNINITIALIZED),
80         result_type_(TRBinaryOpIC::UNINITIALIZED),
81         name_(NULL) {
82     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
83   }
84 
85   TypeRecordingBinaryOpStub(
86       int key,
87       TRBinaryOpIC::TypeInfo operands_type,
88       TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED)
op_(OpBits::decode (key))89       : op_(OpBits::decode(key)),
90         mode_(ModeBits::decode(key)),
91         operands_type_(operands_type),
92         result_type_(result_type),
93         name_(NULL) { }
94 
95  private:
96   enum SmiCodeGenerateHeapNumberResults {
97     ALLOW_HEAPNUMBER_RESULTS,
98     NO_HEAPNUMBER_RESULTS
99   };
100 
101   Token::Value op_;
102   OverwriteMode mode_;
103 
104   // Operand type information determined at runtime.
105   TRBinaryOpIC::TypeInfo operands_type_;
106   TRBinaryOpIC::TypeInfo result_type_;
107 
108   char* name_;
109 
110   const char* GetName();
111 
112 #ifdef DEBUG
Print()113   void Print() {
114     PrintF("TypeRecordingBinaryOpStub %d (op %s), "
115            "(mode %d, runtime_type_info %s)\n",
116            MinorKey(),
117            Token::String(op_),
118            static_cast<int>(mode_),
119            TRBinaryOpIC::GetName(operands_type_));
120   }
121 #endif
122 
123   // Minor key encoding in 15 bits RRRTTTOOOOOOOMM.
124   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
125   class OpBits: public BitField<Token::Value, 2, 7> {};
126   class OperandTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 9, 3> {};
127   class ResultTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 12, 3> {};
128 
MajorKey()129   Major MajorKey() { return TypeRecordingBinaryOp; }
MinorKey()130   int MinorKey() {
131     return OpBits::encode(op_)
132            | ModeBits::encode(mode_)
133            | OperandTypeInfoBits::encode(operands_type_)
134            | ResultTypeInfoBits::encode(result_type_);
135   }
136 
137   void Generate(MacroAssembler* masm);
138   void GenerateGeneric(MacroAssembler* masm);
139   void GenerateSmiCode(MacroAssembler* masm,
140                        Label* slow,
141                        SmiCodeGenerateHeapNumberResults heapnumber_results);
142   void GenerateFloatingPointCode(MacroAssembler* masm,
143                                  Label* allocation_failure,
144                                  Label* non_numeric_failure);
145   void GenerateStringAddCode(MacroAssembler* masm);
146   void GenerateCallRuntimeCode(MacroAssembler* masm);
147   void GenerateLoadArguments(MacroAssembler* masm);
148   void GenerateReturn(MacroAssembler* masm);
149   void GenerateUninitializedStub(MacroAssembler* masm);
150   void GenerateSmiStub(MacroAssembler* masm);
151   void GenerateInt32Stub(MacroAssembler* masm);
152   void GenerateHeapNumberStub(MacroAssembler* masm);
153   void GenerateOddballStub(MacroAssembler* masm);
154   void GenerateStringStub(MacroAssembler* masm);
155   void GenerateGenericStub(MacroAssembler* masm);
156 
157   void GenerateHeapResultAllocation(MacroAssembler* masm, Label* alloc_failure);
158   void GenerateRegisterArgsPush(MacroAssembler* masm);
159   void GenerateTypeTransition(MacroAssembler* masm);
160   void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
161 
GetCodeKind()162   virtual int GetCodeKind() { return Code::TYPE_RECORDING_BINARY_OP_IC; }
163 
GetICState()164   virtual InlineCacheState GetICState() {
165     return TRBinaryOpIC::ToState(operands_type_);
166   }
167 
FinishCode(Code * code)168   virtual void FinishCode(Code* code) {
169     code->set_type_recording_binary_op_type(operands_type_);
170     code->set_type_recording_binary_op_result_type(result_type_);
171   }
172 
173   friend class CodeGenerator;
174 };
175 
176 
177 class StringHelper : public AllStatic {
178  public:
179   // Generate code for copying characters using a simple loop. This should only
180   // be used in places where the number of characters is small and the
181   // additional setup and checking in GenerateCopyCharactersREP adds too much
182   // overhead. Copying of overlapping regions is not supported.
183   static void GenerateCopyCharacters(MacroAssembler* masm,
184                                      Register dest,
185                                      Register src,
186                                      Register count,
187                                      bool ascii);
188 
189   // Generate code for copying characters using the rep movs instruction.
190   // Copies rcx characters from rsi to rdi. Copying of overlapping regions is
191   // not supported.
192   static void GenerateCopyCharactersREP(MacroAssembler* masm,
193                                         Register dest,     // Must be rdi.
194                                         Register src,      // Must be rsi.
195                                         Register count,    // Must be rcx.
196                                         bool ascii);
197 
198 
199   // Probe the symbol table for a two character string. If the string is
200   // not found by probing a jump to the label not_found is performed. This jump
201   // does not guarantee that the string is not in the symbol table. If the
202   // string is found the code falls through with the string in register rax.
203   static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
204                                                    Register c1,
205                                                    Register c2,
206                                                    Register scratch1,
207                                                    Register scratch2,
208                                                    Register scratch3,
209                                                    Register scratch4,
210                                                    Label* not_found);
211 
212   // Generate string hash.
213   static void GenerateHashInit(MacroAssembler* masm,
214                                Register hash,
215                                Register character,
216                                Register scratch);
217   static void GenerateHashAddCharacter(MacroAssembler* masm,
218                                        Register hash,
219                                        Register character,
220                                        Register scratch);
221   static void GenerateHashGetHash(MacroAssembler* masm,
222                                   Register hash,
223                                   Register scratch);
224 
225  private:
226   DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
227 };
228 
229 
230 // Flag that indicates how to generate code for the stub StringAddStub.
231 enum StringAddFlags {
232   NO_STRING_ADD_FLAGS = 0,
233   // Omit left string check in stub (left is definitely a string).
234   NO_STRING_CHECK_LEFT_IN_STUB = 1 << 0,
235   // Omit right string check in stub (right is definitely a string).
236   NO_STRING_CHECK_RIGHT_IN_STUB = 1 << 1,
237   // Omit both string checks in stub.
238   NO_STRING_CHECK_IN_STUB =
239       NO_STRING_CHECK_LEFT_IN_STUB | NO_STRING_CHECK_RIGHT_IN_STUB
240 };
241 
242 
243 class StringAddStub: public CodeStub {
244  public:
StringAddStub(StringAddFlags flags)245   explicit StringAddStub(StringAddFlags flags) : flags_(flags) {}
246 
247  private:
MajorKey()248   Major MajorKey() { return StringAdd; }
MinorKey()249   int MinorKey() { return flags_; }
250 
251   void Generate(MacroAssembler* masm);
252 
253   void GenerateConvertArgument(MacroAssembler* masm,
254                                int stack_offset,
255                                Register arg,
256                                Register scratch1,
257                                Register scratch2,
258                                Register scratch3,
259                                Label* slow);
260 
261   const StringAddFlags flags_;
262 };
263 
264 
265 class SubStringStub: public CodeStub {
266  public:
SubStringStub()267   SubStringStub() {}
268 
269  private:
MajorKey()270   Major MajorKey() { return SubString; }
MinorKey()271   int MinorKey() { return 0; }
272 
273   void Generate(MacroAssembler* masm);
274 };
275 
276 
277 class StringCompareStub: public CodeStub {
278  public:
StringCompareStub()279   explicit StringCompareStub() {}
280 
281   // Compare two flat ascii strings and returns result in rax after popping two
282   // arguments from the stack.
283   static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
284                                               Register left,
285                                               Register right,
286                                               Register scratch1,
287                                               Register scratch2,
288                                               Register scratch3,
289                                               Register scratch4);
290 
291  private:
MajorKey()292   Major MajorKey() { return StringCompare; }
MinorKey()293   int MinorKey() { return 0; }
294 
295   void Generate(MacroAssembler* masm);
296 };
297 
298 
299 class NumberToStringStub: public CodeStub {
300  public:
NumberToStringStub()301   NumberToStringStub() { }
302 
303   // Generate code to do a lookup in the number string cache. If the number in
304   // the register object is found in the cache the generated code falls through
305   // with the result in the result register. The object and the result register
306   // can be the same. If the number is not found in the cache the code jumps to
307   // the label not_found with only the content of register object unchanged.
308   static void GenerateLookupNumberStringCache(MacroAssembler* masm,
309                                               Register object,
310                                               Register result,
311                                               Register scratch1,
312                                               Register scratch2,
313                                               bool object_is_smi,
314                                               Label* not_found);
315 
316  private:
317   static void GenerateConvertHashCodeToIndex(MacroAssembler* masm,
318                                              Register hash,
319                                              Register mask);
320 
MajorKey()321   Major MajorKey() { return NumberToString; }
MinorKey()322   int MinorKey() { return 0; }
323 
324   void Generate(MacroAssembler* masm);
325 
GetName()326   const char* GetName() { return "NumberToStringStub"; }
327 
328 #ifdef DEBUG
Print()329   void Print() {
330     PrintF("NumberToStringStub\n");
331   }
332 #endif
333 };
334 
335 
336 } }  // namespace v8::internal
337 
338 #endif  // V8_X64_CODE_STUBS_X64_H_
339