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

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 6092007: Write buffer based write barrier for IA32 and Crankshaft. Currently... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 11 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/ia32/code-stubs-ia32.cc ('k') | src/ia32/full-codegen-ia32.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 ASSERT(!scope()->is_global_scope()); 258 ASSERT(!scope()->is_global_scope());
259 frame_->PushParameterAt(i); 259 frame_->PushParameterAt(i);
260 Result value = frame_->Pop(); 260 Result value = frame_->Pop();
261 value.ToRegister(); 261 value.ToRegister();
262 262
263 // SlotOperand loads context.reg() with the context object 263 // SlotOperand loads context.reg() with the context object
264 // stored to, used below in RecordWrite. 264 // stored to, used below in RecordWrite.
265 Result context = allocator_->Allocate(); 265 Result context = allocator_->Allocate();
266 ASSERT(context.is_valid()); 266 ASSERT(context.is_valid());
267 __ mov(SlotOperand(slot, context.reg()), value.reg()); 267 __ mov(SlotOperand(slot, context.reg()), value.reg());
268 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER
269 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; 268 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
270 Result scratch = allocator_->Allocate(); 269 Result scratch = allocator_->Allocate();
271 ASSERT(scratch.is_valid()); 270 ASSERT(scratch.is_valid());
272 frame_->Spill(context.reg()); 271 frame_->Spill(context.reg());
273 frame_->Spill(value.reg()); 272 frame_->Spill(value.reg());
274 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg()); 273 __ RecordWrite(context.reg(),
275 #endif 274 offset,
275 value.reg(),
276 scratch.reg(),
277 kDontSaveFPRegs);
276 } 278 }
277 } 279 }
278 } 280 }
279 281
280 // Store the arguments object. This must happen after context 282 // Store the arguments object. This must happen after context
281 // initialization because the arguments object may be stored in 283 // initialization because the arguments object may be stored in
282 // the context. 284 // the context.
283 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { 285 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) {
284 StoreArgumentsObject(true); 286 StoreArgumentsObject(true);
285 } 287 }
(...skipping 5018 matching lines...) Expand 10 before | Expand all | Expand 10 after
5304 // The use of SlotOperand below is safe for an unspilled frame 5306 // The use of SlotOperand below is safe for an unspilled frame
5305 // because the slot is a context slot. 5307 // because the slot is a context slot.
5306 ASSERT(slot->type() == Slot::CONTEXT); 5308 ASSERT(slot->type() == Slot::CONTEXT);
5307 frame_->Dup(); 5309 frame_->Dup();
5308 Result value = frame_->Pop(); 5310 Result value = frame_->Pop();
5309 value.ToRegister(); 5311 value.ToRegister();
5310 Result start = allocator_->Allocate(); 5312 Result start = allocator_->Allocate();
5311 ASSERT(start.is_valid()); 5313 ASSERT(start.is_valid());
5312 __ mov(SlotOperand(slot, start.reg()), value.reg()); 5314 __ mov(SlotOperand(slot, start.reg()), value.reg());
5313 5315
5314 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER
5315 // RecordWrite may destroy the value registers. 5316 // RecordWrite may destroy the value registers.
5316 // 5317 //
5317 // TODO(204): Avoid actually spilling when the value is not 5318 // TODO(204): Avoid actually spilling when the value is not
5318 // needed (probably the common case). 5319 // needed (probably the common case).
5319 frame_->Spill(value.reg()); 5320 frame_->Spill(value.reg());
5320 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; 5321 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
5321 Result temp = allocator_->Allocate(); 5322 Result temp = allocator_->Allocate();
5322 ASSERT(temp.is_valid()); 5323 ASSERT(temp.is_valid());
5323 __ RecordWrite(start.reg(), offset, value.reg(), temp.reg()); 5324 __ RecordWrite(start.reg(),
5325 offset,
5326 value.reg(),
5327 temp.reg(),
5328 kDontSaveFPRegs);
5324 // The results start, value, and temp are unused by going out of 5329 // The results start, value, and temp are unused by going out of
5325 // scope. 5330 // scope.
5326 #endif
5327 } 5331 }
5328 5332
5329 exit.Bind(); 5333 exit.Bind();
5330 } 5334 }
5331 } 5335 }
5332 5336
5333 5337
5334 void CodeGenerator::VisitSlot(Slot* slot) { 5338 void CodeGenerator::VisitSlot(Slot* slot) {
5335 Comment cmnt(masm_, "[ Slot"); 5339 Comment cmnt(masm_, "[ Slot");
5336 if (in_safe_int32_mode()) { 5340 if (in_safe_int32_mode()) {
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
5703 elements.ToRegister(); 5707 elements.ToRegister();
5704 frame_->Spill(elements.reg()); 5708 frame_->Spill(elements.reg());
5705 // Get the elements array. 5709 // Get the elements array.
5706 __ mov(elements.reg(), 5710 __ mov(elements.reg(),
5707 FieldOperand(elements.reg(), JSObject::kElementsOffset)); 5711 FieldOperand(elements.reg(), JSObject::kElementsOffset));
5708 5712
5709 // Write to the indexed properties array. 5713 // Write to the indexed properties array.
5710 int offset = i * kPointerSize + FixedArray::kHeaderSize; 5714 int offset = i * kPointerSize + FixedArray::kHeaderSize;
5711 __ mov(FieldOperand(elements.reg(), offset), prop_value.reg()); 5715 __ mov(FieldOperand(elements.reg(), offset), prop_value.reg());
5712 5716
5713 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER
5714 // Update the write barrier for the array address. 5717 // Update the write barrier for the array address.
5715 frame_->Spill(prop_value.reg()); // Overwritten by the write barrier. 5718 frame_->Spill(prop_value.reg()); // Overwritten by the write barrier.
5716 Result scratch = allocator_->Allocate(); 5719 Result scratch = allocator_->Allocate();
5717 ASSERT(scratch.is_valid()); 5720 ASSERT(scratch.is_valid());
5718 __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg()); 5721 __ RecordWrite(elements.reg(),
5719 #endif 5722 offset,
5723 prop_value.reg(),
5724 scratch.reg(),
5725 kDontSaveFPRegs);
5720 } 5726 }
5721 } 5727 }
5722 5728
5723 5729
5724 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { 5730 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
5725 ASSERT(!in_safe_int32_mode()); 5731 ASSERT(!in_safe_int32_mode());
5726 ASSERT(!in_spilled_code()); 5732 ASSERT(!in_spilled_code());
5727 // Call runtime routine to allocate the catch extension object and 5733 // Call runtime routine to allocate the catch extension object and
5728 // assign the exception value to the catch variable. 5734 // assign the exception value to the catch variable.
5729 Comment cmnt(masm_, "[ CatchExtensionObject"); 5735 Comment cmnt(masm_, "[ CatchExtensionObject");
(...skipping 1509 matching lines...) Expand 10 before | Expand all | Expand 10 after
7239 // It is a heap object - get its map. 7245 // It is a heap object - get its map.
7240 Result scratch = allocator_->Allocate(); 7246 Result scratch = allocator_->Allocate();
7241 ASSERT(scratch.is_valid()); 7247 ASSERT(scratch.is_valid());
7242 // if (!object->IsJSValue()) return value. 7248 // if (!object->IsJSValue()) return value.
7243 __ CmpObjectType(object.reg(), JS_VALUE_TYPE, scratch.reg()); 7249 __ CmpObjectType(object.reg(), JS_VALUE_TYPE, scratch.reg());
7244 leave.Branch(not_equal, &value, not_taken); 7250 leave.Branch(not_equal, &value, not_taken);
7245 7251
7246 // Store the value. 7252 // Store the value.
7247 __ mov(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg()); 7253 __ mov(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg());
7248 7254
7249 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER
7250 // Update the write barrier. Save the value as it will be 7255 // Update the write barrier. Save the value as it will be
7251 // overwritten by the write barrier code and is needed afterward. 7256 // overwritten by the write barrier code and is needed afterward.
7252 Result duplicate_value = allocator_->Allocate(); 7257 Result duplicate_value = allocator_->Allocate();
7253 ASSERT(duplicate_value.is_valid()); 7258 ASSERT(duplicate_value.is_valid());
7254 __ mov(duplicate_value.reg(), value.reg()); 7259 __ mov(duplicate_value.reg(), value.reg());
7255 // The object register is also overwritten by the write barrier and 7260 // The object register is also overwritten by the write barrier and
7256 // possibly aliased in the frame. 7261 // possibly aliased in the frame.
7257 frame_->Spill(object.reg()); 7262 frame_->Spill(object.reg());
7258 __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(), 7263 __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(),
7259 scratch.reg()); 7264 scratch.reg(), kDontSaveFPRegs);
7260 duplicate_value.Unuse(); 7265 duplicate_value.Unuse();
7261 #endif
7262 7266
7263 object.Unuse(); 7267 object.Unuse();
7264 scratch.Unuse(); 7268 scratch.Unuse();
7265 7269
7266 // Leave. 7270 // Leave.
7267 leave.Bind(&value); 7271 leave.Bind(&value);
7268 frame_->Push(&value); 7272 frame_->Push(&value);
7269 } 7273 }
7270 7274
7271 7275
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
7524 __ lea(ebx, Operand(edx, JSFunctionResultCache::kEntrySize << 1)); 7528 __ lea(ebx, Operand(edx, JSFunctionResultCache::kEntrySize << 1));
7525 __ mov(FieldOperand(ecx, JSFunctionResultCache::kCacheSizeOffset), ebx); 7529 __ mov(FieldOperand(ecx, JSFunctionResultCache::kCacheSizeOffset), ebx);
7526 7530
7527 // Update the cache itself. 7531 // Update the cache itself.
7528 // edx holds the index. 7532 // edx holds the index.
7529 __ bind(&update_cache); 7533 __ bind(&update_cache);
7530 __ pop(ebx); // restore the key 7534 __ pop(ebx); // restore the key
7531 __ mov(FieldOperand(ecx, JSFunctionResultCache::kFingerOffset), edx); 7535 __ mov(FieldOperand(ecx, JSFunctionResultCache::kFingerOffset), edx);
7532 // Store key. 7536 // Store key.
7533 __ mov(CodeGenerator::FixedArrayElementOperand(ecx, edx), ebx); 7537 __ mov(CodeGenerator::FixedArrayElementOperand(ecx, edx), ebx);
7534 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER 7538 __ RecordWrite(ecx, 0, ebx, edx, kDontSaveFPRegs);
7535 __ RecordWrite(ecx, 0, ebx, edx);
7536 #endif
7537 7539
7538 // Store value. 7540 // Store value.
7539 __ pop(ecx); // restore the cache. 7541 __ pop(ecx); // restore the cache.
7540 __ mov(edx, FieldOperand(ecx, JSFunctionResultCache::kFingerOffset)); 7542 __ mov(edx, FieldOperand(ecx, JSFunctionResultCache::kFingerOffset));
7541 __ add(Operand(edx), Immediate(Smi::FromInt(1))); 7543 __ add(Operand(edx), Immediate(Smi::FromInt(1)));
7542 __ mov(ebx, eax); 7544 __ mov(ebx, eax);
7543 __ mov(CodeGenerator::FixedArrayElementOperand(ecx, edx), ebx); 7545 __ mov(CodeGenerator::FixedArrayElementOperand(ecx, edx), ebx);
7544 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER 7546 __ RecordWrite(ecx, 0, ebx, edx, kDontSaveFPRegs);
7545 __ RecordWrite(ecx, 0, ebx, edx);
7546 #endif
7547 7547
7548 if (!dst_.is(eax)) { 7548 if (!dst_.is(eax)) {
7549 __ mov(dst_, eax); 7549 __ mov(dst_, eax);
7550 } 7550 }
7551 } 7551 }
7552 7552
7553 7553
7554 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { 7554 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) {
7555 ASSERT_EQ(2, args->length()); 7555 ASSERT_EQ(2, args->length());
7556 7556
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
7701 // Bring addresses into index1 and index2. 7701 // Bring addresses into index1 and index2.
7702 __ lea(index1.reg(), FixedArrayElementOperand(tmp1.reg(), index1.reg())); 7702 __ lea(index1.reg(), FixedArrayElementOperand(tmp1.reg(), index1.reg()));
7703 __ lea(index2.reg(), FixedArrayElementOperand(tmp1.reg(), index2.reg())); 7703 __ lea(index2.reg(), FixedArrayElementOperand(tmp1.reg(), index2.reg()));
7704 7704
7705 // Swap elements. 7705 // Swap elements.
7706 __ mov(object.reg(), Operand(index1.reg(), 0)); 7706 __ mov(object.reg(), Operand(index1.reg(), 0));
7707 __ mov(tmp2.reg(), Operand(index2.reg(), 0)); 7707 __ mov(tmp2.reg(), Operand(index2.reg(), 0));
7708 __ mov(Operand(index2.reg(), 0), object.reg()); 7708 __ mov(Operand(index2.reg(), 0), object.reg());
7709 __ mov(Operand(index1.reg(), 0), tmp2.reg()); 7709 __ mov(Operand(index1.reg(), 0), tmp2.reg());
7710 7710
7711 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER
7712 Label done; 7711 Label done;
7713 __ InNewSpace(tmp1.reg(), tmp2.reg(), equal, &done); 7712 __ InNewSpace(tmp1.reg(), tmp2.reg(), equal, &done);
7714 // Possible optimization: do a check that both values are Smis 7713 // Possible optimization: do a check that both values are Smis
7715 // (or them and test against Smi mask.) 7714 // (or them and test against Smi mask.)
7716 7715
7717 __ mov(tmp2.reg(), tmp1.reg()); 7716 __ mov(tmp2.reg(), tmp1.reg());
7718 __ RecordWriteHelper(tmp2.reg(), index1.reg(), object.reg()); 7717 __ RecordWriteHelper(tmp2.reg(), index1.reg(), object.reg(), kDontSaveFPRegs);
7719 __ RecordWriteHelper(tmp1.reg(), index2.reg(), object.reg()); 7718 __ RecordWriteHelper(tmp1.reg(), index2.reg(), object.reg(), kDontSaveFPRegs);
7720 __ bind(&done); 7719 __ bind(&done);
7721 #endif
7722 7720
7723 deferred->BindExit(); 7721 deferred->BindExit();
7724 frame_->Push(Factory::undefined_value()); 7722 frame_->Push(Factory::undefined_value());
7725 } 7723 }
7726 7724
7727 7725
7728 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { 7726 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) {
7729 Comment cmnt(masm_, "[ GenerateCallFunction"); 7727 Comment cmnt(masm_, "[ GenerateCallFunction");
7730 7728
7731 ASSERT(args->length() >= 2); 7729 ASSERT(args->length() >= 2);
(...skipping 1920 matching lines...) Expand 10 before | Expand all | Expand 10 after
9652 // If the receiver and the value share a register allocate a new 9650 // If the receiver and the value share a register allocate a new
9653 // register for the receiver. 9651 // register for the receiver.
9654 if (receiver.reg().is(value.reg())) { 9652 if (receiver.reg().is(value.reg())) {
9655 receiver = allocator()->Allocate(); 9653 receiver = allocator()->Allocate();
9656 ASSERT(receiver.is_valid()); 9654 ASSERT(receiver.is_valid());
9657 __ mov(receiver.reg(), Operand(value.reg())); 9655 __ mov(receiver.reg(), Operand(value.reg()));
9658 } 9656 }
9659 9657
9660 // Update the write barrier. To save instructions in the inlined 9658 // Update the write barrier. To save instructions in the inlined
9661 // version we do not filter smis. 9659 // version we do not filter smis.
9662 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER
9663 Label skip_write_barrier; 9660 Label skip_write_barrier;
9664 __ InNewSpace(receiver.reg(), value.reg(), equal, &skip_write_barrier); 9661 __ InNewSpace(receiver.reg(), value.reg(), equal, &skip_write_barrier);
9665 int delta_to_record_write = masm_->SizeOfCodeGeneratedSince(&patch_site); 9662 int delta_to_record_write = masm_->SizeOfCodeGeneratedSince(&patch_site);
9666 __ lea(scratch.reg(), Operand(receiver.reg(), offset)); 9663 __ lea(scratch.reg(), Operand(receiver.reg(), offset));
9667 __ RecordWriteHelper(receiver.reg(), scratch.reg(), value.reg()); 9664 __ RecordWriteHelper(receiver.reg(),
9665 scratch.reg(),
9666 value.reg(),
9667 kDontSaveFPRegs);
9668 if (FLAG_debug_code) { 9668 if (FLAG_debug_code) {
9669 __ mov(receiver.reg(), Immediate(BitCast<int32_t>(kZapValue))); 9669 __ mov(receiver.reg(), Immediate(BitCast<int32_t>(kZapValue)));
9670 __ mov(value.reg(), Immediate(BitCast<int32_t>(kZapValue))); 9670 __ mov(value.reg(), Immediate(BitCast<int32_t>(kZapValue)));
9671 __ mov(scratch.reg(), Immediate(BitCast<int32_t>(kZapValue))); 9671 __ mov(scratch.reg(), Immediate(BitCast<int32_t>(kZapValue)));
9672 } 9672 }
9673 __ bind(&skip_write_barrier); 9673 __ bind(&skip_write_barrier);
9674 #else
9675 // Store some dummy value to avoid short encoding of test instruction.
9676 int delta_to_record_write = 0x0001;
9677 #endif
9678 value.Unuse(); 9674 value.Unuse();
9679 scratch.Unuse(); 9675 scratch.Unuse();
9680 receiver.Unuse(); 9676 receiver.Unuse();
9681 done.Jump(&result); 9677 done.Jump(&result);
9682 9678
9683 slow.Bind(&value, &receiver); 9679 slow.Bind(&value, &receiver);
9684 frame()->Push(&receiver); 9680 frame()->Push(&receiver);
9685 frame()->Push(&value); 9681 frame()->Push(&value);
9686 result = frame()->CallStoreIC(name, is_contextual); 9682 result = frame()->CallStoreIC(name, is_contextual);
9687 // Encode the offset to the map check instruction and the offset 9683 // Encode the offset to the map check instruction and the offset
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
9801 // Get the receiver, key and value into registers. 9797 // Get the receiver, key and value into registers.
9802 result = frame()->Pop(); 9798 result = frame()->Pop();
9803 Result key = frame()->Pop(); 9799 Result key = frame()->Pop();
9804 Result receiver = frame()->Pop(); 9800 Result receiver = frame()->Pop();
9805 9801
9806 Result tmp = allocator_->Allocate(); 9802 Result tmp = allocator_->Allocate();
9807 ASSERT(tmp.is_valid()); 9803 ASSERT(tmp.is_valid());
9808 Result tmp2 = allocator_->Allocate(); 9804 Result tmp2 = allocator_->Allocate();
9809 ASSERT(tmp2.is_valid()); 9805 ASSERT(tmp2.is_valid());
9810 9806
9811 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER
9812 // Determine whether the value is a constant before putting it in a 9807 // Determine whether the value is a constant before putting it in a
9813 // register. 9808 // register.
9814 bool value_is_constant = result.is_constant(); 9809 bool value_is_constant = result.is_constant();
9815 #endif
9816 9810
9817 // Make sure that value, key and receiver are in registers. 9811 // Make sure that value, key and receiver are in registers.
9818 result.ToRegister(); 9812 result.ToRegister();
9819 key.ToRegister(); 9813 key.ToRegister();
9820 receiver.ToRegister(); 9814 receiver.ToRegister();
9821 9815
9822 DeferredReferenceSetKeyedValue* deferred = 9816 DeferredReferenceSetKeyedValue* deferred =
9823 new DeferredReferenceSetKeyedValue(result.reg(), 9817 new DeferredReferenceSetKeyedValue(result.reg(),
9824 key.reg(), 9818 key.reg(),
9825 receiver.reg(), 9819 receiver.reg(),
(...skipping 19 matching lines...) Expand all
9845 // the JSArray are smis. Use unsigned comparison to handle negative keys. 9839 // the JSArray are smis. Use unsigned comparison to handle negative keys.
9846 __ cmp(key.reg(), 9840 __ cmp(key.reg(),
9847 FieldOperand(receiver.reg(), JSArray::kLengthOffset)); 9841 FieldOperand(receiver.reg(), JSArray::kLengthOffset));
9848 deferred->Branch(above_equal); 9842 deferred->Branch(above_equal);
9849 9843
9850 // Get the elements array from the receiver and check that it is not a 9844 // Get the elements array from the receiver and check that it is not a
9851 // dictionary. 9845 // dictionary.
9852 __ mov(tmp.reg(), 9846 __ mov(tmp.reg(),
9853 FieldOperand(receiver.reg(), JSArray::kElementsOffset)); 9847 FieldOperand(receiver.reg(), JSArray::kElementsOffset));
9854 9848
9855 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER
9856 // Check whether it is possible to omit the write barrier. If the elements 9849 // Check whether it is possible to omit the write barrier. If the elements
9857 // array is in new space or the value written is a smi we can safely update 9850 // array is in new space or the value written is a smi we can safely update
9858 // the elements array without write barrier. 9851 // the elements array without write barrier.
9859 Label in_new_space; 9852 Label in_new_space;
9860 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space); 9853 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space);
9861 if (!value_is_constant) { 9854 if (!value_is_constant) {
9862 __ test(result.reg(), Immediate(kSmiTagMask)); 9855 __ test(result.reg(), Immediate(kSmiTagMask));
9863 deferred->Branch(not_zero); 9856 deferred->Branch(not_zero);
9864 } 9857 }
9865 9858
9866 9859
9867 __ bind(&in_new_space); 9860 __ bind(&in_new_space);
9868 #endif
9869 // Bind the deferred code patch site to be able to locate the fixed 9861 // Bind the deferred code patch site to be able to locate the fixed
9870 // array map comparison. When debugging, we patch this comparison to 9862 // array map comparison. When debugging, we patch this comparison to
9871 // always fail so that we will hit the IC call in the deferred code 9863 // always fail so that we will hit the IC call in the deferred code
9872 // which will allow the debugger to break for fast case stores. 9864 // which will allow the debugger to break for fast case stores.
9873 __ bind(deferred->patch_site()); 9865 __ bind(deferred->patch_site());
9874 __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset), 9866 __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset),
9875 Immediate(Factory::fixed_array_map())); 9867 Immediate(Factory::fixed_array_map()));
9876 deferred->Branch(not_equal); 9868 deferred->Branch(not_equal);
9877 9869
9878 // Store the value. 9870 // Store the value.
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
10257 memcpy(base, desc.buffer, desc.instr_size); 10249 memcpy(base, desc.buffer, desc.instr_size);
10258 CPU::FlushICache(base, desc.instr_size); 10250 CPU::FlushICache(base, desc.instr_size);
10259 return FUNCTION_CAST<MemCopyFunction>(reinterpret_cast<Address>(base)); 10251 return FUNCTION_CAST<MemCopyFunction>(reinterpret_cast<Address>(base));
10260 } 10252 }
10261 10253
10262 #undef __ 10254 #undef __
10263 10255
10264 } } // namespace v8::internal 10256 } } // namespace v8::internal
10265 10257
10266 #endif // V8_TARGET_ARCH_IA32 10258 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698