| 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 |
| 268 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; | 269 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
| 269 Result scratch = allocator_->Allocate(); | 270 Result scratch = allocator_->Allocate(); |
| 270 ASSERT(scratch.is_valid()); | 271 ASSERT(scratch.is_valid()); |
| 271 frame_->Spill(context.reg()); | 272 frame_->Spill(context.reg()); |
| 272 frame_->Spill(value.reg()); | 273 frame_->Spill(value.reg()); |
| 273 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg()); | 274 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg()); |
| 275 #endif |
| 274 } | 276 } |
| 275 } | 277 } |
| 276 } | 278 } |
| 277 | 279 |
| 278 // Store the arguments object. This must happen after context | 280 // Store the arguments object. This must happen after context |
| 279 // initialization because the arguments object may be stored in | 281 // initialization because the arguments object may be stored in |
| 280 // the context. | 282 // the context. |
| 281 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { | 283 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { |
| 282 StoreArgumentsObject(true); | 284 StoreArgumentsObject(true); |
| 283 } | 285 } |
| (...skipping 5017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5301 // | 5303 // |
| 5302 // The use of SlotOperand below is safe for an unspilled frame | 5304 // The use of SlotOperand below is safe for an unspilled frame |
| 5303 // because the slot is a context slot. | 5305 // because the slot is a context slot. |
| 5304 ASSERT(slot->type() == Slot::CONTEXT); | 5306 ASSERT(slot->type() == Slot::CONTEXT); |
| 5305 frame_->Dup(); | 5307 frame_->Dup(); |
| 5306 Result value = frame_->Pop(); | 5308 Result value = frame_->Pop(); |
| 5307 value.ToRegister(); | 5309 value.ToRegister(); |
| 5308 Result start = allocator_->Allocate(); | 5310 Result start = allocator_->Allocate(); |
| 5309 ASSERT(start.is_valid()); | 5311 ASSERT(start.is_valid()); |
| 5310 __ mov(SlotOperand(slot, start.reg()), value.reg()); | 5312 __ mov(SlotOperand(slot, start.reg()), value.reg()); |
| 5313 |
| 5314 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 5311 // RecordWrite may destroy the value registers. | 5315 // RecordWrite may destroy the value registers. |
| 5312 // | 5316 // |
| 5313 // TODO(204): Avoid actually spilling when the value is not | 5317 // TODO(204): Avoid actually spilling when the value is not |
| 5314 // needed (probably the common case). | 5318 // needed (probably the common case). |
| 5315 frame_->Spill(value.reg()); | 5319 frame_->Spill(value.reg()); |
| 5316 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; | 5320 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
| 5317 Result temp = allocator_->Allocate(); | 5321 Result temp = allocator_->Allocate(); |
| 5318 ASSERT(temp.is_valid()); | 5322 ASSERT(temp.is_valid()); |
| 5319 __ RecordWrite(start.reg(), offset, value.reg(), temp.reg()); | 5323 __ RecordWrite(start.reg(), offset, value.reg(), temp.reg()); |
| 5320 // The results start, value, and temp are unused by going out of | 5324 // The results start, value, and temp are unused by going out of |
| 5321 // scope. | 5325 // scope. |
| 5326 #endif |
| 5322 } | 5327 } |
| 5323 | 5328 |
| 5324 exit.Bind(); | 5329 exit.Bind(); |
| 5325 } | 5330 } |
| 5326 } | 5331 } |
| 5327 | 5332 |
| 5328 | 5333 |
| 5329 void CodeGenerator::VisitSlot(Slot* slot) { | 5334 void CodeGenerator::VisitSlot(Slot* slot) { |
| 5330 Comment cmnt(masm_, "[ Slot"); | 5335 Comment cmnt(masm_, "[ Slot"); |
| 5331 if (in_safe_int32_mode()) { | 5336 if (in_safe_int32_mode()) { |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5698 elements.ToRegister(); | 5703 elements.ToRegister(); |
| 5699 frame_->Spill(elements.reg()); | 5704 frame_->Spill(elements.reg()); |
| 5700 // Get the elements array. | 5705 // Get the elements array. |
| 5701 __ mov(elements.reg(), | 5706 __ mov(elements.reg(), |
| 5702 FieldOperand(elements.reg(), JSObject::kElementsOffset)); | 5707 FieldOperand(elements.reg(), JSObject::kElementsOffset)); |
| 5703 | 5708 |
| 5704 // Write to the indexed properties array. | 5709 // Write to the indexed properties array. |
| 5705 int offset = i * kPointerSize + FixedArray::kHeaderSize; | 5710 int offset = i * kPointerSize + FixedArray::kHeaderSize; |
| 5706 __ mov(FieldOperand(elements.reg(), offset), prop_value.reg()); | 5711 __ mov(FieldOperand(elements.reg(), offset), prop_value.reg()); |
| 5707 | 5712 |
| 5713 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 5708 // Update the write barrier for the array address. | 5714 // Update the write barrier for the array address. |
| 5709 frame_->Spill(prop_value.reg()); // Overwritten by the write barrier. | 5715 frame_->Spill(prop_value.reg()); // Overwritten by the write barrier. |
| 5710 Result scratch = allocator_->Allocate(); | 5716 Result scratch = allocator_->Allocate(); |
| 5711 ASSERT(scratch.is_valid()); | 5717 ASSERT(scratch.is_valid()); |
| 5712 __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg()); | 5718 __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg()); |
| 5719 #endif |
| 5713 } | 5720 } |
| 5714 } | 5721 } |
| 5715 | 5722 |
| 5716 | 5723 |
| 5717 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { | 5724 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { |
| 5718 ASSERT(!in_safe_int32_mode()); | 5725 ASSERT(!in_safe_int32_mode()); |
| 5719 ASSERT(!in_spilled_code()); | 5726 ASSERT(!in_spilled_code()); |
| 5720 // Call runtime routine to allocate the catch extension object and | 5727 // Call runtime routine to allocate the catch extension object and |
| 5721 // assign the exception value to the catch variable. | 5728 // assign the exception value to the catch variable. |
| 5722 Comment cmnt(masm_, "[ CatchExtensionObject"); | 5729 Comment cmnt(masm_, "[ CatchExtensionObject"); |
| (...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7231 | 7238 |
| 7232 // It is a heap object - get its map. | 7239 // It is a heap object - get its map. |
| 7233 Result scratch = allocator_->Allocate(); | 7240 Result scratch = allocator_->Allocate(); |
| 7234 ASSERT(scratch.is_valid()); | 7241 ASSERT(scratch.is_valid()); |
| 7235 // if (!object->IsJSValue()) return value. | 7242 // if (!object->IsJSValue()) return value. |
| 7236 __ CmpObjectType(object.reg(), JS_VALUE_TYPE, scratch.reg()); | 7243 __ CmpObjectType(object.reg(), JS_VALUE_TYPE, scratch.reg()); |
| 7237 leave.Branch(not_equal, &value, not_taken); | 7244 leave.Branch(not_equal, &value, not_taken); |
| 7238 | 7245 |
| 7239 // Store the value. | 7246 // Store the value. |
| 7240 __ mov(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg()); | 7247 __ mov(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg()); |
| 7248 |
| 7249 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 7241 // Update the write barrier. Save the value as it will be | 7250 // Update the write barrier. Save the value as it will be |
| 7242 // overwritten by the write barrier code and is needed afterward. | 7251 // overwritten by the write barrier code and is needed afterward. |
| 7243 Result duplicate_value = allocator_->Allocate(); | 7252 Result duplicate_value = allocator_->Allocate(); |
| 7244 ASSERT(duplicate_value.is_valid()); | 7253 ASSERT(duplicate_value.is_valid()); |
| 7245 __ mov(duplicate_value.reg(), value.reg()); | 7254 __ mov(duplicate_value.reg(), value.reg()); |
| 7246 // The object register is also overwritten by the write barrier and | 7255 // The object register is also overwritten by the write barrier and |
| 7247 // possibly aliased in the frame. | 7256 // possibly aliased in the frame. |
| 7248 frame_->Spill(object.reg()); | 7257 frame_->Spill(object.reg()); |
| 7249 __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(), | 7258 __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(), |
| 7250 scratch.reg()); | 7259 scratch.reg()); |
| 7260 duplicate_value.Unuse(); |
| 7261 #endif |
| 7262 |
| 7251 object.Unuse(); | 7263 object.Unuse(); |
| 7252 scratch.Unuse(); | 7264 scratch.Unuse(); |
| 7253 duplicate_value.Unuse(); | |
| 7254 | 7265 |
| 7255 // Leave. | 7266 // Leave. |
| 7256 leave.Bind(&value); | 7267 leave.Bind(&value); |
| 7257 frame_->Push(&value); | 7268 frame_->Push(&value); |
| 7258 } | 7269 } |
| 7259 | 7270 |
| 7260 | 7271 |
| 7261 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) { | 7272 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) { |
| 7262 ASSERT(args->length() == 1); | 7273 ASSERT(args->length() == 1); |
| 7263 | 7274 |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7513 __ lea(ebx, Operand(edx, JSFunctionResultCache::kEntrySize << 1)); | 7524 __ lea(ebx, Operand(edx, JSFunctionResultCache::kEntrySize << 1)); |
| 7514 __ mov(FieldOperand(ecx, JSFunctionResultCache::kCacheSizeOffset), ebx); | 7525 __ mov(FieldOperand(ecx, JSFunctionResultCache::kCacheSizeOffset), ebx); |
| 7515 | 7526 |
| 7516 // Update the cache itself. | 7527 // Update the cache itself. |
| 7517 // edx holds the index. | 7528 // edx holds the index. |
| 7518 __ bind(&update_cache); | 7529 __ bind(&update_cache); |
| 7519 __ pop(ebx); // restore the key | 7530 __ pop(ebx); // restore the key |
| 7520 __ mov(FieldOperand(ecx, JSFunctionResultCache::kFingerOffset), edx); | 7531 __ mov(FieldOperand(ecx, JSFunctionResultCache::kFingerOffset), edx); |
| 7521 // Store key. | 7532 // Store key. |
| 7522 __ mov(CodeGenerator::FixedArrayElementOperand(ecx, edx), ebx); | 7533 __ mov(CodeGenerator::FixedArrayElementOperand(ecx, edx), ebx); |
| 7534 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 7523 __ RecordWrite(ecx, 0, ebx, edx); | 7535 __ RecordWrite(ecx, 0, ebx, edx); |
| 7536 #endif |
| 7524 | 7537 |
| 7525 // Store value. | 7538 // Store value. |
| 7526 __ pop(ecx); // restore the cache. | 7539 __ pop(ecx); // restore the cache. |
| 7527 __ mov(edx, FieldOperand(ecx, JSFunctionResultCache::kFingerOffset)); | 7540 __ mov(edx, FieldOperand(ecx, JSFunctionResultCache::kFingerOffset)); |
| 7528 __ add(Operand(edx), Immediate(Smi::FromInt(1))); | 7541 __ add(Operand(edx), Immediate(Smi::FromInt(1))); |
| 7529 __ mov(ebx, eax); | 7542 __ mov(ebx, eax); |
| 7530 __ mov(CodeGenerator::FixedArrayElementOperand(ecx, edx), ebx); | 7543 __ mov(CodeGenerator::FixedArrayElementOperand(ecx, edx), ebx); |
| 7544 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 7531 __ RecordWrite(ecx, 0, ebx, edx); | 7545 __ RecordWrite(ecx, 0, ebx, edx); |
| 7546 #endif |
| 7532 | 7547 |
| 7533 if (!dst_.is(eax)) { | 7548 if (!dst_.is(eax)) { |
| 7534 __ mov(dst_, eax); | 7549 __ mov(dst_, eax); |
| 7535 } | 7550 } |
| 7536 } | 7551 } |
| 7537 | 7552 |
| 7538 | 7553 |
| 7539 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { | 7554 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { |
| 7540 ASSERT_EQ(2, args->length()); | 7555 ASSERT_EQ(2, args->length()); |
| 7541 | 7556 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7679 // Bring addresses into index1 and index2. | 7694 // Bring addresses into index1 and index2. |
| 7680 __ lea(index1.reg(), FixedArrayElementOperand(tmp1.reg(), index1.reg())); | 7695 __ lea(index1.reg(), FixedArrayElementOperand(tmp1.reg(), index1.reg())); |
| 7681 __ lea(index2.reg(), FixedArrayElementOperand(tmp1.reg(), index2.reg())); | 7696 __ lea(index2.reg(), FixedArrayElementOperand(tmp1.reg(), index2.reg())); |
| 7682 | 7697 |
| 7683 // Swap elements. | 7698 // Swap elements. |
| 7684 __ mov(object.reg(), Operand(index1.reg(), 0)); | 7699 __ mov(object.reg(), Operand(index1.reg(), 0)); |
| 7685 __ mov(tmp2.reg(), Operand(index2.reg(), 0)); | 7700 __ mov(tmp2.reg(), Operand(index2.reg(), 0)); |
| 7686 __ mov(Operand(index2.reg(), 0), object.reg()); | 7701 __ mov(Operand(index2.reg(), 0), object.reg()); |
| 7687 __ mov(Operand(index1.reg(), 0), tmp2.reg()); | 7702 __ mov(Operand(index1.reg(), 0), tmp2.reg()); |
| 7688 | 7703 |
| 7704 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 7689 Label done; | 7705 Label done; |
| 7690 __ InNewSpace(tmp1.reg(), tmp2.reg(), equal, &done); | 7706 __ InNewSpace(tmp1.reg(), tmp2.reg(), equal, &done); |
| 7691 // Possible optimization: do a check that both values are Smis | 7707 // Possible optimization: do a check that both values are Smis |
| 7692 // (or them and test against Smi mask.) | 7708 // (or them and test against Smi mask.) |
| 7693 | 7709 |
| 7694 __ mov(tmp2.reg(), tmp1.reg()); | 7710 __ mov(tmp2.reg(), tmp1.reg()); |
| 7695 __ RecordWriteHelper(tmp2.reg(), index1.reg(), object.reg()); | 7711 __ RecordWriteHelper(tmp2.reg(), index1.reg(), object.reg()); |
| 7696 __ RecordWriteHelper(tmp1.reg(), index2.reg(), object.reg()); | 7712 __ RecordWriteHelper(tmp1.reg(), index2.reg(), object.reg()); |
| 7697 __ bind(&done); | 7713 __ bind(&done); |
| 7714 #endif |
| 7698 | 7715 |
| 7699 deferred->BindExit(); | 7716 deferred->BindExit(); |
| 7700 frame_->Push(Factory::undefined_value()); | 7717 frame_->Push(Factory::undefined_value()); |
| 7701 } | 7718 } |
| 7702 | 7719 |
| 7703 | 7720 |
| 7704 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { | 7721 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { |
| 7705 Comment cmnt(masm_, "[ GenerateCallFunction"); | 7722 Comment cmnt(masm_, "[ GenerateCallFunction"); |
| 7706 | 7723 |
| 7707 ASSERT(args->length() >= 2); | 7724 ASSERT(args->length() >= 2); |
| (...skipping 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9625 // If the receiver and the value share a register allocate a new | 9642 // If the receiver and the value share a register allocate a new |
| 9626 // register for the receiver. | 9643 // register for the receiver. |
| 9627 if (receiver.reg().is(value.reg())) { | 9644 if (receiver.reg().is(value.reg())) { |
| 9628 receiver = allocator()->Allocate(); | 9645 receiver = allocator()->Allocate(); |
| 9629 ASSERT(receiver.is_valid()); | 9646 ASSERT(receiver.is_valid()); |
| 9630 __ mov(receiver.reg(), Operand(value.reg())); | 9647 __ mov(receiver.reg(), Operand(value.reg())); |
| 9631 } | 9648 } |
| 9632 | 9649 |
| 9633 // Update the write barrier. To save instructions in the inlined | 9650 // Update the write barrier. To save instructions in the inlined |
| 9634 // version we do not filter smis. | 9651 // version we do not filter smis. |
| 9652 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 9635 Label skip_write_barrier; | 9653 Label skip_write_barrier; |
| 9636 __ InNewSpace(receiver.reg(), value.reg(), equal, &skip_write_barrier); | 9654 __ InNewSpace(receiver.reg(), value.reg(), equal, &skip_write_barrier); |
| 9637 int delta_to_record_write = masm_->SizeOfCodeGeneratedSince(&patch_site); | 9655 int delta_to_record_write = masm_->SizeOfCodeGeneratedSince(&patch_site); |
| 9638 __ lea(scratch.reg(), Operand(receiver.reg(), offset)); | 9656 __ lea(scratch.reg(), Operand(receiver.reg(), offset)); |
| 9639 __ RecordWriteHelper(receiver.reg(), scratch.reg(), value.reg()); | 9657 __ RecordWriteHelper(receiver.reg(), scratch.reg(), value.reg()); |
| 9640 if (FLAG_debug_code) { | 9658 if (FLAG_debug_code) { |
| 9641 __ mov(receiver.reg(), Immediate(BitCast<int32_t>(kZapValue))); | 9659 __ mov(receiver.reg(), Immediate(BitCast<int32_t>(kZapValue))); |
| 9642 __ mov(value.reg(), Immediate(BitCast<int32_t>(kZapValue))); | 9660 __ mov(value.reg(), Immediate(BitCast<int32_t>(kZapValue))); |
| 9643 __ mov(scratch.reg(), Immediate(BitCast<int32_t>(kZapValue))); | 9661 __ mov(scratch.reg(), Immediate(BitCast<int32_t>(kZapValue))); |
| 9644 } | 9662 } |
| 9645 __ bind(&skip_write_barrier); | 9663 __ bind(&skip_write_barrier); |
| 9664 #else |
| 9665 // Store some dummy value to avoid short encoding of test instruction. |
| 9666 int delta_to_record_write = 0x0001; |
| 9667 #endif |
| 9646 value.Unuse(); | 9668 value.Unuse(); |
| 9647 scratch.Unuse(); | 9669 scratch.Unuse(); |
| 9648 receiver.Unuse(); | 9670 receiver.Unuse(); |
| 9649 done.Jump(&result); | 9671 done.Jump(&result); |
| 9650 | 9672 |
| 9651 slow.Bind(&value, &receiver); | 9673 slow.Bind(&value, &receiver); |
| 9652 frame()->Push(&receiver); | 9674 frame()->Push(&receiver); |
| 9653 frame()->Push(&value); | 9675 frame()->Push(&value); |
| 9654 result = frame()->CallStoreIC(name, is_contextual); | 9676 result = frame()->CallStoreIC(name, is_contextual); |
| 9655 // Encode the offset to the map check instruction and the offset | 9677 // Encode the offset to the map check instruction and the offset |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9769 // Get the receiver, key and value into registers. | 9791 // Get the receiver, key and value into registers. |
| 9770 result = frame()->Pop(); | 9792 result = frame()->Pop(); |
| 9771 Result key = frame()->Pop(); | 9793 Result key = frame()->Pop(); |
| 9772 Result receiver = frame()->Pop(); | 9794 Result receiver = frame()->Pop(); |
| 9773 | 9795 |
| 9774 Result tmp = allocator_->Allocate(); | 9796 Result tmp = allocator_->Allocate(); |
| 9775 ASSERT(tmp.is_valid()); | 9797 ASSERT(tmp.is_valid()); |
| 9776 Result tmp2 = allocator_->Allocate(); | 9798 Result tmp2 = allocator_->Allocate(); |
| 9777 ASSERT(tmp2.is_valid()); | 9799 ASSERT(tmp2.is_valid()); |
| 9778 | 9800 |
| 9801 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 9779 // Determine whether the value is a constant before putting it in a | 9802 // Determine whether the value is a constant before putting it in a |
| 9780 // register. | 9803 // register. |
| 9781 bool value_is_constant = result.is_constant(); | 9804 bool value_is_constant = result.is_constant(); |
| 9805 #endif |
| 9782 | 9806 |
| 9783 // Make sure that value, key and receiver are in registers. | 9807 // Make sure that value, key and receiver are in registers. |
| 9784 result.ToRegister(); | 9808 result.ToRegister(); |
| 9785 key.ToRegister(); | 9809 key.ToRegister(); |
| 9786 receiver.ToRegister(); | 9810 receiver.ToRegister(); |
| 9787 | 9811 |
| 9788 DeferredReferenceSetKeyedValue* deferred = | 9812 DeferredReferenceSetKeyedValue* deferred = |
| 9789 new DeferredReferenceSetKeyedValue(result.reg(), | 9813 new DeferredReferenceSetKeyedValue(result.reg(), |
| 9790 key.reg(), | 9814 key.reg(), |
| 9791 receiver.reg(), | 9815 receiver.reg(), |
| (...skipping 19 matching lines...) Expand all Loading... |
| 9811 // the JSArray are smis. Use unsigned comparison to handle negative keys. | 9835 // the JSArray are smis. Use unsigned comparison to handle negative keys. |
| 9812 __ cmp(key.reg(), | 9836 __ cmp(key.reg(), |
| 9813 FieldOperand(receiver.reg(), JSArray::kLengthOffset)); | 9837 FieldOperand(receiver.reg(), JSArray::kLengthOffset)); |
| 9814 deferred->Branch(above_equal); | 9838 deferred->Branch(above_equal); |
| 9815 | 9839 |
| 9816 // Get the elements array from the receiver and check that it is not a | 9840 // Get the elements array from the receiver and check that it is not a |
| 9817 // dictionary. | 9841 // dictionary. |
| 9818 __ mov(tmp.reg(), | 9842 __ mov(tmp.reg(), |
| 9819 FieldOperand(receiver.reg(), JSArray::kElementsOffset)); | 9843 FieldOperand(receiver.reg(), JSArray::kElementsOffset)); |
| 9820 | 9844 |
| 9845 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 9821 // Check whether it is possible to omit the write barrier. If the elements | 9846 // Check whether it is possible to omit the write barrier. If the elements |
| 9822 // array is in new space or the value written is a smi we can safely update | 9847 // array is in new space or the value written is a smi we can safely update |
| 9823 // the elements array without write barrier. | 9848 // the elements array without write barrier. |
| 9824 Label in_new_space; | 9849 Label in_new_space; |
| 9825 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space); | 9850 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space); |
| 9826 if (!value_is_constant) { | 9851 if (!value_is_constant) { |
| 9827 __ test(result.reg(), Immediate(kSmiTagMask)); | 9852 __ test(result.reg(), Immediate(kSmiTagMask)); |
| 9828 deferred->Branch(not_zero); | 9853 deferred->Branch(not_zero); |
| 9829 } | 9854 } |
| 9830 | 9855 |
| 9856 |
| 9831 __ bind(&in_new_space); | 9857 __ bind(&in_new_space); |
| 9858 #endif |
| 9832 // Bind the deferred code patch site to be able to locate the fixed | 9859 // Bind the deferred code patch site to be able to locate the fixed |
| 9833 // array map comparison. When debugging, we patch this comparison to | 9860 // array map comparison. When debugging, we patch this comparison to |
| 9834 // always fail so that we will hit the IC call in the deferred code | 9861 // always fail so that we will hit the IC call in the deferred code |
| 9835 // which will allow the debugger to break for fast case stores. | 9862 // which will allow the debugger to break for fast case stores. |
| 9836 __ bind(deferred->patch_site()); | 9863 __ bind(deferred->patch_site()); |
| 9837 __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset), | 9864 __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset), |
| 9838 Immediate(Factory::fixed_array_map())); | 9865 Immediate(Factory::fixed_array_map())); |
| 9839 deferred->Branch(not_equal); | 9866 deferred->Branch(not_equal); |
| 9840 | 9867 |
| 9841 // Store the value. | 9868 // Store the value. |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10217 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); | 10244 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); |
| 10218 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); | 10245 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); |
| 10219 return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress()); | 10246 return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress()); |
| 10220 } | 10247 } |
| 10221 | 10248 |
| 10222 #undef __ | 10249 #undef __ |
| 10223 | 10250 |
| 10224 } } // namespace v8::internal | 10251 } } // namespace v8::internal |
| 10225 | 10252 |
| 10226 #endif // V8_TARGET_ARCH_IA32 | 10253 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |