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

Side by Side Diff: src/code-stubs.h

Issue 17229005: Convert UnaryOpStub to a HydrogenCodeStub (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 #endif 116 #endif
117 117
118 // Combined list of code stubs. 118 // Combined list of code stubs.
119 #define CODE_STUB_LIST(V) \ 119 #define CODE_STUB_LIST(V) \
120 CODE_STUB_LIST_ALL_PLATFORMS(V) \ 120 CODE_STUB_LIST_ALL_PLATFORMS(V) \
121 CODE_STUB_LIST_ARM(V) \ 121 CODE_STUB_LIST_ARM(V) \
122 CODE_STUB_LIST_MIPS(V) 122 CODE_STUB_LIST_MIPS(V)
123 123
124 // Mode to overwrite BinaryExpression values. 124 // Mode to overwrite BinaryExpression values.
125 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; 125 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
126 enum UnaryOverwriteMode { UNARY_OVERWRITE, UNARY_NO_OVERWRITE };
127 126
127 // Forward declarations
128 class HValue;
129 class HInstruction;
130 class HContext;
131 class HGraphBuilder;
128 132
129 // Stub is base classes of all stubs. 133 // Stub is base classes of all stubs.
130 class CodeStub BASE_EMBEDDED { 134 class CodeStub BASE_EMBEDDED {
131 public: 135 public:
132 enum Major { 136 enum Major {
133 #define DEF_ENUM(name) name, 137 #define DEF_ENUM(name) name,
134 CODE_STUB_LIST(DEF_ENUM) 138 CODE_STUB_LIST(DEF_ENUM)
135 #undef DEF_ENUM 139 #undef DEF_ENUM
136 NoCache, // marker for stubs that do custom caching 140 NoCache, // marker for stubs that do custom caching
137 NUMBER_OF_IDS 141 NUMBER_OF_IDS
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 virtual Code::ExtraICState GetExtraICState() { 194 virtual Code::ExtraICState GetExtraICState() {
191 return Code::kNoExtraICState; 195 return Code::kNoExtraICState;
192 } 196 }
193 virtual Code::StubType GetStubType() { 197 virtual Code::StubType GetStubType() {
194 return Code::NORMAL; 198 return Code::NORMAL;
195 } 199 }
196 virtual int GetStubFlags() { 200 virtual int GetStubFlags() {
197 return -1; 201 return -1;
198 } 202 }
199 203
204 virtual void PrintName(StringStream* stream);
205
200 protected: 206 protected:
201 static bool CanUseFPRegisters(); 207 static bool CanUseFPRegisters();
202 208
203 // Generates the assembler code for the stub. 209 // Generates the assembler code for the stub.
204 virtual Handle<Code> GenerateCode() = 0; 210 virtual Handle<Code> GenerateCode() = 0;
205 211
206 212
207 // Returns whether the code generated for this stub needs to be allocated as 213 // Returns whether the code generated for this stub needs to be allocated as
208 // a fixed (non-moveable) code object. 214 // a fixed (non-moveable) code object.
209 virtual bool NeedsImmovableCode() { return false; } 215 virtual bool NeedsImmovableCode() { return false; }
210 216
217 // Returns a name for logging/debugging purposes.
218 SmartArrayPointer<const char> GetName();
219 virtual void PrintBaseName(StringStream* stream);
220 virtual void PrintState(StringStream* stream) { }
221
211 private: 222 private:
212 // Perform bookkeeping required after code generation when stub code is 223 // Perform bookkeeping required after code generation when stub code is
213 // initially generated. 224 // initially generated.
214 void RecordCodeGeneration(Code* code, Isolate* isolate); 225 void RecordCodeGeneration(Code* code, Isolate* isolate);
215 226
216 // Finish the code object after it has been generated. 227 // Finish the code object after it has been generated.
217 virtual void FinishCode(Handle<Code> code) { } 228 virtual void FinishCode(Handle<Code> code) { }
218 229
219 // Activate newly generated stub. Is called after 230 // Activate newly generated stub. Is called after
220 // registering stub in the stub cache. 231 // registering stub in the stub cache.
221 virtual void Activate(Code* code) { } 232 virtual void Activate(Code* code) { }
222 233
223 // BinaryOpStub needs to override this. 234 // BinaryOpStub needs to override this.
224 virtual Code::Kind GetCodeKind() const; 235 virtual Code::Kind GetCodeKind() const;
225 236
226 // Add the code to a specialized cache, specific to an individual 237 // Add the code to a specialized cache, specific to an individual
227 // stub type. Please note, this method must add the code object to a 238 // stub type. Please note, this method must add the code object to a
228 // roots object, otherwise we will remove the code during GC. 239 // roots object, otherwise we will remove the code during GC.
229 virtual void AddToSpecialCache(Handle<Code> new_object) { } 240 virtual void AddToSpecialCache(Handle<Code> new_object) { }
230 241
231 // Find code in a specialized cache, work is delegated to the specific stub. 242 // Find code in a specialized cache, work is delegated to the specific stub.
232 virtual bool FindCodeInSpecialCache(Code** code_out, Isolate* isolate) { 243 virtual bool FindCodeInSpecialCache(Code** code_out, Isolate* isolate) {
233 return false; 244 return false;
234 } 245 }
235 246
236 // If a stub uses a special cache override this. 247 // If a stub uses a special cache override this.
237 virtual bool UseSpecialCache() { return false; } 248 virtual bool UseSpecialCache() { return false; }
238 249
239 // Returns a name for logging/debugging purposes.
240 SmartArrayPointer<const char> GetName();
241 virtual void PrintName(StringStream* stream);
242
243 // Computes the key based on major and minor. 250 // Computes the key based on major and minor.
244 uint32_t GetKey() { 251 uint32_t GetKey() {
245 ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); 252 ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
246 return MinorKeyBits::encode(MinorKey()) | 253 return MinorKeyBits::encode(MinorKey()) |
247 MajorKeyBits::encode(MajorKey()); 254 MajorKeyBits::encode(MajorKey());
248 } 255 }
249 256
250 class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {}; 257 class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {};
251 class MinorKeyBits: public BitField<uint32_t, 258 class MinorKeyBits: public BitField<uint32_t,
252 kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT 259 kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 Isolate* isolate, 354 Isolate* isolate,
348 CodeStubInterfaceDescriptor* descriptor) = 0; 355 CodeStubInterfaceDescriptor* descriptor) = 0;
349 356
350 // Retrieve the code for the stub. Generate the code if needed. 357 // Retrieve the code for the stub. Generate the code if needed.
351 virtual Handle<Code> GenerateCode() = 0; 358 virtual Handle<Code> GenerateCode() = 0;
352 359
353 virtual int NotMissMinorKey() = 0; 360 virtual int NotMissMinorKey() = 0;
354 361
355 Handle<Code> GenerateLightweightMissCode(Isolate* isolate); 362 Handle<Code> GenerateLightweightMissCode(Isolate* isolate);
356 363
364 template<class StateType>
365 void TraceTransition(StateType from, StateType to);
366
357 private: 367 private:
358 class MinorKeyBits: public BitField<int, 0, kStubMinorKeyBits - 1> {}; 368 class MinorKeyBits: public BitField<int, 0, kStubMinorKeyBits - 1> {};
359 class IsMissBits: public BitField<bool, kStubMinorKeyBits - 1, 1> {}; 369 class IsMissBits: public BitField<bool, kStubMinorKeyBits - 1, 1> {};
360 370
361 void GenerateLightweightMiss(MacroAssembler* masm); 371 void GenerateLightweightMiss(MacroAssembler* masm);
362 virtual int MinorKey() { 372 virtual int MinorKey() {
363 return IsMissBits::encode(is_uninitialized_) | 373 return IsMissBits::encode(is_uninitialized_) |
364 MinorKeyBits::encode(NotMissMinorKey()); 374 MinorKeyBits::encode(NotMissMinorKey());
365 } 375 }
366 376
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 void Generate(MacroAssembler* masm); 523 void Generate(MacroAssembler* masm);
514 524
515 private: 525 private:
516 int slots_; 526 int slots_;
517 527
518 Major MajorKey() { return FastNewBlockContext; } 528 Major MajorKey() { return FastNewBlockContext; }
519 int MinorKey() { return slots_; } 529 int MinorKey() { return slots_; }
520 }; 530 };
521 531
522 532
533 class UnaryOpStub : public HydrogenCodeStub {
534 public:
535 enum UnaryOpType {
536 SMI,
537 HEAP_NUMBER,
538 GENERIC,
539 NUMBER_OF_TYPES
540 };
541
542 // At most 7 different Types can be distinguished, because the Code object
543 // only has room for a single byte to hold and we need to store the operator.
544 STATIC_ASSERT(NUMBER_OF_TYPES <= 7);
545
546 class State : public EnumSet<UnaryOpType, byte> {
547 public:
548 State() : EnumSet<UnaryOpType, byte>(0) { }
549 explicit State(byte bits) : EnumSet<UnaryOpType, byte>(bits) { }
550 bool IsGeneric() const { return Contains(GENERIC); }
551
552 void Print(StringStream* stream) const;
553 };
554
555 // Stub without type info available -> construct uninitialized
556 explicit UnaryOpStub(Token::Value operation)
557 : HydrogenCodeStub(UNINITIALIZED), operation_(operation) { }
558 explicit UnaryOpStub(Code::ExtraICState ic_state) :
559 state_(State(ic_state & ((1 << NUMBER_OF_TYPES) - 1))) {
560 operation_ = OperatorBits::decode(ic_state) == UNARY_NOT ?
561 Token::BIT_NOT : Token::SUB;
562 }
563
564 virtual void InitializeInterfaceDescriptor(
565 Isolate* isolate,
566 CodeStubInterfaceDescriptor* descriptor);
567
568 virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; }
569 virtual InlineCacheState GetICState() {
570 if (state_.IsGeneric()) {
571 return MEGAMORPHIC;
572 } else if (state_.IsEmpty()) {
573 return PREMONOMORPHIC;
574 } else {
575 return MONOMORPHIC;
576 }
577 }
578 virtual Code::ExtraICState GetExtraICState() {
579 return OperatorBits::encode((operation_ == Token::BIT_NOT) ?
580 UNARY_NOT : UNARY_MINUS) |
581 state_.ToIntegral();
582 }
583
584 virtual HInstruction* ToHInstruction(HValue* input,
585 Handle<Type> type, HGraphBuilder* builder, HContext* context);
586 Handle<JSFunction> ToJSFunction(Isolate* isolate);
587
588 void Record(Handle<Object> object);
589 MaybeObject* Result(Handle<Object> object, Isolate* isolate);
590 Handle<Code> GenerateCode();
591 Handle<Type> GetType(Isolate* isolate);
592
593 protected:
594 void PrintState(StringStream* stream);
595 void PrintBaseName(StringStream* stream);
596
597 private:
598 enum SupportedOperations {
599 UNARY_MINUS,
600 UNARY_NOT,
601 NUMBER_OF_OPERATIONS
602 };
603 // There is only one bit reserved for the operation
604 STATIC_ASSERT(NUMBER_OF_OPERATIONS == 2);
605
606 Builtins::JavaScript ToJSBuiltin();
607
608 class OperatorBits : public BitField<byte, NUMBER_OF_TYPES, 1> {};
609
610 State state_;
611 Token::Value operation_;
612
613 virtual CodeStub::Major MajorKey() { return UnaryOp; }
614 virtual int NotMissMinorKey() { return GetExtraICState(); }
615 };
616
617
523 class FastCloneShallowArrayStub : public HydrogenCodeStub { 618 class FastCloneShallowArrayStub : public HydrogenCodeStub {
524 public: 619 public:
525 // Maximum length of copied elements array. 620 // Maximum length of copied elements array.
526 static const int kMaximumClonedLength = 8; 621 static const int kMaximumClonedLength = 8;
527 enum Mode { 622 enum Mode {
528 CLONE_ELEMENTS, 623 CLONE_ELEMENTS,
529 CLONE_DOUBLE_ELEMENTS, 624 CLONE_DOUBLE_ELEMENTS,
530 COPY_ON_WRITE_ELEMENTS, 625 COPY_ON_WRITE_ELEMENTS,
531 CLONE_ANY_ELEMENTS, 626 CLONE_ANY_ELEMENTS,
532 LAST_CLONE_MODE = CLONE_ANY_ELEMENTS 627 LAST_CLONE_MODE = CLONE_ANY_ELEMENTS
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 static State Generic() { 1236 static State Generic() {
1142 State set; 1237 State set;
1143 set.Add(UNDEFINED); 1238 set.Add(UNDEFINED);
1144 set.Add(NULL_TYPE); 1239 set.Add(NULL_TYPE);
1145 set.Add(UNDETECTABLE); 1240 set.Add(UNDETECTABLE);
1146 set.Add(GENERIC); 1241 set.Add(GENERIC);
1147 return set; 1242 return set;
1148 } 1243 }
1149 1244
1150 void Print(StringStream* stream) const; 1245 void Print(StringStream* stream) const;
1151 void TraceTransition(State to) const;
1152 }; 1246 };
1153 1247
1154 static Handle<Type> StateToType( 1248 static Handle<Type> StateToType(
1155 Isolate* isolate, State state, Handle<Map> map = Handle<Map>()); 1249 Isolate* isolate, State state, Handle<Map> map = Handle<Map>());
1156 1250
1157 // At most 6 different types can be distinguished, because the Code object 1251 // At most 6 different types can be distinguished, because the Code object
1158 // only has room for a single byte to hold a set and there are two more 1252 // only has room for a single byte to hold a set and there are two more
1159 // boolean flags we need to store. :-P 1253 // boolean flags we need to store. :-P
1160 STATIC_ASSERT(NUMBER_OF_TYPES <= 6); 1254 STATIC_ASSERT(NUMBER_OF_TYPES <= 6);
1161 1255
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 return state & ((1 << NUMBER_OF_TYPES) - 1); 1302 return state & ((1 << NUMBER_OF_TYPES) - 1);
1209 } 1303 }
1210 1304
1211 void Record(Handle<Object> object); 1305 void Record(Handle<Object> object);
1212 1306
1213 bool IsMonomorphic() const { return state_.Contains(MONOMORPHIC_MAP); } 1307 bool IsMonomorphic() const { return state_.Contains(MONOMORPHIC_MAP); }
1214 NilValue GetNilValue() const { return nil_value_; } 1308 NilValue GetNilValue() const { return nil_value_; }
1215 State GetState() const { return state_; } 1309 State GetState() const { return state_; }
1216 void ClearState() { state_.RemoveAll(); } 1310 void ClearState() { state_.RemoveAll(); }
1217 1311
1218 virtual void PrintName(StringStream* stream); 1312 virtual void PrintState(StringStream* stream);
1313 virtual void PrintBaseName(StringStream* stream);
1219 1314
1220 private: 1315 private:
1221 friend class CompareNilIC; 1316 friend class CompareNilIC;
1222 1317
1223 CompareNilICStub(NilValue nil, InitializationState init_state) 1318 CompareNilICStub(NilValue nil, InitializationState init_state)
1224 : HydrogenCodeStub(init_state) { 1319 : HydrogenCodeStub(init_state) {
1225 nil_value_ = nil; 1320 nil_value_ = nil;
1226 } 1321 }
1227 1322
1228 class NilValueField : public BitField<NilValue, NUMBER_OF_TYPES, 1> {}; 1323 class NilValueField : public BitField<NilValue, NUMBER_OF_TYPES, 1> {};
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after
1971 // only has room for a single byte to hold a set of these types. :-P 2066 // only has room for a single byte to hold a set of these types. :-P
1972 STATIC_ASSERT(NUMBER_OF_TYPES <= 8); 2067 STATIC_ASSERT(NUMBER_OF_TYPES <= 8);
1973 2068
1974 class Types : public EnumSet<Type, byte> { 2069 class Types : public EnumSet<Type, byte> {
1975 public: 2070 public:
1976 Types() : EnumSet<Type, byte>(0) {} 2071 Types() : EnumSet<Type, byte>(0) {}
1977 explicit Types(byte bits) : EnumSet<Type, byte>(bits) {} 2072 explicit Types(byte bits) : EnumSet<Type, byte>(bits) {}
1978 2073
1979 byte ToByte() const { return ToIntegral(); } 2074 byte ToByte() const { return ToIntegral(); }
1980 void Print(StringStream* stream) const; 2075 void Print(StringStream* stream) const;
1981 void TraceTransition(Types to) const;
1982 bool Record(Handle<Object> object); 2076 bool Record(Handle<Object> object);
1983 bool NeedsMap() const; 2077 bool NeedsMap() const;
1984 bool CanBeUndetectable() const; 2078 bool CanBeUndetectable() const;
1985 bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); } 2079 bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); }
1986 2080
1987 static Types Generic() { return Types((1 << NUMBER_OF_TYPES) - 1); } 2081 static Types Generic() { return Types((1 << NUMBER_OF_TYPES) - 1); }
1988 }; 2082 };
1989 2083
1990 explicit ToBooleanStub(Types types = Types()) 2084 explicit ToBooleanStub(Types types = Types())
1991 : types_(types) { } 2085 : types_(types) { }
1992 explicit ToBooleanStub(Code::ExtraICState state) 2086 explicit ToBooleanStub(Code::ExtraICState state)
1993 : types_(static_cast<byte>(state)) { } 2087 : types_(static_cast<byte>(state)) { }
1994 2088
1995 bool Record(Handle<Object> object); 2089 bool Record(Handle<Object> object);
1996 Types GetTypes() { return types_; } 2090 Types GetTypes() { return types_; }
1997 2091
1998 virtual Handle<Code> GenerateCode(); 2092 virtual Handle<Code> GenerateCode();
1999 virtual void InitializeInterfaceDescriptor( 2093 virtual void InitializeInterfaceDescriptor(
2000 Isolate* isolate, 2094 Isolate* isolate,
2001 CodeStubInterfaceDescriptor* descriptor); 2095 CodeStubInterfaceDescriptor* descriptor);
2002 2096
2003 virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; } 2097 virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; }
2004 virtual void PrintName(StringStream* stream); 2098 virtual void PrintState(StringStream* stream);
2005 2099
2006 virtual bool SometimesSetsUpAFrame() { return false; } 2100 virtual bool SometimesSetsUpAFrame() { return false; }
2007 2101
2008 static void InitializeForIsolate(Isolate* isolate) { 2102 static void InitializeForIsolate(Isolate* isolate) {
2009 ToBooleanStub stub; 2103 ToBooleanStub stub;
2010 stub.InitializeInterfaceDescriptor( 2104 stub.InitializeInterfaceDescriptor(
2011 isolate, 2105 isolate,
2012 isolate->code_stub_interface_descriptor(CodeStub::ToBoolean)); 2106 isolate->code_stub_interface_descriptor(CodeStub::ToBoolean));
2013 } 2107 }
2014 2108
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2155 2249
2156 // The current function entry hook. 2250 // The current function entry hook.
2157 static FunctionEntryHook entry_hook_; 2251 static FunctionEntryHook entry_hook_;
2158 2252
2159 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); 2253 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub);
2160 }; 2254 };
2161 2255
2162 } } // namespace v8::internal 2256 } } // namespace v8::internal
2163 2257
2164 #endif // V8_CODE_STUBS_H_ 2258 #endif // V8_CODE_STUBS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698