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

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

Issue 10388047: Implement correct checking for inherited readonliness on assignment. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Michael's comments. 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 | src/hydrogen.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 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 428
429 429
430 // Generate StoreField code, value is passed in r0 register. 430 // Generate StoreField code, value is passed in r0 register.
431 // When leaving generated code after success, the receiver_reg and name_reg 431 // When leaving generated code after success, the receiver_reg and name_reg
432 // may be clobbered. Upon branch to miss_label, the receiver and name 432 // may be clobbered. Upon branch to miss_label, the receiver and name
433 // registers have their original values. 433 // registers have their original values.
434 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 434 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
435 Handle<JSObject> object, 435 Handle<JSObject> object,
436 int index, 436 int index,
437 Handle<Map> transition, 437 Handle<Map> transition,
438 Handle<String> name,
438 Register receiver_reg, 439 Register receiver_reg,
439 Register name_reg, 440 Register name_reg,
440 Register scratch, 441 Register scratch1,
442 Register scratch2,
441 Label* miss_label) { 443 Label* miss_label) {
442 // r0 : value 444 // r0 : value
443 Label exit; 445 Label exit;
444 446
447 LookupResult lookup(masm->isolate());
448 object->Lookup(*name, &lookup);
449 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
450 // In sloppy mode, we could just return the value and be done. However, we
451 // might be in strict mode, where we have to throw. Since we cannot tell,
452 // go into slow case unconditionally.
453 __ jmp(miss_label);
454 return;
455 }
456
445 // Check that the map of the object hasn't changed. 457 // Check that the map of the object hasn't changed.
446 CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS 458 CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
447 : REQUIRE_EXACT_MAP; 459 : REQUIRE_EXACT_MAP;
448 __ CheckMap(receiver_reg, scratch, Handle<Map>(object->map()), miss_label, 460 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label,
449 DO_SMI_CHECK, mode); 461 DO_SMI_CHECK, mode);
450 462
451 // Perform global security token check if needed. 463 // Perform global security token check if needed.
452 if (object->IsJSGlobalProxy()) { 464 if (object->IsJSGlobalProxy()) {
453 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); 465 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
466 }
467
468 // Check that we are allowed to write this.
469 if (!transition.is_null() && object->GetPrototype()->IsJSObject()) {
470 JSObject* holder;
471 if (lookup.IsFound()) {
472 holder = lookup.holder();
473 } else {
474 // Find the top object.
475 holder = *object;
476 do {
477 holder = JSObject::cast(holder->GetPrototype());
478 } while (holder->GetPrototype()->IsJSObject());
479 }
480 // We need an extra register, push
481 __ push(name_reg);
482 Label miss_pop, done_check;
483 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
484 scratch1, scratch2, name, &miss_pop);
485 __ jmp(&done_check);
486 __ bind(&miss_pop);
487 __ pop(name_reg);
488 __ jmp(miss_label);
489 __ bind(&done_check);
490 __ pop(name_reg);
454 } 491 }
455 492
456 // Stub never generated for non-global objects that require access 493 // Stub never generated for non-global objects that require access
457 // checks. 494 // checks.
458 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 495 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
459 496
460 // Perform map transition for the receiver if necessary. 497 // Perform map transition for the receiver if necessary.
461 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { 498 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) {
462 // The properties must be extended before we can store the value. 499 // The properties must be extended before we can store the value.
463 // We jump to a runtime call that extends the properties array. 500 // We jump to a runtime call that extends the properties array.
(...skipping 27 matching lines...) Expand all
491 528
492 // Skip updating write barrier if storing a smi. 529 // Skip updating write barrier if storing a smi.
493 __ JumpIfSmi(r0, &exit); 530 __ JumpIfSmi(r0, &exit);
494 531
495 // Update the write barrier for the array address. 532 // Update the write barrier for the array address.
496 // Pass the now unused name_reg as a scratch register. 533 // Pass the now unused name_reg as a scratch register.
497 __ mov(name_reg, r0); 534 __ mov(name_reg, r0);
498 __ RecordWriteField(receiver_reg, 535 __ RecordWriteField(receiver_reg,
499 offset, 536 offset,
500 name_reg, 537 name_reg,
501 scratch, 538 scratch1,
502 kLRHasNotBeenSaved, 539 kLRHasNotBeenSaved,
503 kDontSaveFPRegs); 540 kDontSaveFPRegs);
504 } else { 541 } else {
505 // Write to the properties array. 542 // Write to the properties array.
506 int offset = index * kPointerSize + FixedArray::kHeaderSize; 543 int offset = index * kPointerSize + FixedArray::kHeaderSize;
507 // Get the properties array 544 // Get the properties array
508 __ ldr(scratch, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 545 __ ldr(scratch1,
509 __ str(r0, FieldMemOperand(scratch, offset)); 546 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
547 __ str(r0, FieldMemOperand(scratch1, offset));
510 548
511 // Skip updating write barrier if storing a smi. 549 // Skip updating write barrier if storing a smi.
512 __ JumpIfSmi(r0, &exit); 550 __ JumpIfSmi(r0, &exit);
513 551
514 // Update the write barrier for the array address. 552 // Update the write barrier for the array address.
515 // Ok to clobber receiver_reg and name_reg, since we return. 553 // Ok to clobber receiver_reg and name_reg, since we return.
516 __ mov(name_reg, r0); 554 __ mov(name_reg, r0);
517 __ RecordWriteField(scratch, 555 __ RecordWriteField(scratch1,
518 offset, 556 offset,
519 name_reg, 557 name_reg,
520 receiver_reg, 558 receiver_reg,
521 kLRHasNotBeenSaved, 559 kLRHasNotBeenSaved,
522 kDontSaveFPRegs); 560 kDontSaveFPRegs);
523 } 561 }
524 562
525 // Return the value (register r0). 563 // Return the value (register r0).
526 __ bind(&exit); 564 __ bind(&exit);
527 __ Ret(); 565 __ Ret();
(...skipping 2010 matching lines...) Expand 10 before | Expand all | Expand 10 after
2538 Handle<Map> transition, 2576 Handle<Map> transition,
2539 Handle<String> name) { 2577 Handle<String> name) {
2540 // ----------- S t a t e ------------- 2578 // ----------- S t a t e -------------
2541 // -- r0 : value 2579 // -- r0 : value
2542 // -- r1 : receiver 2580 // -- r1 : receiver
2543 // -- r2 : name 2581 // -- r2 : name
2544 // -- lr : return address 2582 // -- lr : return address
2545 // ----------------------------------- 2583 // -----------------------------------
2546 Label miss; 2584 Label miss;
2547 2585
2548 GenerateStoreField(masm(), object, index, transition, r1, r2, r3, &miss); 2586 GenerateStoreField(masm(),
2587 object,
2588 index,
2589 transition,
2590 name,
2591 r1, r2, r3, r4,
2592 &miss);
2549 __ bind(&miss); 2593 __ bind(&miss);
2550 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2594 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
2551 __ Jump(ic, RelocInfo::CODE_TARGET); 2595 __ Jump(ic, RelocInfo::CODE_TARGET);
2552 2596
2553 // Return the generated code. 2597 // Return the generated code.
2554 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); 2598 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
2555 } 2599 }
2556 2600
2557 2601
2558 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2602 Handle<Code> StoreStubCompiler::CompileStoreCallback(
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
3084 3128
3085 Counters* counters = masm()->isolate()->counters(); 3129 Counters* counters = masm()->isolate()->counters();
3086 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4); 3130 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4);
3087 3131
3088 // Check that the name has not changed. 3132 // Check that the name has not changed.
3089 __ cmp(r1, Operand(name)); 3133 __ cmp(r1, Operand(name));
3090 __ b(ne, &miss); 3134 __ b(ne, &miss);
3091 3135
3092 // r3 is used as scratch register. r1 and r2 keep their values if a jump to 3136 // r3 is used as scratch register. r1 and r2 keep their values if a jump to
3093 // the miss label is generated. 3137 // the miss label is generated.
3094 GenerateStoreField(masm(), object, index, transition, r2, r1, r3, &miss); 3138 GenerateStoreField(masm(),
3139 object,
3140 index,
3141 transition,
3142 name,
3143 r2, r1, r3, r4,
3144 &miss);
3095 __ bind(&miss); 3145 __ bind(&miss);
3096 3146
3097 __ DecrementCounter(counters->keyed_store_field(), 1, r3, r4); 3147 __ DecrementCounter(counters->keyed_store_field(), 1, r3, r4);
3098 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); 3148 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
3099 __ Jump(ic, RelocInfo::CODE_TARGET); 3149 __ Jump(ic, RelocInfo::CODE_TARGET);
3100 3150
3101 // Return the generated code. 3151 // Return the generated code.
3102 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); 3152 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
3103 } 3153 }
3104 3154
(...skipping 1398 matching lines...) Expand 10 before | Expand all | Expand 10 after
4503 __ Jump(ic_slow, RelocInfo::CODE_TARGET); 4553 __ Jump(ic_slow, RelocInfo::CODE_TARGET);
4504 } 4554 }
4505 } 4555 }
4506 4556
4507 4557
4508 #undef __ 4558 #undef __
4509 4559
4510 } } // namespace v8::internal 4560 } } // namespace v8::internal
4511 4561
4512 #endif // V8_TARGET_ARCH_ARM 4562 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698