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