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 84 matching lines...) Loading... |
95 primary->value = code; | 95 primary->value = code; |
96 primary->map = map; | 96 primary->map = map; |
97 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); | 97 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); |
98 return code; | 98 return code; |
99 } | 99 } |
100 | 100 |
101 | 101 |
102 Handle<Code> StubCache::FindIC(Handle<Name> name, | 102 Handle<Code> StubCache::FindIC(Handle<Name> name, |
103 Handle<Map> stub_holder_map, | 103 Handle<Map> stub_holder_map, |
104 Code::Kind kind, | 104 Code::Kind kind, |
105 Code::ExtraICState extra_state) { | 105 Code::ExtraICState extra_state, |
106 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, extra_state); | 106 InlineCacheHolderFlag cache_holder) { |
| 107 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 108 kind, extra_state, cache_holder); |
107 Handle<Object> probe(stub_holder_map->FindInCodeCache(*name, flags), | 109 Handle<Object> probe(stub_holder_map->FindInCodeCache(*name, flags), |
108 isolate_); | 110 isolate_); |
109 if (probe->IsCode()) return Handle<Code>::cast(probe); | 111 if (probe->IsCode()) return Handle<Code>::cast(probe); |
110 return Handle<Code>::null(); | 112 return Handle<Code>::null(); |
111 } | 113 } |
112 | 114 |
113 | 115 |
114 Handle<Code> StubCache::FindIC(Handle<Name> name, | |
115 Handle<JSObject> stub_holder, | |
116 Code::Kind kind, | |
117 Code::ExtraICState extra_ic_state) { | |
118 return FindIC(name, Handle<Map>(stub_holder->map()), kind, extra_ic_state); | |
119 } | |
120 | |
121 | |
122 Handle<Code> StubCache::FindHandler(Handle<Name> name, | 116 Handle<Code> StubCache::FindHandler(Handle<Name> name, |
123 Handle<JSObject> receiver, | 117 Handle<HeapObject> stub_holder, |
124 Code::Kind kind, | 118 Code::Kind kind, |
| 119 InlineCacheHolderFlag cache_holder, |
125 StrictModeFlag strict_mode) { | 120 StrictModeFlag strict_mode) { |
126 Code::ExtraICState extra_ic_state = Code::kNoExtraICState; | 121 Code::ExtraICState extra_ic_state = Code::kNoExtraICState; |
127 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) { | 122 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) { |
128 extra_ic_state = Code::ComputeExtraICState( | 123 extra_ic_state = Code::ComputeExtraICState( |
129 STANDARD_STORE, strict_mode); | 124 STANDARD_STORE, strict_mode); |
130 } | 125 } |
131 Code::Flags flags = Code::ComputeMonomorphicFlags( | 126 Code::Flags flags = Code::ComputeMonomorphicFlags( |
132 Code::HANDLER, extra_ic_state, Code::NORMAL, kind); | 127 Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind); |
133 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 128 |
| 129 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
134 isolate_); | 130 isolate_); |
135 if (probe->IsCode()) return Handle<Code>::cast(probe); | 131 if (probe->IsCode()) return Handle<Code>::cast(probe); |
136 return Handle<Code>::null(); | 132 return Handle<Code>::null(); |
137 } | 133 } |
138 | 134 |
139 | 135 |
140 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<HeapObject> receiver, | 136 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name, |
| 137 Handle<HeapObject> object, |
141 Handle<Code> handler, | 138 Handle<Code> handler, |
142 Handle<Name> name, | |
143 StrictModeFlag strict_mode) { | 139 StrictModeFlag strict_mode) { |
144 Code::Kind kind = handler->handler_kind(); | 140 Code::Kind kind = handler->handler_kind(); |
145 Handle<Map> map(receiver->map()); | 141 // Use the same cache holder for the IC as for the handler. |
146 Handle<Code> ic = FindIC(name, map, kind, strict_mode); | 142 InlineCacheHolderFlag cache_holder = |
| 143 Code::ExtractCacheHolderFromFlags(handler->flags()); |
| 144 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
| 145 isolate(), *object, cache_holder)); |
| 146 Handle<Map> stub_holder_map(stub_holder->map()); |
| 147 Handle<Code> ic = FindIC( |
| 148 name, stub_holder_map, kind, strict_mode, cache_holder); |
147 if (!ic.is_null()) return ic; | 149 if (!ic.is_null()) return ic; |
148 | 150 |
| 151 Handle<Map> map(object->map()); |
149 if (kind == Code::LOAD_IC) { | 152 if (kind == Code::LOAD_IC) { |
150 LoadStubCompiler ic_compiler(isolate()); | 153 LoadStubCompiler ic_compiler(isolate(), cache_holder); |
151 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); | 154 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); |
152 } else if (kind == Code::KEYED_LOAD_IC) { | 155 } else if (kind == Code::KEYED_LOAD_IC) { |
153 KeyedLoadStubCompiler ic_compiler(isolate()); | 156 KeyedLoadStubCompiler ic_compiler(isolate(), cache_holder); |
154 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); | 157 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); |
155 } else if (kind == Code::STORE_IC) { | 158 } else if (kind == Code::STORE_IC) { |
156 StoreStubCompiler ic_compiler(isolate(), strict_mode); | 159 StoreStubCompiler ic_compiler(isolate(), strict_mode); |
157 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); | 160 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); |
158 } else { | 161 } else { |
159 ASSERT(kind == Code::KEYED_STORE_IC); | 162 ASSERT(kind == Code::KEYED_STORE_IC); |
160 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); | 163 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); |
161 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); | 164 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); |
162 } | 165 } |
163 | 166 |
164 HeapObject::UpdateMapCodeCache(receiver, name, ic); | 167 HeapObject::UpdateMapCodeCache(stub_holder, name, ic); |
165 return ic; | 168 return ic; |
166 } | 169 } |
167 | 170 |
168 | 171 |
169 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, | 172 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, |
170 Handle<JSObject> receiver) { | 173 Handle<Object> object) { |
| 174 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); |
| 175 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
| 176 isolate(), *object, cache_holder)); |
171 // If no global objects are present in the prototype chain, the load | 177 // If no global objects are present in the prototype chain, the load |
172 // nonexistent IC stub can be shared for all names for a given map | 178 // nonexistent IC stub can be shared for all names for a given map |
173 // and we use the empty string for the map cache in that case. If | 179 // and we use the empty string for the map cache in that case. If |
174 // there are global objects involved, we need to check global | 180 // there are global objects involved, we need to check global |
175 // property cells in the stub and therefore the stub will be | 181 // property cells in the stub and therefore the stub will be |
176 // specific to the name. | 182 // specific to the name. |
177 Handle<Name> cache_name = factory()->empty_string(); | 183 Handle<Name> cache_name = factory()->empty_string(); |
178 Handle<JSObject> current; | 184 Handle<JSObject> current; |
179 Handle<Object> next = receiver; | 185 Handle<Object> next = stub_holder; |
180 Handle<JSGlobalObject> global; | 186 Handle<JSGlobalObject> global; |
181 do { | 187 do { |
182 current = Handle<JSObject>::cast(next); | 188 current = Handle<JSObject>::cast(next); |
183 next = Handle<Object>(current->GetPrototype(), isolate_); | 189 next = Handle<Object>(current->GetPrototype(), isolate_); |
184 if (current->IsJSGlobalObject()) { | 190 if (current->IsJSGlobalObject()) { |
185 global = Handle<JSGlobalObject>::cast(current); | 191 global = Handle<JSGlobalObject>::cast(current); |
186 cache_name = name; | 192 cache_name = name; |
187 } else if (!current->HasFastProperties()) { | 193 } else if (!current->HasFastProperties()) { |
188 cache_name = name; | 194 cache_name = name; |
189 } | 195 } |
190 } while (!next->IsNull()); | 196 } while (!next->IsNull()); |
191 | 197 |
192 // Compile the stub that is either shared for all names or | 198 // Compile the stub that is either shared for all names or |
193 // name specific if there are global objects involved. | 199 // name specific if there are global objects involved. |
194 Handle<Code> handler = FindHandler(cache_name, receiver, Code::LOAD_IC); | 200 Handle<Code> handler = FindHandler( |
| 201 cache_name, stub_holder, Code::LOAD_IC, cache_holder); |
195 if (!handler.is_null()) return handler; | 202 if (!handler.is_null()) return handler; |
196 | 203 |
197 LoadStubCompiler compiler(isolate_); | 204 LoadStubCompiler compiler(isolate_, cache_holder); |
198 handler = | 205 handler = |
199 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); | 206 compiler.CompileLoadNonexistent(object, current, cache_name, global); |
200 HeapObject::UpdateMapCodeCache(receiver, cache_name, handler); | 207 HeapObject::UpdateMapCodeCache(stub_holder, cache_name, handler); |
201 return handler; | 208 return handler; |
202 } | 209 } |
203 | 210 |
204 | 211 |
205 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { | 212 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { |
206 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); | 213 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); |
207 Handle<Name> name = | 214 Handle<Name> name = |
208 isolate()->factory()->KeyedLoadElementMonomorphic_string(); | 215 isolate()->factory()->KeyedLoadElementMonomorphic_string(); |
209 | 216 |
210 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); | 217 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); |
(...skipping 39 matching lines...) Loading... |
250 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) | 257 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) |
251 | 258 |
252 Handle<Code> StubCache::ComputeCallConstant(int argc, | 259 Handle<Code> StubCache::ComputeCallConstant(int argc, |
253 Code::Kind kind, | 260 Code::Kind kind, |
254 Code::ExtraICState extra_state, | 261 Code::ExtraICState extra_state, |
255 Handle<Name> name, | 262 Handle<Name> name, |
256 Handle<Object> object, | 263 Handle<Object> object, |
257 Handle<JSObject> holder, | 264 Handle<JSObject> holder, |
258 Handle<JSFunction> function) { | 265 Handle<JSFunction> function) { |
259 // Compute the check type and the map. | 266 // Compute the check type and the map. |
260 InlineCacheHolderFlag cache_holder = | 267 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); |
261 IC::GetCodeCacheForObject(*object, *holder); | 268 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
262 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder( | |
263 isolate_, *object, cache_holder)); | 269 isolate_, *object, cache_holder)); |
264 | 270 |
265 // Compute check type based on receiver/holder. | 271 // Compute check type based on receiver/holder. |
266 CheckType check = RECEIVER_MAP_CHECK; | 272 CheckType check = RECEIVER_MAP_CHECK; |
267 if (object->IsString()) { | 273 if (object->IsString()) { |
268 check = STRING_CHECK; | 274 check = STRING_CHECK; |
269 } else if (object->IsSymbol()) { | 275 } else if (object->IsSymbol()) { |
270 check = SYMBOL_CHECK; | 276 check = SYMBOL_CHECK; |
271 } else if (object->IsNumber()) { | 277 } else if (object->IsNumber()) { |
272 check = NUMBER_CHECK; | 278 check = NUMBER_CHECK; |
273 } else if (object->IsBoolean()) { | 279 } else if (object->IsBoolean()) { |
274 check = BOOLEAN_CHECK; | 280 check = BOOLEAN_CHECK; |
275 } | 281 } |
276 | 282 |
277 if (check != RECEIVER_MAP_CHECK && | 283 if (check != RECEIVER_MAP_CHECK && |
278 !function->IsBuiltin() && | 284 !function->IsBuiltin() && |
279 function->shared()->is_classic_mode()) { | 285 function->shared()->is_classic_mode()) { |
280 // Calling non-strict non-builtins with a value as the receiver | 286 // Calling non-strict non-builtins with a value as the receiver |
281 // requires boxing. | 287 // requires boxing. |
282 return Handle<Code>::null(); | 288 return Handle<Code>::null(); |
283 } | 289 } |
284 | 290 |
285 Code::Flags flags = Code::ComputeMonomorphicFlags( | 291 Code::Flags flags = Code::ComputeMonomorphicFlags( |
286 kind, extra_state, Code::CONSTANT, argc, cache_holder); | 292 kind, extra_state, cache_holder, Code::CONSTANT, argc); |
287 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 293 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
288 isolate_); | 294 isolate_); |
289 if (probe->IsCode()) return Handle<Code>::cast(probe); | 295 if (probe->IsCode()) return Handle<Code>::cast(probe); |
290 | 296 |
291 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); | 297 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); |
292 Handle<Code> code = | 298 Handle<Code> code = |
293 compiler.CompileCallConstant(object, holder, name, check, function); | 299 compiler.CompileCallConstant(object, holder, name, check, function); |
294 code->set_check_type(check); | 300 code->set_check_type(check); |
295 ASSERT(flags == code->flags()); | 301 ASSERT(flags == code->flags()); |
296 PROFILE(isolate_, | 302 PROFILE(isolate_, |
297 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 303 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
298 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 304 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
299 | 305 |
300 if (CallStubCompiler::CanBeCached(function)) { | 306 if (CallStubCompiler::CanBeCached(function)) { |
301 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 307 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
302 } | 308 } |
303 return code; | 309 return code; |
304 } | 310 } |
305 | 311 |
306 | 312 |
307 Handle<Code> StubCache::ComputeCallField(int argc, | 313 Handle<Code> StubCache::ComputeCallField(int argc, |
308 Code::Kind kind, | 314 Code::Kind kind, |
309 Code::ExtraICState extra_state, | 315 Code::ExtraICState extra_state, |
310 Handle<Name> name, | 316 Handle<Name> name, |
311 Handle<Object> object, | 317 Handle<Object> object, |
312 Handle<JSObject> holder, | 318 Handle<JSObject> holder, |
313 PropertyIndex index) { | 319 PropertyIndex index) { |
314 // Compute the check type and the map. | 320 // Compute the check type and the map. |
315 InlineCacheHolderFlag cache_holder = | 321 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); |
316 IC::GetCodeCacheForObject(*object, *holder); | 322 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
317 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder( | |
318 isolate_, *object, cache_holder)); | 323 isolate_, *object, cache_holder)); |
319 | 324 |
320 // TODO(1233596): We cannot do receiver map check for non-JS objects | 325 // TODO(1233596): We cannot do receiver map check for non-JS objects |
321 // because they may be represented as immediates without a | 326 // because they may be represented as immediates without a |
322 // map. Instead, we check against the map in the holder. | 327 // map. Instead, we check against the map in the holder. |
323 if (object->IsNumber() || object->IsSymbol() || | 328 if (object->IsNumber() || object->IsSymbol() || |
324 object->IsBoolean() || object->IsString()) { | 329 object->IsBoolean() || object->IsString()) { |
325 object = holder; | 330 object = holder; |
326 } | 331 } |
327 | 332 |
328 Code::Flags flags = Code::ComputeMonomorphicFlags( | 333 Code::Flags flags = Code::ComputeMonomorphicFlags( |
329 kind, extra_state, Code::FIELD, argc, cache_holder); | 334 kind, extra_state, cache_holder, Code::FIELD, argc); |
330 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 335 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
331 isolate_); | 336 isolate_); |
332 if (probe->IsCode()) return Handle<Code>::cast(probe); | 337 if (probe->IsCode()) return Handle<Code>::cast(probe); |
333 | 338 |
334 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); | 339 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); |
335 Handle<Code> code = | 340 Handle<Code> code = |
336 compiler.CompileCallField(Handle<JSObject>::cast(object), | 341 compiler.CompileCallField(Handle<JSObject>::cast(object), |
337 holder, index, name); | 342 holder, index, name); |
338 ASSERT(flags == code->flags()); | 343 ASSERT(flags == code->flags()); |
339 PROFILE(isolate_, | 344 PROFILE(isolate_, |
340 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 345 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
341 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 346 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
342 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 347 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
343 return code; | 348 return code; |
344 } | 349 } |
345 | 350 |
346 | 351 |
347 Handle<Code> StubCache::ComputeCallInterceptor(int argc, | 352 Handle<Code> StubCache::ComputeCallInterceptor(int argc, |
348 Code::Kind kind, | 353 Code::Kind kind, |
349 Code::ExtraICState extra_state, | 354 Code::ExtraICState extra_state, |
350 Handle<Name> name, | 355 Handle<Name> name, |
351 Handle<Object> object, | 356 Handle<Object> object, |
352 Handle<JSObject> holder) { | 357 Handle<JSObject> holder) { |
353 // Compute the check type and the map. | 358 // Compute the check type and the map. |
354 InlineCacheHolderFlag cache_holder = | 359 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); |
355 IC::GetCodeCacheForObject(*object, *holder); | 360 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
356 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder( | |
357 isolate_, *object, cache_holder)); | 361 isolate_, *object, cache_holder)); |
358 | 362 |
359 // TODO(1233596): We cannot do receiver map check for non-JS objects | 363 // TODO(1233596): We cannot do receiver map check for non-JS objects |
360 // because they may be represented as immediates without a | 364 // because they may be represented as immediates without a |
361 // map. Instead, we check against the map in the holder. | 365 // map. Instead, we check against the map in the holder. |
362 if (object->IsNumber() || object->IsSymbol() || | 366 if (object->IsNumber() || object->IsSymbol() || |
363 object->IsBoolean() || object->IsString()) { | 367 object->IsBoolean() || object->IsString()) { |
364 object = holder; | 368 object = holder; |
365 } | 369 } |
366 | 370 |
367 Code::Flags flags = Code::ComputeMonomorphicFlags( | 371 Code::Flags flags = Code::ComputeMonomorphicFlags( |
368 kind, extra_state, Code::INTERCEPTOR, argc, cache_holder); | 372 kind, extra_state, cache_holder, Code::INTERCEPTOR, argc); |
369 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 373 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
370 isolate_); | 374 isolate_); |
371 if (probe->IsCode()) return Handle<Code>::cast(probe); | 375 if (probe->IsCode()) return Handle<Code>::cast(probe); |
372 | 376 |
373 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); | 377 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); |
374 Handle<Code> code = | 378 Handle<Code> code = |
375 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object), | 379 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object), |
376 holder, name); | 380 holder, name); |
377 ASSERT(flags == code->flags()); | 381 ASSERT(flags == code->flags()); |
378 PROFILE(isolate(), | 382 PROFILE(isolate(), |
379 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 383 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
380 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 384 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
381 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 385 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
382 return code; | 386 return code; |
383 } | 387 } |
384 | 388 |
385 | 389 |
386 Handle<Code> StubCache::ComputeCallGlobal(int argc, | 390 Handle<Code> StubCache::ComputeCallGlobal(int argc, |
387 Code::Kind kind, | 391 Code::Kind kind, |
388 Code::ExtraICState extra_state, | 392 Code::ExtraICState extra_state, |
389 Handle<Name> name, | 393 Handle<Name> name, |
390 Handle<JSObject> receiver, | 394 Handle<JSObject> receiver, |
391 Handle<GlobalObject> holder, | 395 Handle<GlobalObject> holder, |
392 Handle<PropertyCell> cell, | 396 Handle<PropertyCell> cell, |
393 Handle<JSFunction> function) { | 397 Handle<JSFunction> function) { |
394 Code::Flags flags = Code::ComputeMonomorphicFlags( | 398 Code::Flags flags = Code::ComputeMonomorphicFlags( |
395 kind, extra_state, Code::NORMAL, argc); | 399 kind, extra_state, OWN_MAP, Code::NORMAL, argc); |
396 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 400 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
397 isolate_); | 401 isolate_); |
398 if (probe->IsCode()) return Handle<Code>::cast(probe); | 402 if (probe->IsCode()) return Handle<Code>::cast(probe); |
399 | 403 |
400 CallStubCompiler compiler(isolate(), argc, kind, extra_state); | 404 CallStubCompiler compiler(isolate(), argc, kind, extra_state); |
401 Handle<Code> code = | 405 Handle<Code> code = |
402 compiler.CompileCallGlobal(receiver, holder, cell, function, name); | 406 compiler.CompileCallGlobal(receiver, holder, cell, function, name); |
403 ASSERT(flags == code->flags()); | 407 ASSERT(flags == code->flags()); |
404 PROFILE(isolate(), | 408 PROFILE(isolate(), |
405 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 409 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
(...skipping 683 matching lines...) Loading... |
1089 #undef CALL_LOGGER_TAG | 1093 #undef CALL_LOGGER_TAG |
1090 | 1094 |
1091 | 1095 |
1092 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, | 1096 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, |
1093 const char* name) { | 1097 const char* name) { |
1094 // Create code object in the heap. | 1098 // Create code object in the heap. |
1095 CodeDesc desc; | 1099 CodeDesc desc; |
1096 masm_.GetCode(&desc); | 1100 masm_.GetCode(&desc); |
1097 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject()); | 1101 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject()); |
1098 #ifdef ENABLE_DISASSEMBLER | 1102 #ifdef ENABLE_DISASSEMBLER |
1099 if (FLAG_print_code_stubs) { | 1103 if (FLAG_print_code_stubs) code->Disassemble(name); |
1100 CodeTracer::Scope trace_scope(isolate()->GetCodeTracer()); | |
1101 code->Disassemble(name, trace_scope.file()); | |
1102 } | |
1103 #endif | 1104 #endif |
1104 return code; | 1105 return code; |
1105 } | 1106 } |
1106 | 1107 |
1107 | 1108 |
1108 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, | 1109 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, |
1109 Handle<Name> name) { | 1110 Handle<Name> name) { |
1110 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) | 1111 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) |
1111 ? GetCodeWithFlags(flags, *Handle<String>::cast(name)->ToCString()) | 1112 ? GetCodeWithFlags(flags, *Handle<String>::cast(name)->ToCString()) |
1112 : GetCodeWithFlags(flags, NULL); | 1113 : GetCodeWithFlags(flags, NULL); |
1113 } | 1114 } |
1114 | 1115 |
1115 | 1116 |
1116 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder, | 1117 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder, |
1117 Handle<Name> name, | 1118 Handle<Name> name, |
1118 LookupResult* lookup) { | 1119 LookupResult* lookup) { |
1119 holder->LocalLookupRealNamedProperty(*name, lookup); | 1120 holder->LocalLookupRealNamedProperty(*name, lookup); |
1120 if (lookup->IsFound()) return; | 1121 if (lookup->IsFound()) return; |
1121 if (holder->GetPrototype()->IsNull()) return; | 1122 if (holder->GetPrototype()->IsNull()) return; |
1122 holder->GetPrototype()->Lookup(*name, lookup); | 1123 holder->GetPrototype()->Lookup(*name, lookup); |
1123 } | 1124 } |
1124 | 1125 |
1125 | 1126 |
1126 #define __ ACCESS_MASM(masm()) | 1127 #define __ ACCESS_MASM(masm()) |
1127 | 1128 |
1128 | 1129 |
1129 Register LoadStubCompiler::HandlerFrontendHeader( | 1130 Register LoadStubCompiler::HandlerFrontendHeader( |
1130 Handle<JSObject> object, | 1131 Handle<Object> object, |
1131 Register object_reg, | 1132 Register object_reg, |
1132 Handle<JSObject> holder, | 1133 Handle<JSObject> holder, |
1133 Handle<Name> name, | 1134 Handle<Name> name, |
1134 Label* miss) { | 1135 Label* miss) { |
1135 return CheckPrototypes(object, object_reg, holder, | 1136 Handle<JSObject> receiver; |
| 1137 PrototypeCheckType check_type = CHECK_ALL_MAPS; |
| 1138 int function_index = -1; |
| 1139 if (object->IsJSObject()) { |
| 1140 receiver = Handle<JSObject>::cast(object); |
| 1141 check_type = SKIP_RECEIVER; |
| 1142 } else { |
| 1143 if (object->IsString()) { |
| 1144 function_index = Context::STRING_FUNCTION_INDEX; |
| 1145 } else if (object->IsSymbol()) { |
| 1146 function_index = Context::SYMBOL_FUNCTION_INDEX; |
| 1147 } else if (object->IsNumber()) { |
| 1148 function_index = Context::NUMBER_FUNCTION_INDEX; |
| 1149 } else { |
| 1150 ASSERT(object->IsBoolean()); |
| 1151 // Booleans use the generic oddball map, so an additional check is |
| 1152 // needed to ensure the receiver is really a boolean. |
| 1153 GenerateBooleanCheck(object_reg, miss); |
| 1154 function_index = Context::BOOLEAN_FUNCTION_INDEX; |
| 1155 } |
| 1156 |
| 1157 GenerateDirectLoadGlobalFunctionPrototype( |
| 1158 masm(), function_index, scratch1(), miss); |
| 1159 receiver = handle(JSObject::cast(object->GetPrototype(isolate()))); |
| 1160 object_reg = scratch1(); |
| 1161 } |
| 1162 |
| 1163 // Check that the maps starting from the prototype haven't changed. |
| 1164 return CheckPrototypes(receiver, object_reg, holder, |
1136 scratch1(), scratch2(), scratch3(), | 1165 scratch1(), scratch2(), scratch3(), |
1137 name, miss, SKIP_RECEIVER); | 1166 name, miss, check_type); |
1138 } | 1167 } |
1139 | 1168 |
1140 | 1169 |
1141 // HandlerFrontend for store uses the name register. It has to be restored | 1170 // HandlerFrontend for store uses the name register. It has to be restored |
1142 // before a miss. | 1171 // before a miss. |
1143 Register StoreStubCompiler::HandlerFrontendHeader( | 1172 Register StoreStubCompiler::HandlerFrontendHeader( |
1144 Handle<JSObject> object, | 1173 Handle<Object> object, |
1145 Register object_reg, | 1174 Register object_reg, |
1146 Handle<JSObject> holder, | 1175 Handle<JSObject> holder, |
1147 Handle<Name> name, | 1176 Handle<Name> name, |
1148 Label* miss) { | 1177 Label* miss) { |
1149 return CheckPrototypes(object, object_reg, holder, | 1178 return CheckPrototypes(Handle<JSObject>::cast(object), object_reg, holder, |
1150 this->name(), scratch1(), scratch2(), | 1179 this->name(), scratch1(), scratch2(), |
1151 name, miss, SKIP_RECEIVER); | 1180 name, miss, SKIP_RECEIVER); |
1152 } | 1181 } |
1153 | 1182 |
1154 | 1183 |
1155 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<JSObject> object, | 1184 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Object> object, |
1156 Register object_reg, | 1185 Register object_reg, |
1157 Handle<JSObject> holder, | 1186 Handle<JSObject> holder, |
1158 Handle<Name> name, | 1187 Handle<Name> name) { |
1159 Label* success) { | |
1160 Label miss; | 1188 Label miss; |
1161 | 1189 |
1162 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); | 1190 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); |
1163 | 1191 |
1164 HandlerFrontendFooter(name, success, &miss); | 1192 HandlerFrontendFooter(name, &miss); |
| 1193 |
1165 return reg; | 1194 return reg; |
1166 } | 1195 } |
1167 | 1196 |
1168 | 1197 |
1169 void LoadStubCompiler::NonexistentHandlerFrontend( | 1198 void LoadStubCompiler::NonexistentHandlerFrontend( |
1170 Handle<JSObject> object, | 1199 Handle<Object> object, |
1171 Handle<JSObject> last, | 1200 Handle<JSObject> last, |
1172 Handle<Name> name, | 1201 Handle<Name> name, |
1173 Label* success, | |
1174 Handle<JSGlobalObject> global) { | 1202 Handle<JSGlobalObject> global) { |
1175 Label miss; | 1203 Label miss; |
1176 | 1204 |
1177 Register holder = | 1205 Register holder = HandlerFrontendHeader( |
1178 HandlerFrontendHeader(object, receiver(), last, name, &miss); | 1206 object, receiver(), last, name, &miss); |
1179 | 1207 |
1180 if (!last->HasFastProperties() && | 1208 if (!last->HasFastProperties() && |
1181 !last->IsJSGlobalObject() && | 1209 !last->IsJSGlobalObject() && |
1182 !last->IsJSGlobalProxy()) { | 1210 !last->IsJSGlobalProxy()) { |
1183 if (!name->IsUniqueName()) { | 1211 if (!name->IsUniqueName()) { |
1184 ASSERT(name->IsString()); | 1212 ASSERT(name->IsString()); |
1185 name = factory()->InternalizeString(Handle<String>::cast(name)); | 1213 name = factory()->InternalizeString(Handle<String>::cast(name)); |
1186 } | 1214 } |
1187 ASSERT(last->property_dictionary()->FindEntry(*name) == | 1215 ASSERT(last->property_dictionary()->FindEntry(*name) == |
1188 NameDictionary::kNotFound); | 1216 NameDictionary::kNotFound); |
1189 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, | 1217 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, |
1190 scratch2(), scratch3()); | 1218 scratch2(), scratch3()); |
1191 } | 1219 } |
1192 | 1220 |
1193 // If the last object in the prototype chain is a global object, | 1221 // If the last object in the prototype chain is a global object, |
1194 // check that the global property cell is empty. | 1222 // check that the global property cell is empty. |
1195 if (!global.is_null()) { | 1223 if (!global.is_null()) { |
1196 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); | 1224 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); |
1197 } | 1225 } |
1198 | 1226 |
1199 HandlerFrontendFooter(name, success, &miss); | 1227 HandlerFrontendFooter(name, &miss); |
1200 } | 1228 } |
1201 | 1229 |
1202 | 1230 |
1203 Handle<Code> LoadStubCompiler::CompileLoadField( | 1231 Handle<Code> LoadStubCompiler::CompileLoadField( |
1204 Handle<JSObject> object, | 1232 Handle<Object> object, |
1205 Handle<JSObject> holder, | 1233 Handle<JSObject> holder, |
1206 Handle<Name> name, | 1234 Handle<Name> name, |
1207 PropertyIndex field, | 1235 PropertyIndex field, |
1208 Representation representation) { | 1236 Representation representation) { |
1209 Label miss; | 1237 Label miss; |
1210 | 1238 |
1211 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); | 1239 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); |
1212 | 1240 |
1213 GenerateLoadField(reg, holder, field, representation); | 1241 GenerateLoadField(reg, holder, field, representation); |
1214 | 1242 |
1215 __ bind(&miss); | 1243 __ bind(&miss); |
1216 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1244 TailCallBuiltin(masm(), MissBuiltin(kind())); |
1217 | 1245 |
1218 // Return the generated code. | 1246 // Return the generated code. |
1219 return GetCode(kind(), Code::FIELD, name); | 1247 return GetCode(kind(), Code::FIELD, name); |
1220 } | 1248 } |
1221 | 1249 |
1222 | 1250 |
1223 Handle<Code> LoadStubCompiler::CompileLoadConstant( | 1251 Handle<Code> LoadStubCompiler::CompileLoadConstant( |
1224 Handle<JSObject> object, | 1252 Handle<Object> object, |
1225 Handle<JSObject> holder, | 1253 Handle<JSObject> holder, |
1226 Handle<Name> name, | 1254 Handle<Name> name, |
1227 Handle<Object> value) { | 1255 Handle<Object> value) { |
1228 Label success; | 1256 HandlerFrontend(object, receiver(), holder, name); |
1229 HandlerFrontend(object, receiver(), holder, name, &success); | |
1230 __ bind(&success); | |
1231 GenerateLoadConstant(value); | 1257 GenerateLoadConstant(value); |
1232 | 1258 |
1233 // Return the generated code. | 1259 // Return the generated code. |
1234 return GetCode(kind(), Code::CONSTANT, name); | 1260 return GetCode(kind(), Code::CONSTANT, name); |
1235 } | 1261 } |
1236 | 1262 |
1237 | 1263 |
1238 Handle<Code> LoadStubCompiler::CompileLoadCallback( | 1264 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
1239 Handle<JSObject> object, | 1265 Handle<Object> object, |
1240 Handle<JSObject> holder, | 1266 Handle<JSObject> holder, |
1241 Handle<Name> name, | 1267 Handle<Name> name, |
1242 Handle<ExecutableAccessorInfo> callback) { | 1268 Handle<ExecutableAccessorInfo> callback) { |
1243 Label success; | |
1244 | |
1245 Register reg = CallbackHandlerFrontend( | 1269 Register reg = CallbackHandlerFrontend( |
1246 object, receiver(), holder, name, &success, callback); | 1270 object, receiver(), holder, name, callback); |
1247 __ bind(&success); | |
1248 GenerateLoadCallback(reg, callback); | 1271 GenerateLoadCallback(reg, callback); |
1249 | 1272 |
1250 // Return the generated code. | 1273 // Return the generated code. |
1251 return GetCode(kind(), Code::CALLBACKS, name); | 1274 return GetCode(kind(), Code::CALLBACKS, name); |
1252 } | 1275 } |
1253 | 1276 |
1254 | 1277 |
1255 Handle<Code> LoadStubCompiler::CompileLoadCallback( | 1278 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
1256 Handle<JSObject> object, | 1279 Handle<Object> object, |
1257 Handle<JSObject> holder, | 1280 Handle<JSObject> holder, |
1258 Handle<Name> name, | 1281 Handle<Name> name, |
1259 const CallOptimization& call_optimization) { | 1282 const CallOptimization& call_optimization) { |
1260 ASSERT(call_optimization.is_simple_api_call()); | 1283 ASSERT(call_optimization.is_simple_api_call()); |
1261 Label success; | |
1262 | |
1263 Handle<JSFunction> callback = call_optimization.constant_function(); | 1284 Handle<JSFunction> callback = call_optimization.constant_function(); |
1264 CallbackHandlerFrontend( | 1285 CallbackHandlerFrontend(object, receiver(), holder, name, callback); |
1265 object, receiver(), holder, name, &success, callback); | |
1266 __ bind(&success); | |
1267 GenerateLoadCallback(call_optimization); | 1286 GenerateLoadCallback(call_optimization); |
1268 | 1287 |
1269 // Return the generated code. | 1288 // Return the generated code. |
1270 return GetCode(kind(), Code::CALLBACKS, name); | 1289 return GetCode(kind(), Code::CALLBACKS, name); |
1271 } | 1290 } |
1272 | 1291 |
1273 | 1292 |
1274 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( | 1293 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( |
1275 Handle<JSObject> object, | 1294 Handle<Object> object, |
1276 Handle<JSObject> holder, | 1295 Handle<JSObject> holder, |
1277 Handle<Name> name) { | 1296 Handle<Name> name) { |
1278 Label success; | |
1279 | |
1280 LookupResult lookup(isolate()); | 1297 LookupResult lookup(isolate()); |
1281 LookupPostInterceptor(holder, name, &lookup); | 1298 LookupPostInterceptor(holder, name, &lookup); |
1282 | 1299 |
1283 Register reg = HandlerFrontend(object, receiver(), holder, name, &success); | 1300 Register reg = HandlerFrontend(object, receiver(), holder, name); |
1284 __ bind(&success); | |
1285 // TODO(368): Compile in the whole chain: all the interceptors in | 1301 // TODO(368): Compile in the whole chain: all the interceptors in |
1286 // prototypes and ultimate answer. | 1302 // prototypes and ultimate answer. |
1287 GenerateLoadInterceptor(reg, object, holder, &lookup, name); | 1303 GenerateLoadInterceptor(reg, object, holder, &lookup, name); |
1288 | 1304 |
1289 // Return the generated code. | 1305 // Return the generated code. |
1290 return GetCode(kind(), Code::INTERCEPTOR, name); | 1306 return GetCode(kind(), Code::INTERCEPTOR, name); |
1291 } | 1307 } |
1292 | 1308 |
1293 | 1309 |
1294 void LoadStubCompiler::GenerateLoadPostInterceptor( | 1310 void LoadStubCompiler::GenerateLoadPostInterceptor( |
1295 Register interceptor_reg, | 1311 Register interceptor_reg, |
1296 Handle<JSObject> interceptor_holder, | 1312 Handle<JSObject> interceptor_holder, |
1297 Handle<Name> name, | 1313 Handle<Name> name, |
1298 LookupResult* lookup) { | 1314 LookupResult* lookup) { |
1299 Label success; | |
1300 Handle<JSObject> holder(lookup->holder()); | 1315 Handle<JSObject> holder(lookup->holder()); |
1301 if (lookup->IsField()) { | 1316 if (lookup->IsField()) { |
1302 PropertyIndex field = lookup->GetFieldIndex(); | 1317 PropertyIndex field = lookup->GetFieldIndex(); |
1303 if (interceptor_holder.is_identical_to(holder)) { | 1318 if (interceptor_holder.is_identical_to(holder)) { |
1304 GenerateLoadField( | 1319 GenerateLoadField( |
1305 interceptor_reg, holder, field, lookup->representation()); | 1320 interceptor_reg, holder, field, lookup->representation()); |
1306 } else { | 1321 } else { |
1307 // We found FIELD property in prototype chain of interceptor's holder. | 1322 // We found FIELD property in prototype chain of interceptor's holder. |
1308 // Retrieve a field from field's holder. | 1323 // Retrieve a field from field's holder. |
1309 Register reg = HandlerFrontend( | 1324 Register reg = HandlerFrontend( |
1310 interceptor_holder, interceptor_reg, holder, name, &success); | 1325 interceptor_holder, interceptor_reg, holder, name); |
1311 __ bind(&success); | |
1312 GenerateLoadField( | 1326 GenerateLoadField( |
1313 reg, holder, field, lookup->representation()); | 1327 reg, holder, field, lookup->representation()); |
1314 } | 1328 } |
1315 } else { | 1329 } else { |
1316 // We found CALLBACKS property in prototype chain of interceptor's | 1330 // We found CALLBACKS property in prototype chain of interceptor's |
1317 // holder. | 1331 // holder. |
1318 ASSERT(lookup->type() == CALLBACKS); | 1332 ASSERT(lookup->type() == CALLBACKS); |
1319 Handle<ExecutableAccessorInfo> callback( | 1333 Handle<ExecutableAccessorInfo> callback( |
1320 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); | 1334 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); |
1321 ASSERT(callback->getter() != NULL); | 1335 ASSERT(callback->getter() != NULL); |
1322 | 1336 |
1323 Register reg = CallbackHandlerFrontend( | 1337 Register reg = CallbackHandlerFrontend( |
1324 interceptor_holder, interceptor_reg, holder, name, &success, callback); | 1338 interceptor_holder, interceptor_reg, holder, name, callback); |
1325 __ bind(&success); | |
1326 GenerateLoadCallback(reg, callback); | 1339 GenerateLoadCallback(reg, callback); |
1327 } | 1340 } |
1328 } | 1341 } |
1329 | 1342 |
1330 | 1343 |
1331 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( | 1344 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( |
1332 Handle<Map> receiver_map, | 1345 Handle<Map> receiver_map, |
1333 Handle<Code> handler, | 1346 Handle<Code> handler, |
1334 Handle<Name> name) { | 1347 Handle<Name> name) { |
1335 MapHandleList receiver_maps(1); | 1348 MapHandleList receiver_maps(1); |
1336 receiver_maps.Add(receiver_map); | 1349 receiver_maps.Add(receiver_map); |
1337 CodeHandleList handlers(1); | 1350 CodeHandleList handlers(1); |
1338 handlers.Add(handler); | 1351 handlers.Add(handler); |
1339 Code::StubType type = handler->type(); | 1352 Code::StubType type = handler->type(); |
1340 return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY); | 1353 return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY); |
1341 } | 1354 } |
1342 | 1355 |
1343 | 1356 |
1344 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 1357 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( |
1345 Handle<JSObject> object, | 1358 Handle<Object> object, |
1346 Handle<JSObject> holder, | 1359 Handle<JSObject> holder, |
1347 Handle<Name> name, | 1360 Handle<Name> name, |
1348 Handle<JSFunction> getter) { | 1361 Handle<JSFunction> getter) { |
1349 Label success; | 1362 HandlerFrontend(object, receiver(), holder, name); |
1350 HandlerFrontend(object, receiver(), holder, name, &success); | |
1351 | |
1352 __ bind(&success); | |
1353 GenerateLoadViaGetter(masm(), receiver(), getter); | 1363 GenerateLoadViaGetter(masm(), receiver(), getter); |
1354 | 1364 |
1355 // Return the generated code. | 1365 // Return the generated code. |
1356 return GetCode(kind(), Code::CALLBACKS, name); | 1366 return GetCode(kind(), Code::CALLBACKS, name); |
1357 } | 1367 } |
1358 | 1368 |
1359 | 1369 |
1360 Handle<Code> StoreStubCompiler::CompileStoreTransition( | 1370 Handle<Code> StoreStubCompiler::CompileStoreTransition( |
1361 Handle<JSObject> object, | 1371 Handle<JSObject> object, |
1362 LookupResult* lookup, | 1372 LookupResult* lookup, |
(...skipping 72 matching lines...) Loading... |
1435 // Return the generated code. | 1445 // Return the generated code. |
1436 return GetCode(kind(), Code::FIELD, name); | 1446 return GetCode(kind(), Code::FIELD, name); |
1437 } | 1447 } |
1438 | 1448 |
1439 | 1449 |
1440 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | 1450 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( |
1441 Handle<JSObject> object, | 1451 Handle<JSObject> object, |
1442 Handle<JSObject> holder, | 1452 Handle<JSObject> holder, |
1443 Handle<Name> name, | 1453 Handle<Name> name, |
1444 Handle<JSFunction> setter) { | 1454 Handle<JSFunction> setter) { |
1445 Label success; | 1455 HandlerFrontend(object, receiver(), holder, name); |
1446 HandlerFrontend(object, receiver(), holder, name, &success); | |
1447 | |
1448 __ bind(&success); | |
1449 GenerateStoreViaSetter(masm(), setter); | 1456 GenerateStoreViaSetter(masm(), setter); |
1450 | 1457 |
1451 return GetCode(kind(), Code::CALLBACKS, name); | 1458 return GetCode(kind(), Code::CALLBACKS, name); |
1452 } | 1459 } |
1453 | 1460 |
1454 | 1461 |
1455 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( | 1462 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( |
1456 Handle<Map> receiver_map) { | 1463 Handle<Map> receiver_map) { |
1457 ElementsKind elements_kind = receiver_map->elements_kind(); | 1464 ElementsKind elements_kind = receiver_map->elements_kind(); |
1458 if (receiver_map->has_fast_elements() || | 1465 if (receiver_map->has_fast_elements() || |
(...skipping 89 matching lines...) Loading... |
1548 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | 1555 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
1549 JitEvent(name, code); | 1556 JitEvent(name, code); |
1550 return code; | 1557 return code; |
1551 } | 1558 } |
1552 | 1559 |
1553 | 1560 |
1554 Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind, | 1561 Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind, |
1555 Code::StubType type, | 1562 Code::StubType type, |
1556 Handle<Name> name) { | 1563 Handle<Name> name) { |
1557 Code::Flags flags = Code::ComputeFlags( | 1564 Code::Flags flags = Code::ComputeFlags( |
1558 Code::HANDLER, MONOMORPHIC, extra_state(), type, kind); | 1565 Code::HANDLER, MONOMORPHIC, extra_state(), type, kind, cache_holder_); |
1559 Handle<Code> code = GetCodeWithFlags(flags, name); | 1566 Handle<Code> code = GetCodeWithFlags(flags, name); |
1560 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | 1567 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
1561 JitEvent(name, code); | 1568 JitEvent(name, code); |
1562 return code; | 1569 return code; |
1563 } | 1570 } |
1564 | 1571 |
1565 | 1572 |
1566 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, | 1573 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, |
1567 CodeHandleList* handlers) { | 1574 CodeHandleList* handlers) { |
1568 for (int i = 0; i < receiver_maps->length(); ++i) { | 1575 for (int i = 0; i < receiver_maps->length(); ++i) { |
(...skipping 147 matching lines...) Loading... |
1716 holder, | 1723 holder, |
1717 cell, | 1724 cell, |
1718 function, | 1725 function, |
1719 fname); | 1726 fname); |
1720 } | 1727 } |
1721 | 1728 |
1722 | 1729 |
1723 Handle<Code> CallStubCompiler::GetCode(Code::StubType type, | 1730 Handle<Code> CallStubCompiler::GetCode(Code::StubType type, |
1724 Handle<Name> name) { | 1731 Handle<Name> name) { |
1725 int argc = arguments_.immediate(); | 1732 int argc = arguments_.immediate(); |
1726 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, | 1733 Code::Flags flags = Code::ComputeMonomorphicFlags( |
1727 extra_state_, | 1734 kind_, extra_state_, cache_holder_, type, argc); |
1728 type, | |
1729 argc, | |
1730 cache_holder_); | |
1731 return GetCodeWithFlags(flags, name); | 1735 return GetCodeWithFlags(flags, name); |
1732 } | 1736 } |
1733 | 1737 |
1734 | 1738 |
1735 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { | 1739 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { |
1736 Handle<String> function_name; | 1740 Handle<String> function_name; |
1737 if (function->shared()->name()->IsString()) { | 1741 if (function->shared()->name()->IsString()) { |
1738 function_name = Handle<String>(String::cast(function->shared()->name())); | 1742 function_name = Handle<String>(String::cast(function->shared()->name())); |
1739 } | 1743 } |
1740 return GetCode(Code::CONSTANT, function_name); | 1744 return GetCode(Code::CONSTANT, function_name); |
(...skipping 67 matching lines...) Loading... |
1808 Handle<FunctionTemplateInfo>( | 1812 Handle<FunctionTemplateInfo>( |
1809 FunctionTemplateInfo::cast(signature->receiver())); | 1813 FunctionTemplateInfo::cast(signature->receiver())); |
1810 } | 1814 } |
1811 } | 1815 } |
1812 | 1816 |
1813 is_simple_api_call_ = true; | 1817 is_simple_api_call_ = true; |
1814 } | 1818 } |
1815 | 1819 |
1816 | 1820 |
1817 } } // namespace v8::internal | 1821 } } // namespace v8::internal |
OLD | NEW |