| 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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 | 112 |
| 113 | 113 |
| 114 Handle<Code> StubCache::FindIC(Handle<Name> name, | 114 Handle<Code> StubCache::FindIC(Handle<Name> name, |
| 115 Handle<JSObject> stub_holder, | 115 Handle<JSObject> stub_holder, |
| 116 Code::Kind kind, | 116 Code::Kind kind, |
| 117 Code::ExtraICState extra_ic_state) { | 117 Code::ExtraICState extra_ic_state) { |
| 118 return FindIC(name, Handle<Map>(stub_holder->map()), kind, extra_ic_state); | 118 return FindIC(name, Handle<Map>(stub_holder->map()), kind, extra_ic_state); |
| 119 } | 119 } |
| 120 | 120 |
| 121 | 121 |
| 122 Handle<Code> StubCache::FindLoadHandler(Handle<Name> name, | 122 Handle<Code> StubCache::FindHandler(Handle<Name> name, |
| 123 Handle<JSObject> receiver, | 123 Handle<JSObject> receiver, |
| 124 Code::Kind kind) { | 124 Code::Kind kind, |
| 125 Code::Flags flags = Code::ComputeMonomorphicFlags( | 125 StrictModeFlag strict_mode) { |
| 126 Code::HANDLER, Code::kNoExtraICState, Code::NORMAL, kind); | 126 Code::ExtraICState extra_ic_state = Code::kNoExtraICState; |
| 127 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 127 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) { |
| 128 isolate_); | 128 extra_ic_state = Code::ComputeExtraICState( |
| 129 if (probe->IsCode()) return Handle<Code>::cast(probe); | 129 STANDARD_STORE, strict_mode); |
| 130 return Handle<Code>::null(); | 130 } |
| 131 } | |
| 132 | |
| 133 | |
| 134 Handle<Code> StubCache::FindStoreHandler(Handle<Name> name, | |
| 135 Handle<JSObject> receiver, | |
| 136 Code::Kind kind, | |
| 137 StrictModeFlag strict_mode) { | |
| 138 Code::ExtraICState extra_ic_state = Code::ComputeExtraICState( | |
| 139 STANDARD_STORE, strict_mode); | |
| 140 Code::Flags flags = Code::ComputeMonomorphicFlags( | 131 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 141 Code::HANDLER, extra_ic_state, Code::NORMAL, kind); | 132 Code::HANDLER, extra_ic_state, Code::NORMAL, kind); |
| 142 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 133 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
| 143 isolate_); | 134 isolate_); |
| 144 if (probe->IsCode()) return Handle<Code>::cast(probe); | 135 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 145 return Handle<Code>::null(); | 136 return Handle<Code>::null(); |
| 146 } | 137 } |
| 147 | 138 |
| 148 | 139 |
| 149 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<HeapObject> receiver, | 140 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<HeapObject> receiver, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 if (current->IsGlobalObject()) { | 184 if (current->IsGlobalObject()) { |
| 194 global = Handle<GlobalObject>::cast(current); | 185 global = Handle<GlobalObject>::cast(current); |
| 195 cache_name = name; | 186 cache_name = name; |
| 196 } else if (!current->HasFastProperties()) { | 187 } else if (!current->HasFastProperties()) { |
| 197 cache_name = name; | 188 cache_name = name; |
| 198 } | 189 } |
| 199 } while (!next->IsNull()); | 190 } while (!next->IsNull()); |
| 200 | 191 |
| 201 // Compile the stub that is either shared for all names or | 192 // Compile the stub that is either shared for all names or |
| 202 // name specific if there are global objects involved. | 193 // name specific if there are global objects involved. |
| 203 Handle<Code> handler = FindLoadHandler(cache_name, receiver, Code::LOAD_IC); | 194 Handle<Code> handler = FindHandler(cache_name, receiver, Code::LOAD_IC); |
| 204 if (!handler.is_null()) return handler; | 195 if (!handler.is_null()) return handler; |
| 205 | 196 |
| 206 LoadStubCompiler compiler(isolate_); | 197 LoadStubCompiler compiler(isolate_); |
| 207 handler = | 198 handler = |
| 208 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); | 199 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); |
| 209 HeapObject::UpdateMapCodeCache(receiver, cache_name, handler); | 200 HeapObject::UpdateMapCodeCache(receiver, cache_name, handler); |
| 210 return handler; | 201 return handler; |
| 211 } | 202 } |
| 212 | 203 |
| 213 | 204 |
| 214 Handle<Code> StubCache::ComputeLoadField(Handle<Name> name, | |
| 215 Handle<JSObject> receiver, | |
| 216 Handle<JSObject> holder, | |
| 217 PropertyIndex field, | |
| 218 Representation representation) { | |
| 219 if (receiver.is_identical_to(holder)) { | |
| 220 LoadFieldStub stub(field.is_inobject(holder), | |
| 221 field.translate(holder), | |
| 222 representation); | |
| 223 return stub.GetCode(isolate()); | |
| 224 } | |
| 225 | |
| 226 Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC); | |
| 227 if (!stub.is_null()) return stub; | |
| 228 | |
| 229 LoadStubCompiler compiler(isolate_); | |
| 230 Handle<Code> handler = | |
| 231 compiler.CompileLoadField(receiver, holder, name, field, representation); | |
| 232 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 233 return handler; | |
| 234 } | |
| 235 | |
| 236 | |
| 237 Handle<Code> StubCache::ComputeLoadCallback( | |
| 238 Handle<Name> name, | |
| 239 Handle<JSObject> receiver, | |
| 240 Handle<JSObject> holder, | |
| 241 Handle<ExecutableAccessorInfo> callback) { | |
| 242 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); | |
| 243 Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC); | |
| 244 if (!stub.is_null()) return stub; | |
| 245 | |
| 246 LoadStubCompiler compiler(isolate_); | |
| 247 Handle<Code> handler = | |
| 248 compiler.CompileLoadCallback(receiver, holder, name, callback); | |
| 249 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 250 return handler; | |
| 251 } | |
| 252 | |
| 253 | |
| 254 Handle<Code> StubCache::ComputeLoadCallback( | |
| 255 Handle<Name> name, | |
| 256 Handle<JSObject> receiver, | |
| 257 Handle<JSObject> holder, | |
| 258 const CallOptimization& call_optimization) { | |
| 259 Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC); | |
| 260 if (!stub.is_null()) return stub; | |
| 261 | |
| 262 LoadStubCompiler compiler(isolate_); | |
| 263 Handle<Code> handler = | |
| 264 compiler.CompileLoadCallback(receiver, holder, name, call_optimization); | |
| 265 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 266 return handler; | |
| 267 } | |
| 268 | |
| 269 | |
| 270 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name, | |
| 271 Handle<JSObject> receiver, | |
| 272 Handle<JSObject> holder, | |
| 273 Handle<JSFunction> getter) { | |
| 274 Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC); | |
| 275 if (!stub.is_null()) return stub; | |
| 276 | |
| 277 LoadStubCompiler compiler(isolate_); | |
| 278 Handle<Code> handler = | |
| 279 compiler.CompileLoadViaGetter(receiver, holder, name, getter); | |
| 280 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 281 return handler; | |
| 282 } | |
| 283 | |
| 284 | |
| 285 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name, | |
| 286 Handle<JSObject> receiver, | |
| 287 Handle<JSObject> holder, | |
| 288 Handle<Object> value) { | |
| 289 Handle<Code> handler = FindLoadHandler(name, receiver, Code::LOAD_IC); | |
| 290 if (!handler.is_null()) return handler; | |
| 291 | |
| 292 LoadStubCompiler compiler(isolate_); | |
| 293 handler = compiler.CompileLoadConstant(receiver, holder, name, value); | |
| 294 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 295 | |
| 296 return handler; | |
| 297 } | |
| 298 | |
| 299 | |
| 300 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name, | |
| 301 Handle<JSObject> receiver, | |
| 302 Handle<JSObject> holder) { | |
| 303 Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC); | |
| 304 if (!stub.is_null()) return stub; | |
| 305 | |
| 306 LoadStubCompiler compiler(isolate_); | |
| 307 Handle<Code> handler = | |
| 308 compiler.CompileLoadInterceptor(receiver, holder, name); | |
| 309 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 310 return handler; | |
| 311 } | |
| 312 | |
| 313 | |
| 314 Handle<Code> StubCache::ComputeLoadNormal(Handle<Name> name, | |
| 315 Handle<JSObject> receiver) { | |
| 316 return isolate_->builtins()->LoadIC_Normal(); | |
| 317 } | |
| 318 | |
| 319 | |
| 320 Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name, | 205 Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name, |
| 321 Handle<JSObject> receiver, | 206 Handle<JSObject> receiver, |
| 322 Handle<GlobalObject> holder, | 207 Handle<GlobalObject> holder, |
| 323 Handle<PropertyCell> cell, | 208 Handle<PropertyCell> cell, |
| 324 bool is_dont_delete) { | 209 bool is_dont_delete) { |
| 325 Handle<Code> stub = FindIC(name, receiver, Code::LOAD_IC); | 210 Handle<Code> stub = FindIC(name, receiver, Code::LOAD_IC); |
| 326 if (!stub.is_null()) return stub; | 211 if (!stub.is_null()) return stub; |
| 327 | 212 |
| 328 LoadStubCompiler compiler(isolate_); | 213 LoadStubCompiler compiler(isolate_); |
| 329 Handle<Code> ic = | 214 Handle<Code> ic = |
| 330 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); | 215 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); |
| 331 HeapObject::UpdateMapCodeCache(receiver, name, ic); | 216 HeapObject::UpdateMapCodeCache(receiver, name, ic); |
| 332 return ic; | 217 return ic; |
| 333 } | 218 } |
| 334 | 219 |
| 335 | 220 |
| 336 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name, | |
| 337 Handle<JSObject> receiver, | |
| 338 Handle<JSObject> holder, | |
| 339 PropertyIndex field, | |
| 340 Representation representation) { | |
| 341 if (receiver.is_identical_to(holder)) { | |
| 342 // TODO(titzer): this should use an HObjectAccess | |
| 343 KeyedLoadFieldStub stub(field.is_inobject(holder), | |
| 344 field.translate(holder), | |
| 345 representation); | |
| 346 return stub.GetCode(isolate()); | |
| 347 } | |
| 348 | |
| 349 Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC); | |
| 350 if (!stub.is_null()) return stub; | |
| 351 | |
| 352 KeyedLoadStubCompiler compiler(isolate_); | |
| 353 Handle<Code> handler = | |
| 354 compiler.CompileLoadField(receiver, holder, name, field, representation); | |
| 355 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 356 return handler; | |
| 357 } | |
| 358 | |
| 359 | |
| 360 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name, | |
| 361 Handle<JSObject> receiver, | |
| 362 Handle<JSObject> holder, | |
| 363 Handle<Object> value) { | |
| 364 Handle<Code> handler = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC); | |
| 365 if (!handler.is_null()) return handler; | |
| 366 | |
| 367 KeyedLoadStubCompiler compiler(isolate_); | |
| 368 handler = compiler.CompileLoadConstant(receiver, holder, name, value); | |
| 369 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 370 return handler; | |
| 371 } | |
| 372 | |
| 373 | |
| 374 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name, | |
| 375 Handle<JSObject> receiver, | |
| 376 Handle<JSObject> holder) { | |
| 377 Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC); | |
| 378 if (!stub.is_null()) return stub; | |
| 379 | |
| 380 KeyedLoadStubCompiler compiler(isolate_); | |
| 381 Handle<Code> handler = | |
| 382 compiler.CompileLoadInterceptor(receiver, holder, name); | |
| 383 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 384 return handler; | |
| 385 } | |
| 386 | |
| 387 | |
| 388 Handle<Code> StubCache::ComputeKeyedLoadCallback( | |
| 389 Handle<Name> name, | |
| 390 Handle<JSObject> receiver, | |
| 391 Handle<JSObject> holder, | |
| 392 Handle<ExecutableAccessorInfo> callback) { | |
| 393 Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC); | |
| 394 if (!stub.is_null()) return stub; | |
| 395 | |
| 396 KeyedLoadStubCompiler compiler(isolate_); | |
| 397 Handle<Code> handler = | |
| 398 compiler.CompileLoadCallback(receiver, holder, name, callback); | |
| 399 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 400 return handler; | |
| 401 } | |
| 402 | |
| 403 | |
| 404 Handle<Code> StubCache::ComputeKeyedLoadCallback( | |
| 405 Handle<Name> name, | |
| 406 Handle<JSObject> receiver, | |
| 407 Handle<JSObject> holder, | |
| 408 const CallOptimization& call_optimization) { | |
| 409 Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC); | |
| 410 if (!stub.is_null()) return stub; | |
| 411 | |
| 412 KeyedLoadStubCompiler compiler(isolate_); | |
| 413 Handle<Code> handler = | |
| 414 compiler.CompileLoadCallback(receiver, holder, name, call_optimization); | |
| 415 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 416 return handler; | |
| 417 } | |
| 418 | |
| 419 | |
| 420 Handle<Code> StubCache::ComputeStoreField(Handle<Name> name, | |
| 421 Handle<JSObject> receiver, | |
| 422 LookupResult* lookup, | |
| 423 StrictModeFlag strict_mode) { | |
| 424 Handle<Code> stub = FindStoreHandler( | |
| 425 name, receiver, Code::STORE_IC, strict_mode); | |
| 426 if (!stub.is_null()) return stub; | |
| 427 | |
| 428 StoreStubCompiler compiler(isolate_, strict_mode); | |
| 429 Handle<Code> handler = compiler.CompileStoreField(receiver, lookup, name); | |
| 430 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 431 return handler; | |
| 432 } | |
| 433 | |
| 434 | |
| 435 Handle<Code> StubCache::ComputeStoreTransition(Handle<Name> name, | |
| 436 Handle<JSObject> receiver, | |
| 437 LookupResult* lookup, | |
| 438 Handle<Map> transition, | |
| 439 StrictModeFlag strict_mode) { | |
| 440 Handle<Code> stub = FindStoreHandler( | |
| 441 name, receiver, Code::STORE_IC, strict_mode); | |
| 442 if (!stub.is_null()) return stub; | |
| 443 | |
| 444 StoreStubCompiler compiler(isolate_, strict_mode); | |
| 445 Handle<Code> handler = | |
| 446 compiler.CompileStoreTransition(receiver, lookup, transition, name); | |
| 447 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 448 return handler; | |
| 449 } | |
| 450 | |
| 451 | |
| 452 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { | 221 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { |
| 453 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); | 222 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); |
| 454 Handle<Name> name = | 223 Handle<Name> name = |
| 455 isolate()->factory()->KeyedLoadElementMonomorphic_string(); | 224 isolate()->factory()->KeyedLoadElementMonomorphic_string(); |
| 456 | 225 |
| 457 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); | 226 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); |
| 458 if (probe->IsCode()) return Handle<Code>::cast(probe); | 227 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 459 | 228 |
| 460 KeyedLoadStubCompiler compiler(isolate()); | 229 KeyedLoadStubCompiler compiler(isolate()); |
| 461 Handle<Code> code = compiler.CompileLoadElement(receiver_map); | 230 Handle<Code> code = compiler.CompileLoadElement(receiver_map); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 486 | 255 |
| 487 KeyedStoreStubCompiler compiler(isolate(), strict_mode, store_mode); | 256 KeyedStoreStubCompiler compiler(isolate(), strict_mode, store_mode); |
| 488 Handle<Code> code = compiler.CompileStoreElement(receiver_map); | 257 Handle<Code> code = compiler.CompileStoreElement(receiver_map); |
| 489 | 258 |
| 490 Map::UpdateCodeCache(receiver_map, name, code); | 259 Map::UpdateCodeCache(receiver_map, name, code); |
| 491 ASSERT(Code::GetKeyedAccessStoreMode(code->extra_ic_state()) == store_mode); | 260 ASSERT(Code::GetKeyedAccessStoreMode(code->extra_ic_state()) == store_mode); |
| 492 return code; | 261 return code; |
| 493 } | 262 } |
| 494 | 263 |
| 495 | 264 |
| 496 Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) { | |
| 497 return (strict_mode == kStrictMode) | |
| 498 ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict() | |
| 499 : isolate_->builtins()->Builtins::StoreIC_Normal(); | |
| 500 } | |
| 501 | |
| 502 | |
| 503 Handle<Code> StubCache::ComputeStoreGlobal(Handle<Name> name, | 265 Handle<Code> StubCache::ComputeStoreGlobal(Handle<Name> name, |
| 504 Handle<GlobalObject> receiver, | 266 Handle<GlobalObject> receiver, |
| 505 Handle<PropertyCell> cell, | 267 Handle<PropertyCell> cell, |
| 506 Handle<Object> value, | 268 Handle<Object> value, |
| 507 StrictModeFlag strict_mode) { | 269 StrictModeFlag strict_mode) { |
| 508 Isolate* isolate = cell->GetIsolate(); | 270 Handle<Type> union_type = PropertyCell::UpdatedType(cell, value); |
| 509 Handle<Type> union_type(PropertyCell::UpdateType(cell, value), isolate); | |
| 510 bool is_constant = union_type->IsConstant(); | 271 bool is_constant = union_type->IsConstant(); |
| 511 StoreGlobalStub stub(strict_mode, is_constant); | 272 StoreGlobalStub stub(strict_mode, is_constant); |
| 512 | 273 |
| 513 Handle<Code> code = FindIC( | 274 Handle<Code> code = FindIC( |
| 514 name, Handle<JSObject>::cast(receiver), | 275 name, Handle<JSObject>::cast(receiver), |
| 515 Code::STORE_IC, stub.GetExtraICState()); | 276 Code::STORE_IC, stub.GetExtraICState()); |
| 516 if (!code.is_null()) return code; | 277 if (!code.is_null()) return code; |
| 517 | 278 |
| 518 // Replace the placeholder cell and global object map with the actual global | 279 // Replace the placeholder cell and global object map with the actual global |
| 519 // cell and receiver map. | 280 // cell and receiver map. |
| 520 Handle<Map> meta_map(isolate_->heap()->meta_map()); | 281 Handle<Map> meta_map(isolate_->heap()->meta_map()); |
| 521 Handle<Object> receiver_map(receiver->map(), isolate_); | 282 Handle<Object> receiver_map(receiver->map(), isolate_); |
| 522 code = stub.GetCodeCopyFromTemplate(isolate_); | 283 code = stub.GetCodeCopyFromTemplate(isolate_); |
| 523 code->ReplaceNthObject(1, *meta_map, *receiver_map); | 284 code->ReplaceNthObject(1, *meta_map, *receiver_map); |
| 524 Handle<Map> cell_map(isolate_->heap()->global_property_cell_map()); | 285 Handle<Map> cell_map(isolate_->heap()->global_property_cell_map()); |
| 525 code->ReplaceNthObject(1, *cell_map, *cell); | 286 code->ReplaceNthObject(1, *cell_map, *cell); |
| 526 | 287 |
| 527 HeapObject::UpdateMapCodeCache(receiver, name, code); | 288 HeapObject::UpdateMapCodeCache(receiver, name, code); |
| 528 | 289 |
| 529 return code; | 290 return code; |
| 530 } | 291 } |
| 531 | 292 |
| 532 | 293 |
| 533 Handle<Code> StubCache::ComputeStoreCallback( | |
| 534 Handle<Name> name, | |
| 535 Handle<JSObject> receiver, | |
| 536 Handle<JSObject> holder, | |
| 537 Handle<ExecutableAccessorInfo> callback, | |
| 538 StrictModeFlag strict_mode) { | |
| 539 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); | |
| 540 Handle<Code> stub = FindStoreHandler( | |
| 541 name, receiver, Code::STORE_IC, strict_mode); | |
| 542 if (!stub.is_null()) return stub; | |
| 543 | |
| 544 StoreStubCompiler compiler(isolate_, strict_mode); | |
| 545 Handle<Code> handler = compiler.CompileStoreCallback( | |
| 546 receiver, holder, name, callback); | |
| 547 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 548 return handler; | |
| 549 } | |
| 550 | |
| 551 | |
| 552 Handle<Code> StubCache::ComputeStoreCallback( | |
| 553 Handle<Name> name, | |
| 554 Handle<JSObject> receiver, | |
| 555 Handle<JSObject> holder, | |
| 556 const CallOptimization& call_optimization, | |
| 557 StrictModeFlag strict_mode) { | |
| 558 Handle<Code> stub = FindStoreHandler( | |
| 559 name, receiver, Code::STORE_IC, strict_mode); | |
| 560 if (!stub.is_null()) return stub; | |
| 561 | |
| 562 StoreStubCompiler compiler(isolate_, strict_mode); | |
| 563 Handle<Code> handler = compiler.CompileStoreCallback( | |
| 564 receiver, holder, name, call_optimization); | |
| 565 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 566 return handler; | |
| 567 } | |
| 568 | |
| 569 | |
| 570 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<Name> name, | |
| 571 Handle<JSObject> receiver, | |
| 572 Handle<JSObject> holder, | |
| 573 Handle<JSFunction> setter, | |
| 574 StrictModeFlag strict_mode) { | |
| 575 Handle<Code> stub = FindStoreHandler( | |
| 576 name, receiver, Code::STORE_IC, strict_mode); | |
| 577 if (!stub.is_null()) return stub; | |
| 578 | |
| 579 StoreStubCompiler compiler(isolate_, strict_mode); | |
| 580 Handle<Code> handler = compiler.CompileStoreViaSetter( | |
| 581 receiver, holder, name, setter); | |
| 582 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 583 return handler; | |
| 584 } | |
| 585 | |
| 586 | |
| 587 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<Name> name, | |
| 588 Handle<JSObject> receiver, | |
| 589 StrictModeFlag strict_mode) { | |
| 590 Handle<Code> stub = FindStoreHandler( | |
| 591 name, receiver, Code::STORE_IC, strict_mode); | |
| 592 if (!stub.is_null()) return stub; | |
| 593 | |
| 594 StoreStubCompiler compiler(isolate_, strict_mode); | |
| 595 Handle<Code> handler = compiler.CompileStoreInterceptor(receiver, name); | |
| 596 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 597 return handler; | |
| 598 } | |
| 599 | |
| 600 | |
| 601 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<Name> name, | |
| 602 Handle<JSObject> receiver, | |
| 603 LookupResult* lookup, | |
| 604 StrictModeFlag strict_mode) { | |
| 605 Handle<Code> stub = FindStoreHandler( | |
| 606 name, receiver, Code::KEYED_STORE_IC, strict_mode); | |
| 607 if (!stub.is_null()) return stub; | |
| 608 | |
| 609 KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE); | |
| 610 Handle<Code> handler = compiler.CompileStoreField(receiver, lookup, name); | |
| 611 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 612 return handler; | |
| 613 } | |
| 614 | |
| 615 | |
| 616 Handle<Code> StubCache::ComputeKeyedStoreTransition( | |
| 617 Handle<Name> name, | |
| 618 Handle<JSObject> receiver, | |
| 619 LookupResult* lookup, | |
| 620 Handle<Map> transition, | |
| 621 StrictModeFlag strict_mode) { | |
| 622 Handle<Code> stub = FindStoreHandler( | |
| 623 name, receiver, Code::KEYED_STORE_IC, strict_mode); | |
| 624 if (!stub.is_null()) return stub; | |
| 625 | |
| 626 KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE); | |
| 627 Handle<Code> handler = | |
| 628 compiler.CompileStoreTransition(receiver, lookup, transition, name); | |
| 629 HeapObject::UpdateMapCodeCache(receiver, name, handler); | |
| 630 return handler; | |
| 631 } | |
| 632 | |
| 633 | |
| 634 #define CALL_LOGGER_TAG(kind, type) \ | 294 #define CALL_LOGGER_TAG(kind, type) \ |
| 635 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) | 295 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) |
| 636 | 296 |
| 637 Handle<Code> StubCache::ComputeCallConstant(int argc, | 297 Handle<Code> StubCache::ComputeCallConstant(int argc, |
| 638 Code::Kind kind, | 298 Code::Kind kind, |
| 639 Code::ExtraICState extra_state, | 299 Code::ExtraICState extra_state, |
| 640 Handle<Name> name, | 300 Handle<Name> name, |
| 641 Handle<Object> object, | 301 Handle<Object> object, |
| 642 Handle<JSObject> holder, | 302 Handle<JSObject> holder, |
| 643 Handle<JSFunction> function) { | 303 Handle<JSFunction> function) { |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 | 876 |
| 1217 // Throw a reference error. | 877 // Throw a reference error. |
| 1218 Handle<Name> name_handle(name); | 878 Handle<Name> name_handle(name); |
| 1219 Handle<Object> error = | 879 Handle<Object> error = |
| 1220 isolate->factory()->NewReferenceError("not_defined", | 880 isolate->factory()->NewReferenceError("not_defined", |
| 1221 HandleVector(&name_handle, 1)); | 881 HandleVector(&name_handle, 1)); |
| 1222 return isolate->Throw(*error); | 882 return isolate->Throw(*error); |
| 1223 } | 883 } |
| 1224 | 884 |
| 1225 | 885 |
| 1226 static MaybeObject* LoadWithInterceptor(Arguments* args, | 886 static Handle<Object> LoadWithInterceptor(Arguments* args, |
| 1227 PropertyAttributes* attrs) { | 887 PropertyAttributes* attrs) { |
| 1228 ASSERT(args->length() == StubCache::kInterceptorArgsLength); | 888 ASSERT(args->length() == StubCache::kInterceptorArgsLength); |
| 1229 Handle<Name> name_handle = | 889 Handle<Name> name_handle = |
| 1230 args->at<Name>(StubCache::kInterceptorArgsNameIndex); | 890 args->at<Name>(StubCache::kInterceptorArgsNameIndex); |
| 1231 Handle<InterceptorInfo> interceptor_info = | 891 Handle<InterceptorInfo> interceptor_info = |
| 1232 args->at<InterceptorInfo>(StubCache::kInterceptorArgsInfoIndex); | 892 args->at<InterceptorInfo>(StubCache::kInterceptorArgsInfoIndex); |
| 1233 Handle<JSObject> receiver_handle = | 893 Handle<JSObject> receiver_handle = |
| 1234 args->at<JSObject>(StubCache::kInterceptorArgsThisIndex); | 894 args->at<JSObject>(StubCache::kInterceptorArgsThisIndex); |
| 1235 Handle<JSObject> holder_handle = | 895 Handle<JSObject> holder_handle = |
| 1236 args->at<JSObject>(StubCache::kInterceptorArgsHolderIndex); | 896 args->at<JSObject>(StubCache::kInterceptorArgsHolderIndex); |
| 1237 | 897 |
| 1238 Isolate* isolate = receiver_handle->GetIsolate(); | 898 Isolate* isolate = receiver_handle->GetIsolate(); |
| 1239 | 899 |
| 1240 // TODO(rossberg): Support symbols in the API. | 900 // TODO(rossberg): Support symbols in the API. |
| 1241 if (name_handle->IsSymbol()) | 901 if (name_handle->IsSymbol()) { |
| 1242 return holder_handle->GetPropertyPostInterceptor( | 902 return JSObject::GetPropertyPostInterceptor( |
| 1243 *receiver_handle, *name_handle, attrs); | 903 holder_handle, receiver_handle, name_handle, attrs); |
| 904 } |
| 1244 Handle<String> name = Handle<String>::cast(name_handle); | 905 Handle<String> name = Handle<String>::cast(name_handle); |
| 1245 | 906 |
| 1246 Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); | 907 Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); |
| 1247 v8::NamedPropertyGetterCallback getter = | 908 v8::NamedPropertyGetterCallback getter = |
| 1248 FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address); | 909 FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address); |
| 1249 ASSERT(getter != NULL); | 910 ASSERT(getter != NULL); |
| 1250 | 911 |
| 1251 PropertyCallbackArguments callback_args(isolate, | 912 PropertyCallbackArguments callback_args(isolate, |
| 1252 interceptor_info->data(), | 913 interceptor_info->data(), |
| 1253 *receiver_handle, | 914 *receiver_handle, |
| 1254 *holder_handle); | 915 *holder_handle); |
| 1255 { | 916 { |
| 917 HandleScope scope(isolate); |
| 1256 // Use the interceptor getter. | 918 // Use the interceptor getter. |
| 1257 HandleScope scope(isolate); | |
| 1258 v8::Handle<v8::Value> r = | 919 v8::Handle<v8::Value> r = |
| 1259 callback_args.Call(getter, v8::Utils::ToLocal(name)); | 920 callback_args.Call(getter, v8::Utils::ToLocal(name)); |
| 1260 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 921 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 1261 if (!r.IsEmpty()) { | 922 if (!r.IsEmpty()) { |
| 1262 *attrs = NONE; | 923 *attrs = NONE; |
| 1263 Handle<Object> result = v8::Utils::OpenHandle(*r); | 924 Handle<Object> result = v8::Utils::OpenHandle(*r); |
| 1264 result->VerifyApiCallResultType(); | 925 result->VerifyApiCallResultType(); |
| 1265 return *result; | 926 return scope.CloseAndEscape(result); |
| 1266 } | 927 } |
| 1267 } | 928 } |
| 1268 | 929 |
| 1269 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( | 930 Handle<Object> result = JSObject::GetPropertyPostInterceptor( |
| 1270 *receiver_handle, | 931 holder_handle, receiver_handle, name_handle, attrs); |
| 1271 *name_handle, | |
| 1272 attrs); | |
| 1273 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | |
| 1274 return result; | 932 return result; |
| 1275 } | 933 } |
| 1276 | 934 |
| 1277 | 935 |
| 1278 /** | 936 /** |
| 1279 * Loads a property with an interceptor performing post interceptor | 937 * Loads a property with an interceptor performing post interceptor |
| 1280 * lookup if interceptor failed. | 938 * lookup if interceptor failed. |
| 1281 */ | 939 */ |
| 1282 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) { | 940 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) { |
| 1283 PropertyAttributes attr = NONE; | 941 PropertyAttributes attr = NONE; |
| 1284 Object* result; | 942 HandleScope scope(isolate); |
| 1285 { MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr); | 943 Handle<Object> result = LoadWithInterceptor(&args, &attr); |
| 1286 if (!maybe_result->ToObject(&result)) return maybe_result; | 944 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 1287 } | |
| 1288 | 945 |
| 1289 // If the property is present, return it. | 946 // If the property is present, return it. |
| 1290 if (attr != ABSENT) return result; | 947 if (attr != ABSENT) return *result; |
| 1291 return ThrowReferenceError(isolate, Name::cast(args[0])); | 948 return ThrowReferenceError(isolate, Name::cast(args[0])); |
| 1292 } | 949 } |
| 1293 | 950 |
| 1294 | 951 |
| 1295 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) { | 952 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) { |
| 1296 PropertyAttributes attr; | 953 PropertyAttributes attr; |
| 1297 MaybeObject* result = LoadWithInterceptor(&args, &attr); | 954 HandleScope scope(isolate); |
| 1298 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 955 Handle<Object> result = LoadWithInterceptor(&args, &attr); |
| 956 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 1299 // This is call IC. In this case, we simply return the undefined result which | 957 // This is call IC. In this case, we simply return the undefined result which |
| 1300 // will lead to an exception when trying to invoke the result as a | 958 // will lead to an exception when trying to invoke the result as a |
| 1301 // function. | 959 // function. |
| 1302 return result; | 960 return *result; |
| 1303 } | 961 } |
| 1304 | 962 |
| 1305 | 963 |
| 1306 RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { | 964 RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { |
| 1307 HandleScope scope(isolate); | 965 HandleScope scope(isolate); |
| 1308 ASSERT(args.length() == 4); | 966 ASSERT(args.length() == 4); |
| 1309 Handle<JSObject> recv(JSObject::cast(args[0])); | 967 Handle<JSObject> recv(JSObject::cast(args[0])); |
| 1310 Handle<Name> name(Name::cast(args[1])); | 968 Handle<Name> name(Name::cast(args[1])); |
| 1311 Handle<Object> value(args[2], isolate); | 969 Handle<Object> value(args[2], isolate); |
| 1312 ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode); | 970 ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode); |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1503 holder->LocalLookupRealNamedProperty(*name, lookup); | 1161 holder->LocalLookupRealNamedProperty(*name, lookup); |
| 1504 if (lookup->IsFound()) return; | 1162 if (lookup->IsFound()) return; |
| 1505 if (holder->GetPrototype()->IsNull()) return; | 1163 if (holder->GetPrototype()->IsNull()) return; |
| 1506 holder->GetPrototype()->Lookup(*name, lookup); | 1164 holder->GetPrototype()->Lookup(*name, lookup); |
| 1507 } | 1165 } |
| 1508 | 1166 |
| 1509 | 1167 |
| 1510 #define __ ACCESS_MASM(masm()) | 1168 #define __ ACCESS_MASM(masm()) |
| 1511 | 1169 |
| 1512 | 1170 |
| 1513 Register BaseLoadStubCompiler::HandlerFrontendHeader( | 1171 Register LoadStubCompiler::HandlerFrontendHeader( |
| 1514 Handle<JSObject> object, | 1172 Handle<JSObject> object, |
| 1515 Register object_reg, | 1173 Register object_reg, |
| 1516 Handle<JSObject> holder, | 1174 Handle<JSObject> holder, |
| 1517 Handle<Name> name, | 1175 Handle<Name> name, |
| 1518 Label* miss) { | 1176 Label* miss) { |
| 1519 return CheckPrototypes(object, object_reg, holder, | 1177 return CheckPrototypes(object, object_reg, holder, |
| 1520 scratch1(), scratch2(), scratch3(), | 1178 scratch1(), scratch2(), scratch3(), |
| 1521 name, miss, SKIP_RECEIVER); | 1179 name, miss, SKIP_RECEIVER); |
| 1522 } | 1180 } |
| 1523 | 1181 |
| 1524 | 1182 |
| 1525 // HandlerFrontend for store uses the name register. It has to be restored | 1183 // HandlerFrontend for store uses the name register. It has to be restored |
| 1526 // before a miss. | 1184 // before a miss. |
| 1527 Register BaseStoreStubCompiler::HandlerFrontendHeader( | 1185 Register StoreStubCompiler::HandlerFrontendHeader( |
| 1528 Handle<JSObject> object, | 1186 Handle<JSObject> object, |
| 1529 Register object_reg, | 1187 Register object_reg, |
| 1530 Handle<JSObject> holder, | 1188 Handle<JSObject> holder, |
| 1531 Handle<Name> name, | 1189 Handle<Name> name, |
| 1532 Label* miss) { | 1190 Label* miss) { |
| 1533 return CheckPrototypes(object, object_reg, holder, | 1191 return CheckPrototypes(object, object_reg, holder, |
| 1534 this->name(), scratch1(), scratch2(), | 1192 this->name(), scratch1(), scratch2(), |
| 1535 name, miss, SKIP_RECEIVER); | 1193 name, miss, SKIP_RECEIVER); |
| 1536 } | 1194 } |
| 1537 | 1195 |
| 1538 | 1196 |
| 1539 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<JSObject> object, | 1197 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<JSObject> object, |
| 1540 Register object_reg, | 1198 Register object_reg, |
| 1541 Handle<JSObject> holder, | 1199 Handle<JSObject> holder, |
| 1542 Handle<Name> name, | 1200 Handle<Name> name, |
| 1543 Label* success) { | 1201 Label* success) { |
| 1544 Label miss; | 1202 Label miss; |
| 1545 | 1203 |
| 1546 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); | 1204 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); |
| 1547 | 1205 |
| 1548 HandlerFrontendFooter(name, success, &miss); | 1206 HandlerFrontendFooter(name, success, &miss); |
| 1549 return reg; | 1207 return reg; |
| 1550 } | 1208 } |
| 1551 | 1209 |
| 1552 | 1210 |
| 1553 Handle<Code> BaseLoadStubCompiler::CompileLoadField( | 1211 Handle<Code> LoadStubCompiler::CompileLoadField( |
| 1554 Handle<JSObject> object, | 1212 Handle<JSObject> object, |
| 1555 Handle<JSObject> holder, | 1213 Handle<JSObject> holder, |
| 1556 Handle<Name> name, | 1214 Handle<Name> name, |
| 1557 PropertyIndex field, | 1215 PropertyIndex field, |
| 1558 Representation representation) { | 1216 Representation representation) { |
| 1559 Label miss; | 1217 Label miss; |
| 1560 | 1218 |
| 1561 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); | 1219 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); |
| 1562 | 1220 |
| 1563 GenerateLoadField(reg, holder, field, representation); | 1221 GenerateLoadField(reg, holder, field, representation); |
| 1564 | 1222 |
| 1565 __ bind(&miss); | 1223 __ bind(&miss); |
| 1566 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1224 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 1567 | 1225 |
| 1568 // Return the generated code. | 1226 // Return the generated code. |
| 1569 return GetCode(kind(), Code::FIELD, name); | 1227 return GetCode(kind(), Code::FIELD, name); |
| 1570 } | 1228 } |
| 1571 | 1229 |
| 1572 | 1230 |
| 1573 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( | 1231 Handle<Code> LoadStubCompiler::CompileLoadConstant( |
| 1574 Handle<JSObject> object, | 1232 Handle<JSObject> object, |
| 1575 Handle<JSObject> holder, | 1233 Handle<JSObject> holder, |
| 1576 Handle<Name> name, | 1234 Handle<Name> name, |
| 1577 Handle<Object> value) { | 1235 Handle<Object> value) { |
| 1578 Label success; | 1236 Label success; |
| 1579 HandlerFrontend(object, receiver(), holder, name, &success); | 1237 HandlerFrontend(object, receiver(), holder, name, &success); |
| 1580 __ bind(&success); | 1238 __ bind(&success); |
| 1581 GenerateLoadConstant(value); | 1239 GenerateLoadConstant(value); |
| 1582 | 1240 |
| 1583 // Return the generated code. | 1241 // Return the generated code. |
| 1584 return GetCode(kind(), Code::CONSTANT, name); | 1242 return GetCode(kind(), Code::CONSTANT, name); |
| 1585 } | 1243 } |
| 1586 | 1244 |
| 1587 | 1245 |
| 1588 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( | 1246 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
| 1589 Handle<JSObject> object, | 1247 Handle<JSObject> object, |
| 1590 Handle<JSObject> holder, | 1248 Handle<JSObject> holder, |
| 1591 Handle<Name> name, | 1249 Handle<Name> name, |
| 1592 Handle<ExecutableAccessorInfo> callback) { | 1250 Handle<ExecutableAccessorInfo> callback) { |
| 1593 Label success; | 1251 Label success; |
| 1594 | 1252 |
| 1595 Register reg = CallbackHandlerFrontend( | 1253 Register reg = CallbackHandlerFrontend( |
| 1596 object, receiver(), holder, name, &success, callback); | 1254 object, receiver(), holder, name, &success, callback); |
| 1597 __ bind(&success); | 1255 __ bind(&success); |
| 1598 GenerateLoadCallback(reg, callback); | 1256 GenerateLoadCallback(reg, callback); |
| 1599 | 1257 |
| 1600 // Return the generated code. | 1258 // Return the generated code. |
| 1601 return GetCode(kind(), Code::CALLBACKS, name); | 1259 return GetCode(kind(), Code::CALLBACKS, name); |
| 1602 } | 1260 } |
| 1603 | 1261 |
| 1604 | 1262 |
| 1605 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( | 1263 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
| 1606 Handle<JSObject> object, | 1264 Handle<JSObject> object, |
| 1607 Handle<JSObject> holder, | 1265 Handle<JSObject> holder, |
| 1608 Handle<Name> name, | 1266 Handle<Name> name, |
| 1609 const CallOptimization& call_optimization) { | 1267 const CallOptimization& call_optimization) { |
| 1610 ASSERT(call_optimization.is_simple_api_call()); | 1268 ASSERT(call_optimization.is_simple_api_call()); |
| 1611 Label success; | 1269 Label success; |
| 1612 | 1270 |
| 1613 Handle<JSFunction> callback = call_optimization.constant_function(); | 1271 Handle<JSFunction> callback = call_optimization.constant_function(); |
| 1614 CallbackHandlerFrontend( | 1272 CallbackHandlerFrontend( |
| 1615 object, receiver(), holder, name, &success, callback); | 1273 object, receiver(), holder, name, &success, callback); |
| 1616 __ bind(&success); | 1274 __ bind(&success); |
| 1617 GenerateLoadCallback(call_optimization); | 1275 GenerateLoadCallback(call_optimization); |
| 1618 | 1276 |
| 1619 // Return the generated code. | 1277 // Return the generated code. |
| 1620 return GetCode(kind(), Code::CALLBACKS, name); | 1278 return GetCode(kind(), Code::CALLBACKS, name); |
| 1621 } | 1279 } |
| 1622 | 1280 |
| 1623 | 1281 |
| 1624 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( | 1282 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( |
| 1625 Handle<JSObject> object, | 1283 Handle<JSObject> object, |
| 1626 Handle<JSObject> holder, | 1284 Handle<JSObject> holder, |
| 1627 Handle<Name> name) { | 1285 Handle<Name> name) { |
| 1628 Label success; | 1286 Label success; |
| 1629 | 1287 |
| 1630 LookupResult lookup(isolate()); | 1288 LookupResult lookup(isolate()); |
| 1631 LookupPostInterceptor(holder, name, &lookup); | 1289 LookupPostInterceptor(holder, name, &lookup); |
| 1632 | 1290 |
| 1633 Register reg = HandlerFrontend(object, receiver(), holder, name, &success); | 1291 Register reg = HandlerFrontend(object, receiver(), holder, name, &success); |
| 1634 __ bind(&success); | 1292 __ bind(&success); |
| 1635 // TODO(368): Compile in the whole chain: all the interceptors in | 1293 // TODO(368): Compile in the whole chain: all the interceptors in |
| 1636 // prototypes and ultimate answer. | 1294 // prototypes and ultimate answer. |
| 1637 GenerateLoadInterceptor(reg, object, holder, &lookup, name); | 1295 GenerateLoadInterceptor(reg, object, holder, &lookup, name); |
| 1638 | 1296 |
| 1639 // Return the generated code. | 1297 // Return the generated code. |
| 1640 return GetCode(kind(), Code::INTERCEPTOR, name); | 1298 return GetCode(kind(), Code::INTERCEPTOR, name); |
| 1641 } | 1299 } |
| 1642 | 1300 |
| 1643 | 1301 |
| 1644 void BaseLoadStubCompiler::GenerateLoadPostInterceptor( | 1302 void LoadStubCompiler::GenerateLoadPostInterceptor( |
| 1645 Register interceptor_reg, | 1303 Register interceptor_reg, |
| 1646 Handle<JSObject> interceptor_holder, | 1304 Handle<JSObject> interceptor_holder, |
| 1647 Handle<Name> name, | 1305 Handle<Name> name, |
| 1648 LookupResult* lookup) { | 1306 LookupResult* lookup) { |
| 1649 Label success; | 1307 Label success; |
| 1650 Handle<JSObject> holder(lookup->holder()); | 1308 Handle<JSObject> holder(lookup->holder()); |
| 1651 if (lookup->IsField()) { | 1309 if (lookup->IsField()) { |
| 1652 PropertyIndex field = lookup->GetFieldIndex(); | 1310 PropertyIndex field = lookup->GetFieldIndex(); |
| 1653 if (interceptor_holder.is_identical_to(holder)) { | 1311 if (interceptor_holder.is_identical_to(holder)) { |
| 1654 GenerateLoadField( | 1312 GenerateLoadField( |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1693 | 1351 |
| 1694 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 1352 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( |
| 1695 Handle<JSObject> object, | 1353 Handle<JSObject> object, |
| 1696 Handle<JSObject> holder, | 1354 Handle<JSObject> holder, |
| 1697 Handle<Name> name, | 1355 Handle<Name> name, |
| 1698 Handle<JSFunction> getter) { | 1356 Handle<JSFunction> getter) { |
| 1699 Label success; | 1357 Label success; |
| 1700 HandlerFrontend(object, receiver(), holder, name, &success); | 1358 HandlerFrontend(object, receiver(), holder, name, &success); |
| 1701 | 1359 |
| 1702 __ bind(&success); | 1360 __ bind(&success); |
| 1703 GenerateLoadViaGetter(masm(), getter); | 1361 GenerateLoadViaGetter(masm(), receiver(), getter); |
| 1704 | 1362 |
| 1705 // Return the generated code. | 1363 // Return the generated code. |
| 1706 return GetCode(kind(), Code::CALLBACKS, name); | 1364 return GetCode(kind(), Code::CALLBACKS, name); |
| 1707 } | 1365 } |
| 1708 | 1366 |
| 1709 | 1367 |
| 1710 Handle<Code> BaseStoreStubCompiler::CompileStoreTransition( | 1368 Handle<Code> StoreStubCompiler::CompileStoreTransition( |
| 1711 Handle<JSObject> object, | 1369 Handle<JSObject> object, |
| 1712 LookupResult* lookup, | 1370 LookupResult* lookup, |
| 1713 Handle<Map> transition, | 1371 Handle<Map> transition, |
| 1714 Handle<Name> name) { | 1372 Handle<Name> name) { |
| 1715 Label miss, slow; | 1373 Label miss, slow; |
| 1716 | 1374 |
| 1717 // Ensure no transitions to deprecated maps are followed. | 1375 // Ensure no transitions to deprecated maps are followed. |
| 1718 __ CheckMapDeprecated(transition, scratch1(), &miss); | 1376 __ CheckMapDeprecated(transition, scratch1(), &miss); |
| 1719 | 1377 |
| 1720 // Check that we are allowed to write this. | 1378 // Check that we are allowed to write this. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1415 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 1758 | 1416 |
| 1759 GenerateRestoreName(masm(), &slow, name); | 1417 GenerateRestoreName(masm(), &slow, name); |
| 1760 TailCallBuiltin(masm(), SlowBuiltin(kind())); | 1418 TailCallBuiltin(masm(), SlowBuiltin(kind())); |
| 1761 | 1419 |
| 1762 // Return the generated code. | 1420 // Return the generated code. |
| 1763 return GetCode(kind(), Code::TRANSITION, name); | 1421 return GetCode(kind(), Code::TRANSITION, name); |
| 1764 } | 1422 } |
| 1765 | 1423 |
| 1766 | 1424 |
| 1767 Handle<Code> BaseStoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 1425 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
| 1768 LookupResult* lookup, | 1426 LookupResult* lookup, |
| 1769 Handle<Name> name) { | 1427 Handle<Name> name) { |
| 1770 Label miss; | 1428 Label miss; |
| 1771 | 1429 |
| 1772 HandlerFrontendHeader(object, receiver(), object, name, &miss); | 1430 HandlerFrontendHeader(object, receiver(), object, name, &miss); |
| 1773 | 1431 |
| 1774 // Generate store field code. | 1432 // Generate store field code. |
| 1775 GenerateStoreField(masm(), | 1433 GenerateStoreField(masm(), |
| 1776 object, | 1434 object, |
| 1777 lookup, | 1435 lookup, |
| 1778 receiver(), this->name(), value(), scratch1(), scratch2(), | 1436 receiver(), this->name(), value(), scratch1(), scratch2(), |
| 1779 &miss); | 1437 &miss); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1852 | 1510 |
| 1853 #undef __ | 1511 #undef __ |
| 1854 | 1512 |
| 1855 | 1513 |
| 1856 void StubCompiler::TailCallBuiltin(MacroAssembler* masm, Builtins::Name name) { | 1514 void StubCompiler::TailCallBuiltin(MacroAssembler* masm, Builtins::Name name) { |
| 1857 Handle<Code> code(masm->isolate()->builtins()->builtin(name)); | 1515 Handle<Code> code(masm->isolate()->builtins()->builtin(name)); |
| 1858 GenerateTailCall(masm, code); | 1516 GenerateTailCall(masm, code); |
| 1859 } | 1517 } |
| 1860 | 1518 |
| 1861 | 1519 |
| 1862 void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { | 1520 void BaseLoadStoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { |
| 1863 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 1521 #ifdef ENABLE_GDB_JIT_INTERFACE |
| 1522 GDBJITInterface::CodeTag tag; |
| 1523 if (kind_ == Code::LOAD_IC) { |
| 1524 tag = GDBJITInterface::LOAD_IC; |
| 1525 } else if (kind_ == Code::KEYED_LOAD_IC) { |
| 1526 tag = GDBJITInterface::KEYED_LOAD_IC; |
| 1527 } else if (kind_ == Code::STORE_IC) { |
| 1528 tag = GDBJITInterface::STORE_IC; |
| 1529 } else { |
| 1530 tag = GDBJITInterface::KEYED_STORE_IC; |
| 1531 } |
| 1532 GDBJIT(AddCode(tag, *name, *code)); |
| 1533 #endif |
| 1864 } | 1534 } |
| 1865 | 1535 |
| 1866 | 1536 |
| 1867 void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { | 1537 void BaseLoadStoreStubCompiler::InitializeRegisters() { |
| 1868 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); | 1538 if (kind_ == Code::LOAD_IC) { |
| 1539 registers_ = LoadStubCompiler::registers(); |
| 1540 } else if (kind_ == Code::KEYED_LOAD_IC) { |
| 1541 registers_ = KeyedLoadStubCompiler::registers(); |
| 1542 } else if (kind_ == Code::STORE_IC) { |
| 1543 registers_ = StoreStubCompiler::registers(); |
| 1544 } else { |
| 1545 registers_ = KeyedStoreStubCompiler::registers(); |
| 1546 } |
| 1869 } | 1547 } |
| 1870 | 1548 |
| 1871 | 1549 |
| 1872 void StoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { | |
| 1873 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); | |
| 1874 } | |
| 1875 | |
| 1876 | |
| 1877 void KeyedStoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { | |
| 1878 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); | |
| 1879 } | |
| 1880 | |
| 1881 | |
| 1882 Handle<Code> BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind, | 1550 Handle<Code> BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind, |
| 1883 Code::StubType type, | 1551 Code::StubType type, |
| 1884 Handle<Name> name, | 1552 Handle<Name> name, |
| 1885 InlineCacheState state) { | 1553 InlineCacheState state) { |
| 1886 Code::Flags flags = Code::ComputeFlags(kind, state, extra_state(), type); | 1554 Code::Flags flags = Code::ComputeFlags(kind, state, extra_state(), type); |
| 1887 Handle<Code> code = GetCodeWithFlags(flags, name); | 1555 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1888 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | 1556 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
| 1889 JitEvent(name, code); | 1557 JitEvent(name, code); |
| 1890 return code; | 1558 return code; |
| 1891 } | 1559 } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2149 Handle<FunctionTemplateInfo>( | 1817 Handle<FunctionTemplateInfo>( |
| 2150 FunctionTemplateInfo::cast(signature->receiver())); | 1818 FunctionTemplateInfo::cast(signature->receiver())); |
| 2151 } | 1819 } |
| 2152 } | 1820 } |
| 2153 | 1821 |
| 2154 is_simple_api_call_ = true; | 1822 is_simple_api_call_ = true; |
| 2155 } | 1823 } |
| 2156 | 1824 |
| 2157 | 1825 |
| 2158 } } // namespace v8::internal | 1826 } } // namespace v8::internal |
| OLD | NEW |