Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_IC_HANDLER_COMPILER_H_
6 : #define V8_IC_HANDLER_COMPILER_H_
7 :
8 : #include "src/ic/access-compiler.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 :
13 : class CallOptimization;
14 :
15 : class PropertyHandlerCompiler : public PropertyAccessCompiler {
16 : protected:
17 : PropertyHandlerCompiler(Isolate* isolate, Type type, Handle<Map> map,
18 : Handle<JSObject> holder)
19 245699 : : PropertyAccessCompiler(isolate, type), map_(map), holder_(holder) {}
20 :
21 245699 : virtual ~PropertyHandlerCompiler() {}
22 :
23 : // The ICs that don't pass slot and vector through the stack have to
24 : // save/restore them in the dispatcher.
25 : bool ShouldPushPopSlotAndVector();
26 :
27 0 : virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
28 : Label* miss) {
29 0 : UNREACHABLE();
30 : }
31 :
32 0 : virtual void FrontendFooter(Handle<Name> name, Label* miss) { UNREACHABLE(); }
33 :
34 : // Frontend loads from receiver(), returns holder register which may be
35 : // different.
36 : Register Frontend(Handle<Name> name);
37 :
38 : // When FLAG_vector_ics is true, handlers that have the possibility of missing
39 : // will need to save and pass these to miss handlers.
40 245699 : void PushVectorAndSlot() { PushVectorAndSlot(vector(), slot()); }
41 : void PushVectorAndSlot(Register vector, Register slot);
42 491366 : void PopVectorAndSlot() { PopVectorAndSlot(vector(), slot()); }
43 : void PopVectorAndSlot(Register vector, Register slot);
44 :
45 : void DiscardVectorAndSlot();
46 :
47 : // TODO(verwaest): Make non-static.
48 : static void GenerateApiAccessorCall(MacroAssembler* masm,
49 : const CallOptimization& optimization,
50 : Handle<Map> receiver_map,
51 : Register receiver, Register scratch,
52 : bool is_store, Register store_parameter,
53 : Register accessor_holder,
54 : int accessor_index);
55 :
56 : // Helper function used to check that the dictionary doesn't contain
57 : // the property. This function may return false negatives, so miss_label
58 : // must always call a backup property check that is complete.
59 : // This function is safe to call if the receiver has fast properties.
60 : // Name must be unique and receiver must be a heap object.
61 : static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
62 : Label* miss_label,
63 : Register receiver,
64 : Handle<Name> name, Register r0,
65 : Register r1);
66 :
67 : // Generate code to check that a global property cell is empty. Create
68 : // the property cell at compilation time if no cell exists for the
69 : // property.
70 : static void GenerateCheckPropertyCell(MacroAssembler* masm,
71 : Handle<JSGlobalObject> global,
72 : Handle<Name> name, Register scratch,
73 : Label* miss);
74 :
75 : // Generates check that current native context has the same access rights
76 : // as the given |native_context_cell|.
77 : // If |compare_native_contexts_only| is true then access check is considered
78 : // passed if the execution-time native context is equal to contents of
79 : // |native_context_cell|.
80 : // If |compare_native_contexts_only| is false then access check is considered
81 : // passed if the execution-time native context is equal to contents of
82 : // |native_context_cell| or security tokens of both contexts are equal.
83 : void GenerateAccessCheck(Handle<WeakCell> native_context_cell,
84 : Register scratch1, Register scratch2, Label* miss,
85 : bool compare_native_contexts_only);
86 :
87 : // Generates code that verifies that the property holder has not changed
88 : // (checking maps of objects in the prototype chain for fast and global
89 : // objects or doing negative lookup for slow objects, ensures that the
90 : // property cells for global objects are still empty) and checks that the map
91 : // of the holder has not changed. If necessary the function also generates
92 : // code for security check in case of global object holders. Helps to make
93 : // sure that the current IC is still valid.
94 : //
95 : // The scratch and holder registers are always clobbered, but the object
96 : // register is only clobbered if it the same as the holder register. The
97 : // function returns a register containing the holder - either object_reg or
98 : // holder_reg.
99 : Register CheckPrototypes(Register object_reg, Register holder_reg,
100 : Register scratch1, Register scratch2,
101 : Handle<Name> name, Label* miss);
102 :
103 : Handle<Code> GetCode(Handle<Name> name);
104 : Handle<Map> map() const { return map_; }
105 : Handle<JSObject> holder() const { return holder_; }
106 :
107 : private:
108 : Handle<Map> map_;
109 : Handle<JSObject> holder_;
110 : };
111 :
112 :
113 : class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
114 : public:
115 : NamedLoadHandlerCompiler(Isolate* isolate, Handle<Map> map,
116 : Handle<JSObject> holder)
117 3512 : : PropertyHandlerCompiler(isolate, LOAD, map, holder) {}
118 :
119 3512 : virtual ~NamedLoadHandlerCompiler() {}
120 :
121 : Handle<Code> CompileLoadCallback(Handle<Name> name,
122 : const CallOptimization& call_optimization,
123 : int accessor_index, Handle<Code> slow_stub);
124 :
125 : static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm);
126 :
127 : protected:
128 : virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
129 : Label* miss);
130 :
131 : virtual void FrontendFooter(Handle<Name> name, Label* miss);
132 :
133 : private:
134 3512 : Register scratch3() { return registers_[4]; }
135 : };
136 :
137 :
138 : class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
139 : public:
140 : // All store handlers use StoreWithVectorDescriptor calling convention.
141 : typedef StoreWithVectorDescriptor Descriptor;
142 :
143 : explicit NamedStoreHandlerCompiler(Isolate* isolate, Handle<Map> map,
144 : Handle<JSObject> holder)
145 242187 : : PropertyHandlerCompiler(isolate, STORE, map, holder) {
146 : #ifdef DEBUG
147 : if (Descriptor::kPassLastArgsOnStack) {
148 : ZapStackArgumentsRegisterAliases();
149 : }
150 : #endif
151 : }
152 :
153 242187 : virtual ~NamedStoreHandlerCompiler() {}
154 :
155 : void ZapStackArgumentsRegisterAliases();
156 :
157 : Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
158 : Handle<AccessorInfo> callback,
159 : LanguageMode language_mode);
160 : Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
161 : const CallOptimization& call_optimization,
162 : int accessor_index, Handle<Code> slow_stub);
163 : Handle<Code> CompileStoreViaSetter(Handle<JSObject> object, Handle<Name> name,
164 : int accessor_index,
165 : int expected_arguments);
166 :
167 : static void GenerateStoreViaSetter(MacroAssembler* masm, Handle<Map> map,
168 : Register receiver, Register holder,
169 : int accessor_index, int expected_arguments,
170 : Register scratch);
171 :
172 31 : static void GenerateStoreViaSetterForDeopt(MacroAssembler* masm) {
173 : GenerateStoreViaSetter(masm, Handle<Map>::null(), no_reg, no_reg, -1, -1,
174 31 : no_reg);
175 31 : }
176 :
177 : protected:
178 : virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
179 : Label* miss);
180 :
181 : virtual void FrontendFooter(Handle<Name> name, Label* miss);
182 : void GenerateRestoreName(Label* label, Handle<Name> name);
183 :
184 : private:
185 : static Register value();
186 : };
187 :
188 : } // namespace internal
189 : } // namespace v8
190 :
191 : #endif // V8_IC_HANDLER_COMPILER_H_
|