| 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<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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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 |