Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: src/arm/stub-cache-arm.cc

Issue 148883002: Synchronize with r15594. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/ast.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name); 430 Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name);
431 ASSERT(cell->value()->IsTheHole()); 431 ASSERT(cell->value()->IsTheHole());
432 __ mov(scratch, Operand(cell)); 432 __ mov(scratch, Operand(cell));
433 __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 433 __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
434 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 434 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
435 __ cmp(scratch, ip); 435 __ cmp(scratch, ip);
436 __ b(ne, miss); 436 __ b(ne, miss);
437 } 437 }
438 438
439 439
440 void BaseStoreStubCompiler::GenerateNegativeHolderLookup(
441 MacroAssembler* masm,
442 Handle<JSObject> holder,
443 Register holder_reg,
444 Handle<Name> name,
445 Label* miss) {
446 if (holder->IsJSGlobalObject()) {
447 GenerateCheckPropertyCell(
448 masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss);
449 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
450 GenerateDictionaryNegativeLookup(
451 masm, miss, holder_reg, name, scratch1(), scratch2());
452 }
453 }
454
455
440 // Generate StoreTransition code, value is passed in r0 register. 456 // Generate StoreTransition code, value is passed in r0 register.
441 // When leaving generated code after success, the receiver_reg and name_reg 457 // When leaving generated code after success, the receiver_reg and name_reg
442 // may be clobbered. Upon branch to miss_label, the receiver and name 458 // may be clobbered. Upon branch to miss_label, the receiver and name
443 // registers have their original values. 459 // registers have their original values.
444 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, 460 void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
445 Handle<JSObject> object, 461 Handle<JSObject> object,
446 LookupResult* lookup, 462 LookupResult* lookup,
447 Handle<Map> transition, 463 Handle<Map> transition,
448 Handle<Name> name, 464 Handle<Name> name,
449 Register receiver_reg, 465 Register receiver_reg,
450 Register name_reg, 466 Register storage_reg,
451 Register value_reg, 467 Register value_reg,
452 Register scratch1, 468 Register scratch1,
453 Register scratch2, 469 Register scratch2,
454 Register scratch3, 470 Register scratch3,
455 Label* miss_label, 471 Label* miss_label,
456 Label* miss_restore_name, 472 Label* slow) {
457 Label* slow) {
458 // r0 : value 473 // r0 : value
459 Label exit; 474 Label exit;
460 475
461 // Check that the map of the object hasn't changed.
462 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label,
463 DO_SMI_CHECK);
464
465 // Perform global security token check if needed.
466 if (object->IsJSGlobalProxy()) {
467 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
468 }
469
470 int descriptor = transition->LastAdded(); 476 int descriptor = transition->LastAdded();
471 DescriptorArray* descriptors = transition->instance_descriptors(); 477 DescriptorArray* descriptors = transition->instance_descriptors();
472 PropertyDetails details = descriptors->GetDetails(descriptor); 478 PropertyDetails details = descriptors->GetDetails(descriptor);
473 Representation representation = details.representation(); 479 Representation representation = details.representation();
474 ASSERT(!representation.IsNone()); 480 ASSERT(!representation.IsNone());
475 481
476 // Ensure no transitions to deprecated maps are followed.
477 __ CheckMapDeprecated(transition, scratch1, miss_label);
478
479 // Check that we are allowed to write this.
480 if (object->GetPrototype()->IsJSObject()) {
481 JSObject* holder;
482 // holder == object indicates that no property was found.
483 if (lookup->holder() != *object) {
484 holder = lookup->holder();
485 } else {
486 // Find the top object.
487 holder = *object;
488 do {
489 holder = JSObject::cast(holder->GetPrototype());
490 } while (holder->GetPrototype()->IsJSObject());
491 }
492 Register holder_reg = CheckPrototypes(
493 object, receiver_reg, Handle<JSObject>(holder), name_reg,
494 scratch1, scratch2, name, miss_restore_name, SKIP_RECEIVER);
495 // If no property was found, and the holder (the last object in the
496 // prototype chain) is in slow mode, we need to do a negative lookup on the
497 // holder.
498 if (lookup->holder() == *object) {
499 if (holder->IsJSGlobalObject()) {
500 GenerateCheckPropertyCell(
501 masm,
502 Handle<GlobalObject>(GlobalObject::cast(holder)),
503 name,
504 scratch1,
505 miss_restore_name);
506 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
507 GenerateDictionaryNegativeLookup(
508 masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
509 }
510 }
511 }
512
513 Register storage_reg = name_reg;
514
515 if (details.type() == CONSTANT_FUNCTION) { 482 if (details.type() == CONSTANT_FUNCTION) {
516 Handle<HeapObject> constant( 483 Handle<HeapObject> constant(
517 HeapObject::cast(descriptors->GetValue(descriptor))); 484 HeapObject::cast(descriptors->GetValue(descriptor)));
518 __ LoadHeapObject(scratch1, constant); 485 __ LoadHeapObject(scratch1, constant);
519 __ cmp(value_reg, scratch1); 486 __ cmp(value_reg, scratch1);
520 __ b(ne, miss_restore_name); 487 __ b(ne, miss_label);
521 } else if (FLAG_track_fields && representation.IsSmi()) { 488 } else if (FLAG_track_fields && representation.IsSmi()) {
522 __ JumpIfNotSmi(value_reg, miss_restore_name); 489 __ JumpIfNotSmi(value_reg, miss_label);
523 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 490 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
524 __ JumpIfSmi(value_reg, miss_restore_name); 491 __ JumpIfSmi(value_reg, miss_label);
525 } else if (FLAG_track_double_fields && representation.IsDouble()) { 492 } else if (FLAG_track_double_fields && representation.IsDouble()) {
526 Label do_store, heap_number; 493 Label do_store, heap_number;
527 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); 494 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex);
528 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow); 495 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow);
529 496
530 __ JumpIfNotSmi(value_reg, &heap_number); 497 __ JumpIfNotSmi(value_reg, &heap_number);
531 __ SmiUntag(scratch1, value_reg); 498 __ SmiUntag(scratch1, value_reg);
532 __ vmov(s0, scratch1); 499 __ vmov(s0, scratch1);
533 __ vcvt_f64_s32(d0, s0); 500 __ vcvt_f64_s32(d0, s0);
534 __ jmp(&do_store); 501 __ jmp(&do_store);
535 502
536 __ bind(&heap_number); 503 __ bind(&heap_number);
537 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, 504 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
538 miss_restore_name, DONT_DO_SMI_CHECK); 505 miss_label, DONT_DO_SMI_CHECK);
539 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 506 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
540 507
541 __ bind(&do_store); 508 __ bind(&do_store);
542 __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); 509 __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
543 } 510 }
544 511
545 // Stub never generated for non-global objects that require access 512 // Stub never generated for non-global objects that require access
546 // checks. 513 // checks.
547 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 514 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
548 515
(...skipping 10 matching lines...) Expand all
559 masm->isolate()), 526 masm->isolate()),
560 3, 527 3,
561 1); 528 1);
562 return; 529 return;
563 } 530 }
564 531
565 // Update the map of the object. 532 // Update the map of the object.
566 __ mov(scratch1, Operand(transition)); 533 __ mov(scratch1, Operand(transition));
567 __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 534 __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
568 535
569 // Update the write barrier for the map field and pass the now unused 536 // Update the write barrier for the map field.
570 // name_reg as scratch register.
571 __ RecordWriteField(receiver_reg, 537 __ RecordWriteField(receiver_reg,
572 HeapObject::kMapOffset, 538 HeapObject::kMapOffset,
573 scratch1, 539 scratch1,
574 scratch2, 540 scratch2,
575 kLRHasNotBeenSaved, 541 kLRHasNotBeenSaved,
576 kDontSaveFPRegs, 542 kDontSaveFPRegs,
577 OMIT_REMEMBERED_SET, 543 OMIT_REMEMBERED_SET,
578 OMIT_SMI_CHECK); 544 OMIT_SMI_CHECK);
579 545
580 if (details.type() == CONSTANT_FUNCTION) { 546 if (details.type() == CONSTANT_FUNCTION) {
(...skipping 16 matching lines...) Expand all
597 if (index < 0) { 563 if (index < 0) {
598 // Set the property straight into the object. 564 // Set the property straight into the object.
599 int offset = object->map()->instance_size() + (index * kPointerSize); 565 int offset = object->map()->instance_size() + (index * kPointerSize);
600 if (FLAG_track_double_fields && representation.IsDouble()) { 566 if (FLAG_track_double_fields && representation.IsDouble()) {
601 __ str(storage_reg, FieldMemOperand(receiver_reg, offset)); 567 __ str(storage_reg, FieldMemOperand(receiver_reg, offset));
602 } else { 568 } else {
603 __ str(value_reg, FieldMemOperand(receiver_reg, offset)); 569 __ str(value_reg, FieldMemOperand(receiver_reg, offset));
604 } 570 }
605 571
606 if (!FLAG_track_fields || !representation.IsSmi()) { 572 if (!FLAG_track_fields || !representation.IsSmi()) {
607 // Skip updating write barrier if storing a smi.
608 __ JumpIfSmi(value_reg, &exit);
609
610 // Update the write barrier for the array address. 573 // Update the write barrier for the array address.
611 // Pass the now unused name_reg as a scratch register.
612 if (!FLAG_track_double_fields || !representation.IsDouble()) { 574 if (!FLAG_track_double_fields || !representation.IsDouble()) {
613 __ mov(name_reg, value_reg); 575 __ mov(storage_reg, value_reg);
614 } else {
615 ASSERT(storage_reg.is(name_reg));
616 } 576 }
617 __ RecordWriteField(receiver_reg, 577 __ RecordWriteField(receiver_reg,
618 offset, 578 offset,
619 name_reg, 579 storage_reg,
620 scratch1, 580 scratch1,
621 kLRHasNotBeenSaved, 581 kLRHasNotBeenSaved,
622 kDontSaveFPRegs, 582 kDontSaveFPRegs,
623 EMIT_REMEMBERED_SET, 583 EMIT_REMEMBERED_SET,
624 smi_check); 584 smi_check);
625 } 585 }
626 } else { 586 } else {
627 // Write to the properties array. 587 // Write to the properties array.
628 int offset = index * kPointerSize + FixedArray::kHeaderSize; 588 int offset = index * kPointerSize + FixedArray::kHeaderSize;
629 // Get the properties array 589 // Get the properties array
630 __ ldr(scratch1, 590 __ ldr(scratch1,
631 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 591 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
632 if (FLAG_track_double_fields && representation.IsDouble()) { 592 if (FLAG_track_double_fields && representation.IsDouble()) {
633 __ str(storage_reg, FieldMemOperand(scratch1, offset)); 593 __ str(storage_reg, FieldMemOperand(scratch1, offset));
634 } else { 594 } else {
635 __ str(value_reg, FieldMemOperand(scratch1, offset)); 595 __ str(value_reg, FieldMemOperand(scratch1, offset));
636 } 596 }
637 597
638 if (!FLAG_track_fields || !representation.IsSmi()) { 598 if (!FLAG_track_fields || !representation.IsSmi()) {
639 // Skip updating write barrier if storing a smi.
640 __ JumpIfSmi(value_reg, &exit);
641
642 // Update the write barrier for the array address. 599 // Update the write barrier for the array address.
643 // Ok to clobber receiver_reg and name_reg, since we return.
644 if (!FLAG_track_double_fields || !representation.IsDouble()) { 600 if (!FLAG_track_double_fields || !representation.IsDouble()) {
645 __ mov(name_reg, value_reg); 601 __ mov(storage_reg, value_reg);
646 } else {
647 ASSERT(storage_reg.is(name_reg));
648 } 602 }
649 __ RecordWriteField(scratch1, 603 __ RecordWriteField(scratch1,
650 offset, 604 offset,
651 name_reg, 605 storage_reg,
652 receiver_reg, 606 receiver_reg,
653 kLRHasNotBeenSaved, 607 kLRHasNotBeenSaved,
654 kDontSaveFPRegs, 608 kDontSaveFPRegs,
655 EMIT_REMEMBERED_SET, 609 EMIT_REMEMBERED_SET,
656 smi_check); 610 smi_check);
657 } 611 }
658 } 612 }
659 613
660 // Return the value (register r0). 614 // Return the value (register r0).
661 ASSERT(value_reg.is(r0)); 615 ASSERT(value_reg.is(r0));
662 __ bind(&exit); 616 __ bind(&exit);
663 __ Ret(); 617 __ Ret();
664 } 618 }
665 619
666 620
667 // Generate StoreField code, value is passed in r0 register. 621 // Generate StoreField code, value is passed in r0 register.
668 // When leaving generated code after success, the receiver_reg and name_reg 622 // When leaving generated code after success, the receiver_reg and name_reg
669 // may be clobbered. Upon branch to miss_label, the receiver and name 623 // may be clobbered. Upon branch to miss_label, the receiver and name
670 // registers have their original values. 624 // registers have their original values.
671 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 625 void BaseStoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
672 Handle<JSObject> object, 626 Handle<JSObject> object,
673 LookupResult* lookup, 627 LookupResult* lookup,
674 Register receiver_reg, 628 Register receiver_reg,
675 Register name_reg, 629 Register name_reg,
676 Register value_reg, 630 Register value_reg,
677 Register scratch1, 631 Register scratch1,
678 Register scratch2, 632 Register scratch2,
679 Label* miss_label) { 633 Label* miss_label) {
680 // r0 : value 634 // r0 : value
681 Label exit; 635 Label exit;
682 636
683 // Check that the map of the object hasn't changed.
684 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label,
685 DO_SMI_CHECK);
686
687 // Perform global security token check if needed.
688 if (object->IsJSGlobalProxy()) {
689 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
690 }
691
692 // Stub never generated for non-global objects that require access 637 // Stub never generated for non-global objects that require access
693 // checks. 638 // checks.
694 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 639 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
695 640
696 int index = lookup->GetFieldIndex().field_index(); 641 int index = lookup->GetFieldIndex().field_index();
697 642
698 // Adjust for the number of properties stored in the object. Even in the 643 // Adjust for the number of properties stored in the object. Even in the
699 // face of a transition we can use the old map here because the size of the 644 // face of a transition we can use the old map here because the size of the
700 // object and the number of in-object properties is not going to change. 645 // object and the number of in-object properties is not going to change.
701 index -= object->map()->inobject_properties(); 646 index -= object->map()->inobject_properties();
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 // If we've skipped any global objects, it's not enough to verify that 1280 // If we've skipped any global objects, it's not enough to verify that
1336 // their maps haven't changed. We also need to check that the property 1281 // their maps haven't changed. We also need to check that the property
1337 // cell for the property is still empty. 1282 // cell for the property is still empty.
1338 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1283 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1339 1284
1340 // Return the register containing the holder. 1285 // Return the register containing the holder.
1341 return reg; 1286 return reg;
1342 } 1287 }
1343 1288
1344 1289
1345 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, 1290 void BaseLoadStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1291 Label* success,
1346 Label* miss) { 1292 Label* miss) {
1347 if (!miss->is_unused()) { 1293 if (!miss->is_unused()) {
1348 __ b(success); 1294 __ b(success);
1349 __ bind(miss); 1295 __ bind(miss);
1350 TailCallBuiltin(masm(), MissBuiltin(kind())); 1296 TailCallBuiltin(masm(), MissBuiltin(kind()));
1351 } 1297 }
1352 } 1298 }
1353 1299
1354 1300
1301 void BaseStoreStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1302 Label* success,
1303 Label* miss) {
1304 if (!miss->is_unused()) {
1305 __ b(success);
1306 GenerateRestoreName(masm(), miss, name);
1307 TailCallBuiltin(masm(), MissBuiltin(kind()));
1308 }
1309 }
1310
1311
1355 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1312 Register BaseLoadStubCompiler::CallbackHandlerFrontend(
1356 Handle<JSObject> object, 1313 Handle<JSObject> object,
1357 Register object_reg, 1314 Register object_reg,
1358 Handle<JSObject> holder, 1315 Handle<JSObject> holder,
1359 Handle<Name> name, 1316 Handle<Name> name,
1360 Label* success, 1317 Label* success,
1361 Handle<ExecutableAccessorInfo> callback) { 1318 Handle<ExecutableAccessorInfo> callback) {
1362 Label miss; 1319 Label miss;
1363 1320
1364 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1321 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
(...skipping 22 matching lines...) Expand all
1387 // pointer into the dictionary. Check that the value is the callback. 1344 // pointer into the dictionary. Check that the value is the callback.
1388 Register pointer = scratch3(); 1345 Register pointer = scratch3();
1389 const int kElementsStartOffset = NameDictionary::kHeaderSize + 1346 const int kElementsStartOffset = NameDictionary::kHeaderSize +
1390 NameDictionary::kElementsStartIndex * kPointerSize; 1347 NameDictionary::kElementsStartIndex * kPointerSize;
1391 const int kValueOffset = kElementsStartOffset + kPointerSize; 1348 const int kValueOffset = kElementsStartOffset + kPointerSize;
1392 __ ldr(scratch2(), FieldMemOperand(pointer, kValueOffset)); 1349 __ ldr(scratch2(), FieldMemOperand(pointer, kValueOffset));
1393 __ cmp(scratch2(), Operand(callback)); 1350 __ cmp(scratch2(), Operand(callback));
1394 __ b(ne, &miss); 1351 __ b(ne, &miss);
1395 } 1352 }
1396 1353
1397 HandlerFrontendFooter(success, &miss); 1354 HandlerFrontendFooter(name, success, &miss);
1398 return reg; 1355 return reg;
1399 } 1356 }
1400 1357
1401 1358
1402 void BaseLoadStubCompiler::NonexistentHandlerFrontend( 1359 void BaseLoadStubCompiler::NonexistentHandlerFrontend(
1403 Handle<JSObject> object, 1360 Handle<JSObject> object,
1404 Handle<JSObject> last, 1361 Handle<JSObject> last,
1405 Handle<Name> name, 1362 Handle<Name> name,
1406 Label* success, 1363 Label* success,
1407 Handle<GlobalObject> global) { 1364 Handle<GlobalObject> global) {
1408 Label miss; 1365 Label miss;
1409 1366
1410 HandlerFrontendHeader(object, receiver(), last, name, &miss); 1367 HandlerFrontendHeader(object, receiver(), last, name, &miss);
1411 1368
1412 // If the last object in the prototype chain is a global object, 1369 // If the last object in the prototype chain is a global object,
1413 // check that the global property cell is empty. 1370 // check that the global property cell is empty.
1414 if (!global.is_null()) { 1371 if (!global.is_null()) {
1415 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1372 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1416 } 1373 }
1417 1374
1418 HandlerFrontendFooter(success, &miss); 1375 HandlerFrontendFooter(name, success, &miss);
1419 } 1376 }
1420 1377
1421 1378
1422 void BaseLoadStubCompiler::GenerateLoadField(Register reg, 1379 void BaseLoadStubCompiler::GenerateLoadField(Register reg,
1423 Handle<JSObject> holder, 1380 Handle<JSObject> holder,
1424 PropertyIndex field, 1381 PropertyIndex field,
1425 Representation representation) { 1382 Representation representation) {
1426 if (!reg.is(receiver())) __ mov(receiver(), reg); 1383 if (!reg.is(receiver())) __ mov(receiver(), reg);
1427 if (kind() == Code::LOAD_IC) { 1384 if (kind() == Code::LOAD_IC) {
1428 LoadFieldStub stub(field.is_inobject(holder), 1385 LoadFieldStub stub(field.is_inobject(holder),
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
1722 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, r3, r0, 1679 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, r3, r0,
1723 r4, name, &miss); 1680 r4, name, &miss);
1724 } else { 1681 } else {
1725 ASSERT(cell->value() == *function); 1682 ASSERT(cell->value() == *function);
1726 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1683 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1727 &miss); 1684 &miss);
1728 GenerateLoadFunctionFromCell(cell, function, &miss); 1685 GenerateLoadFunctionFromCell(cell, function, &miss);
1729 } 1686 }
1730 1687
1731 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1688 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1732 site->set_payload(Smi::FromInt(GetInitialFastElementsKind())); 1689 site->set_transition_info(Smi::FromInt(GetInitialFastElementsKind()));
1733 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1690 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1734 __ mov(r0, Operand(argc)); 1691 __ mov(r0, Operand(argc));
1735 __ mov(r2, Operand(site_feedback_cell)); 1692 __ mov(r2, Operand(site_feedback_cell));
1736 __ mov(r1, Operand(function)); 1693 __ mov(r1, Operand(function));
1737 1694
1738 ArrayConstructorStub stub(isolate()); 1695 ArrayConstructorStub stub(isolate());
1739 __ TailCallStub(&stub); 1696 __ TailCallStub(&stub);
1740 1697
1741 __ bind(&miss); 1698 __ bind(&miss);
1742 GenerateMissBranch(); 1699 GenerateMissBranch();
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
2817 __ bind(&miss); 2774 __ bind(&miss);
2818 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); 2775 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3);
2819 GenerateMissBranch(); 2776 GenerateMissBranch();
2820 2777
2821 // Return the generated code. 2778 // Return the generated code.
2822 return GetCode(Code::NORMAL, name); 2779 return GetCode(Code::NORMAL, name);
2823 } 2780 }
2824 2781
2825 2782
2826 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2783 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2827 Handle<Name> name,
2828 Handle<JSObject> object, 2784 Handle<JSObject> object,
2829 Handle<JSObject> holder, 2785 Handle<JSObject> holder,
2786 Handle<Name> name,
2830 Handle<ExecutableAccessorInfo> callback) { 2787 Handle<ExecutableAccessorInfo> callback) {
2831 Label miss; 2788 Label success;
2832 // Check that the maps haven't changed. 2789 HandlerFrontend(object, receiver(), holder, name, &success);
2833 __ JumpIfSmi(receiver(), &miss); 2790 __ bind(&success);
2834 CheckPrototypes(object, receiver(), holder,
2835 scratch1(), scratch2(), scratch3(), name, &miss);
2836 2791
2837 // Stub never generated for non-global objects that require access checks. 2792 // Stub never generated for non-global objects that require access checks.
2838 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 2793 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
2839 2794
2840 __ push(receiver()); // receiver 2795 __ push(receiver()); // receiver
2841 __ mov(ip, Operand(callback)); // callback info 2796 __ mov(ip, Operand(callback)); // callback info
2842 __ Push(ip, this->name(), value()); 2797 __ push(ip);
2798 __ mov(ip, Operand(name));
2799 __ Push(ip, value());
2843 2800
2844 // Do tail-call to the runtime system. 2801 // Do tail-call to the runtime system.
2845 ExternalReference store_callback_property = 2802 ExternalReference store_callback_property =
2846 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2803 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2847 __ TailCallExternalReference(store_callback_property, 4, 1); 2804 __ TailCallExternalReference(store_callback_property, 4, 1);
2848 2805
2849 // Handle store cache miss.
2850 __ bind(&miss);
2851 TailCallBuiltin(masm(), MissBuiltin(kind()));
2852
2853 // Return the generated code. 2806 // Return the generated code.
2854 return GetICCode(kind(), Code::CALLBACKS, name); 2807 return GetCode(kind(), Code::CALLBACKS, name);
2855 } 2808 }
2856 2809
2857 2810
2858 #undef __ 2811 #undef __
2859 #define __ ACCESS_MASM(masm) 2812 #define __ ACCESS_MASM(masm)
2860 2813
2861 2814
2862 void StoreStubCompiler::GenerateStoreViaSetter( 2815 void StoreStubCompiler::GenerateStoreViaSetter(
2863 MacroAssembler* masm, 2816 MacroAssembler* masm,
2864 Handle<JSFunction> setter) { 2817 Handle<JSFunction> setter) {
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
3098 __ mov(r3, Operand(cell)); 3051 __ mov(r3, Operand(cell));
3099 __ ldr(r4, FieldMemOperand(r3, Cell::kValueOffset)); 3052 __ ldr(r4, FieldMemOperand(r3, Cell::kValueOffset));
3100 3053
3101 // Check for deleted property if property can actually be deleted. 3054 // Check for deleted property if property can actually be deleted.
3102 if (!is_dont_delete) { 3055 if (!is_dont_delete) {
3103 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 3056 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
3104 __ cmp(r4, ip); 3057 __ cmp(r4, ip);
3105 __ b(eq, &miss); 3058 __ b(eq, &miss);
3106 } 3059 }
3107 3060
3108 HandlerFrontendFooter(&success, &miss); 3061 HandlerFrontendFooter(name, &success, &miss);
3109 __ bind(&success); 3062 __ bind(&success);
3110 3063
3111 Counters* counters = isolate()->counters(); 3064 Counters* counters = isolate()->counters();
3112 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); 3065 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
3113 __ mov(r0, r4); 3066 __ mov(r0, r4);
3114 __ Ret(); 3067 __ Ret();
3115 3068
3116 // Return the generated code. 3069 // Return the generated code.
3117 return GetICCode(kind(), Code::NORMAL, name); 3070 return GetICCode(kind(), Code::NORMAL, name);
3118 } 3071 }
3119 3072
3120 3073
3121 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( 3074 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
3122 MapHandleList* receiver_maps, 3075 MapHandleList* receiver_maps,
3123 CodeHandleList* handlers, 3076 CodeHandleList* handlers,
3124 Handle<Name> name, 3077 Handle<Name> name,
3125 Code::StubType type, 3078 Code::StubType type,
3126 IcCheckType check) { 3079 IcCheckType check) {
3127 Label miss; 3080 Label miss;
3128 3081
3129 if (check == PROPERTY) { 3082 if (check == PROPERTY) {
3130 GenerateNameCheck(name, this->name(), &miss); 3083 GenerateNameCheck(name, this->name(), &miss);
3131 } 3084 }
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
3735 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3688 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3736 } 3689 }
3737 } 3690 }
3738 3691
3739 3692
3740 #undef __ 3693 #undef __
3741 3694
3742 } } // namespace v8::internal 3695 } } // namespace v8::internal
3743 3696
3744 #endif // V8_TARGET_ARCH_ARM 3697 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/ast.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698