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

Side by Side Diff: src/mips/stub-cache-mips.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/mips/lithium-codegen-mips.cc ('k') | src/objects.h » ('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 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 Label* miss) { 422 Label* miss) {
423 Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name); 423 Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name);
424 ASSERT(cell->value()->IsTheHole()); 424 ASSERT(cell->value()->IsTheHole());
425 __ li(scratch, Operand(cell)); 425 __ li(scratch, Operand(cell));
426 __ lw(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 426 __ lw(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
427 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 427 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
428 __ Branch(miss, ne, scratch, Operand(at)); 428 __ Branch(miss, ne, scratch, Operand(at));
429 } 429 }
430 430
431 431
432 void BaseStoreStubCompiler::GenerateNegativeHolderLookup(
433 MacroAssembler* masm,
434 Handle<JSObject> holder,
435 Register holder_reg,
436 Handle<Name> name,
437 Label* miss) {
438 if (holder->IsJSGlobalObject()) {
439 GenerateCheckPropertyCell(
440 masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss);
441 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
442 GenerateDictionaryNegativeLookup(
443 masm, miss, holder_reg, name, scratch1(), scratch2());
444 }
445 }
446
447
432 // Generate StoreTransition code, value is passed in a0 register. 448 // Generate StoreTransition code, value is passed in a0 register.
433 // After executing generated code, the receiver_reg and name_reg 449 // After executing generated code, the receiver_reg and name_reg
434 // may be clobbered. 450 // may be clobbered.
435 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, 451 void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
436 Handle<JSObject> object, 452 Handle<JSObject> object,
437 LookupResult* lookup, 453 LookupResult* lookup,
438 Handle<Map> transition, 454 Handle<Map> transition,
439 Handle<Name> name, 455 Handle<Name> name,
440 Register receiver_reg, 456 Register receiver_reg,
441 Register name_reg, 457 Register storage_reg,
442 Register value_reg, 458 Register value_reg,
443 Register scratch1, 459 Register scratch1,
444 Register scratch2, 460 Register scratch2,
445 Register scratch3, 461 Register scratch3,
446 Label* miss_label, 462 Label* miss_label,
447 Label* miss_restore_name, 463 Label* slow) {
448 Label* slow) {
449 // a0 : value. 464 // a0 : value.
450 Label exit; 465 Label exit;
451 466
452 // Check that the map of the object hasn't changed.
453 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label,
454 DO_SMI_CHECK);
455
456 // Perform global security token check if needed.
457 if (object->IsJSGlobalProxy()) {
458 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
459 }
460
461 int descriptor = transition->LastAdded(); 467 int descriptor = transition->LastAdded();
462 DescriptorArray* descriptors = transition->instance_descriptors(); 468 DescriptorArray* descriptors = transition->instance_descriptors();
463 PropertyDetails details = descriptors->GetDetails(descriptor); 469 PropertyDetails details = descriptors->GetDetails(descriptor);
464 Representation representation = details.representation(); 470 Representation representation = details.representation();
465 ASSERT(!representation.IsNone()); 471 ASSERT(!representation.IsNone());
466 472
467 // Ensure no transitions to deprecated maps are followed.
468 __ CheckMapDeprecated(transition, scratch1, miss_label);
469
470 // Check that we are allowed to write this.
471 if (object->GetPrototype()->IsJSObject()) {
472 JSObject* holder;
473 // holder == object indicates that no property was found.
474 if (lookup->holder() != *object) {
475 holder = lookup->holder();
476 } else {
477 // Find the top object.
478 holder = *object;
479 do {
480 holder = JSObject::cast(holder->GetPrototype());
481 } while (holder->GetPrototype()->IsJSObject());
482 }
483 Register holder_reg = CheckPrototypes(
484 object, receiver_reg, Handle<JSObject>(holder), name_reg,
485 scratch1, scratch2, name, miss_restore_name, SKIP_RECEIVER);
486 // If no property was found, and the holder (the last object in the
487 // prototype chain) is in slow mode, we need to do a negative lookup on the
488 // holder.
489 if (lookup->holder() == *object) {
490 if (holder->IsJSGlobalObject()) {
491 GenerateCheckPropertyCell(
492 masm,
493 Handle<GlobalObject>(GlobalObject::cast(holder)),
494 name,
495 scratch1,
496 miss_restore_name);
497 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
498 GenerateDictionaryNegativeLookup(
499 masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
500 }
501 }
502 }
503
504 Register storage_reg = name_reg;
505
506 if (details.type() == CONSTANT_FUNCTION) { 473 if (details.type() == CONSTANT_FUNCTION) {
507 Handle<HeapObject> constant( 474 Handle<HeapObject> constant(
508 HeapObject::cast(descriptors->GetValue(descriptor))); 475 HeapObject::cast(descriptors->GetValue(descriptor)));
509 __ LoadHeapObject(scratch1, constant); 476 __ LoadHeapObject(scratch1, constant);
510 __ Branch(miss_restore_name, ne, value_reg, Operand(scratch1)); 477 __ Branch(miss_label, ne, value_reg, Operand(scratch1));
511 } else if (FLAG_track_fields && representation.IsSmi()) { 478 } else if (FLAG_track_fields && representation.IsSmi()) {
512 __ JumpIfNotSmi(value_reg, miss_restore_name); 479 __ JumpIfNotSmi(value_reg, miss_label);
513 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 480 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
514 __ JumpIfSmi(value_reg, miss_restore_name); 481 __ JumpIfSmi(value_reg, miss_label);
515 } else if (FLAG_track_double_fields && representation.IsDouble()) { 482 } else if (FLAG_track_double_fields && representation.IsDouble()) {
516 Label do_store, heap_number; 483 Label do_store, heap_number;
517 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); 484 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex);
518 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow); 485 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow);
519 486
520 __ JumpIfNotSmi(value_reg, &heap_number); 487 __ JumpIfNotSmi(value_reg, &heap_number);
521 __ SmiUntag(scratch1, value_reg); 488 __ SmiUntag(scratch1, value_reg);
522 __ mtc1(scratch1, f6); 489 __ mtc1(scratch1, f6);
523 __ cvt_d_w(f4, f6); 490 __ cvt_d_w(f4, f6);
524 __ jmp(&do_store); 491 __ jmp(&do_store);
525 492
526 __ bind(&heap_number); 493 __ bind(&heap_number);
527 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, 494 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
528 miss_restore_name, DONT_DO_SMI_CHECK); 495 miss_label, DONT_DO_SMI_CHECK);
529 __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 496 __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
530 497
531 __ bind(&do_store); 498 __ bind(&do_store);
532 __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); 499 __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
533 } 500 }
534 501
535 // Stub never generated for non-global objects that require access 502 // Stub never generated for non-global objects that require access
536 // checks. 503 // checks.
537 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 504 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
538 505
539 // Perform map transition for the receiver if necessary. 506 // Perform map transition for the receiver if necessary.
540 if (details.type() == FIELD && 507 if (details.type() == FIELD &&
541 object->map()->unused_property_fields() == 0) { 508 object->map()->unused_property_fields() == 0) {
542 // The properties must be extended before we can store the value. 509 // The properties must be extended before we can store the value.
543 // We jump to a runtime call that extends the properties array. 510 // We jump to a runtime call that extends the properties array.
544 __ push(receiver_reg); 511 __ push(receiver_reg);
545 __ li(a2, Operand(transition)); 512 __ li(a2, Operand(transition));
546 __ Push(a2, a0); 513 __ Push(a2, a0);
547 __ TailCallExternalReference( 514 __ TailCallExternalReference(
548 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 515 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
549 masm->isolate()), 516 masm->isolate()),
550 3, 1); 517 3, 1);
551 return; 518 return;
552 } 519 }
553 520
554 // Update the map of the object. 521 // Update the map of the object.
555 __ li(scratch1, Operand(transition)); 522 __ li(scratch1, Operand(transition));
556 __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 523 __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
557 524
558 // Update the write barrier for the map field and pass the now unused 525 // Update the write barrier for the map field.
559 // name_reg as scratch register.
560 __ RecordWriteField(receiver_reg, 526 __ RecordWriteField(receiver_reg,
561 HeapObject::kMapOffset, 527 HeapObject::kMapOffset,
562 scratch1, 528 scratch1,
563 scratch2, 529 scratch2,
564 kRAHasNotBeenSaved, 530 kRAHasNotBeenSaved,
565 kDontSaveFPRegs, 531 kDontSaveFPRegs,
566 OMIT_REMEMBERED_SET, 532 OMIT_REMEMBERED_SET,
567 OMIT_SMI_CHECK); 533 OMIT_SMI_CHECK);
568 534
569 if (details.type() == CONSTANT_FUNCTION) { 535 if (details.type() == CONSTANT_FUNCTION) {
(...skipping 17 matching lines...) Expand all
587 if (index < 0) { 553 if (index < 0) {
588 // Set the property straight into the object. 554 // Set the property straight into the object.
589 int offset = object->map()->instance_size() + (index * kPointerSize); 555 int offset = object->map()->instance_size() + (index * kPointerSize);
590 if (FLAG_track_double_fields && representation.IsDouble()) { 556 if (FLAG_track_double_fields && representation.IsDouble()) {
591 __ sw(storage_reg, FieldMemOperand(receiver_reg, offset)); 557 __ sw(storage_reg, FieldMemOperand(receiver_reg, offset));
592 } else { 558 } else {
593 __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); 559 __ sw(value_reg, FieldMemOperand(receiver_reg, offset));
594 } 560 }
595 561
596 if (!FLAG_track_fields || !representation.IsSmi()) { 562 if (!FLAG_track_fields || !representation.IsSmi()) {
597 // Skip updating write barrier if storing a smi.
598 __ JumpIfSmi(value_reg, &exit);
599
600 // Update the write barrier for the array address. 563 // Update the write barrier for the array address.
601 // Pass the now unused name_reg as a scratch register.
602 if (!FLAG_track_double_fields || !representation.IsDouble()) { 564 if (!FLAG_track_double_fields || !representation.IsDouble()) {
603 __ mov(name_reg, value_reg); 565 __ mov(storage_reg, value_reg);
604 } else {
605 ASSERT(storage_reg.is(name_reg));
606 } 566 }
607 __ RecordWriteField(receiver_reg, 567 __ RecordWriteField(receiver_reg,
608 offset, 568 offset,
609 name_reg, 569 storage_reg,
610 scratch1, 570 scratch1,
611 kRAHasNotBeenSaved, 571 kRAHasNotBeenSaved,
612 kDontSaveFPRegs, 572 kDontSaveFPRegs,
613 EMIT_REMEMBERED_SET, 573 EMIT_REMEMBERED_SET,
614 smi_check); 574 smi_check);
615 } 575 }
616 } else { 576 } else {
617 // Write to the properties array. 577 // Write to the properties array.
618 int offset = index * kPointerSize + FixedArray::kHeaderSize; 578 int offset = index * kPointerSize + FixedArray::kHeaderSize;
619 // Get the properties array 579 // Get the properties array
620 __ lw(scratch1, 580 __ lw(scratch1,
621 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 581 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
622 if (FLAG_track_double_fields && representation.IsDouble()) { 582 if (FLAG_track_double_fields && representation.IsDouble()) {
623 __ sw(storage_reg, FieldMemOperand(scratch1, offset)); 583 __ sw(storage_reg, FieldMemOperand(scratch1, offset));
624 } else { 584 } else {
625 __ sw(value_reg, FieldMemOperand(scratch1, offset)); 585 __ sw(value_reg, FieldMemOperand(scratch1, offset));
626 } 586 }
627 587
628 if (!FLAG_track_fields || !representation.IsSmi()) { 588 if (!FLAG_track_fields || !representation.IsSmi()) {
629 // Skip updating write barrier if storing a smi.
630 __ JumpIfSmi(value_reg, &exit);
631
632 // Update the write barrier for the array address. 589 // Update the write barrier for the array address.
633 // Ok to clobber receiver_reg and name_reg, since we return.
634 if (!FLAG_track_double_fields || !representation.IsDouble()) { 590 if (!FLAG_track_double_fields || !representation.IsDouble()) {
635 __ mov(name_reg, value_reg); 591 __ mov(storage_reg, value_reg);
636 } else {
637 ASSERT(storage_reg.is(name_reg));
638 } 592 }
639 __ RecordWriteField(scratch1, 593 __ RecordWriteField(scratch1,
640 offset, 594 offset,
641 name_reg, 595 storage_reg,
642 receiver_reg, 596 receiver_reg,
643 kRAHasNotBeenSaved, 597 kRAHasNotBeenSaved,
644 kDontSaveFPRegs, 598 kDontSaveFPRegs,
645 EMIT_REMEMBERED_SET, 599 EMIT_REMEMBERED_SET,
646 smi_check); 600 smi_check);
647 } 601 }
648 } 602 }
649 603
650 // Return the value (register v0). 604 // Return the value (register v0).
651 ASSERT(value_reg.is(a0)); 605 ASSERT(value_reg.is(a0));
652 __ bind(&exit); 606 __ bind(&exit);
653 __ Ret(USE_DELAY_SLOT); 607 __ Ret(USE_DELAY_SLOT);
654 __ mov(v0, a0); 608 __ mov(v0, a0);
655 } 609 }
656 610
657 611
658 // Generate StoreField code, value is passed in a0 register. 612 // Generate StoreField code, value is passed in a0 register.
659 // When leaving generated code after success, the receiver_reg and name_reg 613 // When leaving generated code after success, the receiver_reg and name_reg
660 // may be clobbered. Upon branch to miss_label, the receiver and name 614 // may be clobbered. Upon branch to miss_label, the receiver and name
661 // registers have their original values. 615 // registers have their original values.
662 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 616 void BaseStoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
663 Handle<JSObject> object, 617 Handle<JSObject> object,
664 LookupResult* lookup, 618 LookupResult* lookup,
665 Register receiver_reg, 619 Register receiver_reg,
666 Register name_reg, 620 Register name_reg,
667 Register value_reg, 621 Register value_reg,
668 Register scratch1, 622 Register scratch1,
669 Register scratch2, 623 Register scratch2,
670 Label* miss_label) { 624 Label* miss_label) {
671 // a0 : value 625 // a0 : value
672 Label exit; 626 Label exit;
673 627
674 // Check that the map of the object hasn't changed.
675 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label,
676 DO_SMI_CHECK);
677
678 // Perform global security token check if needed.
679 if (object->IsJSGlobalProxy()) {
680 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
681 }
682
683 // Stub never generated for non-global objects that require access 628 // Stub never generated for non-global objects that require access
684 // checks. 629 // checks.
685 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 630 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
686 631
687 int index = lookup->GetFieldIndex().field_index(); 632 int index = lookup->GetFieldIndex().field_index();
688 633
689 // Adjust for the number of properties stored in the object. Even in the 634 // Adjust for the number of properties stored in the object. Even in the
690 // face of a transition we can use the old map here because the size of the 635 // face of a transition we can use the old map here because the size of the
691 // object and the number of in-object properties is not going to change. 636 // object and the number of in-object properties is not going to change.
692 index -= object->map()->inobject_properties(); 637 index -= object->map()->inobject_properties();
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 // If we've skipped any global objects, it's not enough to verify that 1286 // If we've skipped any global objects, it's not enough to verify that
1342 // their maps haven't changed. We also need to check that the property 1287 // their maps haven't changed. We also need to check that the property
1343 // cell for the property is still empty. 1288 // cell for the property is still empty.
1344 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1289 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1345 1290
1346 // Return the register containing the holder. 1291 // Return the register containing the holder.
1347 return reg; 1292 return reg;
1348 } 1293 }
1349 1294
1350 1295
1351 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, 1296 void BaseLoadStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1297 Label* success,
1352 Label* miss) { 1298 Label* miss) {
1353 if (!miss->is_unused()) { 1299 if (!miss->is_unused()) {
1354 __ Branch(success); 1300 __ Branch(success);
1355 __ bind(miss); 1301 __ bind(miss);
1356 TailCallBuiltin(masm(), MissBuiltin(kind())); 1302 TailCallBuiltin(masm(), MissBuiltin(kind()));
1357 } 1303 }
1358 } 1304 }
1359 1305
1360 1306
1307 void BaseStoreStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1308 Label* success,
1309 Label* miss) {
1310 if (!miss->is_unused()) {
1311 __ b(success);
1312 GenerateRestoreName(masm(), miss, name);
1313 TailCallBuiltin(masm(), MissBuiltin(kind()));
1314 }
1315 }
1316
1317
1361 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1318 Register BaseLoadStubCompiler::CallbackHandlerFrontend(
1362 Handle<JSObject> object, 1319 Handle<JSObject> object,
1363 Register object_reg, 1320 Register object_reg,
1364 Handle<JSObject> holder, 1321 Handle<JSObject> holder,
1365 Handle<Name> name, 1322 Handle<Name> name,
1366 Label* success, 1323 Label* success,
1367 Handle<ExecutableAccessorInfo> callback) { 1324 Handle<ExecutableAccessorInfo> callback) {
1368 Label miss; 1325 Label miss;
1369 1326
1370 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1327 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
(...skipping 21 matching lines...) Expand all
1392 // If probing finds an entry in the dictionary, scratch3 contains the 1349 // If probing finds an entry in the dictionary, scratch3 contains the
1393 // pointer into the dictionary. Check that the value is the callback. 1350 // pointer into the dictionary. Check that the value is the callback.
1394 Register pointer = scratch3(); 1351 Register pointer = scratch3();
1395 const int kElementsStartOffset = NameDictionary::kHeaderSize + 1352 const int kElementsStartOffset = NameDictionary::kHeaderSize +
1396 NameDictionary::kElementsStartIndex * kPointerSize; 1353 NameDictionary::kElementsStartIndex * kPointerSize;
1397 const int kValueOffset = kElementsStartOffset + kPointerSize; 1354 const int kValueOffset = kElementsStartOffset + kPointerSize;
1398 __ lw(scratch2(), FieldMemOperand(pointer, kValueOffset)); 1355 __ lw(scratch2(), FieldMemOperand(pointer, kValueOffset));
1399 __ Branch(&miss, ne, scratch2(), Operand(callback)); 1356 __ Branch(&miss, ne, scratch2(), Operand(callback));
1400 } 1357 }
1401 1358
1402 HandlerFrontendFooter(success, &miss); 1359 HandlerFrontendFooter(name, success, &miss);
1403 return reg; 1360 return reg;
1404 } 1361 }
1405 1362
1406 1363
1407 void BaseLoadStubCompiler::NonexistentHandlerFrontend( 1364 void BaseLoadStubCompiler::NonexistentHandlerFrontend(
1408 Handle<JSObject> object, 1365 Handle<JSObject> object,
1409 Handle<JSObject> last, 1366 Handle<JSObject> last,
1410 Handle<Name> name, 1367 Handle<Name> name,
1411 Label* success, 1368 Label* success,
1412 Handle<GlobalObject> global) { 1369 Handle<GlobalObject> global) {
1413 Label miss; 1370 Label miss;
1414 1371
1415 HandlerFrontendHeader(object, receiver(), last, name, &miss); 1372 HandlerFrontendHeader(object, receiver(), last, name, &miss);
1416 1373
1417 // If the last object in the prototype chain is a global object, 1374 // If the last object in the prototype chain is a global object,
1418 // check that the global property cell is empty. 1375 // check that the global property cell is empty.
1419 if (!global.is_null()) { 1376 if (!global.is_null()) {
1420 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1377 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1421 } 1378 }
1422 1379
1423 HandlerFrontendFooter(success, &miss); 1380 HandlerFrontendFooter(name, success, &miss);
1424 } 1381 }
1425 1382
1426 1383
1427 void BaseLoadStubCompiler::GenerateLoadField(Register reg, 1384 void BaseLoadStubCompiler::GenerateLoadField(Register reg,
1428 Handle<JSObject> holder, 1385 Handle<JSObject> holder,
1429 PropertyIndex field, 1386 PropertyIndex field,
1430 Representation representation) { 1387 Representation representation) {
1431 if (!reg.is(receiver())) __ mov(receiver(), reg); 1388 if (!reg.is(receiver())) __ mov(receiver(), reg);
1432 if (kind() == Code::LOAD_IC) { 1389 if (kind() == Code::LOAD_IC) {
1433 LoadFieldStub stub(field.is_inobject(holder), 1390 LoadFieldStub stub(field.is_inobject(holder),
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1737 // Check that the maps haven't changed. 1694 // Check that the maps haven't changed.
1738 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, a0, 1695 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, a0,
1739 t0, name, &miss); 1696 t0, name, &miss);
1740 } else { 1697 } else {
1741 ASSERT(cell->value() == *function); 1698 ASSERT(cell->value() == *function);
1742 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1699 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1743 &miss); 1700 &miss);
1744 GenerateLoadFunctionFromCell(cell, function, &miss); 1701 GenerateLoadFunctionFromCell(cell, function, &miss);
1745 } 1702 }
1746 1703
1747 Handle<Smi> kind(Smi::FromInt(GetInitialFastElementsKind()), isolate()); 1704 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1748 Handle<Cell> kind_feedback_cell = 1705 site->set_transition_info(Smi::FromInt(GetInitialFastElementsKind()));
1749 isolate()->factory()->NewCell(kind); 1706 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1750 __ li(a0, Operand(argc)); 1707 __ li(a0, Operand(argc));
1751 __ li(a2, Operand(kind_feedback_cell)); 1708 __ li(a2, Operand(site_feedback_cell));
1752 __ li(a1, Operand(function)); 1709 __ li(a1, Operand(function));
1753 1710
1754 ArrayConstructorStub stub(isolate()); 1711 ArrayConstructorStub stub(isolate());
1755 __ TailCallStub(&stub); 1712 __ TailCallStub(&stub);
1756 1713
1757 __ bind(&miss); 1714 __ bind(&miss);
1758 GenerateMissBranch(); 1715 GenerateMissBranch();
1759 1716
1760 // Return the generated code. 1717 // Return the generated code.
1761 return GetCode(type, name); 1718 return GetCode(type, name);
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
2859 __ bind(&miss); 2816 __ bind(&miss);
2860 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); 2817 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3);
2861 GenerateMissBranch(); 2818 GenerateMissBranch();
2862 2819
2863 // Return the generated code. 2820 // Return the generated code.
2864 return GetCode(Code::NORMAL, name); 2821 return GetCode(Code::NORMAL, name);
2865 } 2822 }
2866 2823
2867 2824
2868 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2825 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2869 Handle<Name> name,
2870 Handle<JSObject> object, 2826 Handle<JSObject> object,
2871 Handle<JSObject> holder, 2827 Handle<JSObject> holder,
2828 Handle<Name> name,
2872 Handle<ExecutableAccessorInfo> callback) { 2829 Handle<ExecutableAccessorInfo> callback) {
2873 Label miss; 2830 Label success;
2874 // Check that the maps haven't changed. 2831 HandlerFrontend(object, receiver(), holder, name, &success);
2875 __ JumpIfSmi(receiver(), &miss); 2832 __ bind(&success);
2876 CheckPrototypes(object, receiver(), holder,
2877 scratch1(), scratch2(), scratch3(), name, &miss);
2878 2833
2879 // Stub never generated for non-global objects that require access 2834 // Stub never generated for non-global objects that require access
2880 // checks. 2835 // checks.
2881 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 2836 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
2882 2837
2883 __ push(receiver()); // Receiver. 2838 __ push(receiver()); // Receiver.
2884 __ li(at, Operand(callback)); // Callback info. 2839 __ li(at, Operand(callback)); // Callback info.
2885 __ Push(at, this->name(), value()); 2840 __ push(at);
2841 __ li(at, Operand(name));
2842 __ Push(at, value());
2886 2843
2887 // Do tail-call to the runtime system. 2844 // Do tail-call to the runtime system.
2888 ExternalReference store_callback_property = 2845 ExternalReference store_callback_property =
2889 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2846 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2890 __ TailCallExternalReference(store_callback_property, 4, 1); 2847 __ TailCallExternalReference(store_callback_property, 4, 1);
2891 2848
2892 // Handle store cache miss.
2893 __ bind(&miss);
2894 TailCallBuiltin(masm(), MissBuiltin(kind()));
2895
2896 // Return the generated code. 2849 // Return the generated code.
2897 return GetICCode(kind(), Code::CALLBACKS, name); 2850 return GetCode(kind(), Code::CALLBACKS, name);
2898 } 2851 }
2899 2852
2900 2853
2901 #undef __ 2854 #undef __
2902 #define __ ACCESS_MASM(masm) 2855 #define __ ACCESS_MASM(masm)
2903 2856
2904 2857
2905 void StoreStubCompiler::GenerateStoreViaSetter( 2858 void StoreStubCompiler::GenerateStoreViaSetter(
2906 MacroAssembler* masm, 2859 MacroAssembler* masm,
2907 Handle<JSFunction> setter) { 2860 Handle<JSFunction> setter) {
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
3137 // Get the value from the cell. 3090 // Get the value from the cell.
3138 __ li(a3, Operand(cell)); 3091 __ li(a3, Operand(cell));
3139 __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset)); 3092 __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset));
3140 3093
3141 // Check for deleted property if property can actually be deleted. 3094 // Check for deleted property if property can actually be deleted.
3142 if (!is_dont_delete) { 3095 if (!is_dont_delete) {
3143 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 3096 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
3144 __ Branch(&miss, eq, t0, Operand(at)); 3097 __ Branch(&miss, eq, t0, Operand(at));
3145 } 3098 }
3146 3099
3147 HandlerFrontendFooter(&success, &miss); 3100 HandlerFrontendFooter(name, &success, &miss);
3148 __ bind(&success); 3101 __ bind(&success);
3149 3102
3150 Counters* counters = isolate()->counters(); 3103 Counters* counters = isolate()->counters();
3151 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); 3104 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
3152 __ Ret(USE_DELAY_SLOT); 3105 __ Ret(USE_DELAY_SLOT);
3153 __ mov(v0, t0); 3106 __ mov(v0, t0);
3154 3107
3155 // Return the generated code. 3108 // Return the generated code.
3156 return GetICCode(kind(), Code::NORMAL, name); 3109 return GetICCode(kind(), Code::NORMAL, name);
3157 } 3110 }
3158 3111
3159 3112
3160 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( 3113 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
3161 MapHandleList* receiver_maps, 3114 MapHandleList* receiver_maps,
3162 CodeHandleList* handlers, 3115 CodeHandleList* handlers,
3163 Handle<Name> name, 3116 Handle<Name> name,
3164 Code::StubType type, 3117 Code::StubType type,
3165 IcCheckType check) { 3118 IcCheckType check) {
3166 Label miss; 3119 Label miss;
3167 3120
3168 if (check == PROPERTY) { 3121 if (check == PROPERTY) {
3169 GenerateNameCheck(name, this->name(), &miss); 3122 GenerateNameCheck(name, this->name(), &miss);
3170 } 3123 }
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after
3835 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3788 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3836 } 3789 }
3837 } 3790 }
3838 3791
3839 3792
3840 #undef __ 3793 #undef __
3841 3794
3842 } } // namespace v8::internal 3795 } } // namespace v8::internal
3843 3796
3844 #endif // V8_TARGET_ARCH_MIPS 3797 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/lithium-codegen-mips.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698