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

Side by Side Diff: src/a64/stub-cache-a64.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/a64/lithium-codegen-a64.cc ('k') | src/arm/code-stubs-arm.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 Label* miss) { 423 Label* miss) {
424 Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name); 424 Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name);
425 ASSERT(cell->value()->IsTheHole()); 425 ASSERT(cell->value()->IsTheHole());
426 __ Mov(scratch, Operand(cell)); 426 __ Mov(scratch, Operand(cell));
427 __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 427 __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
428 __ Cmp(scratch, the_hole); 428 __ Cmp(scratch, the_hole);
429 __ B(ne, miss); 429 __ B(ne, miss);
430 } 430 }
431 431
432 432
433 void BaseStoreStubCompiler::GenerateNegativeHolderLookup(
434 MacroAssembler* masm,
435 Handle<JSObject> holder,
436 Register holder_reg,
437 Handle<Name> name,
438 Label* miss) {
439 if (holder->IsJSGlobalObject()) {
440 __ LoadRoot(scratch2(), Heap::kTheHoleValueRootIndex);
441 GenerateCheckPropertyCell(
442 masm, Handle<GlobalObject>::cast(holder), name,
443 scratch1(), scratch2(), miss);
444 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
445 GenerateDictionaryNegativeLookup(
446 masm, miss, holder_reg, name, scratch1(), scratch2());
447 }
448 }
449
450
433 // Generate StoreTransition code, value is passed in x0 register. 451 // Generate StoreTransition code, value is passed in x0 register.
434 // When leaving generated code after success, the receiver_reg and name_reg may 452 // When leaving generated code after success, the receiver_reg and storage_reg
435 // be clobbered. Upon branch to miss_label, the receiver and name registers have 453 // may be clobbered. Upon branch to miss_label, the receiver and name registers
436 // their original values. 454 // have their original values.
437 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, 455 void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
438 Handle<JSObject> object, 456 Handle<JSObject> object,
439 LookupResult* lookup, 457 LookupResult* lookup,
440 Handle<Map> transition, 458 Handle<Map> transition,
441 Handle<Name> name, 459 Handle<Name> name,
442 Register receiver_reg, 460 Register receiver_reg,
443 Register name_reg, 461 Register storage_reg,
444 Register value_reg, 462 Register value_reg,
445 Register scratch1, 463 Register scratch1,
446 Register scratch2, 464 Register scratch2,
447 Register scratch3, 465 Register scratch3,
448 Label* miss_label, 466 Label* miss_label,
449 Label* miss_restore_name, 467 Label* slow) {
450 Label* slow) {
451 Label exit; 468 Label exit;
452 469
453 ASSERT(!AreAliased(receiver_reg, name_reg, value_reg, 470 ASSERT(!AreAliased(receiver_reg, storage_reg, value_reg,
454 scratch1, scratch2, scratch3)); 471 scratch1, scratch2, scratch3));
455 472
456 // We don't need scratch3. 473 // We don't need scratch3.
457 scratch3 = NoReg; 474 scratch3 = NoReg;
458 475
459 // Check that the map of the object hasn't changed.
460 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label,
461 DO_SMI_CHECK);
462
463 // Perform global security token check if needed.
464 if (object->IsJSGlobalProxy()) {
465 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
466 }
467
468 int descriptor = transition->LastAdded(); 476 int descriptor = transition->LastAdded();
469 DescriptorArray* descriptors = transition->instance_descriptors(); 477 DescriptorArray* descriptors = transition->instance_descriptors();
470 PropertyDetails details = descriptors->GetDetails(descriptor); 478 PropertyDetails details = descriptors->GetDetails(descriptor);
471 Representation representation = details.representation(); 479 Representation representation = details.representation();
472 ASSERT(!representation.IsNone()); 480 ASSERT(!representation.IsNone());
473 481
474 // Ensure no transitions to deprecated maps are followed.
475 __ CheckMapDeprecated(transition, scratch1, miss_label);
476
477 // Check that we are allowed to write this.
478 if (object->GetPrototype()->IsJSObject()) {
479 JSObject* holder;
480 // holder == object indicates that no property was found.
481 if (lookup->holder() != *object) {
482 holder = lookup->holder();
483 } else {
484 // Find the top object.
485 holder = *object;
486 do {
487 holder = JSObject::cast(holder->GetPrototype());
488 } while (holder->GetPrototype()->IsJSObject());
489 }
490 Register holder_reg = CheckPrototypes(
491 object, receiver_reg, Handle<JSObject>(holder), name_reg,
492 scratch1, scratch2, name, miss_restore_name, SKIP_RECEIVER);
493 // If no property was found, and the holder (the last object in the
494 // prototype chain) is in slow mode, we need to do a negative lookup on the
495 // holder.
496 if (lookup->holder() == *object) {
497 if (holder->IsJSGlobalObject()) {
498 __ LoadRoot(scratch2, Heap::kTheHoleValueRootIndex);
499 GenerateCheckPropertyCell(
500 masm,
501 Handle<GlobalObject>(GlobalObject::cast(holder)),
502 name,
503 scratch1,
504 scratch2, // The hole.
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 // We've possibly already clobbered name_reg at this point, so use it for
514 // storage_reg.
515 Register storage_reg = name_reg;
516
517 if (details.type() == CONSTANT_FUNCTION) { 482 if (details.type() == CONSTANT_FUNCTION) {
518 Handle<HeapObject> constant( 483 Handle<HeapObject> constant(
519 HeapObject::cast(descriptors->GetValue(descriptor))); 484 HeapObject::cast(descriptors->GetValue(descriptor)));
520 __ LoadHeapObject(scratch1, constant); 485 __ LoadHeapObject(scratch1, constant);
521 __ Cmp(value_reg, scratch1); 486 __ Cmp(value_reg, scratch1);
522 __ B(ne, miss_restore_name); 487 __ B(ne, miss_label);
523 } else if (FLAG_track_fields && representation.IsSmi()) { 488 } else if (FLAG_track_fields && representation.IsSmi()) {
524 __ JumpIfNotSmi(value_reg, miss_restore_name); 489 __ JumpIfNotSmi(value_reg, miss_label);
525 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 490 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
526 __ JumpIfSmi(value_reg, miss_restore_name); 491 __ JumpIfSmi(value_reg, miss_label);
527 } else if (FLAG_track_double_fields && representation.IsDouble()) { 492 } else if (FLAG_track_double_fields && representation.IsDouble()) {
528 Label do_store, heap_number; 493 Label do_store, heap_number;
529 __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2); 494 __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2);
530 495
531 // TODO(jbramley): Is fp_scratch the most appropriate FP scratch register? 496 // TODO(jbramley): Is fp_scratch the most appropriate FP scratch register?
532 // It's only used in Fcmp, but it's not really safe to use it like this. 497 // It's only used in Fcmp, but it's not really safe to use it like this.
533 __ JumpIfNotSmi(value_reg, &heap_number); 498 __ JumpIfNotSmi(value_reg, &heap_number);
534 __ SmiUntagToDouble(fp_scratch, value_reg); 499 __ SmiUntagToDouble(fp_scratch, value_reg);
535 __ B(&do_store); 500 __ B(&do_store);
536 501
537 __ Bind(&heap_number); 502 __ Bind(&heap_number);
538 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, 503 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
539 miss_restore_name, DONT_DO_SMI_CHECK); 504 miss_label, DONT_DO_SMI_CHECK);
540 __ Ldr(fp_scratch, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 505 __ Ldr(fp_scratch, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
541 506
542 __ Bind(&do_store); 507 __ Bind(&do_store);
543 __ Str(fp_scratch, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); 508 __ Str(fp_scratch, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
544 } 509 }
545 510
546 // Stub never generated for non-global objects that require access checks. 511 // Stub never generated for non-global objects that require access checks.
547 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 512 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
548 513
549 // Perform map transition for the receiver if necessary. 514 // Perform map transition for the receiver if necessary.
550 if ((details.type() == FIELD) && 515 if ((details.type() == FIELD) &&
551 (object->map()->unused_property_fields() == 0)) { 516 (object->map()->unused_property_fields() == 0)) {
552 // The properties must be extended before we can store the value. 517 // The properties must be extended before we can store the value.
553 // We jump to a runtime call that extends the properties array. 518 // We jump to a runtime call that extends the properties array.
554 __ Mov(scratch1, Operand(transition)); 519 __ Mov(scratch1, Operand(transition));
555 __ Push(receiver_reg, scratch1, value_reg); 520 __ Push(receiver_reg, scratch1, value_reg);
556 __ TailCallExternalReference( 521 __ TailCallExternalReference(
557 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 522 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
558 masm->isolate()), 523 masm->isolate()),
559 3, 524 3,
560 1); 525 1);
561 return; 526 return;
562 } 527 }
563 528
564 // Update the map of the object. 529 // Update the map of the object.
565 __ Mov(scratch1, Operand(transition)); 530 __ Mov(scratch1, Operand(transition));
566 __ Str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 531 __ Str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
567 532
568 // Update the write barrier for the map field and pass the now unused 533 // Update the write barrier for the map field.
569 // name_reg as scratch register.
570 __ RecordWriteField(receiver_reg, 534 __ RecordWriteField(receiver_reg,
571 HeapObject::kMapOffset, 535 HeapObject::kMapOffset,
572 scratch1, 536 scratch1,
573 scratch2, 537 scratch2,
574 kLRHasNotBeenSaved, 538 kLRHasNotBeenSaved,
575 kDontSaveFPRegs, 539 kDontSaveFPRegs,
576 OMIT_REMEMBERED_SET, 540 OMIT_REMEMBERED_SET,
577 OMIT_SMI_CHECK); 541 OMIT_SMI_CHECK);
578 542
579 if (details.type() == CONSTANT_FUNCTION) { 543 if (details.type() == CONSTANT_FUNCTION) {
(...skipping 18 matching lines...) Expand all
598 int offset = object->map()->instance_size() + (index * kPointerSize); 562 int offset = object->map()->instance_size() + (index * kPointerSize);
599 // TODO(jbramley): This construct appears in several places in this 563 // TODO(jbramley): This construct appears in several places in this
600 // function. Try to clean it up, perhaps using a result_reg. 564 // function. Try to clean it up, perhaps using a result_reg.
601 if (FLAG_track_double_fields && representation.IsDouble()) { 565 if (FLAG_track_double_fields && representation.IsDouble()) {
602 __ Str(storage_reg, FieldMemOperand(receiver_reg, offset)); 566 __ Str(storage_reg, FieldMemOperand(receiver_reg, offset));
603 } else { 567 } else {
604 __ Str(value_reg, FieldMemOperand(receiver_reg, offset)); 568 __ Str(value_reg, FieldMemOperand(receiver_reg, offset));
605 } 569 }
606 570
607 if (!FLAG_track_fields || !representation.IsSmi()) { 571 if (!FLAG_track_fields || !representation.IsSmi()) {
608 // Skip updating write barrier if storing a smi.
609 __ JumpIfSmi(value_reg, &exit);
610
611 // Update the write barrier for the array address. 572 // Update the write barrier for the array address.
612 // Pass the now unused name_reg as a scratch register.
613 if (!FLAG_track_double_fields || !representation.IsDouble()) { 573 if (!FLAG_track_double_fields || !representation.IsDouble()) {
614 __ Mov(name_reg, value_reg); 574 __ Mov(storage_reg, value_reg);
615 } else {
616 ASSERT(storage_reg.is(name_reg));
617 } 575 }
618 __ RecordWriteField(receiver_reg, 576 __ RecordWriteField(receiver_reg,
619 offset, 577 offset,
620 name_reg, 578 storage_reg,
621 scratch1, 579 scratch1,
622 kLRHasNotBeenSaved, 580 kLRHasNotBeenSaved,
623 kDontSaveFPRegs, 581 kDontSaveFPRegs,
624 EMIT_REMEMBERED_SET, 582 EMIT_REMEMBERED_SET,
625 smi_check); 583 smi_check);
626 } 584 }
627 } else { 585 } else {
628 // Write to the properties array. 586 // Write to the properties array.
629 int offset = index * kPointerSize + FixedArray::kHeaderSize; 587 int offset = index * kPointerSize + FixedArray::kHeaderSize;
630 // Get the properties array 588 // Get the properties array
631 __ Ldr(scratch1, 589 __ Ldr(scratch1,
632 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 590 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
633 if (FLAG_track_double_fields && representation.IsDouble()) { 591 if (FLAG_track_double_fields && representation.IsDouble()) {
634 __ Str(storage_reg, FieldMemOperand(scratch1, offset)); 592 __ Str(storage_reg, FieldMemOperand(scratch1, offset));
635 } else { 593 } else {
636 __ Str(value_reg, FieldMemOperand(scratch1, offset)); 594 __ Str(value_reg, FieldMemOperand(scratch1, offset));
637 } 595 }
638 596
639 if (!FLAG_track_fields || !representation.IsSmi()) { 597 if (!FLAG_track_fields || !representation.IsSmi()) {
640 // Skip updating write barrier if storing a smi.
641 __ JumpIfSmi(value_reg, &exit);
642
643 // Update the write barrier for the array address. 598 // Update the write barrier for the array address.
644 // Ok to clobber receiver_reg and name_reg, since we return.
645 if (!FLAG_track_double_fields || !representation.IsDouble()) { 599 if (!FLAG_track_double_fields || !representation.IsDouble()) {
646 __ Mov(name_reg, value_reg); 600 __ Mov(storage_reg, value_reg);
647 } else {
648 ASSERT(storage_reg.is(name_reg));
649 } 601 }
650 __ RecordWriteField(scratch1, 602 __ RecordWriteField(scratch1,
651 offset, 603 offset,
652 name_reg, 604 storage_reg,
653 receiver_reg, 605 receiver_reg,
654 kLRHasNotBeenSaved, 606 kLRHasNotBeenSaved,
655 kDontSaveFPRegs, 607 kDontSaveFPRegs,
656 EMIT_REMEMBERED_SET, 608 EMIT_REMEMBERED_SET,
657 smi_check); 609 smi_check);
658 } 610 }
659 } 611 }
660 612
661 __ Bind(&exit); 613 __ Bind(&exit);
662 // Return the value (register x0). 614 // Return the value (register x0).
663 ASSERT(value_reg.is(x0)); 615 ASSERT(value_reg.is(x0));
664 __ Ret(); 616 __ Ret();
665 } 617 }
666 618
667 619
668 // Generate StoreField code, value is passed in x0 register. 620 // Generate StoreField code, value is passed in x0 register.
669 // When leaving generated code after success, the receiver_reg and name_reg may 621 // When leaving generated code after success, the receiver_reg and name_reg may
670 // be clobbered. Upon branch to miss_label, the receiver and name registers have 622 // be clobbered. Upon branch to miss_label, the receiver and name registers have
671 // their original values. 623 // their original values.
672 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 624 void BaseStoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
673 Handle<JSObject> object, 625 Handle<JSObject> object,
674 LookupResult* lookup, 626 LookupResult* lookup,
675 Register receiver_reg, 627 Register receiver_reg,
676 Register name_reg, 628 Register name_reg,
677 Register value_reg, 629 Register value_reg,
678 Register scratch1, 630 Register scratch1,
679 Register scratch2, 631 Register scratch2,
680 Label* miss_label) { 632 Label* miss_label) {
681 // x0 : value 633 // x0 : value
682 Label exit; 634 Label exit;
683 635
684 // Check that the map of the object hasn't changed.
685 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label,
686 DO_SMI_CHECK);
687
688 // Perform global security token check if needed.
689 if (object->IsJSGlobalProxy()) {
690 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
691 }
692
693 // Stub never generated for non-global objects that require access 636 // Stub never generated for non-global objects that require access
694 // checks. 637 // checks.
695 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 638 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
696 639
697 int index = lookup->GetFieldIndex().field_index(); 640 int index = lookup->GetFieldIndex().field_index();
698 641
699 // Adjust for the number of properties stored in the object. Even in the 642 // Adjust for the number of properties stored in the object. Even in the
700 // face of a transition we can use the old map here because the size of the 643 // face of a transition we can use the old map here because the size of the
701 // object and the number of in-object properties is not going to change. 644 // object and the number of in-object properties is not going to change.
702 index -= object->map()->inobject_properties(); 645 index -= object->map()->inobject_properties();
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 // their maps haven't changed. We also need to check that the property 1302 // their maps haven't changed. We also need to check that the property
1360 // cell for the property is still empty. 1303 // cell for the property is still empty.
1361 GenerateCheckPropertyCells(masm(), object, holder, name, 1304 GenerateCheckPropertyCells(masm(), object, holder, name,
1362 scratch1, scratch2, miss); 1305 scratch1, scratch2, miss);
1363 1306
1364 // Return the register containing the holder. 1307 // Return the register containing the holder.
1365 return reg; 1308 return reg;
1366 } 1309 }
1367 1310
1368 1311
1369 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, 1312 void BaseLoadStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1313 Label* success,
1370 Label* miss) { 1314 Label* miss) {
1371 if (!miss->is_unused()) { 1315 if (!miss->is_unused()) {
1372 __ B(success); 1316 __ B(success);
1373 __ Bind(miss); 1317 __ Bind(miss);
1374 TailCallBuiltin(masm(), MissBuiltin(kind())); 1318 TailCallBuiltin(masm(), MissBuiltin(kind()));
1375 } 1319 }
1376 } 1320 }
1377 1321
1378 1322
1323 void BaseStoreStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1324 Label* success,
1325 Label* miss) {
1326 if (!miss->is_unused()) {
1327 __ B(success);
1328 GenerateRestoreName(masm(), miss, name);
1329 TailCallBuiltin(masm(), MissBuiltin(kind()));
1330 }
1331 }
1332
1333
1379 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1334 Register BaseLoadStubCompiler::CallbackHandlerFrontend(
1380 Handle<JSObject> object, 1335 Handle<JSObject> object,
1381 Register object_reg, 1336 Register object_reg,
1382 Handle<JSObject> holder, 1337 Handle<JSObject> holder,
1383 Handle<Name> name, 1338 Handle<Name> name,
1384 Label* success, 1339 Label* success,
1385 Handle<ExecutableAccessorInfo> callback) { 1340 Handle<ExecutableAccessorInfo> callback) {
1386 Label miss; 1341 Label miss;
1387 1342
1388 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1343 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
(...skipping 24 matching lines...) Expand all
1413 // pointer into the dictionary. Check that the value is the callback. 1368 // pointer into the dictionary. Check that the value is the callback.
1414 Register pointer = scratch3(); 1369 Register pointer = scratch3();
1415 const int kElementsStartOffset = NameDictionary::kHeaderSize + 1370 const int kElementsStartOffset = NameDictionary::kHeaderSize +
1416 NameDictionary::kElementsStartIndex * kPointerSize; 1371 NameDictionary::kElementsStartIndex * kPointerSize;
1417 const int kValueOffset = kElementsStartOffset + kPointerSize; 1372 const int kValueOffset = kElementsStartOffset + kPointerSize;
1418 __ Ldr(scratch2(), FieldMemOperand(pointer, kValueOffset)); 1373 __ Ldr(scratch2(), FieldMemOperand(pointer, kValueOffset));
1419 __ Cmp(scratch2(), Operand(callback)); 1374 __ Cmp(scratch2(), Operand(callback));
1420 __ B(ne, &miss); 1375 __ B(ne, &miss);
1421 } 1376 }
1422 1377
1423 HandlerFrontendFooter(success, &miss); 1378 HandlerFrontendFooter(name, success, &miss);
1424 return reg; 1379 return reg;
1425 } 1380 }
1426 1381
1427 1382
1428 void BaseLoadStubCompiler::NonexistentHandlerFrontend( 1383 void BaseLoadStubCompiler::NonexistentHandlerFrontend(
1429 Handle<JSObject> object, 1384 Handle<JSObject> object,
1430 Handle<JSObject> last, 1385 Handle<JSObject> last,
1431 Handle<Name> name, 1386 Handle<Name> name,
1432 Label* success, 1387 Label* success,
1433 Handle<GlobalObject> global) { 1388 Handle<GlobalObject> global) {
1434 Label miss; 1389 Label miss;
1435 1390
1436 HandlerFrontendHeader(object, receiver(), last, name, &miss); 1391 HandlerFrontendHeader(object, receiver(), last, name, &miss);
1437 1392
1438 // If the last object in the prototype chain is a global object, 1393 // If the last object in the prototype chain is a global object,
1439 // check that the global property cell is empty. 1394 // check that the global property cell is empty.
1440 if (!global.is_null()) { 1395 if (!global.is_null()) {
1441 GenerateCheckPropertyCell(masm(), global, name, 1396 GenerateCheckPropertyCell(masm(), global, name,
1442 scratch1(), scratch2(), &miss); 1397 scratch1(), scratch2(), &miss);
1443 } 1398 }
1444 1399
1445 HandlerFrontendFooter(success, &miss); 1400 HandlerFrontendFooter(name, success, &miss);
1446 } 1401 }
1447 1402
1448 1403
1449 void BaseLoadStubCompiler::GenerateLoadField(Register reg, 1404 void BaseLoadStubCompiler::GenerateLoadField(Register reg,
1450 Handle<JSObject> holder, 1405 Handle<JSObject> holder,
1451 PropertyIndex field, 1406 PropertyIndex field,
1452 Representation representation) { 1407 Representation representation) {
1453 __ Mov(receiver(), reg); 1408 __ Mov(receiver(), reg);
1454 if (kind() == Code::LOAD_IC) { 1409 if (kind() == Code::LOAD_IC) {
1455 LoadFieldStub stub(field.is_inobject(holder), 1410 LoadFieldStub stub(field.is_inobject(holder),
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, x3, x0, 1748 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, x3, x0,
1794 x4, name, &miss); 1749 x4, name, &miss);
1795 } else { 1750 } else {
1796 ASSERT(cell->value() == *function); 1751 ASSERT(cell->value() == *function);
1797 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1752 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1798 &miss); 1753 &miss);
1799 GenerateLoadFunctionFromCell(cell, function, &miss); 1754 GenerateLoadFunctionFromCell(cell, function, &miss);
1800 } 1755 }
1801 1756
1802 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1757 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1803 site->set_payload(Smi::FromInt(GetInitialFastElementsKind())); 1758 site->set_transition_info(Smi::FromInt(GetInitialFastElementsKind()));
1804 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1759 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1805 __ Mov(x0, argc); 1760 __ Mov(x0, argc);
1806 __ Mov(x1, Operand(function)); 1761 __ Mov(x1, Operand(function));
1807 __ Mov(x2, Operand(site_feedback_cell)); 1762 __ Mov(x2, Operand(site_feedback_cell));
1808 1763
1809 ArrayConstructorStub stub(isolate()); 1764 ArrayConstructorStub stub(isolate());
1810 __ TailCallStub(&stub); 1765 __ TailCallStub(&stub);
1811 1766
1812 __ Bind(&miss); 1767 __ Bind(&miss);
1813 GenerateMissBranch(); 1768 GenerateMissBranch();
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2918 __ Bind(&miss); 2873 __ Bind(&miss);
2919 __ IncrementCounter(counters->call_global_inline_miss(), 1, x1, x3); 2874 __ IncrementCounter(counters->call_global_inline_miss(), 1, x1, x3);
2920 GenerateMissBranch(); 2875 GenerateMissBranch();
2921 2876
2922 // Return the generated code. 2877 // Return the generated code.
2923 return GetCode(Code::NORMAL, name); 2878 return GetCode(Code::NORMAL, name);
2924 } 2879 }
2925 2880
2926 2881
2927 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2882 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2928 Handle<Name> name,
2929 Handle<JSObject> object, 2883 Handle<JSObject> object,
2930 Handle<JSObject> holder, 2884 Handle<JSObject> holder,
2885 Handle<Name> name,
2931 Handle<ExecutableAccessorInfo> callback) { 2886 Handle<ExecutableAccessorInfo> callback) {
2932 Label miss;
2933
2934 ASM_LOCATION("StoreStubCompiler::CompileStoreCallback"); 2887 ASM_LOCATION("StoreStubCompiler::CompileStoreCallback");
2935 2888
2936 // Check that the maps haven't changed. 2889 Label success;
2937 __ JumpIfSmi(receiver(), &miss); 2890 HandlerFrontend(object, receiver(), holder, name, &success);
2938 CheckPrototypes(object, receiver(), holder, 2891 __ Bind(&success);
2939 scratch1(), scratch2(), scratch3(), name, &miss);
2940 2892
2941 // Stub never generated for non-global objects that require access checks. 2893 // Stub never generated for non-global objects that require access checks.
2942 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 2894 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
2943 2895
2944 __ Mov(scratch1(), Operand(callback)); 2896 __ Mov(scratch1(), Operand(callback));
2945 __ Push(receiver(), scratch1(), this->name(), value()); 2897 __ Mov(scratch2(), Operand(name));
2898 __ Push(receiver(), scratch1(), scratch2(), value());
2946 2899
2947 // Do tail-call to the runtime system. 2900 // Do tail-call to the runtime system.
2948 ExternalReference store_callback_property = 2901 ExternalReference store_callback_property =
2949 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2902 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2950 __ TailCallExternalReference(store_callback_property, 4, 1); 2903 __ TailCallExternalReference(store_callback_property, 4, 1);
2951 2904
2952 // Handle store cache miss.
2953 __ Bind(&miss);
2954 TailCallBuiltin(masm(), MissBuiltin(kind()));
2955
2956 // Return the generated code. 2905 // Return the generated code.
2957 return GetICCode(kind(), Code::CALLBACKS, name); 2906 return GetCode(kind(), Code::CALLBACKS, name);
2958 } 2907 }
2959 2908
2960 2909
2961 #undef __ 2910 #undef __
2962 #define __ ACCESS_MASM(masm) 2911 #define __ ACCESS_MASM(masm)
2963 2912
2964 2913
2965 void StoreStubCompiler::GenerateStoreViaSetter( 2914 void StoreStubCompiler::GenerateStoreViaSetter(
2966 MacroAssembler* masm, 2915 MacroAssembler* masm,
2967 Handle<JSFunction> setter) { 2916 Handle<JSFunction> setter) {
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
3208 3157
3209 // Get the value from the cell. 3158 // Get the value from the cell.
3210 __ Mov(x3, Operand(cell)); 3159 __ Mov(x3, Operand(cell));
3211 __ Ldr(x4, FieldMemOperand(x3, Cell::kValueOffset)); 3160 __ Ldr(x4, FieldMemOperand(x3, Cell::kValueOffset));
3212 3161
3213 // Check for deleted property if property can actually be deleted. 3162 // Check for deleted property if property can actually be deleted.
3214 if (!is_dont_delete) { 3163 if (!is_dont_delete) {
3215 __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss); 3164 __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss);
3216 } 3165 }
3217 3166
3218 HandlerFrontendFooter(&success, &miss); 3167 HandlerFrontendFooter(name, &success, &miss);
3219 __ bind(&success); 3168 __ Bind(&success);
3220 3169
3221 Counters* counters = isolate()->counters(); 3170 Counters* counters = isolate()->counters();
3222 __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3); 3171 __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3);
3223 __ Mov(x0, x4); 3172 __ Mov(x0, x4);
3224 __ Ret(); 3173 __ Ret();
3225 3174
3226 // Return the generated code. 3175 // Return the generated code.
3227 return GetICCode(kind(), Code::NORMAL, name); 3176 return GetICCode(kind(), Code::NORMAL, name);
3228 } 3177 }
3229 3178
3230 3179
3231 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( 3180 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
3232 MapHandleList* receiver_maps, 3181 MapHandleList* receiver_maps,
3233 CodeHandleList* handlers, 3182 CodeHandleList* handlers,
3234 Handle<Name> name, 3183 Handle<Name> name,
3235 Code::StubType type, 3184 Code::StubType type,
3236 IcCheckType check) { 3185 IcCheckType check) {
3237 Label miss; 3186 Label miss;
3238 3187
3239 if (check == PROPERTY) { 3188 if (check == PROPERTY) {
3240 GenerateNameCheck(name, this->name(), &miss); 3189 GenerateNameCheck(name, this->name(), &miss);
3241 } 3190 }
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
3807 // ----------- S t a t e ------------- 3756 // ----------- S t a t e -------------
3808 3757
3809 GenerateStoreFastSmiOrDoubleElement(masm, is_js_array, FAST_DOUBLE_ELEMENTS, 3758 GenerateStoreFastSmiOrDoubleElement(masm, is_js_array, FAST_DOUBLE_ELEMENTS,
3810 store_mode, true); 3759 store_mode, true);
3811 } 3760 }
3812 3761
3813 3762
3814 } } // namespace v8::internal 3763 } } // namespace v8::internal
3815 3764
3816 #endif // V8_TARGET_ARCH_A64 3765 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/lithium-codegen-a64.cc ('k') | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698