OLD | NEW |
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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 } | 49 } |
50 | 50 |
51 | 51 |
52 void StubCache::Initialize() { | 52 void StubCache::Initialize() { |
53 ASSERT(IsPowerOf2(kPrimaryTableSize)); | 53 ASSERT(IsPowerOf2(kPrimaryTableSize)); |
54 ASSERT(IsPowerOf2(kSecondaryTableSize)); | 54 ASSERT(IsPowerOf2(kSecondaryTableSize)); |
55 Clear(); | 55 Clear(); |
56 } | 56 } |
57 | 57 |
58 | 58 |
59 Code* StubCache::Set(String* name, Map* map, Code* code) { | 59 Code* StubCache::Set(Name* name, Map* map, Code* code) { |
60 // Get the flags from the code. | 60 // Get the flags from the code. |
61 Code::Flags flags = Code::RemoveTypeFromFlags(code->flags()); | 61 Code::Flags flags = Code::RemoveTypeFromFlags(code->flags()); |
62 | 62 |
63 // Validate that the name does not move on scavenge, and that we | 63 // Validate that the name does not move on scavenge, and that we |
64 // can use identity checks instead of string equality checks. | 64 // can use identity checks instead of structural equality checks. |
65 ASSERT(!heap()->InNewSpace(name)); | 65 ASSERT(!heap()->InNewSpace(name)); |
66 ASSERT(name->IsInternalizedString()); | 66 ASSERT(name->IsUniqueName()); |
67 | 67 |
68 // The state bits are not important to the hash function because | 68 // The state bits are not important to the hash function because |
69 // the stub cache only contains monomorphic stubs. Make sure that | 69 // the stub cache only contains monomorphic stubs. Make sure that |
70 // the bits are the least significant so they will be the ones | 70 // the bits are the least significant so they will be the ones |
71 // masked out. | 71 // masked out. |
72 ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC); | 72 ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC); |
73 STATIC_ASSERT((Code::ICStateField::kMask & 1) == 1); | 73 STATIC_ASSERT((Code::ICStateField::kMask & 1) == 1); |
74 | 74 |
75 // Make sure that the code type is not included in the hash. | 75 // Make sure that the code type is not included in the hash. |
76 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); | 76 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); |
(...skipping 16 matching lines...) Expand all Loading... |
93 | 93 |
94 // Update primary cache. | 94 // Update primary cache. |
95 primary->key = name; | 95 primary->key = name; |
96 primary->value = code; | 96 primary->value = code; |
97 primary->map = map; | 97 primary->map = map; |
98 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); | 98 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); |
99 return code; | 99 return code; |
100 } | 100 } |
101 | 101 |
102 | 102 |
103 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name, | 103 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, |
104 Handle<JSObject> receiver) { | 104 Handle<JSObject> receiver) { |
105 // If no global objects are present in the prototype chain, the load | 105 // If no global objects are present in the prototype chain, the load |
106 // nonexistent IC stub can be shared for all names for a given map | 106 // nonexistent IC stub can be shared for all names for a given map |
107 // and we use the empty string for the map cache in that case. If | 107 // and we use the empty string for the map cache in that case. If |
108 // there are global objects involved, we need to check global | 108 // there are global objects involved, we need to check global |
109 // property cells in the stub and therefore the stub will be | 109 // property cells in the stub and therefore the stub will be |
110 // specific to the name. | 110 // specific to the name. |
111 Handle<String> cache_name = factory()->empty_string(); | 111 Handle<Name> cache_name = factory()->empty_string(); |
112 Handle<JSObject> current; | 112 Handle<JSObject> current; |
113 Handle<Object> next = receiver; | 113 Handle<Object> next = receiver; |
114 Handle<GlobalObject> global; | 114 Handle<GlobalObject> global; |
115 do { | 115 do { |
116 current = Handle<JSObject>::cast(next); | 116 current = Handle<JSObject>::cast(next); |
117 next = Handle<Object>(current->GetPrototype()); | 117 next = Handle<Object>(current->GetPrototype()); |
118 if (current->IsGlobalObject()) { | 118 if (current->IsGlobalObject()) { |
119 global = Handle<GlobalObject>::cast(current); | 119 global = Handle<GlobalObject>::cast(current); |
120 cache_name = name; | 120 cache_name = name; |
121 } else if (!current->HasFastProperties()) { | 121 } else if (!current->HasFastProperties()) { |
(...skipping 12 matching lines...) Expand all Loading... |
134 LoadStubCompiler compiler(isolate_); | 134 LoadStubCompiler compiler(isolate_); |
135 Handle<Code> code = | 135 Handle<Code> code = |
136 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); | 136 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); |
137 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name)); | 137 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name)); |
138 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code)); | 138 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code)); |
139 JSObject::UpdateMapCodeCache(receiver, cache_name, code); | 139 JSObject::UpdateMapCodeCache(receiver, cache_name, code); |
140 return code; | 140 return code; |
141 } | 141 } |
142 | 142 |
143 | 143 |
144 Handle<Code> StubCache::ComputeLoadField(Handle<String> name, | 144 Handle<Code> StubCache::ComputeLoadField(Handle<Name> name, |
145 Handle<JSObject> receiver, | 145 Handle<JSObject> receiver, |
146 Handle<JSObject> holder, | 146 Handle<JSObject> holder, |
147 PropertyIndex field) { | 147 PropertyIndex field) { |
148 InlineCacheHolderFlag cache_holder = | 148 InlineCacheHolderFlag cache_holder = |
149 IC::GetCodeCacheForObject(*receiver, *holder); | 149 IC::GetCodeCacheForObject(*receiver, *holder); |
150 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 150 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
151 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::FIELD); | 151 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::FIELD); |
152 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), | 152 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), |
153 isolate_); | 153 isolate_); |
154 if (probe->IsCode()) return Handle<Code>::cast(probe); | 154 if (probe->IsCode()) return Handle<Code>::cast(probe); |
155 | 155 |
156 LoadStubCompiler compiler(isolate_); | 156 LoadStubCompiler compiler(isolate_); |
157 Handle<Code> code = compiler.CompileLoadField(receiver, holder, name, field); | 157 Handle<Code> code = compiler.CompileLoadField(receiver, holder, name, field); |
158 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 158 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
159 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 159 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
160 JSObject::UpdateMapCodeCache(map_holder, name, code); | 160 JSObject::UpdateMapCodeCache(map_holder, name, code); |
161 return code; | 161 return code; |
162 } | 162 } |
163 | 163 |
164 | 164 |
165 Handle<Code> StubCache::ComputeLoadCallback(Handle<String> name, | 165 Handle<Code> StubCache::ComputeLoadCallback(Handle<Name> name, |
166 Handle<JSObject> receiver, | 166 Handle<JSObject> receiver, |
167 Handle<JSObject> holder, | 167 Handle<JSObject> holder, |
168 Handle<AccessorInfo> callback) { | 168 Handle<AccessorInfo> callback) { |
169 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); | 169 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); |
170 InlineCacheHolderFlag cache_holder = | 170 InlineCacheHolderFlag cache_holder = |
171 IC::GetCodeCacheForObject(*receiver, *holder); | 171 IC::GetCodeCacheForObject(*receiver, *holder); |
172 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 172 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
173 Code::Flags flags = | 173 Code::Flags flags = |
174 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS); | 174 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS); |
175 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), | 175 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), |
176 isolate_); | 176 isolate_); |
177 if (probe->IsCode()) return Handle<Code>::cast(probe); | 177 if (probe->IsCode()) return Handle<Code>::cast(probe); |
178 | 178 |
179 LoadStubCompiler compiler(isolate_); | 179 LoadStubCompiler compiler(isolate_); |
180 Handle<Code> code = | 180 Handle<Code> code = |
181 compiler.CompileLoadCallback(receiver, holder, name, callback); | 181 compiler.CompileLoadCallback(receiver, holder, name, callback); |
182 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 182 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
183 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 183 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
184 JSObject::UpdateMapCodeCache(map_holder, name, code); | 184 JSObject::UpdateMapCodeCache(map_holder, name, code); |
185 return code; | 185 return code; |
186 } | 186 } |
187 | 187 |
188 | 188 |
189 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name, | 189 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name, |
190 Handle<JSObject> receiver, | 190 Handle<JSObject> receiver, |
191 Handle<JSObject> holder, | 191 Handle<JSObject> holder, |
192 Handle<JSFunction> getter) { | 192 Handle<JSFunction> getter) { |
193 InlineCacheHolderFlag cache_holder = | 193 InlineCacheHolderFlag cache_holder = |
194 IC::GetCodeCacheForObject(*receiver, *holder); | 194 IC::GetCodeCacheForObject(*receiver, *holder); |
195 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 195 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
196 Code::Flags flags = | 196 Code::Flags flags = |
197 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS); | 197 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS); |
198 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), | 198 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), |
199 isolate_); | 199 isolate_); |
200 if (probe->IsCode()) return Handle<Code>::cast(probe); | 200 if (probe->IsCode()) return Handle<Code>::cast(probe); |
201 | 201 |
202 LoadStubCompiler compiler(isolate_); | 202 LoadStubCompiler compiler(isolate_); |
203 Handle<Code> code = | 203 Handle<Code> code = |
204 compiler.CompileLoadViaGetter(receiver, holder, name, getter); | 204 compiler.CompileLoadViaGetter(receiver, holder, name, getter); |
205 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 205 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
206 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 206 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
207 JSObject::UpdateMapCodeCache(map_holder, name, code); | 207 JSObject::UpdateMapCodeCache(map_holder, name, code); |
208 return code; | 208 return code; |
209 } | 209 } |
210 | 210 |
211 | 211 |
212 Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name, | 212 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name, |
213 Handle<JSObject> receiver, | 213 Handle<JSObject> receiver, |
214 Handle<JSObject> holder, | 214 Handle<JSObject> holder, |
215 Handle<JSFunction> value) { | 215 Handle<JSFunction> value) { |
216 InlineCacheHolderFlag cache_holder = | 216 InlineCacheHolderFlag cache_holder = |
217 IC::GetCodeCacheForObject(*receiver, *holder); | 217 IC::GetCodeCacheForObject(*receiver, *holder); |
218 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 218 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
219 Code::Flags flags = | 219 Code::Flags flags = |
220 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CONSTANT_FUNCTION); | 220 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CONSTANT_FUNCTION); |
221 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), | 221 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), |
222 isolate_); | 222 isolate_); |
223 if (probe->IsCode()) return Handle<Code>::cast(probe); | 223 if (probe->IsCode()) return Handle<Code>::cast(probe); |
224 | 224 |
225 LoadStubCompiler compiler(isolate_); | 225 LoadStubCompiler compiler(isolate_); |
226 Handle<Code> code = | 226 Handle<Code> code = |
227 compiler.CompileLoadConstant(receiver, holder, name, value); | 227 compiler.CompileLoadConstant(receiver, holder, name, value); |
228 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 228 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
229 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 229 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
230 JSObject::UpdateMapCodeCache(map_holder, name, code); | 230 JSObject::UpdateMapCodeCache(map_holder, name, code); |
231 return code; | 231 return code; |
232 } | 232 } |
233 | 233 |
234 | 234 |
235 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name, | 235 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name, |
236 Handle<JSObject> receiver, | 236 Handle<JSObject> receiver, |
237 Handle<JSObject> holder) { | 237 Handle<JSObject> holder) { |
238 InlineCacheHolderFlag cache_holder = | 238 InlineCacheHolderFlag cache_holder = |
239 IC::GetCodeCacheForObject(*receiver, *holder); | 239 IC::GetCodeCacheForObject(*receiver, *holder); |
240 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 240 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
241 Code::Flags flags = | 241 Code::Flags flags = |
242 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::INTERCEPTOR); | 242 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::INTERCEPTOR); |
243 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), | 243 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), |
244 isolate_); | 244 isolate_); |
245 if (probe->IsCode()) return Handle<Code>::cast(probe); | 245 if (probe->IsCode()) return Handle<Code>::cast(probe); |
246 | 246 |
247 LoadStubCompiler compiler(isolate_); | 247 LoadStubCompiler compiler(isolate_); |
248 Handle<Code> code = | 248 Handle<Code> code = |
249 compiler.CompileLoadInterceptor(receiver, holder, name); | 249 compiler.CompileLoadInterceptor(receiver, holder, name); |
250 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 250 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
251 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 251 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
252 JSObject::UpdateMapCodeCache(map_holder, name, code); | 252 JSObject::UpdateMapCodeCache(map_holder, name, code); |
253 return code; | 253 return code; |
254 } | 254 } |
255 | 255 |
256 | 256 |
257 Handle<Code> StubCache::ComputeLoadNormal() { | 257 Handle<Code> StubCache::ComputeLoadNormal() { |
258 return isolate_->builtins()->LoadIC_Normal(); | 258 return isolate_->builtins()->LoadIC_Normal(); |
259 } | 259 } |
260 | 260 |
261 | 261 |
262 Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name, | 262 Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name, |
263 Handle<JSObject> receiver, | 263 Handle<JSObject> receiver, |
264 Handle<GlobalObject> holder, | 264 Handle<GlobalObject> holder, |
265 Handle<JSGlobalPropertyCell> cell, | 265 Handle<JSGlobalPropertyCell> cell, |
266 bool is_dont_delete) { | 266 bool is_dont_delete) { |
267 InlineCacheHolderFlag cache_holder = | 267 InlineCacheHolderFlag cache_holder = |
268 IC::GetCodeCacheForObject(*receiver, *holder); | 268 IC::GetCodeCacheForObject(*receiver, *holder); |
269 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 269 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
270 Code::Flags flags = | 270 Code::Flags flags = |
271 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL); | 271 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL); |
272 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), | 272 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), |
273 isolate_); | 273 isolate_); |
274 if (probe->IsCode()) return Handle<Code>::cast(probe); | 274 if (probe->IsCode()) return Handle<Code>::cast(probe); |
275 | 275 |
276 LoadStubCompiler compiler(isolate_); | 276 LoadStubCompiler compiler(isolate_); |
277 Handle<Code> code = | 277 Handle<Code> code = |
278 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); | 278 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); |
279 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 279 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
280 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 280 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
281 JSObject::UpdateMapCodeCache(map_holder, name, code); | 281 JSObject::UpdateMapCodeCache(map_holder, name, code); |
282 return code; | 282 return code; |
283 } | 283 } |
284 | 284 |
285 | 285 |
286 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name, | 286 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name, |
287 Handle<JSObject> receiver, | 287 Handle<JSObject> receiver, |
288 Handle<JSObject> holder, | 288 Handle<JSObject> holder, |
289 PropertyIndex field) { | 289 PropertyIndex field) { |
290 InlineCacheHolderFlag cache_holder = | 290 InlineCacheHolderFlag cache_holder = |
291 IC::GetCodeCacheForObject(*receiver, *holder); | 291 IC::GetCodeCacheForObject(*receiver, *holder); |
292 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 292 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
293 Code::Flags flags = | 293 Code::Flags flags = |
294 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::FIELD); | 294 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::FIELD); |
295 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), | 295 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), |
296 isolate_); | 296 isolate_); |
297 if (probe->IsCode()) return Handle<Code>::cast(probe); | 297 if (probe->IsCode()) return Handle<Code>::cast(probe); |
298 | 298 |
299 KeyedLoadStubCompiler compiler(isolate_); | 299 KeyedLoadStubCompiler compiler(isolate_); |
300 Handle<Code> code = compiler.CompileLoadField(receiver, holder, name, field); | 300 Handle<Code> code = compiler.CompileLoadField(receiver, holder, name, field); |
301 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); | 301 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
302 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); | 302 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
303 JSObject::UpdateMapCodeCache(map_holder, name, code); | 303 JSObject::UpdateMapCodeCache(map_holder, name, code); |
304 return code; | 304 return code; |
305 } | 305 } |
306 | 306 |
307 | 307 |
308 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name, | 308 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name, |
309 Handle<JSObject> receiver, | 309 Handle<JSObject> receiver, |
310 Handle<JSObject> holder, | 310 Handle<JSObject> holder, |
311 Handle<JSFunction> value) { | 311 Handle<JSFunction> value) { |
312 InlineCacheHolderFlag cache_holder = | 312 InlineCacheHolderFlag cache_holder = |
313 IC::GetCodeCacheForObject(*receiver, *holder); | 313 IC::GetCodeCacheForObject(*receiver, *holder); |
314 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 314 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
315 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, | 315 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, |
316 Code::CONSTANT_FUNCTION); | 316 Code::CONSTANT_FUNCTION); |
317 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), | 317 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), |
318 isolate_); | 318 isolate_); |
319 if (probe->IsCode()) return Handle<Code>::cast(probe); | 319 if (probe->IsCode()) return Handle<Code>::cast(probe); |
320 | 320 |
321 KeyedLoadStubCompiler compiler(isolate_); | 321 KeyedLoadStubCompiler compiler(isolate_); |
322 Handle<Code> code = | 322 Handle<Code> code = |
323 compiler.CompileLoadConstant(receiver, holder, name, value); | 323 compiler.CompileLoadConstant(receiver, holder, name, value); |
324 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); | 324 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
325 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); | 325 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
326 JSObject::UpdateMapCodeCache(map_holder, name, code); | 326 JSObject::UpdateMapCodeCache(map_holder, name, code); |
327 return code; | 327 return code; |
328 } | 328 } |
329 | 329 |
330 | 330 |
331 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name, | 331 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name, |
332 Handle<JSObject> receiver, | 332 Handle<JSObject> receiver, |
333 Handle<JSObject> holder) { | 333 Handle<JSObject> holder) { |
334 InlineCacheHolderFlag cache_holder = | 334 InlineCacheHolderFlag cache_holder = |
335 IC::GetCodeCacheForObject(*receiver, *holder); | 335 IC::GetCodeCacheForObject(*receiver, *holder); |
336 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 336 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
337 Code::Flags flags = | 337 Code::Flags flags = |
338 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::INTERCEPTOR); | 338 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::INTERCEPTOR); |
339 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), | 339 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), |
340 isolate_); | 340 isolate_); |
341 if (probe->IsCode()) return Handle<Code>::cast(probe); | 341 if (probe->IsCode()) return Handle<Code>::cast(probe); |
342 | 342 |
343 KeyedLoadStubCompiler compiler(isolate_); | 343 KeyedLoadStubCompiler compiler(isolate_); |
344 Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name); | 344 Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name); |
345 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); | 345 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
346 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); | 346 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
347 JSObject::UpdateMapCodeCache(map_holder, name, code); | 347 JSObject::UpdateMapCodeCache(map_holder, name, code); |
348 return code; | 348 return code; |
349 } | 349 } |
350 | 350 |
351 | 351 |
352 Handle<Code> StubCache::ComputeKeyedLoadCallback( | 352 Handle<Code> StubCache::ComputeKeyedLoadCallback( |
353 Handle<String> name, | 353 Handle<Name> name, |
354 Handle<JSObject> receiver, | 354 Handle<JSObject> receiver, |
355 Handle<JSObject> holder, | 355 Handle<JSObject> holder, |
356 Handle<AccessorInfo> callback) { | 356 Handle<AccessorInfo> callback) { |
357 InlineCacheHolderFlag cache_holder = | 357 InlineCacheHolderFlag cache_holder = |
358 IC::GetCodeCacheForObject(*receiver, *holder); | 358 IC::GetCodeCacheForObject(*receiver, *holder); |
359 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 359 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
360 Code::Flags flags = | 360 Code::Flags flags = |
361 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS); | 361 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS); |
362 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), | 362 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), |
363 isolate_); | 363 isolate_); |
364 if (probe->IsCode()) return Handle<Code>::cast(probe); | 364 if (probe->IsCode()) return Handle<Code>::cast(probe); |
365 | 365 |
366 KeyedLoadStubCompiler compiler(isolate_); | 366 KeyedLoadStubCompiler compiler(isolate_); |
367 Handle<Code> code = | 367 Handle<Code> code = |
368 compiler.CompileLoadCallback(receiver, holder, name, callback); | 368 compiler.CompileLoadCallback(receiver, holder, name, callback); |
369 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); | 369 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
370 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); | 370 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
371 JSObject::UpdateMapCodeCache(map_holder, name, code); | 371 JSObject::UpdateMapCodeCache(map_holder, name, code); |
372 return code; | 372 return code; |
373 } | 373 } |
374 | 374 |
375 | 375 |
376 Handle<Code> StubCache::ComputeStoreField(Handle<String> name, | 376 Handle<Code> StubCache::ComputeStoreField(Handle<Name> name, |
377 Handle<JSObject> receiver, | 377 Handle<JSObject> receiver, |
378 int field_index, | 378 int field_index, |
379 Handle<Map> transition, | 379 Handle<Map> transition, |
380 StrictModeFlag strict_mode) { | 380 StrictModeFlag strict_mode) { |
381 Code::StubType type = | 381 Code::StubType type = |
382 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION; | 382 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION; |
383 Code::Flags flags = Code::ComputeMonomorphicFlags( | 383 Code::Flags flags = Code::ComputeMonomorphicFlags( |
384 Code::STORE_IC, type, strict_mode); | 384 Code::STORE_IC, type, strict_mode); |
385 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 385 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
386 isolate_); | 386 isolate_); |
387 if (probe->IsCode()) return Handle<Code>::cast(probe); | 387 if (probe->IsCode()) return Handle<Code>::cast(probe); |
388 | 388 |
389 StoreStubCompiler compiler(isolate_, strict_mode); | 389 StoreStubCompiler compiler(isolate_, strict_mode); |
390 Handle<Code> code = | 390 Handle<Code> code = |
391 compiler.CompileStoreField(receiver, field_index, transition, name); | 391 compiler.CompileStoreField(receiver, field_index, transition, name); |
392 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); | 392 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
393 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); | 393 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
394 JSObject::UpdateMapCodeCache(receiver, name, code); | 394 JSObject::UpdateMapCodeCache(receiver, name, code); |
395 return code; | 395 return code; |
396 } | 396 } |
397 | 397 |
398 | 398 |
399 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { | 399 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { |
400 Code::Flags flags = | 400 Code::Flags flags = |
401 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::NORMAL); | 401 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::NORMAL); |
402 Handle<String> name = | 402 Handle<Name> name = |
403 isolate()->factory()->KeyedLoadElementMonomorphic_string(); | 403 isolate()->factory()->KeyedLoadElementMonomorphic_string(); |
404 | 404 |
405 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); | 405 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); |
406 if (probe->IsCode()) return Handle<Code>::cast(probe); | 406 if (probe->IsCode()) return Handle<Code>::cast(probe); |
407 | 407 |
408 KeyedLoadStubCompiler compiler(isolate()); | 408 KeyedLoadStubCompiler compiler(isolate()); |
409 Handle<Code> code = compiler.CompileLoadElement(receiver_map); | 409 Handle<Code> code = compiler.CompileLoadElement(receiver_map); |
410 | 410 |
411 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0)); | 411 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0)); |
412 Map::UpdateCodeCache(receiver_map, name, code); | 412 Map::UpdateCodeCache(receiver_map, name, code); |
413 return code; | 413 return code; |
414 } | 414 } |
415 | 415 |
416 | 416 |
417 Handle<Code> StubCache::ComputeKeyedStoreElement( | 417 Handle<Code> StubCache::ComputeKeyedStoreElement( |
418 Handle<Map> receiver_map, | 418 Handle<Map> receiver_map, |
419 KeyedStoreIC::StubKind stub_kind, | 419 KeyedStoreIC::StubKind stub_kind, |
420 StrictModeFlag strict_mode, | 420 StrictModeFlag strict_mode, |
421 KeyedAccessGrowMode grow_mode) { | 421 KeyedAccessGrowMode grow_mode) { |
422 Code::ExtraICState extra_state = | 422 Code::ExtraICState extra_state = |
423 Code::ComputeExtraICState(grow_mode, strict_mode); | 423 Code::ComputeExtraICState(grow_mode, strict_mode); |
424 Code::Flags flags = Code::ComputeMonomorphicFlags( | 424 Code::Flags flags = Code::ComputeMonomorphicFlags( |
425 Code::KEYED_STORE_IC, Code::NORMAL, extra_state); | 425 Code::KEYED_STORE_IC, Code::NORMAL, extra_state); |
426 | 426 |
427 ASSERT(stub_kind == KeyedStoreIC::STORE_NO_TRANSITION || | 427 ASSERT(stub_kind == KeyedStoreIC::STORE_NO_TRANSITION || |
428 stub_kind == KeyedStoreIC::STORE_AND_GROW_NO_TRANSITION); | 428 stub_kind == KeyedStoreIC::STORE_AND_GROW_NO_TRANSITION); |
429 | 429 |
430 Handle<String> name = stub_kind == KeyedStoreIC::STORE_NO_TRANSITION | 430 Handle<Name> name = stub_kind == KeyedStoreIC::STORE_NO_TRANSITION |
431 ? isolate()->factory()->KeyedStoreElementMonomorphic_string() | 431 ? isolate()->factory()->KeyedStoreElementMonomorphic_string() |
432 : isolate()->factory()->KeyedStoreAndGrowElementMonomorphic_string(); | 432 : isolate()->factory()->KeyedStoreAndGrowElementMonomorphic_string(); |
433 | 433 |
434 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); | 434 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); |
435 if (probe->IsCode()) return Handle<Code>::cast(probe); | 435 if (probe->IsCode()) return Handle<Code>::cast(probe); |
436 | 436 |
437 KeyedStoreStubCompiler compiler(isolate(), strict_mode, grow_mode); | 437 KeyedStoreStubCompiler compiler(isolate(), strict_mode, grow_mode); |
438 Handle<Code> code = compiler.CompileStoreElement(receiver_map); | 438 Handle<Code> code = compiler.CompileStoreElement(receiver_map); |
439 | 439 |
440 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0)); | 440 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0)); |
441 Map::UpdateCodeCache(receiver_map, name, code); | 441 Map::UpdateCodeCache(receiver_map, name, code); |
442 return code; | 442 return code; |
443 } | 443 } |
444 | 444 |
445 | 445 |
446 Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) { | 446 Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) { |
447 return (strict_mode == kStrictMode) | 447 return (strict_mode == kStrictMode) |
448 ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict() | 448 ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict() |
449 : isolate_->builtins()->Builtins::StoreIC_Normal(); | 449 : isolate_->builtins()->Builtins::StoreIC_Normal(); |
450 } | 450 } |
451 | 451 |
452 | 452 |
453 Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name, | 453 Handle<Code> StubCache::ComputeStoreGlobal(Handle<Name> name, |
454 Handle<GlobalObject> receiver, | 454 Handle<GlobalObject> receiver, |
455 Handle<JSGlobalPropertyCell> cell, | 455 Handle<JSGlobalPropertyCell> cell, |
456 StrictModeFlag strict_mode) { | 456 StrictModeFlag strict_mode) { |
457 Code::Flags flags = Code::ComputeMonomorphicFlags( | 457 Code::Flags flags = Code::ComputeMonomorphicFlags( |
458 Code::STORE_IC, Code::NORMAL, strict_mode); | 458 Code::STORE_IC, Code::NORMAL, strict_mode); |
459 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 459 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
460 isolate_); | 460 isolate_); |
461 if (probe->IsCode()) return Handle<Code>::cast(probe); | 461 if (probe->IsCode()) return Handle<Code>::cast(probe); |
462 | 462 |
463 StoreStubCompiler compiler(isolate_, strict_mode); | 463 StoreStubCompiler compiler(isolate_, strict_mode); |
464 Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name); | 464 Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name); |
465 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); | 465 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
466 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); | 466 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
467 JSObject::UpdateMapCodeCache(receiver, name, code); | 467 JSObject::UpdateMapCodeCache(receiver, name, code); |
468 return code; | 468 return code; |
469 } | 469 } |
470 | 470 |
471 | 471 |
472 Handle<Code> StubCache::ComputeStoreCallback(Handle<String> name, | 472 Handle<Code> StubCache::ComputeStoreCallback(Handle<Name> name, |
473 Handle<JSObject> receiver, | 473 Handle<JSObject> receiver, |
474 Handle<JSObject> holder, | 474 Handle<JSObject> holder, |
475 Handle<AccessorInfo> callback, | 475 Handle<AccessorInfo> callback, |
476 StrictModeFlag strict_mode) { | 476 StrictModeFlag strict_mode) { |
477 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); | 477 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); |
478 Code::Flags flags = Code::ComputeMonomorphicFlags( | 478 Code::Flags flags = Code::ComputeMonomorphicFlags( |
479 Code::STORE_IC, Code::CALLBACKS, strict_mode); | 479 Code::STORE_IC, Code::CALLBACKS, strict_mode); |
480 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 480 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
481 isolate_); | 481 isolate_); |
482 if (probe->IsCode()) return Handle<Code>::cast(probe); | 482 if (probe->IsCode()) return Handle<Code>::cast(probe); |
483 | 483 |
484 StoreStubCompiler compiler(isolate_, strict_mode); | 484 StoreStubCompiler compiler(isolate_, strict_mode); |
485 Handle<Code> code = | 485 Handle<Code> code = |
486 compiler.CompileStoreCallback(name, receiver, holder, callback); | 486 compiler.CompileStoreCallback(name, receiver, holder, callback); |
487 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); | 487 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
488 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); | 488 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
489 JSObject::UpdateMapCodeCache(receiver, name, code); | 489 JSObject::UpdateMapCodeCache(receiver, name, code); |
490 return code; | 490 return code; |
491 } | 491 } |
492 | 492 |
493 | 493 |
494 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<String> name, | 494 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<Name> name, |
495 Handle<JSObject> receiver, | 495 Handle<JSObject> receiver, |
496 Handle<JSObject> holder, | 496 Handle<JSObject> holder, |
497 Handle<JSFunction> setter, | 497 Handle<JSFunction> setter, |
498 StrictModeFlag strict_mode) { | 498 StrictModeFlag strict_mode) { |
499 Code::Flags flags = Code::ComputeMonomorphicFlags( | 499 Code::Flags flags = Code::ComputeMonomorphicFlags( |
500 Code::STORE_IC, Code::CALLBACKS, strict_mode); | 500 Code::STORE_IC, Code::CALLBACKS, strict_mode); |
501 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 501 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
502 isolate_); | 502 isolate_); |
503 if (probe->IsCode()) return Handle<Code>::cast(probe); | 503 if (probe->IsCode()) return Handle<Code>::cast(probe); |
504 | 504 |
505 StoreStubCompiler compiler(isolate_, strict_mode); | 505 StoreStubCompiler compiler(isolate_, strict_mode); |
506 Handle<Code> code = | 506 Handle<Code> code = |
507 compiler.CompileStoreViaSetter(name, receiver, holder, setter); | 507 compiler.CompileStoreViaSetter(name, receiver, holder, setter); |
508 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); | 508 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
509 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); | 509 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
510 JSObject::UpdateMapCodeCache(receiver, name, code); | 510 JSObject::UpdateMapCodeCache(receiver, name, code); |
511 return code; | 511 return code; |
512 } | 512 } |
513 | 513 |
514 | 514 |
515 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name, | 515 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<Name> name, |
516 Handle<JSObject> receiver, | 516 Handle<JSObject> receiver, |
517 StrictModeFlag strict_mode) { | 517 StrictModeFlag strict_mode) { |
518 Code::Flags flags = Code::ComputeMonomorphicFlags( | 518 Code::Flags flags = Code::ComputeMonomorphicFlags( |
519 Code::STORE_IC, Code::INTERCEPTOR, strict_mode); | 519 Code::STORE_IC, Code::INTERCEPTOR, strict_mode); |
520 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 520 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
521 isolate_); | 521 isolate_); |
522 if (probe->IsCode()) return Handle<Code>::cast(probe); | 522 if (probe->IsCode()) return Handle<Code>::cast(probe); |
523 | 523 |
524 StoreStubCompiler compiler(isolate_, strict_mode); | 524 StoreStubCompiler compiler(isolate_, strict_mode); |
525 Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name); | 525 Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name); |
526 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); | 526 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
527 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); | 527 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
528 JSObject::UpdateMapCodeCache(receiver, name, code); | 528 JSObject::UpdateMapCodeCache(receiver, name, code); |
529 return code; | 529 return code; |
530 } | 530 } |
531 | 531 |
532 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name, | 532 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<Name> name, |
533 Handle<JSObject> receiver, | 533 Handle<JSObject> receiver, |
534 int field_index, | 534 int field_index, |
535 Handle<Map> transition, | 535 Handle<Map> transition, |
536 StrictModeFlag strict_mode) { | 536 StrictModeFlag strict_mode) { |
537 Code::StubType type = | 537 Code::StubType type = |
538 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION; | 538 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION; |
539 Code::Flags flags = Code::ComputeMonomorphicFlags( | 539 Code::Flags flags = Code::ComputeMonomorphicFlags( |
540 Code::KEYED_STORE_IC, type, strict_mode); | 540 Code::KEYED_STORE_IC, type, strict_mode); |
541 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 541 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
542 isolate_); | 542 isolate_); |
543 if (probe->IsCode()) return Handle<Code>::cast(probe); | 543 if (probe->IsCode()) return Handle<Code>::cast(probe); |
544 | 544 |
545 KeyedStoreStubCompiler compiler(isolate(), strict_mode, | 545 KeyedStoreStubCompiler compiler(isolate(), strict_mode, |
546 DO_NOT_ALLOW_JSARRAY_GROWTH); | 546 DO_NOT_ALLOW_JSARRAY_GROWTH); |
547 Handle<Code> code = | 547 Handle<Code> code = |
548 compiler.CompileStoreField(receiver, field_index, transition, name); | 548 compiler.CompileStoreField(receiver, field_index, transition, name); |
549 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); | 549 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); |
550 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); | 550 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); |
551 JSObject::UpdateMapCodeCache(receiver, name, code); | 551 JSObject::UpdateMapCodeCache(receiver, name, code); |
552 return code; | 552 return code; |
553 } | 553 } |
554 | 554 |
555 | 555 |
556 #define CALL_LOGGER_TAG(kind, type) \ | 556 #define CALL_LOGGER_TAG(kind, type) \ |
557 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) | 557 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) |
558 | 558 |
559 Handle<Code> StubCache::ComputeCallConstant(int argc, | 559 Handle<Code> StubCache::ComputeCallConstant(int argc, |
560 Code::Kind kind, | 560 Code::Kind kind, |
561 Code::ExtraICState extra_state, | 561 Code::ExtraICState extra_state, |
562 Handle<String> name, | 562 Handle<Name> name, |
563 Handle<Object> object, | 563 Handle<Object> object, |
564 Handle<JSObject> holder, | 564 Handle<JSObject> holder, |
565 Handle<JSFunction> function) { | 565 Handle<JSFunction> function) { |
566 // Compute the check type and the map. | 566 // Compute the check type and the map. |
567 InlineCacheHolderFlag cache_holder = | 567 InlineCacheHolderFlag cache_holder = |
568 IC::GetCodeCacheForObject(*object, *holder); | 568 IC::GetCodeCacheForObject(*object, *holder); |
569 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); | 569 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); |
570 | 570 |
571 // Compute check type based on receiver/holder. | 571 // Compute check type based on receiver/holder. |
572 CheckType check = RECEIVER_MAP_CHECK; | 572 CheckType check = RECEIVER_MAP_CHECK; |
(...skipping 23 matching lines...) Expand all Loading... |
596 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 596 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
597 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 597 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
598 JSObject::UpdateMapCodeCache(map_holder, name, code); | 598 JSObject::UpdateMapCodeCache(map_holder, name, code); |
599 return code; | 599 return code; |
600 } | 600 } |
601 | 601 |
602 | 602 |
603 Handle<Code> StubCache::ComputeCallField(int argc, | 603 Handle<Code> StubCache::ComputeCallField(int argc, |
604 Code::Kind kind, | 604 Code::Kind kind, |
605 Code::ExtraICState extra_state, | 605 Code::ExtraICState extra_state, |
606 Handle<String> name, | 606 Handle<Name> name, |
607 Handle<Object> object, | 607 Handle<Object> object, |
608 Handle<JSObject> holder, | 608 Handle<JSObject> holder, |
609 PropertyIndex index) { | 609 PropertyIndex index) { |
610 // Compute the check type and the map. | 610 // Compute the check type and the map. |
611 InlineCacheHolderFlag cache_holder = | 611 InlineCacheHolderFlag cache_holder = |
612 IC::GetCodeCacheForObject(*object, *holder); | 612 IC::GetCodeCacheForObject(*object, *holder); |
613 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); | 613 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); |
614 | 614 |
615 // TODO(1233596): We cannot do receiver map check for non-JS objects | 615 // TODO(1233596): We cannot do receiver map check for non-JS objects |
616 // because they may be represented as immediates without a | 616 // because they may be represented as immediates without a |
(...skipping 19 matching lines...) Expand all Loading... |
636 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 636 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
637 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 637 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
638 JSObject::UpdateMapCodeCache(map_holder, name, code); | 638 JSObject::UpdateMapCodeCache(map_holder, name, code); |
639 return code; | 639 return code; |
640 } | 640 } |
641 | 641 |
642 | 642 |
643 Handle<Code> StubCache::ComputeCallInterceptor(int argc, | 643 Handle<Code> StubCache::ComputeCallInterceptor(int argc, |
644 Code::Kind kind, | 644 Code::Kind kind, |
645 Code::ExtraICState extra_state, | 645 Code::ExtraICState extra_state, |
646 Handle<String> name, | 646 Handle<Name> name, |
647 Handle<Object> object, | 647 Handle<Object> object, |
648 Handle<JSObject> holder) { | 648 Handle<JSObject> holder) { |
649 // Compute the check type and the map. | 649 // Compute the check type and the map. |
650 InlineCacheHolderFlag cache_holder = | 650 InlineCacheHolderFlag cache_holder = |
651 IC::GetCodeCacheForObject(*object, *holder); | 651 IC::GetCodeCacheForObject(*object, *holder); |
652 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); | 652 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); |
653 | 653 |
654 // TODO(1233596): We cannot do receiver map check for non-JS objects | 654 // TODO(1233596): We cannot do receiver map check for non-JS objects |
655 // because they may be represented as immediates without a | 655 // because they may be represented as immediates without a |
656 // map. Instead, we check against the map in the holder. | 656 // map. Instead, we check against the map in the holder. |
(...skipping 18 matching lines...) Expand all Loading... |
675 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 675 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
676 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 676 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
677 JSObject::UpdateMapCodeCache(map_holder, name, code); | 677 JSObject::UpdateMapCodeCache(map_holder, name, code); |
678 return code; | 678 return code; |
679 } | 679 } |
680 | 680 |
681 | 681 |
682 Handle<Code> StubCache::ComputeCallGlobal(int argc, | 682 Handle<Code> StubCache::ComputeCallGlobal(int argc, |
683 Code::Kind kind, | 683 Code::Kind kind, |
684 Code::ExtraICState extra_state, | 684 Code::ExtraICState extra_state, |
685 Handle<String> name, | 685 Handle<Name> name, |
686 Handle<JSObject> receiver, | 686 Handle<JSObject> receiver, |
687 Handle<GlobalObject> holder, | 687 Handle<GlobalObject> holder, |
688 Handle<JSGlobalPropertyCell> cell, | 688 Handle<JSGlobalPropertyCell> cell, |
689 Handle<JSFunction> function) { | 689 Handle<JSFunction> function) { |
690 InlineCacheHolderFlag cache_holder = | 690 InlineCacheHolderFlag cache_holder = |
691 IC::GetCodeCacheForObject(*receiver, *holder); | 691 IC::GetCodeCacheForObject(*receiver, *holder); |
692 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); | 692 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
693 Code::Flags flags = | 693 Code::Flags flags = |
694 Code::ComputeMonomorphicFlags(kind, Code::NORMAL, extra_state, | 694 Code::ComputeMonomorphicFlags(kind, Code::NORMAL, extra_state, |
695 cache_holder, argc); | 695 cache_holder, argc); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 primary_[i].value = empty; | 940 primary_[i].value = empty; |
941 } | 941 } |
942 for (int j = 0; j < kSecondaryTableSize; j++) { | 942 for (int j = 0; j < kSecondaryTableSize; j++) { |
943 secondary_[j].key = heap()->empty_string(); | 943 secondary_[j].key = heap()->empty_string(); |
944 secondary_[j].value = empty; | 944 secondary_[j].value = empty; |
945 } | 945 } |
946 } | 946 } |
947 | 947 |
948 | 948 |
949 void StubCache::CollectMatchingMaps(SmallMapList* types, | 949 void StubCache::CollectMatchingMaps(SmallMapList* types, |
950 String* name, | 950 Name* name, |
951 Code::Flags flags, | 951 Code::Flags flags, |
952 Handle<Context> native_context, | 952 Handle<Context> native_context, |
953 Zone* zone) { | 953 Zone* zone) { |
954 for (int i = 0; i < kPrimaryTableSize; i++) { | 954 for (int i = 0; i < kPrimaryTableSize; i++) { |
955 if (primary_[i].key == name) { | 955 if (primary_[i].key == name) { |
956 Map* map = primary_[i].value->FindFirstMap(); | 956 Map* map = primary_[i].value->FindFirstMap(); |
957 // Map can be NULL, if the stub is constant function call | 957 // Map can be NULL, if the stub is constant function call |
958 // with a primitive receiver. | 958 // with a primitive receiver. |
959 if (map == NULL) continue; | 959 if (map == NULL) continue; |
960 | 960 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 } | 1022 } |
1023 | 1023 |
1024 | 1024 |
1025 RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) { | 1025 RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) { |
1026 JSObject* recv = JSObject::cast(args[0]); | 1026 JSObject* recv = JSObject::cast(args[0]); |
1027 AccessorInfo* callback = AccessorInfo::cast(args[1]); | 1027 AccessorInfo* callback = AccessorInfo::cast(args[1]); |
1028 Address setter_address = v8::ToCData<Address>(callback->setter()); | 1028 Address setter_address = v8::ToCData<Address>(callback->setter()); |
1029 v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address); | 1029 v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address); |
1030 ASSERT(fun != NULL); | 1030 ASSERT(fun != NULL); |
1031 ASSERT(callback->IsCompatibleReceiver(recv)); | 1031 ASSERT(callback->IsCompatibleReceiver(recv)); |
1032 Handle<String> name = args.at<String>(2); | 1032 Handle<Name> name = args.at<Name>(2); |
1033 Handle<Object> value = args.at<Object>(3); | 1033 Handle<Object> value = args.at<Object>(3); |
1034 HandleScope scope(isolate); | 1034 HandleScope scope(isolate); |
| 1035 |
| 1036 // TODO(rossberg): Support symbols in the API. |
| 1037 if (name->IsSymbol()) return *value; |
| 1038 Handle<String> str = Handle<String>::cast(name); |
| 1039 |
1035 LOG(isolate, ApiNamedPropertyAccess("store", recv, *name)); | 1040 LOG(isolate, ApiNamedPropertyAccess("store", recv, *name)); |
1036 CustomArguments custom_args(isolate, callback->data(), recv, recv); | 1041 CustomArguments custom_args(isolate, callback->data(), recv, recv); |
1037 v8::AccessorInfo info(custom_args.end()); | 1042 v8::AccessorInfo info(custom_args.end()); |
1038 { | 1043 { |
1039 // Leaving JavaScript. | 1044 // Leaving JavaScript. |
1040 VMState state(isolate, EXTERNAL); | 1045 VMState state(isolate, EXTERNAL); |
1041 ExternalCallbackScope call_scope(isolate, setter_address); | 1046 ExternalCallbackScope call_scope(isolate, setter_address); |
1042 fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info); | 1047 fun(v8::Utils::ToLocal(str), v8::Utils::ToLocal(value), info); |
1043 } | 1048 } |
1044 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1049 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1045 return *value; | 1050 return *value; |
1046 } | 1051 } |
1047 | 1052 |
1048 | 1053 |
1049 static const int kAccessorInfoOffsetInInterceptorArgs = 2; | 1054 static const int kAccessorInfoOffsetInInterceptorArgs = 2; |
1050 | 1055 |
1051 | 1056 |
1052 /** | 1057 /** |
1053 * Attempts to load a property with an interceptor (which must be present), | 1058 * Attempts to load a property with an interceptor (which must be present), |
1054 * but doesn't search the prototype chain. | 1059 * but doesn't search the prototype chain. |
1055 * | 1060 * |
1056 * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't | 1061 * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't |
1057 * provide any value for the given name. | 1062 * provide any value for the given name. |
1058 */ | 1063 */ |
1059 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) { | 1064 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) { |
1060 Handle<String> name_handle = args.at<String>(0); | 1065 Handle<Name> name_handle = args.at<Name>(0); |
1061 Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(1); | 1066 Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(1); |
1062 ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); | 1067 ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); |
1063 ASSERT(args[2]->IsJSObject()); // Receiver. | 1068 ASSERT(args[2]->IsJSObject()); // Receiver. |
1064 ASSERT(args[3]->IsJSObject()); // Holder. | 1069 ASSERT(args[3]->IsJSObject()); // Holder. |
1065 ASSERT(args[5]->IsSmi()); // Isolate. | 1070 ASSERT(args[5]->IsSmi()); // Isolate. |
1066 ASSERT(args.length() == 6); | 1071 ASSERT(args.length() == 6); |
1067 | 1072 |
| 1073 // TODO(rossberg): Support symbols in the API. |
| 1074 if (name_handle->IsSymbol()) |
| 1075 return isolate->heap()->no_interceptor_result_sentinel(); |
| 1076 Handle<String> name = Handle<String>::cast(name_handle); |
| 1077 |
1068 Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); | 1078 Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); |
1069 v8::NamedPropertyGetter getter = | 1079 v8::NamedPropertyGetter getter = |
1070 FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address); | 1080 FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address); |
1071 ASSERT(getter != NULL); | 1081 ASSERT(getter != NULL); |
1072 | 1082 |
1073 { | 1083 { |
1074 // Use the interceptor getter. | 1084 // Use the interceptor getter. |
1075 v8::AccessorInfo info(args.arguments() - | 1085 v8::AccessorInfo info(args.arguments() - |
1076 kAccessorInfoOffsetInInterceptorArgs); | 1086 kAccessorInfoOffsetInInterceptorArgs); |
1077 HandleScope scope(isolate); | 1087 HandleScope scope(isolate); |
1078 v8::Handle<v8::Value> r; | 1088 v8::Handle<v8::Value> r; |
1079 { | 1089 { |
1080 // Leaving JavaScript. | 1090 // Leaving JavaScript. |
1081 VMState state(isolate, EXTERNAL); | 1091 VMState state(isolate, EXTERNAL); |
1082 r = getter(v8::Utils::ToLocal(name_handle), info); | 1092 r = getter(v8::Utils::ToLocal(name), info); |
1083 } | 1093 } |
1084 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1094 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1085 if (!r.IsEmpty()) { | 1095 if (!r.IsEmpty()) { |
1086 Handle<Object> result = v8::Utils::OpenHandle(*r); | 1096 Handle<Object> result = v8::Utils::OpenHandle(*r); |
1087 result->VerifyApiCallResultType(); | 1097 result->VerifyApiCallResultType(); |
1088 return *v8::Utils::OpenHandle(*r); | 1098 return *v8::Utils::OpenHandle(*r); |
1089 } | 1099 } |
1090 } | 1100 } |
1091 | 1101 |
1092 return isolate->heap()->no_interceptor_result_sentinel(); | 1102 return isolate->heap()->no_interceptor_result_sentinel(); |
1093 } | 1103 } |
1094 | 1104 |
1095 | 1105 |
1096 static MaybeObject* ThrowReferenceError(String* name) { | 1106 static MaybeObject* ThrowReferenceError(Name* name) { |
1097 // If the load is non-contextual, just return the undefined result. | 1107 // If the load is non-contextual, just return the undefined result. |
1098 // Note that both keyed and non-keyed loads may end up here, so we | 1108 // Note that both keyed and non-keyed loads may end up here, so we |
1099 // can't use either LoadIC or KeyedLoadIC constructors. | 1109 // can't use either LoadIC or KeyedLoadIC constructors. |
1100 IC ic(IC::NO_EXTRA_FRAME, Isolate::Current()); | 1110 IC ic(IC::NO_EXTRA_FRAME, Isolate::Current()); |
1101 ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub()); | 1111 ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub()); |
1102 if (!ic.SlowIsUndeclaredGlobal()) return HEAP->undefined_value(); | 1112 if (!ic.SlowIsUndeclaredGlobal()) return HEAP->undefined_value(); |
1103 | 1113 |
1104 // Throw a reference error. | 1114 // Throw a reference error. |
1105 HandleScope scope; | 1115 HandleScope scope; |
1106 Handle<String> name_handle(name); | 1116 Handle<Name> name_handle(name); |
1107 Handle<Object> error = | 1117 Handle<Object> error = |
1108 FACTORY->NewReferenceError("not_defined", | 1118 FACTORY->NewReferenceError("not_defined", |
1109 HandleVector(&name_handle, 1)); | 1119 HandleVector(&name_handle, 1)); |
1110 return Isolate::Current()->Throw(*error); | 1120 return Isolate::Current()->Throw(*error); |
1111 } | 1121 } |
1112 | 1122 |
1113 | 1123 |
1114 static MaybeObject* LoadWithInterceptor(Arguments* args, | 1124 static MaybeObject* LoadWithInterceptor(Arguments* args, |
1115 PropertyAttributes* attrs) { | 1125 PropertyAttributes* attrs) { |
1116 Handle<String> name_handle = args->at<String>(0); | 1126 Handle<Name> name_handle = args->at<Name>(0); |
1117 Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1); | 1127 Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1); |
1118 ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); | 1128 ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); |
1119 Handle<JSObject> receiver_handle = args->at<JSObject>(2); | 1129 Handle<JSObject> receiver_handle = args->at<JSObject>(2); |
1120 Handle<JSObject> holder_handle = args->at<JSObject>(3); | 1130 Handle<JSObject> holder_handle = args->at<JSObject>(3); |
1121 ASSERT(args->length() == 6); | 1131 ASSERT(args->length() == 6); |
1122 | 1132 |
1123 Isolate* isolate = receiver_handle->GetIsolate(); | 1133 Isolate* isolate = receiver_handle->GetIsolate(); |
1124 | 1134 |
| 1135 // TODO(rossberg): Support symbols in the API. |
| 1136 if (name_handle->IsSymbol()) |
| 1137 return holder_handle->GetPropertyPostInterceptor( |
| 1138 *receiver_handle, *name_handle, attrs); |
| 1139 Handle<String> name = Handle<String>::cast(name_handle); |
| 1140 |
1125 Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); | 1141 Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); |
1126 v8::NamedPropertyGetter getter = | 1142 v8::NamedPropertyGetter getter = |
1127 FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address); | 1143 FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address); |
1128 ASSERT(getter != NULL); | 1144 ASSERT(getter != NULL); |
1129 | 1145 |
1130 { | 1146 { |
1131 // Use the interceptor getter. | 1147 // Use the interceptor getter. |
1132 v8::AccessorInfo info(args->arguments() - | 1148 v8::AccessorInfo info(args->arguments() - |
1133 kAccessorInfoOffsetInInterceptorArgs); | 1149 kAccessorInfoOffsetInInterceptorArgs); |
1134 HandleScope scope(isolate); | 1150 HandleScope scope(isolate); |
1135 v8::Handle<v8::Value> r; | 1151 v8::Handle<v8::Value> r; |
1136 { | 1152 { |
1137 // Leaving JavaScript. | 1153 // Leaving JavaScript. |
1138 VMState state(isolate, EXTERNAL); | 1154 VMState state(isolate, EXTERNAL); |
1139 r = getter(v8::Utils::ToLocal(name_handle), info); | 1155 r = getter(v8::Utils::ToLocal(name), info); |
1140 } | 1156 } |
1141 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1157 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1142 if (!r.IsEmpty()) { | 1158 if (!r.IsEmpty()) { |
1143 *attrs = NONE; | 1159 *attrs = NONE; |
1144 Handle<Object> result = v8::Utils::OpenHandle(*r); | 1160 Handle<Object> result = v8::Utils::OpenHandle(*r); |
1145 result->VerifyApiCallResultType(); | 1161 result->VerifyApiCallResultType(); |
1146 return *result; | 1162 return *result; |
1147 } | 1163 } |
1148 } | 1164 } |
1149 | 1165 |
(...skipping 12 matching lines...) Expand all Loading... |
1162 */ | 1178 */ |
1163 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) { | 1179 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) { |
1164 PropertyAttributes attr = NONE; | 1180 PropertyAttributes attr = NONE; |
1165 Object* result; | 1181 Object* result; |
1166 { MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr); | 1182 { MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr); |
1167 if (!maybe_result->ToObject(&result)) return maybe_result; | 1183 if (!maybe_result->ToObject(&result)) return maybe_result; |
1168 } | 1184 } |
1169 | 1185 |
1170 // If the property is present, return it. | 1186 // If the property is present, return it. |
1171 if (attr != ABSENT) return result; | 1187 if (attr != ABSENT) return result; |
1172 return ThrowReferenceError(String::cast(args[0])); | 1188 return ThrowReferenceError(Name::cast(args[0])); |
1173 } | 1189 } |
1174 | 1190 |
1175 | 1191 |
1176 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) { | 1192 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) { |
1177 PropertyAttributes attr; | 1193 PropertyAttributes attr; |
1178 MaybeObject* result = LoadWithInterceptor(&args, &attr); | 1194 MaybeObject* result = LoadWithInterceptor(&args, &attr); |
1179 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1195 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1180 // This is call IC. In this case, we simply return the undefined result which | 1196 // This is call IC. In this case, we simply return the undefined result which |
1181 // will lead to an exception when trying to invoke the result as a | 1197 // will lead to an exception when trying to invoke the result as a |
1182 // function. | 1198 // function. |
1183 return result; | 1199 return result; |
1184 } | 1200 } |
1185 | 1201 |
1186 | 1202 |
1187 RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { | 1203 RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { |
1188 ASSERT(args.length() == 4); | 1204 ASSERT(args.length() == 4); |
1189 JSObject* recv = JSObject::cast(args[0]); | 1205 JSObject* recv = JSObject::cast(args[0]); |
1190 String* name = String::cast(args[1]); | 1206 Name* name = Name::cast(args[1]); |
1191 Object* value = args[2]; | 1207 Object* value = args[2]; |
1192 ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode); | 1208 ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode); |
1193 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3)); | 1209 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3)); |
1194 ASSERT(recv->HasNamedInterceptor()); | 1210 ASSERT(recv->HasNamedInterceptor()); |
1195 PropertyAttributes attr = NONE; | 1211 PropertyAttributes attr = NONE; |
1196 MaybeObject* result = recv->SetPropertyWithInterceptor( | 1212 MaybeObject* result = recv->SetPropertyWithInterceptor( |
1197 name, value, attr, strict_mode); | 1213 name, value, attr, strict_mode); |
1198 return result; | 1214 return result; |
1199 } | 1215 } |
1200 | 1216 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1362 masm_.GetCode(&desc); | 1378 masm_.GetCode(&desc); |
1363 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject()); | 1379 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject()); |
1364 #ifdef ENABLE_DISASSEMBLER | 1380 #ifdef ENABLE_DISASSEMBLER |
1365 if (FLAG_print_code_stubs) code->Disassemble(name); | 1381 if (FLAG_print_code_stubs) code->Disassemble(name); |
1366 #endif | 1382 #endif |
1367 return code; | 1383 return code; |
1368 } | 1384 } |
1369 | 1385 |
1370 | 1386 |
1371 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, | 1387 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, |
1372 Handle<String> name) { | 1388 Handle<Name> name) { |
1373 return (FLAG_print_code_stubs && !name.is_null()) | 1389 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) |
1374 ? GetCodeWithFlags(flags, *name->ToCString()) | 1390 ? GetCodeWithFlags(flags, *Handle<String>::cast(name)->ToCString()) |
1375 : GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL)); | 1391 : GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL)); |
1376 } | 1392 } |
1377 | 1393 |
1378 | 1394 |
1379 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder, | 1395 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder, |
1380 Handle<String> name, | 1396 Handle<Name> name, |
1381 LookupResult* lookup) { | 1397 LookupResult* lookup) { |
1382 holder->LocalLookupRealNamedProperty(*name, lookup); | 1398 holder->LocalLookupRealNamedProperty(*name, lookup); |
1383 if (lookup->IsFound()) return; | 1399 if (lookup->IsFound()) return; |
1384 if (holder->GetPrototype()->IsNull()) return; | 1400 if (holder->GetPrototype()->IsNull()) return; |
1385 holder->GetPrototype()->Lookup(*name, lookup); | 1401 holder->GetPrototype()->Lookup(*name, lookup); |
1386 } | 1402 } |
1387 | 1403 |
1388 | 1404 |
1389 #define __ ACCESS_MASM(masm()) | 1405 #define __ ACCESS_MASM(masm()) |
1390 | 1406 |
1391 | 1407 |
1392 Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object, | 1408 Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object, |
1393 Handle<JSObject> holder, | 1409 Handle<JSObject> holder, |
1394 Handle<String> name, | 1410 Handle<Name> name, |
1395 PropertyIndex index) { | 1411 PropertyIndex index) { |
1396 Label miss; | 1412 Label miss; |
1397 | 1413 |
1398 GenerateNameCheck(name, this->name(), &miss); | 1414 GenerateNameCheck(name, this->name(), &miss); |
1399 GenerateLoadField(object, holder, receiver(), | 1415 GenerateLoadField(object, holder, receiver(), |
1400 scratch1(), scratch2(), scratch3(), | 1416 scratch1(), scratch2(), scratch3(), |
1401 index, name, &miss); | 1417 index, name, &miss); |
1402 __ bind(&miss); | 1418 __ bind(&miss); |
1403 GenerateLoadMiss(masm(), kind()); | 1419 GenerateLoadMiss(masm(), kind()); |
1404 | 1420 |
1405 // Return the generated code. | 1421 // Return the generated code. |
1406 return GetCode(Code::FIELD, name); | 1422 return GetCode(Code::FIELD, name); |
1407 } | 1423 } |
1408 | 1424 |
1409 | 1425 |
1410 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( | 1426 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( |
1411 Handle<JSObject> object, | 1427 Handle<JSObject> object, |
1412 Handle<JSObject> holder, | 1428 Handle<JSObject> holder, |
1413 Handle<String> name, | 1429 Handle<Name> name, |
1414 Handle<AccessorInfo> callback) { | 1430 Handle<AccessorInfo> callback) { |
1415 Label miss; | 1431 Label miss; |
1416 | 1432 |
1417 GenerateNameCheck(name, this->name(), &miss); | 1433 GenerateNameCheck(name, this->name(), &miss); |
1418 GenerateLoadCallback(object, holder, receiver(), this->name(), | 1434 GenerateLoadCallback(object, holder, receiver(), this->name(), |
1419 scratch1(), scratch2(), scratch3(), scratch4(), | 1435 scratch1(), scratch2(), scratch3(), scratch4(), |
1420 callback, name, &miss); | 1436 callback, name, &miss); |
1421 __ bind(&miss); | 1437 __ bind(&miss); |
1422 GenerateLoadMiss(masm(), kind()); | 1438 GenerateLoadMiss(masm(), kind()); |
1423 | 1439 |
1424 // Return the generated code. | 1440 // Return the generated code. |
1425 return GetCode(Code::CALLBACKS, name); | 1441 return GetCode(Code::CALLBACKS, name); |
1426 } | 1442 } |
1427 | 1443 |
1428 | 1444 |
1429 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( | 1445 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( |
1430 Handle<JSObject> object, | 1446 Handle<JSObject> object, |
1431 Handle<JSObject> holder, | 1447 Handle<JSObject> holder, |
1432 Handle<String> name, | 1448 Handle<Name> name, |
1433 Handle<JSFunction> value) { | 1449 Handle<JSFunction> value) { |
1434 Label miss; | 1450 Label miss; |
1435 | 1451 |
1436 GenerateNameCheck(name, this->name(), &miss); | 1452 GenerateNameCheck(name, this->name(), &miss); |
1437 GenerateLoadConstant(object, holder, receiver(), | 1453 GenerateLoadConstant(object, holder, receiver(), |
1438 scratch1(), scratch2(), scratch3(), | 1454 scratch1(), scratch2(), scratch3(), |
1439 value, name, &miss); | 1455 value, name, &miss); |
1440 __ bind(&miss); | 1456 __ bind(&miss); |
1441 GenerateLoadMiss(masm(), kind()); | 1457 GenerateLoadMiss(masm(), kind()); |
1442 | 1458 |
1443 // Return the generated code. | 1459 // Return the generated code. |
1444 return GetCode(Code::CONSTANT_FUNCTION, name); | 1460 return GetCode(Code::CONSTANT_FUNCTION, name); |
1445 } | 1461 } |
1446 | 1462 |
1447 | 1463 |
1448 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( | 1464 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( |
1449 Handle<JSObject> object, | 1465 Handle<JSObject> object, |
1450 Handle<JSObject> holder, | 1466 Handle<JSObject> holder, |
1451 Handle<String> name) { | 1467 Handle<Name> name) { |
1452 Label miss; | 1468 Label miss; |
1453 | 1469 |
1454 LookupResult lookup(isolate()); | 1470 LookupResult lookup(isolate()); |
1455 LookupPostInterceptor(holder, name, &lookup); | 1471 LookupPostInterceptor(holder, name, &lookup); |
1456 | 1472 |
1457 GenerateNameCheck(name, this->name(), &miss); | 1473 GenerateNameCheck(name, this->name(), &miss); |
1458 // TODO(368): Compile in the whole chain: all the interceptors in | 1474 // TODO(368): Compile in the whole chain: all the interceptors in |
1459 // prototypes and ultimate answer. | 1475 // prototypes and ultimate answer. |
1460 GenerateLoadInterceptor(object, holder, &lookup, receiver(), this->name(), | 1476 GenerateLoadInterceptor(object, holder, &lookup, receiver(), this->name(), |
1461 scratch1(), scratch2(), scratch3(), | 1477 scratch1(), scratch2(), scratch3(), |
1462 name, &miss); | 1478 name, &miss); |
1463 | 1479 |
1464 __ bind(&miss); | 1480 __ bind(&miss); |
1465 GenerateLoadMiss(masm(), kind()); | 1481 GenerateLoadMiss(masm(), kind()); |
1466 | 1482 |
1467 // Return the generated code. | 1483 // Return the generated code. |
1468 return GetCode(Code::INTERCEPTOR, name); | 1484 return GetCode(Code::INTERCEPTOR, name); |
1469 } | 1485 } |
1470 | 1486 |
1471 | 1487 |
1472 #undef __ | 1488 #undef __ |
1473 | 1489 |
1474 | 1490 |
1475 Handle<Code> LoadStubCompiler::GetCode(Code::StubType type, | 1491 Handle<Code> LoadStubCompiler::GetCode(Code::StubType type, |
1476 Handle<String> name, | 1492 Handle<Name> name, |
1477 InlineCacheState state) { | 1493 InlineCacheState state) { |
1478 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); | 1494 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); |
1479 Handle<Code> code = GetCodeWithFlags(flags, name); | 1495 Handle<Code> code = GetCodeWithFlags(flags, name); |
1480 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 1496 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
1481 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 1497 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
1482 return code; | 1498 return code; |
1483 } | 1499 } |
1484 | 1500 |
1485 | 1501 |
1486 Handle<Code> KeyedLoadStubCompiler::GetCode(Code::StubType type, | 1502 Handle<Code> KeyedLoadStubCompiler::GetCode(Code::StubType type, |
1487 Handle<String> name, | 1503 Handle<Name> name, |
1488 InlineCacheState state) { | 1504 InlineCacheState state) { |
1489 Code::Flags flags = Code::ComputeFlags( | 1505 Code::Flags flags = Code::ComputeFlags( |
1490 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type); | 1506 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type); |
1491 Handle<Code> code = GetCodeWithFlags(flags, name); | 1507 Handle<Code> code = GetCodeWithFlags(flags, name); |
1492 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); | 1508 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
1493 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 1509 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
1494 return code; | 1510 return code; |
1495 } | 1511 } |
1496 | 1512 |
1497 | 1513 |
(...skipping 25 matching lines...) Expand all Loading... |
1523 Handle<Code> code = CompileLoadPolymorphic(receiver_maps, &handler_ics); | 1539 Handle<Code> code = CompileLoadPolymorphic(receiver_maps, &handler_ics); |
1524 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); | 1540 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); |
1525 PROFILE(isolate(), | 1541 PROFILE(isolate(), |
1526 CodeCreateEvent(Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG, *code, 0)); | 1542 CodeCreateEvent(Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG, *code, 0)); |
1527 return code; | 1543 return code; |
1528 } | 1544 } |
1529 | 1545 |
1530 | 1546 |
1531 | 1547 |
1532 Handle<Code> StoreStubCompiler::GetCode(Code::StubType type, | 1548 Handle<Code> StoreStubCompiler::GetCode(Code::StubType type, |
1533 Handle<String> name) { | 1549 Handle<Name> name) { |
1534 Code::Flags flags = | 1550 Code::Flags flags = |
1535 Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_); | 1551 Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_); |
1536 Handle<Code> code = GetCodeWithFlags(flags, name); | 1552 Handle<Code> code = GetCodeWithFlags(flags, name); |
1537 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); | 1553 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
1538 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); | 1554 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
1539 return code; | 1555 return code; |
1540 } | 1556 } |
1541 | 1557 |
1542 | 1558 |
1543 Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type, | 1559 Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type, |
1544 Handle<String> name, | 1560 Handle<Name> name, |
1545 InlineCacheState state) { | 1561 InlineCacheState state) { |
1546 Code::ExtraICState extra_state = | 1562 Code::ExtraICState extra_state = |
1547 Code::ComputeExtraICState(grow_mode_, strict_mode_); | 1563 Code::ComputeExtraICState(grow_mode_, strict_mode_); |
1548 Code::Flags flags = | 1564 Code::Flags flags = |
1549 Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type); | 1565 Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type); |
1550 Handle<Code> code = GetCodeWithFlags(flags, name); | 1566 Handle<Code> code = GetCodeWithFlags(flags, name); |
1551 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); | 1567 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); |
1552 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); | 1568 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); |
1553 return code; | 1569 return code; |
1554 } | 1570 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 return CompileFastApiCall(optimization, | 1672 return CompileFastApiCall(optimization, |
1657 object, | 1673 object, |
1658 holder, | 1674 holder, |
1659 cell, | 1675 cell, |
1660 function, | 1676 function, |
1661 fname); | 1677 fname); |
1662 } | 1678 } |
1663 | 1679 |
1664 | 1680 |
1665 Handle<Code> CallStubCompiler::GetCode(Code::StubType type, | 1681 Handle<Code> CallStubCompiler::GetCode(Code::StubType type, |
1666 Handle<String> name) { | 1682 Handle<Name> name) { |
1667 int argc = arguments_.immediate(); | 1683 int argc = arguments_.immediate(); |
1668 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, | 1684 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, |
1669 type, | 1685 type, |
1670 extra_state_, | 1686 extra_state_, |
1671 cache_holder_, | 1687 cache_holder_, |
1672 argc); | 1688 argc); |
1673 return GetCodeWithFlags(flags, name); | 1689 return GetCodeWithFlags(flags, name); |
1674 } | 1690 } |
1675 | 1691 |
1676 | 1692 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1758 Handle<FunctionTemplateInfo>( | 1774 Handle<FunctionTemplateInfo>( |
1759 FunctionTemplateInfo::cast(signature->receiver())); | 1775 FunctionTemplateInfo::cast(signature->receiver())); |
1760 } | 1776 } |
1761 } | 1777 } |
1762 | 1778 |
1763 is_simple_api_call_ = true; | 1779 is_simple_api_call_ = true; |
1764 } | 1780 } |
1765 | 1781 |
1766 | 1782 |
1767 } } // namespace v8::internal | 1783 } } // namespace v8::internal |
OLD | NEW |