| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 __ mov(dst, FieldOperand(src, offset)); | 266 __ mov(dst, FieldOperand(src, offset)); |
| 267 } else { | 267 } else { |
| 268 // Calculate the offset into the properties array. | 268 // Calculate the offset into the properties array. |
| 269 int offset = index * kPointerSize + Array::kHeaderSize; | 269 int offset = index * kPointerSize + Array::kHeaderSize; |
| 270 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); | 270 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); |
| 271 __ mov(dst, FieldOperand(dst, offset)); | 271 __ mov(dst, FieldOperand(dst, offset)); |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 | 274 |
| 275 | 275 |
| 276 void StubCompiler::GenerateLoadField(MacroAssembler* masm, | |
| 277 JSObject* object, | |
| 278 JSObject* holder, | |
| 279 Register receiver, | |
| 280 Register scratch1, | |
| 281 Register scratch2, | |
| 282 int index, | |
| 283 Label* miss_label) { | |
| 284 // Check that the receiver isn't a smi. | |
| 285 __ test(receiver, Immediate(kSmiTagMask)); | |
| 286 __ j(zero, miss_label, not_taken); | |
| 287 | |
| 288 // Check that the maps haven't changed. | |
| 289 Register reg = | |
| 290 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
| 291 | |
| 292 // Get the value from the properties. | |
| 293 GenerateFastPropertyLoad(masm, eax, reg, holder, index); | |
| 294 __ ret(0); | |
| 295 } | |
| 296 | |
| 297 | |
| 298 void StubCompiler::GenerateLoadCallback(MacroAssembler* masm, | |
| 299 JSObject* object, | |
| 300 JSObject* holder, | |
| 301 Register receiver, | |
| 302 Register name, | |
| 303 Register scratch1, | |
| 304 Register scratch2, | |
| 305 AccessorInfo* callback, | |
| 306 Label* miss_label) { | |
| 307 // Check that the receiver isn't a smi. | |
| 308 __ test(receiver, Immediate(kSmiTagMask)); | |
| 309 __ j(zero, miss_label, not_taken); | |
| 310 | |
| 311 // Check that the maps haven't changed. | |
| 312 Register reg = | |
| 313 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
| 314 | |
| 315 // Push the arguments on the JS stack of the caller. | |
| 316 __ pop(scratch2); // remove return address | |
| 317 __ push(receiver); // receiver | |
| 318 __ push(Immediate(Handle<AccessorInfo>(callback))); // callback data | |
| 319 __ push(name); // name | |
| 320 __ push(reg); // holder | |
| 321 __ push(scratch2); // restore return address | |
| 322 | |
| 323 // Do tail-call to the runtime system. | |
| 324 ExternalReference load_callback_property = | |
| 325 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | |
| 326 __ TailCallRuntime(load_callback_property, 4); | |
| 327 } | |
| 328 | |
| 329 | |
| 330 void StubCompiler::GenerateLoadConstant(MacroAssembler* masm, | |
| 331 JSObject* object, | |
| 332 JSObject* holder, | |
| 333 Register receiver, | |
| 334 Register scratch1, | |
| 335 Register scratch2, | |
| 336 Object* value, | |
| 337 Label* miss_label) { | |
| 338 // Check that the receiver isn't a smi. | |
| 339 __ test(receiver, Immediate(kSmiTagMask)); | |
| 340 __ j(zero, miss_label, not_taken); | |
| 341 | |
| 342 // Check that the maps haven't changed. | |
| 343 Register reg = | |
| 344 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
| 345 | |
| 346 // Return the constant value. | |
| 347 __ mov(eax, Handle<Object>(value)); | |
| 348 __ ret(0); | |
| 349 } | |
| 350 | |
| 351 | |
| 352 void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm, | |
| 353 JSObject* object, | |
| 354 JSObject* holder, | |
| 355 Smi* lookup_hint, | |
| 356 Register receiver, | |
| 357 Register name, | |
| 358 Register scratch1, | |
| 359 Register scratch2, | |
| 360 Label* miss_label) { | |
| 361 // Check that the receiver isn't a smi. | |
| 362 __ test(receiver, Immediate(kSmiTagMask)); | |
| 363 __ j(zero, miss_label, not_taken); | |
| 364 | |
| 365 // Check that the maps haven't changed. | |
| 366 Register reg = | |
| 367 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
| 368 | |
| 369 // Push the arguments on the JS stack of the caller. | |
| 370 __ pop(scratch2); // remove return address | |
| 371 __ push(receiver); // receiver | |
| 372 __ push(reg); // holder | |
| 373 __ push(name); // name | |
| 374 // TODO(367): Maybe don't push lookup_hint for LOOKUP_IN_HOLDER and/or | |
| 375 // LOOKUP_IN_PROTOTYPE, but use a special version of lookup method? | |
| 376 __ push(Immediate(lookup_hint)); | |
| 377 __ push(scratch2); // restore return address | |
| 378 | |
| 379 // Do tail-call to the runtime system. | |
| 380 ExternalReference load_ic_property = | |
| 381 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); | |
| 382 __ TailCallRuntime(load_ic_property, 4); | |
| 383 } | |
| 384 | 276 |
| 385 | 277 |
| 386 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 278 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { |
| 387 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 279 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); |
| 388 Code* code = NULL; | 280 Code* code = NULL; |
| 389 if (kind == Code::LOAD_IC) { | 281 if (kind == Code::LOAD_IC) { |
| 390 code = Builtins::builtin(Builtins::LoadIC_Miss); | 282 code = Builtins::builtin(Builtins::LoadIC_Miss); |
| 391 } else { | 283 } else { |
| 392 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); | 284 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); |
| 393 } | 285 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 __ mov(name_reg, Operand(eax)); | 359 __ mov(name_reg, Operand(eax)); |
| 468 __ RecordWrite(scratch, offset, name_reg, receiver_reg); | 360 __ RecordWrite(scratch, offset, name_reg, receiver_reg); |
| 469 } | 361 } |
| 470 | 362 |
| 471 // Return the value (register eax). | 363 // Return the value (register eax). |
| 472 __ ret(0); | 364 __ ret(0); |
| 473 } | 365 } |
| 474 | 366 |
| 475 | 367 |
| 476 #undef __ | 368 #undef __ |
| 369 #define __ ACCESS_MASM(masm()) |
| 477 | 370 |
| 478 #define __ ACCESS_MASM(masm()) | 371 |
| 372 Register StubCompiler::CheckPrototypes(JSObject* object, |
| 373 Register object_reg, |
| 374 JSObject* holder, |
| 375 Register holder_reg, |
| 376 Register scratch, |
| 377 String* name, |
| 378 Label* miss) { |
| 379 // Check that the maps haven't changed. |
| 380 Register result = |
| 381 masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch, miss); |
| 382 |
| 383 // If we've skipped any global objects, it's not enough to verify |
| 384 // that their maps haven't changed. |
| 385 while (object != holder) { |
| 386 if (object->IsGlobalObject()) { |
| 387 GlobalObject* global = GlobalObject::cast(object); |
| 388 Object* probe = global->EnsurePropertyCell(name); |
| 389 if (probe->IsFailure()) { |
| 390 set_failure(Failure::cast(probe)); |
| 391 return result; |
| 392 } |
| 393 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
| 394 ASSERT(cell->value()->IsTheHole()); |
| 395 __ mov(scratch, Immediate(Handle<Object>(cell))); |
| 396 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
| 397 Immediate(Factory::the_hole_value())); |
| 398 __ j(not_equal, miss, not_taken); |
| 399 } |
| 400 object = JSObject::cast(object->GetPrototype()); |
| 401 } |
| 402 |
| 403 // Return the register containin the holder. |
| 404 return result; |
| 405 } |
| 406 |
| 407 |
| 408 void StubCompiler::GenerateLoadField(JSObject* object, |
| 409 JSObject* holder, |
| 410 Register receiver, |
| 411 Register scratch1, |
| 412 Register scratch2, |
| 413 int index, |
| 414 String* name, |
| 415 Label* miss) { |
| 416 // Check that the receiver isn't a smi. |
| 417 __ test(receiver, Immediate(kSmiTagMask)); |
| 418 __ j(zero, miss, not_taken); |
| 419 |
| 420 // Check the prototype chain. |
| 421 Register reg = |
| 422 CheckPrototypes(object, receiver, holder, |
| 423 scratch1, scratch2, name, miss); |
| 424 |
| 425 // Get the value from the properties. |
| 426 GenerateFastPropertyLoad(masm(), eax, reg, holder, index); |
| 427 __ ret(0); |
| 428 } |
| 429 |
| 430 |
| 431 void StubCompiler::GenerateLoadCallback(JSObject* object, |
| 432 JSObject* holder, |
| 433 Register receiver, |
| 434 Register name_reg, |
| 435 Register scratch1, |
| 436 Register scratch2, |
| 437 AccessorInfo* callback, |
| 438 String* name, |
| 439 Label* miss) { |
| 440 // Check that the receiver isn't a smi. |
| 441 __ test(receiver, Immediate(kSmiTagMask)); |
| 442 __ j(zero, miss, not_taken); |
| 443 |
| 444 // Check that the maps haven't changed. |
| 445 Register reg = |
| 446 CheckPrototypes(object, receiver, holder, |
| 447 scratch1, scratch2, name, miss); |
| 448 |
| 449 // Push the arguments on the JS stack of the caller. |
| 450 __ pop(scratch2); // remove return address |
| 451 __ push(receiver); // receiver |
| 452 __ push(Immediate(Handle<AccessorInfo>(callback))); // callback data |
| 453 __ push(name_reg); // name |
| 454 __ push(reg); // holder |
| 455 __ push(scratch2); // restore return address |
| 456 |
| 457 // Do tail-call to the runtime system. |
| 458 ExternalReference load_callback_property = |
| 459 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); |
| 460 __ TailCallRuntime(load_callback_property, 4); |
| 461 } |
| 462 |
| 463 |
| 464 void StubCompiler::GenerateLoadConstant(JSObject* object, |
| 465 JSObject* holder, |
| 466 Register receiver, |
| 467 Register scratch1, |
| 468 Register scratch2, |
| 469 Object* value, |
| 470 String* name, |
| 471 Label* miss) { |
| 472 // Check that the receiver isn't a smi. |
| 473 __ test(receiver, Immediate(kSmiTagMask)); |
| 474 __ j(zero, miss, not_taken); |
| 475 |
| 476 // Check that the maps haven't changed. |
| 477 Register reg = |
| 478 CheckPrototypes(object, receiver, holder, |
| 479 scratch1, scratch2, name, miss); |
| 480 |
| 481 // Return the constant value. |
| 482 __ mov(eax, Handle<Object>(value)); |
| 483 __ ret(0); |
| 484 } |
| 485 |
| 486 |
| 487 void StubCompiler::GenerateLoadInterceptor(JSObject* object, |
| 488 JSObject* holder, |
| 489 Smi* lookup_hint, |
| 490 Register receiver, |
| 491 Register name_reg, |
| 492 Register scratch1, |
| 493 Register scratch2, |
| 494 String* name, |
| 495 Label* miss) { |
| 496 // Check that the receiver isn't a smi. |
| 497 __ test(receiver, Immediate(kSmiTagMask)); |
| 498 __ j(zero, miss, not_taken); |
| 499 |
| 500 // Check that the maps haven't changed. |
| 501 Register reg = |
| 502 CheckPrototypes(object, receiver, holder, |
| 503 scratch1, scratch2, name, miss); |
| 504 |
| 505 // Push the arguments on the JS stack of the caller. |
| 506 __ pop(scratch2); // remove return address |
| 507 __ push(receiver); // receiver |
| 508 __ push(reg); // holder |
| 509 __ push(name_reg); // name |
| 510 // TODO(367): Maybe don't push lookup_hint for LOOKUP_IN_HOLDER and/or |
| 511 // LOOKUP_IN_PROTOTYPE, but use a special version of lookup method? |
| 512 __ push(Immediate(lookup_hint)); |
| 513 __ push(scratch2); // restore return address |
| 514 |
| 515 // Do tail-call to the runtime system. |
| 516 ExternalReference load_ic_property = |
| 517 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); |
| 518 __ TailCallRuntime(load_ic_property, 4); |
| 519 } |
| 479 | 520 |
| 480 | 521 |
| 481 // TODO(1241006): Avoid having lazy compile stubs specialized by the | 522 // TODO(1241006): Avoid having lazy compile stubs specialized by the |
| 482 // number of arguments. It is not needed anymore. | 523 // number of arguments. It is not needed anymore. |
| 483 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) { | 524 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) { |
| 484 // Enter an internal frame. | 525 // Enter an internal frame. |
| 485 __ EnterInternalFrame(); | 526 __ EnterInternalFrame(); |
| 486 | 527 |
| 487 // Push a copy of the function onto the stack. | 528 // Push a copy of the function onto the stack. |
| 488 __ push(edi); | 529 __ push(edi); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 513 // Get the receiver from the stack. | 554 // Get the receiver from the stack. |
| 514 const int argc = arguments().immediate(); | 555 const int argc = arguments().immediate(); |
| 515 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 556 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 516 | 557 |
| 517 // Check that the receiver isn't a smi. | 558 // Check that the receiver isn't a smi. |
| 518 __ test(edx, Immediate(kSmiTagMask)); | 559 __ test(edx, Immediate(kSmiTagMask)); |
| 519 __ j(zero, &miss, not_taken); | 560 __ j(zero, &miss, not_taken); |
| 520 | 561 |
| 521 // Do the right check and compute the holder register. | 562 // Do the right check and compute the holder register. |
| 522 Register reg = | 563 Register reg = |
| 523 masm()->CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss); | 564 CheckPrototypes(JSObject::cast(object), edx, holder, |
| 565 ebx, ecx, name, &miss); |
| 524 | 566 |
| 525 GenerateFastPropertyLoad(masm(), edi, reg, holder, index); | 567 GenerateFastPropertyLoad(masm(), edi, reg, holder, index); |
| 526 | 568 |
| 527 // Check that the function really is a function. | 569 // Check that the function really is a function. |
| 528 __ test(edi, Immediate(kSmiTagMask)); | 570 __ test(edi, Immediate(kSmiTagMask)); |
| 529 __ j(zero, &miss, not_taken); | 571 __ j(zero, &miss, not_taken); |
| 530 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); | 572 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); |
| 531 __ j(not_equal, &miss, not_taken); | 573 __ j(not_equal, &miss, not_taken); |
| 532 | 574 |
| 533 // Patch the receiver on the stack with the global proxy if | 575 // Patch the receiver on the stack with the global proxy if |
| (...skipping 12 matching lines...) Expand all Loading... |
| 546 __ jmp(ic, RelocInfo::CODE_TARGET); | 588 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 547 | 589 |
| 548 // Return the generated code. | 590 // Return the generated code. |
| 549 return GetCode(FIELD, name); | 591 return GetCode(FIELD, name); |
| 550 } | 592 } |
| 551 | 593 |
| 552 | 594 |
| 553 Object* CallStubCompiler::CompileCallConstant(Object* object, | 595 Object* CallStubCompiler::CompileCallConstant(Object* object, |
| 554 JSObject* holder, | 596 JSObject* holder, |
| 555 JSFunction* function, | 597 JSFunction* function, |
| 598 String* name, |
| 556 CheckType check) { | 599 CheckType check) { |
| 557 // ----------- S t a t e ------------- | 600 // ----------- S t a t e ------------- |
| 558 // ----------------------------------- | 601 // ----------------------------------- |
| 559 Label miss; | 602 Label miss; |
| 560 | 603 |
| 561 // Get the receiver from the stack. | 604 // Get the receiver from the stack. |
| 562 const int argc = arguments().immediate(); | 605 const int argc = arguments().immediate(); |
| 563 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 606 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 564 | 607 |
| 565 // Check that the receiver isn't a smi. | 608 // Check that the receiver isn't a smi. |
| 566 if (check != NUMBER_CHECK) { | 609 if (check != NUMBER_CHECK) { |
| 567 __ test(edx, Immediate(kSmiTagMask)); | 610 __ test(edx, Immediate(kSmiTagMask)); |
| 568 __ j(zero, &miss, not_taken); | 611 __ j(zero, &miss, not_taken); |
| 569 } | 612 } |
| 570 | 613 |
| 571 // Make sure that it's okay not to patch the on stack receiver | 614 // Make sure that it's okay not to patch the on stack receiver |
| 572 // unless we're doing a receiver map check. | 615 // unless we're doing a receiver map check. |
| 573 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 616 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 574 | 617 |
| 575 switch (check) { | 618 switch (check) { |
| 576 case RECEIVER_MAP_CHECK: | 619 case RECEIVER_MAP_CHECK: |
| 577 // Check that the maps haven't changed. | 620 // Check that the maps haven't changed. |
| 578 __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss); | 621 CheckPrototypes(JSObject::cast(object), edx, holder, |
| 622 ebx, ecx, name, &miss); |
| 579 | 623 |
| 580 // Patch the receiver on the stack with the global proxy if | 624 // Patch the receiver on the stack with the global proxy if |
| 581 // necessary. | 625 // necessary. |
| 582 if (object->IsGlobalObject()) { | 626 if (object->IsGlobalObject()) { |
| 583 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 627 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 584 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 628 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 585 } | 629 } |
| 586 break; | 630 break; |
| 587 | 631 |
| 588 case STRING_CHECK: | 632 case STRING_CHECK: |
| 589 // Check that the object is a two-byte string or a symbol. | 633 // Check that the object is a two-byte string or a symbol. |
| 590 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 634 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 591 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 635 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| 592 __ cmp(ecx, FIRST_NONSTRING_TYPE); | 636 __ cmp(ecx, FIRST_NONSTRING_TYPE); |
| 593 __ j(above_equal, &miss, not_taken); | 637 __ j(above_equal, &miss, not_taken); |
| 594 // Check that the maps starting from the prototype haven't changed. | 638 // Check that the maps starting from the prototype haven't changed. |
| 595 GenerateLoadGlobalFunctionPrototype(masm(), | 639 GenerateLoadGlobalFunctionPrototype(masm(), |
| 596 Context::STRING_FUNCTION_INDEX, | 640 Context::STRING_FUNCTION_INDEX, |
| 597 ecx); | 641 ecx); |
| 598 __ CheckMaps(JSObject::cast(object->GetPrototype()), | 642 CheckPrototypes(JSObject::cast(object->GetPrototype()), ecx, holder, |
| 599 ecx, holder, ebx, edx, &miss); | 643 ebx, edx, name, &miss); |
| 600 break; | 644 break; |
| 601 | 645 |
| 602 case NUMBER_CHECK: { | 646 case NUMBER_CHECK: { |
| 603 Label fast; | 647 Label fast; |
| 604 // Check that the object is a smi or a heap number. | 648 // Check that the object is a smi or a heap number. |
| 605 __ test(edx, Immediate(kSmiTagMask)); | 649 __ test(edx, Immediate(kSmiTagMask)); |
| 606 __ j(zero, &fast, taken); | 650 __ j(zero, &fast, taken); |
| 607 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx); | 651 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx); |
| 608 __ j(not_equal, &miss, not_taken); | 652 __ j(not_equal, &miss, not_taken); |
| 609 __ bind(&fast); | 653 __ bind(&fast); |
| 610 // Check that the maps starting from the prototype haven't changed. | 654 // Check that the maps starting from the prototype haven't changed. |
| 611 GenerateLoadGlobalFunctionPrototype(masm(), | 655 GenerateLoadGlobalFunctionPrototype(masm(), |
| 612 Context::NUMBER_FUNCTION_INDEX, | 656 Context::NUMBER_FUNCTION_INDEX, |
| 613 ecx); | 657 ecx); |
| 614 __ CheckMaps(JSObject::cast(object->GetPrototype()), | 658 CheckPrototypes(JSObject::cast(object->GetPrototype()), ecx, holder, |
| 615 ecx, holder, ebx, edx, &miss); | 659 ebx, edx, name, &miss); |
| 616 break; | 660 break; |
| 617 } | 661 } |
| 618 | 662 |
| 619 case BOOLEAN_CHECK: { | 663 case BOOLEAN_CHECK: { |
| 620 Label fast; | 664 Label fast; |
| 621 // Check that the object is a boolean. | 665 // Check that the object is a boolean. |
| 622 __ cmp(edx, Factory::true_value()); | 666 __ cmp(edx, Factory::true_value()); |
| 623 __ j(equal, &fast, taken); | 667 __ j(equal, &fast, taken); |
| 624 __ cmp(edx, Factory::false_value()); | 668 __ cmp(edx, Factory::false_value()); |
| 625 __ j(not_equal, &miss, not_taken); | 669 __ j(not_equal, &miss, not_taken); |
| 626 __ bind(&fast); | 670 __ bind(&fast); |
| 627 // Check that the maps starting from the prototype haven't changed. | 671 // Check that the maps starting from the prototype haven't changed. |
| 628 GenerateLoadGlobalFunctionPrototype(masm(), | 672 GenerateLoadGlobalFunctionPrototype(masm(), |
| 629 Context::BOOLEAN_FUNCTION_INDEX, | 673 Context::BOOLEAN_FUNCTION_INDEX, |
| 630 ecx); | 674 ecx); |
| 631 __ CheckMaps(JSObject::cast(object->GetPrototype()), | 675 CheckPrototypes(JSObject::cast(object->GetPrototype()), ecx, holder, |
| 632 ecx, holder, ebx, edx, &miss); | 676 ebx, edx, name, &miss); |
| 633 break; | 677 break; |
| 634 } | 678 } |
| 635 | 679 |
| 636 case JSARRAY_HAS_FAST_ELEMENTS_CHECK: | 680 case JSARRAY_HAS_FAST_ELEMENTS_CHECK: |
| 637 __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss); | 681 CheckPrototypes(JSObject::cast(object), edx, holder, |
| 682 ebx, ecx, name, &miss); |
| 638 // Make sure object->elements()->map() != Heap::dictionary_array_map() | 683 // Make sure object->elements()->map() != Heap::dictionary_array_map() |
| 639 // Get the elements array of the object. | 684 // Get the elements array of the object. |
| 640 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); | 685 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); |
| 641 // Check that the object is in fast mode (not dictionary). | 686 // Check that the object is in fast mode (not dictionary). |
| 642 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), | 687 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), |
| 643 Immediate(Factory::hash_table_map())); | 688 Immediate(Factory::hash_table_map())); |
| 644 __ j(equal, &miss, not_taken); | 689 __ j(equal, &miss, not_taken); |
| 645 break; | 690 break; |
| 646 | 691 |
| 647 default: | 692 default: |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 | 730 |
| 686 // Get the receiver from the stack. | 731 // Get the receiver from the stack. |
| 687 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 732 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 688 | 733 |
| 689 // Check that the receiver isn't a smi. | 734 // Check that the receiver isn't a smi. |
| 690 __ test(edx, Immediate(kSmiTagMask)); | 735 __ test(edx, Immediate(kSmiTagMask)); |
| 691 __ j(zero, &miss, not_taken); | 736 __ j(zero, &miss, not_taken); |
| 692 | 737 |
| 693 // Check that maps have not changed and compute the holder register. | 738 // Check that maps have not changed and compute the holder register. |
| 694 Register reg = | 739 Register reg = |
| 695 masm()->CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss); | 740 CheckPrototypes(JSObject::cast(object), edx, holder, |
| 741 ebx, ecx, name, &miss); |
| 696 | 742 |
| 697 // Enter an internal frame. | 743 // Enter an internal frame. |
| 698 __ EnterInternalFrame(); | 744 __ EnterInternalFrame(); |
| 699 | 745 |
| 700 // Push arguments on the expression stack. | 746 // Push arguments on the expression stack. |
| 701 __ push(edx); // receiver | 747 __ push(edx); // receiver |
| 702 __ push(reg); // holder | 748 __ push(reg); // holder |
| 703 __ push(Operand(ebp, (argc + 3) * kPointerSize)); // name | 749 __ push(Operand(ebp, (argc + 3) * kPointerSize)); // name |
| 704 __ push(Immediate(holder->InterceptorPropertyLookupHint(name))); | 750 __ push(Immediate(holder->InterceptorPropertyLookupHint(name))); |
| 705 | 751 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 | 810 |
| 765 // If the object is the holder then we know that it's a global | 811 // If the object is the holder then we know that it's a global |
| 766 // object which can only happen for contextual calls. In this case, | 812 // object which can only happen for contextual calls. In this case, |
| 767 // the receiver cannot be a smi. | 813 // the receiver cannot be a smi. |
| 768 if (object != holder) { | 814 if (object != holder) { |
| 769 __ test(edx, Immediate(kSmiTagMask)); | 815 __ test(edx, Immediate(kSmiTagMask)); |
| 770 __ j(zero, &miss, not_taken); | 816 __ j(zero, &miss, not_taken); |
| 771 } | 817 } |
| 772 | 818 |
| 773 // Check that the maps haven't changed. | 819 // Check that the maps haven't changed. |
| 774 masm()->CheckMaps(object, edx, holder, ebx, ecx, &miss); | 820 CheckPrototypes(object, edx, holder, ebx, ecx, name, &miss); |
| 775 | 821 |
| 776 // Get the value from the cell. | 822 // Get the value from the cell. |
| 777 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 823 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
| 778 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); | 824 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); |
| 779 | 825 |
| 780 // Check that the cell contains the same function. | 826 // Check that the cell contains the same function. |
| 781 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); | 827 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); |
| 782 __ j(not_equal, &miss, not_taken); | 828 __ j(not_equal, &miss, not_taken); |
| 783 | 829 |
| 784 // Patch the receiver on the stack with the global proxy. | 830 // Patch the receiver on the stack with the global proxy. |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1026 __ bind(&miss); | 1072 __ bind(&miss); |
| 1027 __ DecrementCounter(&Counters::keyed_store_field, 1); | 1073 __ DecrementCounter(&Counters::keyed_store_field, 1); |
| 1028 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 1074 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); |
| 1029 __ jmp(ic, RelocInfo::CODE_TARGET); | 1075 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 1030 | 1076 |
| 1031 // Return the generated code. | 1077 // Return the generated code. |
| 1032 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 1078 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
| 1033 } | 1079 } |
| 1034 | 1080 |
| 1035 | 1081 |
| 1082 |
| 1036 Object* LoadStubCompiler::CompileLoadField(JSObject* object, | 1083 Object* LoadStubCompiler::CompileLoadField(JSObject* object, |
| 1037 JSObject* holder, | 1084 JSObject* holder, |
| 1038 int index, | 1085 int index, |
| 1039 String* name) { | 1086 String* name) { |
| 1040 // ----------- S t a t e ------------- | 1087 // ----------- S t a t e ------------- |
| 1041 // -- ecx : name | 1088 // -- ecx : name |
| 1042 // -- esp[0] : return address | 1089 // -- esp[0] : return address |
| 1043 // -- esp[4] : receiver | 1090 // -- esp[4] : receiver |
| 1044 // ----------------------------------- | 1091 // ----------------------------------- |
| 1045 Label miss; | 1092 Label miss; |
| 1046 | 1093 |
| 1047 __ mov(eax, (Operand(esp, kPointerSize))); | 1094 __ mov(eax, (Operand(esp, kPointerSize))); |
| 1048 GenerateLoadField(masm(), object, holder, eax, ebx, edx, index, &miss); | 1095 GenerateLoadField(object, holder, eax, ebx, edx, index, name, &miss); |
| 1049 __ bind(&miss); | 1096 __ bind(&miss); |
| 1050 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1097 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 1051 | 1098 |
| 1052 // Return the generated code. | 1099 // Return the generated code. |
| 1053 return GetCode(FIELD, name); | 1100 return GetCode(FIELD, name); |
| 1054 } | 1101 } |
| 1055 | 1102 |
| 1056 | 1103 |
| 1057 Object* LoadStubCompiler::CompileLoadCallback(JSObject* object, | 1104 Object* LoadStubCompiler::CompileLoadCallback(JSObject* object, |
| 1058 JSObject* holder, | 1105 JSObject* holder, |
| 1059 AccessorInfo* callback, | 1106 AccessorInfo* callback, |
| 1060 String* name) { | 1107 String* name) { |
| 1061 // ----------- S t a t e ------------- | 1108 // ----------- S t a t e ------------- |
| 1062 // -- ecx : name | 1109 // -- ecx : name |
| 1063 // -- esp[0] : return address | 1110 // -- esp[0] : return address |
| 1064 // -- esp[4] : receiver | 1111 // -- esp[4] : receiver |
| 1065 // ----------------------------------- | 1112 // ----------------------------------- |
| 1066 Label miss; | 1113 Label miss; |
| 1067 | 1114 |
| 1068 __ mov(eax, (Operand(esp, kPointerSize))); | 1115 __ mov(eax, (Operand(esp, kPointerSize))); |
| 1069 GenerateLoadCallback(masm(), object, holder, eax, ecx, ebx, | 1116 GenerateLoadCallback(object, holder, eax, ecx, ebx, edx, |
| 1070 edx, callback, &miss); | 1117 callback, name, &miss); |
| 1071 __ bind(&miss); | 1118 __ bind(&miss); |
| 1072 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1119 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 1073 | 1120 |
| 1074 // Return the generated code. | 1121 // Return the generated code. |
| 1075 return GetCode(CALLBACKS, name); | 1122 return GetCode(CALLBACKS, name); |
| 1076 } | 1123 } |
| 1077 | 1124 |
| 1078 | 1125 |
| 1079 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 1126 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, |
| 1080 JSObject* holder, | 1127 JSObject* holder, |
| 1081 Object* value, | 1128 Object* value, |
| 1082 String* name) { | 1129 String* name) { |
| 1083 // ----------- S t a t e ------------- | 1130 // ----------- S t a t e ------------- |
| 1084 // -- ecx : name | 1131 // -- ecx : name |
| 1085 // -- esp[0] : return address | 1132 // -- esp[0] : return address |
| 1086 // -- esp[4] : receiver | 1133 // -- esp[4] : receiver |
| 1087 // ----------------------------------- | 1134 // ----------------------------------- |
| 1088 Label miss; | 1135 Label miss; |
| 1089 | 1136 |
| 1090 __ mov(eax, (Operand(esp, kPointerSize))); | 1137 __ mov(eax, (Operand(esp, kPointerSize))); |
| 1091 GenerateLoadConstant(masm(), object, holder, eax, ebx, edx, value, &miss); | 1138 GenerateLoadConstant(object, holder, eax, ebx, edx, value, name, &miss); |
| 1092 __ bind(&miss); | 1139 __ bind(&miss); |
| 1093 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1140 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 1094 | 1141 |
| 1095 // Return the generated code. | 1142 // Return the generated code. |
| 1096 return GetCode(CONSTANT_FUNCTION, name); | 1143 return GetCode(CONSTANT_FUNCTION, name); |
| 1097 } | 1144 } |
| 1098 | 1145 |
| 1099 | 1146 |
| 1100 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 1147 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
| 1101 JSObject* holder, | 1148 JSObject* holder, |
| 1102 String* name) { | 1149 String* name) { |
| 1103 // ----------- S t a t e ------------- | 1150 // ----------- S t a t e ------------- |
| 1104 // -- ecx : name | 1151 // -- ecx : name |
| 1105 // -- esp[0] : return address | 1152 // -- esp[0] : return address |
| 1106 // -- esp[4] : receiver | 1153 // -- esp[4] : receiver |
| 1107 // ----------------------------------- | 1154 // ----------------------------------- |
| 1108 Label miss; | 1155 Label miss; |
| 1109 | 1156 |
| 1110 __ mov(eax, (Operand(esp, kPointerSize))); | 1157 __ mov(eax, (Operand(esp, kPointerSize))); |
| 1111 // TODO(368): Compile in the whole chain: all the interceptors in | 1158 // TODO(368): Compile in the whole chain: all the interceptors in |
| 1112 // prototypes and ultimate answer. | 1159 // prototypes and ultimate answer. |
| 1113 GenerateLoadInterceptor(masm(), | 1160 GenerateLoadInterceptor(receiver, |
| 1114 receiver, | |
| 1115 holder, | 1161 holder, |
| 1116 holder->InterceptorPropertyLookupHint(name), | 1162 holder->InterceptorPropertyLookupHint(name), |
| 1117 eax, | 1163 eax, |
| 1118 ecx, | 1164 ecx, |
| 1119 edx, | 1165 edx, |
| 1120 ebx, | 1166 ebx, |
| 1167 name, |
| 1121 &miss); | 1168 &miss); |
| 1122 | 1169 |
| 1123 __ bind(&miss); | 1170 __ bind(&miss); |
| 1124 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1171 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 1125 | 1172 |
| 1126 // Return the generated code. | 1173 // Return the generated code. |
| 1127 return GetCode(INTERCEPTOR, name); | 1174 return GetCode(INTERCEPTOR, name); |
| 1128 } | 1175 } |
| 1129 | 1176 |
| 1130 | 1177 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1147 | 1194 |
| 1148 // If the object is the holder then we know that it's a global | 1195 // If the object is the holder then we know that it's a global |
| 1149 // object which can only happen for contextual loads. In this case, | 1196 // object which can only happen for contextual loads. In this case, |
| 1150 // the receiver cannot be a smi. | 1197 // the receiver cannot be a smi. |
| 1151 if (object != holder) { | 1198 if (object != holder) { |
| 1152 __ test(eax, Immediate(kSmiTagMask)); | 1199 __ test(eax, Immediate(kSmiTagMask)); |
| 1153 __ j(zero, &miss, not_taken); | 1200 __ j(zero, &miss, not_taken); |
| 1154 } | 1201 } |
| 1155 | 1202 |
| 1156 // Check that the maps haven't changed. | 1203 // Check that the maps haven't changed. |
| 1157 masm()->CheckMaps(object, eax, holder, ebx, edx, &miss); | 1204 CheckPrototypes(object, eax, holder, ebx, edx, name, &miss); |
| 1158 | 1205 |
| 1159 // Get the value from the cell. | 1206 // Get the value from the cell. |
| 1160 __ mov(eax, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 1207 __ mov(eax, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
| 1161 __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset)); | 1208 __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset)); |
| 1162 | 1209 |
| 1163 // Check for deleted property if property can actually be deleted. | 1210 // Check for deleted property if property can actually be deleted. |
| 1164 if (!is_dont_delete) { | 1211 if (!is_dont_delete) { |
| 1165 __ cmp(eax, Factory::the_hole_value()); | 1212 __ cmp(eax, Factory::the_hole_value()); |
| 1166 __ j(equal, &miss, not_taken); | 1213 __ j(equal, &miss, not_taken); |
| 1167 } else if (FLAG_debug_code) { | 1214 } else if (FLAG_debug_code) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1193 Label miss; | 1240 Label miss; |
| 1194 | 1241 |
| 1195 __ mov(eax, (Operand(esp, kPointerSize))); | 1242 __ mov(eax, (Operand(esp, kPointerSize))); |
| 1196 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); | 1243 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); |
| 1197 __ IncrementCounter(&Counters::keyed_load_field, 1); | 1244 __ IncrementCounter(&Counters::keyed_load_field, 1); |
| 1198 | 1245 |
| 1199 // Check that the name has not changed. | 1246 // Check that the name has not changed. |
| 1200 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1247 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
| 1201 __ j(not_equal, &miss, not_taken); | 1248 __ j(not_equal, &miss, not_taken); |
| 1202 | 1249 |
| 1203 GenerateLoadField(masm(), receiver, holder, ecx, ebx, edx, index, &miss); | 1250 GenerateLoadField(receiver, holder, ecx, ebx, edx, index, name, &miss); |
| 1251 |
| 1204 __ bind(&miss); | 1252 __ bind(&miss); |
| 1205 __ DecrementCounter(&Counters::keyed_load_field, 1); | 1253 __ DecrementCounter(&Counters::keyed_load_field, 1); |
| 1206 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1254 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1207 | 1255 |
| 1208 // Return the generated code. | 1256 // Return the generated code. |
| 1209 return GetCode(FIELD, name); | 1257 return GetCode(FIELD, name); |
| 1210 } | 1258 } |
| 1211 | 1259 |
| 1212 | 1260 |
| 1213 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, | 1261 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, |
| 1214 JSObject* receiver, | 1262 JSObject* receiver, |
| 1215 JSObject* holder, | 1263 JSObject* holder, |
| 1216 AccessorInfo* callback) { | 1264 AccessorInfo* callback) { |
| 1217 // ----------- S t a t e ------------- | 1265 // ----------- S t a t e ------------- |
| 1218 // -- esp[0] : return address | 1266 // -- esp[0] : return address |
| 1219 // -- esp[4] : name | 1267 // -- esp[4] : name |
| 1220 // -- esp[8] : receiver | 1268 // -- esp[8] : receiver |
| 1221 // ----------------------------------- | 1269 // ----------------------------------- |
| 1222 Label miss; | 1270 Label miss; |
| 1223 | 1271 |
| 1224 __ mov(eax, (Operand(esp, kPointerSize))); | 1272 __ mov(eax, (Operand(esp, kPointerSize))); |
| 1225 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); | 1273 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); |
| 1226 __ IncrementCounter(&Counters::keyed_load_callback, 1); | 1274 __ IncrementCounter(&Counters::keyed_load_callback, 1); |
| 1227 | 1275 |
| 1228 // Check that the name has not changed. | 1276 // Check that the name has not changed. |
| 1229 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1277 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
| 1230 __ j(not_equal, &miss, not_taken); | 1278 __ j(not_equal, &miss, not_taken); |
| 1231 | 1279 |
| 1232 GenerateLoadCallback(masm(), receiver, holder, ecx, eax, ebx, edx, | 1280 GenerateLoadCallback(receiver, holder, ecx, eax, ebx, edx, |
| 1233 callback, &miss); | 1281 callback, name, &miss); |
| 1234 __ bind(&miss); | 1282 __ bind(&miss); |
| 1235 __ DecrementCounter(&Counters::keyed_load_callback, 1); | 1283 __ DecrementCounter(&Counters::keyed_load_callback, 1); |
| 1236 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1284 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1237 | 1285 |
| 1238 // Return the generated code. | 1286 // Return the generated code. |
| 1239 return GetCode(CALLBACKS, name); | 1287 return GetCode(CALLBACKS, name); |
| 1240 } | 1288 } |
| 1241 | 1289 |
| 1242 | 1290 |
| 1243 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 1291 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, |
| 1244 JSObject* receiver, | 1292 JSObject* receiver, |
| 1245 JSObject* holder, | 1293 JSObject* holder, |
| 1246 Object* value) { | 1294 Object* value) { |
| 1247 // ----------- S t a t e ------------- | 1295 // ----------- S t a t e ------------- |
| 1248 // -- esp[0] : return address | 1296 // -- esp[0] : return address |
| 1249 // -- esp[4] : name | 1297 // -- esp[4] : name |
| 1250 // -- esp[8] : receiver | 1298 // -- esp[8] : receiver |
| 1251 // ----------------------------------- | 1299 // ----------------------------------- |
| 1252 Label miss; | 1300 Label miss; |
| 1253 | 1301 |
| 1254 __ mov(eax, (Operand(esp, kPointerSize))); | 1302 __ mov(eax, (Operand(esp, kPointerSize))); |
| 1255 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); | 1303 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); |
| 1256 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); | 1304 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); |
| 1257 | 1305 |
| 1258 // Check that the name has not changed. | 1306 // Check that the name has not changed. |
| 1259 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1307 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
| 1260 __ j(not_equal, &miss, not_taken); | 1308 __ j(not_equal, &miss, not_taken); |
| 1261 | 1309 |
| 1262 GenerateLoadConstant(masm(), receiver, holder, ecx, ebx, edx, value, &miss); | 1310 GenerateLoadConstant(receiver, holder, ecx, ebx, edx, |
| 1311 value, name, &miss); |
| 1263 __ bind(&miss); | 1312 __ bind(&miss); |
| 1264 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); | 1313 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); |
| 1265 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1314 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1266 | 1315 |
| 1267 // Return the generated code. | 1316 // Return the generated code. |
| 1268 return GetCode(CONSTANT_FUNCTION, name); | 1317 return GetCode(CONSTANT_FUNCTION, name); |
| 1269 } | 1318 } |
| 1270 | 1319 |
| 1271 | 1320 |
| 1272 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 1321 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
| 1273 JSObject* holder, | 1322 JSObject* holder, |
| 1274 String* name) { | 1323 String* name) { |
| 1275 // ----------- S t a t e ------------- | 1324 // ----------- S t a t e ------------- |
| 1276 // -- esp[0] : return address | 1325 // -- esp[0] : return address |
| 1277 // -- esp[4] : name | 1326 // -- esp[4] : name |
| 1278 // -- esp[8] : receiver | 1327 // -- esp[8] : receiver |
| 1279 // ----------------------------------- | 1328 // ----------------------------------- |
| 1280 Label miss; | 1329 Label miss; |
| 1281 | 1330 |
| 1282 __ mov(eax, (Operand(esp, kPointerSize))); | 1331 __ mov(eax, (Operand(esp, kPointerSize))); |
| 1283 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); | 1332 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); |
| 1284 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); | 1333 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); |
| 1285 | 1334 |
| 1286 // Check that the name has not changed. | 1335 // Check that the name has not changed. |
| 1287 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1336 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
| 1288 __ j(not_equal, &miss, not_taken); | 1337 __ j(not_equal, &miss, not_taken); |
| 1289 | 1338 |
| 1290 GenerateLoadInterceptor(masm(), | 1339 GenerateLoadInterceptor(receiver, |
| 1291 receiver, | |
| 1292 holder, | 1340 holder, |
| 1293 Smi::FromInt(JSObject::kLookupInHolder), | 1341 Smi::FromInt(JSObject::kLookupInHolder), |
| 1294 ecx, | 1342 ecx, |
| 1295 eax, | 1343 eax, |
| 1296 edx, | 1344 edx, |
| 1297 ebx, | 1345 ebx, |
| 1346 name, |
| 1298 &miss); | 1347 &miss); |
| 1299 __ bind(&miss); | 1348 __ bind(&miss); |
| 1300 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); | 1349 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); |
| 1301 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1350 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1302 | 1351 |
| 1303 // Return the generated code. | 1352 // Return the generated code. |
| 1304 return GetCode(INTERCEPTOR, name); | 1353 return GetCode(INTERCEPTOR, name); |
| 1305 } | 1354 } |
| 1306 | 1355 |
| 1307 | 1356 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1430 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1382 | 1431 |
| 1383 // Return the generated code. | 1432 // Return the generated code. |
| 1384 return GetCode(CALLBACKS, name); | 1433 return GetCode(CALLBACKS, name); |
| 1385 } | 1434 } |
| 1386 | 1435 |
| 1387 | 1436 |
| 1388 #undef __ | 1437 #undef __ |
| 1389 | 1438 |
| 1390 } } // namespace v8::internal | 1439 } } // namespace v8::internal |
| OLD | NEW |