| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |