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

Side by Side Diff: src/codegen.h

Issue 2087009: Custom call IC-s for String.prototype.{charAt,charCodeAt}. (Closed)
Patch Set: ARM port. Created 10 years, 7 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/arm/stub-cache-arm.cc ('k') | src/full-codegen.h » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 F(IsNonNegativeSmi, 1, 1) \ 103 F(IsNonNegativeSmi, 1, 1) \
104 F(IsArray, 1, 1) \ 104 F(IsArray, 1, 1) \
105 F(IsRegExp, 1, 1) \ 105 F(IsRegExp, 1, 1) \
106 F(CallFunction, -1 /* receiver + n args + function */, 1) \ 106 F(CallFunction, -1 /* receiver + n args + function */, 1) \
107 F(IsConstructCall, 0, 1) \ 107 F(IsConstructCall, 0, 1) \
108 F(ArgumentsLength, 0, 1) \ 108 F(ArgumentsLength, 0, 1) \
109 F(Arguments, 1, 1) \ 109 F(Arguments, 1, 1) \
110 F(ClassOf, 1, 1) \ 110 F(ClassOf, 1, 1) \
111 F(ValueOf, 1, 1) \ 111 F(ValueOf, 1, 1) \
112 F(SetValueOf, 2, 1) \ 112 F(SetValueOf, 2, 1) \
113 F(FastCharCodeAt, 2, 1) \ 113 F(StringCharCodeAt, 2, 1) \
114 F(CharFromCode, 1, 1) \ 114 F(StringCharFromCode, 1, 1) \
115 F(StringCharAt, 2, 1) \
115 F(ObjectEquals, 2, 1) \ 116 F(ObjectEquals, 2, 1) \
116 F(Log, 3, 1) \ 117 F(Log, 3, 1) \
117 F(RandomHeapNumber, 0, 1) \ 118 F(RandomHeapNumber, 0, 1) \
118 F(IsObject, 1, 1) \ 119 F(IsObject, 1, 1) \
119 F(IsFunction, 1, 1) \ 120 F(IsFunction, 1, 1) \
120 F(IsUndetectableObject, 1, 1) \ 121 F(IsUndetectableObject, 1, 1) \
121 F(StringAdd, 2, 1) \ 122 F(StringAdd, 2, 1) \
122 F(SubString, 3, 1) \ 123 F(SubString, 3, 1) \
123 F(StringCompare, 2, 1) \ 124 F(StringCompare, 2, 1) \
124 F(RegExpExec, 4, 1) \ 125 F(RegExpExec, 4, 1) \
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 ASSERT(top_ != NULL); 173 ASSERT(top_ != NULL);
173 return top_; 174 return top_;
174 } 175 }
175 176
176 private: 177 private:
177 static CodeGenerator* top_; 178 static CodeGenerator* top_;
178 CodeGenerator* previous_; 179 CodeGenerator* previous_;
179 }; 180 };
180 181
181 182
183 // State of used registers in a virtual frame.
184 class FrameRegisterState {
185 public:
186 // Captures the current state of the given frame.
187 explicit FrameRegisterState(VirtualFrame* frame);
188
189 // Saves the state in the stack.
190 void Save(MacroAssembler* masm) const;
191
192 // Restores the state from the stack.
193 void Restore(MacroAssembler* masm) const;
194
195 private:
196 // Constants indicating special actions. They should not be multiples
197 // of kPointerSize so they will not collide with valid offsets from
198 // the frame pointer.
199 static const int kIgnore = -1;
200 static const int kPush = 1;
201
202 // This flag is ored with a valid offset from the frame pointer, so
203 // it should fit in the low zero bits of a valid offset.
204 static const int kSyncedFlag = 2;
205
206 // C++ doesn't allow zero length arrays, so we make the array length 1 even
207 // if we don't need it.
208 static const int kRegistersArrayLength =
209 (RegisterAllocator::kNumRegisters == 0) ?
210 1 : RegisterAllocator::kNumRegisters;
211 int registers_[kRegistersArrayLength];
212 };
213
214
215 // Helper interface to prepare to/restore after making runtime calls.
216 class RuntimeCallHelper {
217 public:
218 virtual ~RuntimeCallHelper() {}
219
220 virtual void BeforeCall(MacroAssembler* masm) const = 0;
221
222 virtual void AfterCall(MacroAssembler* masm) const = 0;
223
224 protected:
225 RuntimeCallHelper() {}
226
227 private:
228 DISALLOW_COPY_AND_ASSIGN(RuntimeCallHelper);
229 };
230
231
232 // RuntimeCallHelper implementation that saves/restores state of a
233 // virtual frame.
234 class VirtualFrameRuntimeCallHelper : public RuntimeCallHelper {
235 public:
236 // Does not take ownership of |frame_state|.
237 explicit VirtualFrameRuntimeCallHelper(const FrameRegisterState* frame_state)
238 : frame_state_(frame_state) {}
239
240 virtual void BeforeCall(MacroAssembler* masm) const;
241
242 virtual void AfterCall(MacroAssembler* masm) const;
243
244 private:
245 const FrameRegisterState* frame_state_;
246 };
247
248
249 // RuntimeCallHelper implementation used in IC stubs: enters/leaves a
250 // newly created internal frame before/after the runtime call.
251 class ICRuntimeCallHelper : public RuntimeCallHelper {
252 public:
253 ICRuntimeCallHelper() {}
254
255 virtual void BeforeCall(MacroAssembler* masm) const;
256
257 virtual void AfterCall(MacroAssembler* masm) const;
258 };
259
260
261 // Trivial RuntimeCallHelper implementation.
262 class NopRuntimeCallHelper : public RuntimeCallHelper {
263 public:
264 NopRuntimeCallHelper() {}
265
266 virtual void BeforeCall(MacroAssembler* masm) const {}
267
268 virtual void AfterCall(MacroAssembler* masm) const {}
269 };
270
271
182 // Deferred code objects are small pieces of code that are compiled 272 // Deferred code objects are small pieces of code that are compiled
183 // out of line. They are used to defer the compilation of uncommon 273 // out of line. They are used to defer the compilation of uncommon
184 // paths thereby avoiding expensive jumps around uncommon code parts. 274 // paths thereby avoiding expensive jumps around uncommon code parts.
185 class DeferredCode: public ZoneObject { 275 class DeferredCode: public ZoneObject {
186 public: 276 public:
187 DeferredCode(); 277 DeferredCode();
188 virtual ~DeferredCode() { } 278 virtual ~DeferredCode() { }
189 279
190 virtual void Generate() = 0; 280 virtual void Generate() = 0;
191 281
(...skipping 10 matching lines...) Expand all
202 const char* comment() const { return comment_; } 292 const char* comment() const { return comment_; }
203 #else 293 #else
204 void set_comment(const char* comment) { } 294 void set_comment(const char* comment) { }
205 const char* comment() const { return ""; } 295 const char* comment() const { return ""; }
206 #endif 296 #endif
207 297
208 inline void Jump(); 298 inline void Jump();
209 inline void Branch(Condition cc); 299 inline void Branch(Condition cc);
210 void BindExit() { masm_->bind(&exit_label_); } 300 void BindExit() { masm_->bind(&exit_label_); }
211 301
302 const FrameRegisterState* frame_state() const { return &frame_state_; }
303
212 void SaveRegisters(); 304 void SaveRegisters();
213 void RestoreRegisters(); 305 void RestoreRegisters();
214 306
215 protected: 307 protected:
216 MacroAssembler* masm_; 308 MacroAssembler* masm_;
217 309
218 private: 310 private:
219 // Constants indicating special actions. They should not be multiples
220 // of kPointerSize so they will not collide with valid offsets from
221 // the frame pointer.
222 static const int kIgnore = -1;
223 static const int kPush = 1;
224
225 // This flag is ored with a valid offset from the frame pointer, so
226 // it should fit in the low zero bits of a valid offset.
227 static const int kSyncedFlag = 2;
228
229 int statement_position_; 311 int statement_position_;
230 int position_; 312 int position_;
231 313
232 Label entry_label_; 314 Label entry_label_;
233 Label exit_label_; 315 Label exit_label_;
234 316
235 // C++ doesn't allow zero length arrays, so we make the array length 1 even 317 FrameRegisterState frame_state_;
236 // if we don't need it.
237 static const int kRegistersArrayLength =
238 (RegisterAllocator::kNumRegisters == 0) ?
239 1 : RegisterAllocator::kNumRegisters;
240 int registers_[kRegistersArrayLength];
241 318
242 #ifdef DEBUG 319 #ifdef DEBUG
243 const char* comment_; 320 const char* comment_;
244 #endif 321 #endif
245 DISALLOW_COPY_AND_ASSIGN(DeferredCode); 322 DISALLOW_COPY_AND_ASSIGN(DeferredCode);
246 }; 323 };
247 324
248 class StackCheckStub : public CodeStub { 325 class StackCheckStub : public CodeStub {
249 public: 326 public:
250 StackCheckStub() { } 327 StackCheckStub() { }
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 ToBooleanStub() { } 681 ToBooleanStub() { }
605 682
606 void Generate(MacroAssembler* masm); 683 void Generate(MacroAssembler* masm);
607 684
608 private: 685 private:
609 Major MajorKey() { return ToBoolean; } 686 Major MajorKey() { return ToBoolean; }
610 int MinorKey() { return 0; } 687 int MinorKey() { return 0; }
611 }; 688 };
612 689
613 690
691 enum StringIndexFlags {
Mads Ager (chromium) 2010/05/26 09:17:07 How about renaming these to something like: INDEX
692 // Accepts smis or heap numbers.
693 STRING_ANY_NUMBER_INDEX,
694
695 // Accepts smis or heap numbers that are valid array indices
696 // (ECMA-262 15.4). Invalid indices are reported as being out of
697 // range.
698 STRING_REQUIRE_ARRAY_INDEX
699 };
700
701
702 // Generates code implementing String.prototype.charCodeAt.
703 //
704 // Only supports the case when the receiver is a string and the index
705 // is a number (smi or heap number) that is a valid index into the
706 // string. Otherwise, bails out to the provided labels.
707 //
708 // Register usage: |object| may be changed to another string in a way
709 // that doesn't affect charCodeAt/charAt semantics, |index| is
710 // preserved, |scratch| and |result| are clobbered.
711 class StringCharCodeAtGenerator {
712 public:
713 StringCharCodeAtGenerator(Register object,
714 Register index,
715 Register scratch,
716 Register result,
717 Label* receiver_not_string,
718 Label* index_not_number,
719 Label* index_out_of_range,
720 StringIndexFlags index_flags)
721 : object_(object),
722 index_(index),
723 scratch_(scratch),
724 result_(result),
725 receiver_not_string_(receiver_not_string),
726 index_not_number_(index_not_number),
727 index_out_of_range_(index_out_of_range),
728 index_flags_(index_flags) {
729 ASSERT(!scratch_.is(object_));
730 ASSERT(!scratch_.is(index_));
731 ASSERT(!scratch_.is(result_));
732 ASSERT(!result_.is(object_));
733 ASSERT(!result_.is(index_));
734 }
735
736 // Generates the fast case code. On the fallthrough path |result|
737 // register contains the result.
738 void GenerateFast(MacroAssembler* masm);
739
740 // Generates the slow case code. Must not be naturally
741 // reachable. Expected to be put after a ret instruction (e.g., in
742 // deferred code). Always jumps back to the fast case.
743 void GenerateSlow(MacroAssembler* masm,
744 const RuntimeCallHelper& call_helper);
745
746 private:
747 Register object_;
748 Register index_;
749 Register scratch_;
750 Register result_;
751
752 Label* receiver_not_string_;
753 Label* index_not_number_;
754 Label* index_out_of_range_;
755
756 StringIndexFlags index_flags_;
757
758 Label call_runtime_;
759 Label index_not_smi_;
760 Label got_smi_index_;
761 Label exit_;
762
763 DISALLOW_COPY_AND_ASSIGN(StringCharCodeAtGenerator);
764 };
765
766
767 // Generates code for creating a one-char string from a char code.
768 class StringCharFromCodeGenerator {
769 public:
770 StringCharFromCodeGenerator(Register code,
771 Register result)
772 : code_(code),
773 result_(result) {
774 ASSERT(!code_.is(result_));
775 }
776
777 // Generates the fast case code. On the fallthrough path |result|
778 // register contains the result.
779 void GenerateFast(MacroAssembler* masm);
780
781 // Generates the slow case code. Must not be naturally
782 // reachable. Expected to be put after a ret instruction (e.g., in
783 // deferred code). Always jumps back to the fast case.
784 void GenerateSlow(MacroAssembler* masm,
785 const RuntimeCallHelper& call_helper);
786
787 private:
788 Register code_;
789 Register result_;
790
791 Label slow_case_;
792 Label exit_;
793
794 DISALLOW_COPY_AND_ASSIGN(StringCharFromCodeGenerator);
795 };
796
797
798 // Generates code implementing String.prototype.charAt.
799 //
800 // Only supports the case when the receiver is a string and the index
801 // is a number (smi or heap number) that is a valid index into the
802 // string. Otherwise, bails out to the provided labels.
803 //
804 // Register usage: |object| may be changed to another string in a way
805 // that doesn't affect charCodeAt/charAt semantics, |index| is
806 // preserved, |scratch1|, |scratch2|, and |result| are clobbered.
807 class StringCharAtGenerator {
808 public:
809 StringCharAtGenerator(Register object,
810 Register index,
811 Register scratch1,
812 Register scratch2,
813 Register result,
814 Label* receiver_not_string,
815 Label* index_not_number,
816 Label* index_out_of_range,
817 StringIndexFlags index_flags)
818 : char_code_at_generator_(object,
819 index,
820 scratch1,
821 scratch2,
822 receiver_not_string,
823 index_not_number,
824 index_out_of_range,
825 index_flags),
826 char_from_code_generator_(scratch2, result) {}
827
828 // Generates the fast case code. On the fallthrough path |result|
829 // register contains the result.
830 void GenerateFast(MacroAssembler* masm);
831
832 // Generates the slow case code. Must not be naturally
833 // reachable. Expected to be put after a ret instruction (e.g., in
834 // deferred code). Always jumps back to the fast case.
835 void GenerateSlow(MacroAssembler* masm,
836 const RuntimeCallHelper& call_helper);
837
838 private:
839 StringCharCodeAtGenerator char_code_at_generator_;
840 StringCharFromCodeGenerator char_from_code_generator_;
841
842 DISALLOW_COPY_AND_ASSIGN(StringCharAtGenerator);
843 };
844
845
614 } // namespace internal 846 } // namespace internal
615 } // namespace v8 847 } // namespace v8
616 848
617 #endif // V8_CODEGEN_H_ 849 #endif // V8_CODEGEN_H_
OLDNEW
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698