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

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

Issue 10539004: MIPS: Implement correct checking for inherited readonliness on assignment. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 6 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 | « no previous file | no next file » | 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 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 } 415 }
416 416
417 417
418 // Generate StoreField code, value is passed in a0 register. 418 // Generate StoreField code, value is passed in a0 register.
419 // After executing generated code, the receiver_reg and name_reg 419 // After executing generated code, the receiver_reg and name_reg
420 // may be clobbered. 420 // may be clobbered.
421 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 421 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
422 Handle<JSObject> object, 422 Handle<JSObject> object,
423 int index, 423 int index,
424 Handle<Map> transition, 424 Handle<Map> transition,
425 Handle<String> name,
425 Register receiver_reg, 426 Register receiver_reg,
426 Register name_reg, 427 Register name_reg,
427 Register scratch, 428 Register scratch1,
429 Register scratch2,
428 Label* miss_label) { 430 Label* miss_label) {
429 // a0 : value. 431 // a0 : value.
430 Label exit; 432 Label exit;
433
434 LookupResult lookup(masm->isolate());
435 object->Lookup(*name, &lookup);
436 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
437 // In sloppy mode, we could just return the value and be done. However, we
438 // might be in strict mode, where we have to throw. Since we cannot tell,
439 // go into slow case unconditionally.
440 __ jmp(miss_label);
441 return;
442 }
443
431 // Check that the map of the object hasn't changed. 444 // Check that the map of the object hasn't changed.
432 CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS 445 CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
433 : REQUIRE_EXACT_MAP; 446 : REQUIRE_EXACT_MAP;
434 __ CheckMap(receiver_reg, scratch, Handle<Map>(object->map()), miss_label, 447 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label,
435 DO_SMI_CHECK, mode); 448 DO_SMI_CHECK, mode);
436 449
437 // Perform global security token check if needed. 450 // Perform global security token check if needed.
438 if (object->IsJSGlobalProxy()) { 451 if (object->IsJSGlobalProxy()) {
439 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); 452 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
453 }
454
455 // Check that we are allowed to write this.
456 if (!transition.is_null() && object->GetPrototype()->IsJSObject()) {
457 JSObject* holder;
458 if (lookup.IsFound()) {
459 holder = lookup.holder();
460 } else {
461 // Find the top object.
462 holder = *object;
463 do {
464 holder = JSObject::cast(holder->GetPrototype());
465 } while (holder->GetPrototype()->IsJSObject());
466 }
467 // We need an extra register, push
468 __ push(name_reg);
469 Label miss_pop, done_check;
470 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
471 scratch1, scratch2, name, &miss_pop);
472 __ jmp(&done_check);
473 __ bind(&miss_pop);
474 __ pop(name_reg);
475 __ jmp(miss_label);
476 __ bind(&done_check);
477 __ pop(name_reg);
440 } 478 }
441 479
442 // Stub never generated for non-global objects that require access 480 // Stub never generated for non-global objects that require access
443 // checks. 481 // checks.
444 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 482 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
445 483
446 // Perform map transition for the receiver if necessary. 484 // Perform map transition for the receiver if necessary.
447 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { 485 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) {
448 // The properties must be extended before we can store the value. 486 // The properties must be extended before we can store the value.
449 // We jump to a runtime call that extends the properties array. 487 // We jump to a runtime call that extends the properties array.
450 __ push(receiver_reg); 488 __ push(receiver_reg);
451 __ li(a2, Operand(transition)); 489 __ li(a2, Operand(transition));
452 __ Push(a2, a0); 490 __ Push(a2, a0);
453 __ TailCallExternalReference( 491 __ TailCallExternalReference(
454 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 492 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
455 masm->isolate()), 493 masm->isolate()),
456 3, 1); 494 3, 1);
457 return; 495 return;
458 } 496 }
459 497
460 if (!transition.is_null()) { 498 if (!transition.is_null()) {
461 // Update the map of the object. 499 // Update the map of the object.
462 __ li(scratch, Operand(transition)); 500 __ li(scratch1, Operand(transition));
463 __ sw(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 501 __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
464 502
465 // Update the write barrier for the map field and pass the now unused 503 // Update the write barrier for the map field and pass the now unused
466 // name_reg as scratch register. 504 // name_reg as scratch register.
467 __ RecordWriteField(receiver_reg, 505 __ RecordWriteField(receiver_reg,
468 HeapObject::kMapOffset, 506 HeapObject::kMapOffset,
469 scratch, 507 scratch1,
470 name_reg, 508 name_reg,
471 kRAHasNotBeenSaved, 509 kRAHasNotBeenSaved,
472 kDontSaveFPRegs, 510 kDontSaveFPRegs,
473 OMIT_REMEMBERED_SET, 511 OMIT_REMEMBERED_SET,
474 OMIT_SMI_CHECK); 512 OMIT_SMI_CHECK);
475 } 513 }
476 514
477 // Adjust for the number of properties stored in the object. Even in the 515 // Adjust for the number of properties stored in the object. Even in the
478 // face of a transition we can use the old map here because the size of the 516 // face of a transition we can use the old map here because the size of the
479 // object and the number of in-object properties is not going to change. 517 // object and the number of in-object properties is not going to change.
480 index -= object->map()->inobject_properties(); 518 index -= object->map()->inobject_properties();
481 519
482 if (index < 0) { 520 if (index < 0) {
483 // Set the property straight into the object. 521 // Set the property straight into the object.
484 int offset = object->map()->instance_size() + (index * kPointerSize); 522 int offset = object->map()->instance_size() + (index * kPointerSize);
485 __ sw(a0, FieldMemOperand(receiver_reg, offset)); 523 __ sw(a0, FieldMemOperand(receiver_reg, offset));
486 524
487 // Skip updating write barrier if storing a smi. 525 // Skip updating write barrier if storing a smi.
488 __ JumpIfSmi(a0, &exit, scratch); 526 __ JumpIfSmi(a0, &exit, scratch1);
489 527
490 // Update the write barrier for the array address. 528 // Update the write barrier for the array address.
491 // Pass the now unused name_reg as a scratch register. 529 // Pass the now unused name_reg as a scratch register.
492 __ mov(name_reg, a0); 530 __ mov(name_reg, a0);
493 __ RecordWriteField(receiver_reg, 531 __ RecordWriteField(receiver_reg,
494 offset, 532 offset,
495 name_reg, 533 name_reg,
496 scratch, 534 scratch1,
497 kRAHasNotBeenSaved, 535 kRAHasNotBeenSaved,
498 kDontSaveFPRegs); 536 kDontSaveFPRegs);
499 } else { 537 } else {
500 // Write to the properties array. 538 // Write to the properties array.
501 int offset = index * kPointerSize + FixedArray::kHeaderSize; 539 int offset = index * kPointerSize + FixedArray::kHeaderSize;
502 // Get the properties array. 540 // Get the properties array.
503 __ lw(scratch, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 541 __ lw(scratch1,
504 __ sw(a0, FieldMemOperand(scratch, offset)); 542 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
543 __ sw(a0, FieldMemOperand(scratch1, offset));
505 544
506 // Skip updating write barrier if storing a smi. 545 // Skip updating write barrier if storing a smi.
507 __ JumpIfSmi(a0, &exit); 546 __ JumpIfSmi(a0, &exit);
508 547
509 // Update the write barrier for the array address. 548 // Update the write barrier for the array address.
510 // Ok to clobber receiver_reg and name_reg, since we return. 549 // Ok to clobber receiver_reg and name_reg, since we return.
511 __ mov(name_reg, a0); 550 __ mov(name_reg, a0);
512 __ RecordWriteField(scratch, 551 __ RecordWriteField(scratch1,
513 offset, 552 offset,
514 name_reg, 553 name_reg,
515 receiver_reg, 554 receiver_reg,
516 kRAHasNotBeenSaved, 555 kRAHasNotBeenSaved,
517 kDontSaveFPRegs); 556 kDontSaveFPRegs);
518 } 557 }
519 558
520 // Return the value (register v0). 559 // Return the value (register v0).
521 __ bind(&exit); 560 __ bind(&exit);
522 __ mov(v0, a0); 561 __ mov(v0, a0);
(...skipping 2040 matching lines...) Expand 10 before | Expand all | Expand 10 after
2563 Handle<String> name) { 2602 Handle<String> name) {
2564 // ----------- S t a t e ------------- 2603 // ----------- S t a t e -------------
2565 // -- a0 : value 2604 // -- a0 : value
2566 // -- a1 : receiver 2605 // -- a1 : receiver
2567 // -- a2 : name 2606 // -- a2 : name
2568 // -- ra : return address 2607 // -- ra : return address
2569 // ----------------------------------- 2608 // -----------------------------------
2570 Label miss; 2609 Label miss;
2571 2610
2572 // Name register might be clobbered. 2611 // Name register might be clobbered.
2573 GenerateStoreField(masm(), object, index, transition, a1, a2, a3, &miss); 2612 GenerateStoreField(masm(),
2613 object,
2614 index,
2615 transition,
2616 name,
2617 a1, a2, a3, t0,
2618 &miss);
2574 __ bind(&miss); 2619 __ bind(&miss);
2575 __ li(a2, Operand(Handle<String>(name))); // Restore name. 2620 __ li(a2, Operand(Handle<String>(name))); // Restore name.
2576 Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss(); 2621 Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss();
2577 __ Jump(ic, RelocInfo::CODE_TARGET); 2622 __ Jump(ic, RelocInfo::CODE_TARGET);
2578 2623
2579 // Return the generated code. 2624 // Return the generated code.
2580 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); 2625 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
2581 } 2626 }
2582 2627
2583 2628
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
3102 Label miss; 3147 Label miss;
3103 3148
3104 Counters* counters = masm()->isolate()->counters(); 3149 Counters* counters = masm()->isolate()->counters();
3105 __ IncrementCounter(counters->keyed_store_field(), 1, a3, t0); 3150 __ IncrementCounter(counters->keyed_store_field(), 1, a3, t0);
3106 3151
3107 // Check that the name has not changed. 3152 // Check that the name has not changed.
3108 __ Branch(&miss, ne, a1, Operand(name)); 3153 __ Branch(&miss, ne, a1, Operand(name));
3109 3154
3110 // a3 is used as scratch register. a1 and a2 keep their values if a jump to 3155 // a3 is used as scratch register. a1 and a2 keep their values if a jump to
3111 // the miss label is generated. 3156 // the miss label is generated.
3112 GenerateStoreField(masm(), object, index, transition, a2, a1, a3, &miss); 3157 GenerateStoreField(masm(),
3158 object,
3159 index,
3160 transition,
3161 name,
3162 a2, a1, a3, t0,
3163 &miss);
3113 __ bind(&miss); 3164 __ bind(&miss);
3114 3165
3115 __ DecrementCounter(counters->keyed_store_field(), 1, a3, t0); 3166 __ DecrementCounter(counters->keyed_store_field(), 1, a3, t0);
3116 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); 3167 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
3117 __ Jump(ic, RelocInfo::CODE_TARGET); 3168 __ Jump(ic, RelocInfo::CODE_TARGET);
3118 3169
3119 // Return the generated code. 3170 // Return the generated code.
3120 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); 3171 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
3121 } 3172 }
3122 3173
(...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after
4601 __ Jump(ic_slow, RelocInfo::CODE_TARGET); 4652 __ Jump(ic_slow, RelocInfo::CODE_TARGET);
4602 } 4653 }
4603 } 4654 }
4604 4655
4605 4656
4606 #undef __ 4657 #undef __
4607 4658
4608 } } // namespace v8::internal 4659 } } // namespace v8::internal
4609 4660
4610 #endif // V8_TARGET_ARCH_MIPS 4661 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698