| 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 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 ASSERT(!scope()->is_global_scope()); | 255 ASSERT(!scope()->is_global_scope()); |
| 256 frame_->PushParameterAt(i); | 256 frame_->PushParameterAt(i); |
| 257 Result value = frame_->Pop(); | 257 Result value = frame_->Pop(); |
| 258 value.ToRegister(); | 258 value.ToRegister(); |
| 259 | 259 |
| 260 // SlotOperand loads context.reg() with the context object | 260 // SlotOperand loads context.reg() with the context object |
| 261 // stored to, used below in RecordWrite. | 261 // stored to, used below in RecordWrite. |
| 262 Result context = allocator_->Allocate(); | 262 Result context = allocator_->Allocate(); |
| 263 ASSERT(context.is_valid()); | 263 ASSERT(context.is_valid()); |
| 264 __ movq(SlotOperand(slot, context.reg()), value.reg()); | 264 __ movq(SlotOperand(slot, context.reg()), value.reg()); |
| 265 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | |
| 266 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; | 265 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
| 267 Result scratch = allocator_->Allocate(); | 266 Result scratch = allocator_->Allocate(); |
| 268 ASSERT(scratch.is_valid()); | 267 ASSERT(scratch.is_valid()); |
| 269 frame_->Spill(context.reg()); | 268 frame_->Spill(context.reg()); |
| 270 frame_->Spill(value.reg()); | 269 frame_->Spill(value.reg()); |
| 271 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg()); | 270 __ RecordWrite(context.reg(), |
| 272 #endif | 271 offset, |
| 272 value.reg(), |
| 273 scratch.reg(), |
| 274 kDontSaveFPRegs); |
| 273 } | 275 } |
| 274 } | 276 } |
| 275 } | 277 } |
| 276 | 278 |
| 277 // Store the arguments object. This must happen after context | 279 // Store the arguments object. This must happen after context |
| 278 // initialization because the arguments object may be stored in | 280 // initialization because the arguments object may be stored in |
| 279 // the context. | 281 // the context. |
| 280 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { | 282 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { |
| 281 StoreArgumentsObject(true); | 283 StoreArgumentsObject(true); |
| 282 } | 284 } |
| (...skipping 4365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4648 // | 4650 // |
| 4649 // The use of SlotOperand below is safe for an unspilled frame | 4651 // The use of SlotOperand below is safe for an unspilled frame |
| 4650 // because the slot is a context slot. | 4652 // because the slot is a context slot. |
| 4651 ASSERT(slot->type() == Slot::CONTEXT); | 4653 ASSERT(slot->type() == Slot::CONTEXT); |
| 4652 frame_->Dup(); | 4654 frame_->Dup(); |
| 4653 Result value = frame_->Pop(); | 4655 Result value = frame_->Pop(); |
| 4654 value.ToRegister(); | 4656 value.ToRegister(); |
| 4655 Result start = allocator_->Allocate(); | 4657 Result start = allocator_->Allocate(); |
| 4656 ASSERT(start.is_valid()); | 4658 ASSERT(start.is_valid()); |
| 4657 __ movq(SlotOperand(slot, start.reg()), value.reg()); | 4659 __ movq(SlotOperand(slot, start.reg()), value.reg()); |
| 4658 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | |
| 4659 // RecordWrite may destroy the value registers. | 4660 // RecordWrite may destroy the value registers. |
| 4660 // | 4661 // |
| 4661 // TODO(204): Avoid actually spilling when the value is not | 4662 // TODO(204): Avoid actually spilling when the value is not |
| 4662 // needed (probably the common case). | 4663 // needed (probably the common case). |
| 4663 frame_->Spill(value.reg()); | 4664 frame_->Spill(value.reg()); |
| 4664 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; | 4665 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
| 4665 Result temp = allocator_->Allocate(); | 4666 Result temp = allocator_->Allocate(); |
| 4666 ASSERT(temp.is_valid()); | 4667 ASSERT(temp.is_valid()); |
| 4667 __ RecordWrite(start.reg(), offset, value.reg(), temp.reg()); | 4668 __ RecordWrite(start.reg(), |
| 4668 #endif | 4669 offset, |
| 4670 value.reg(), |
| 4671 temp.reg(), |
| 4672 kDontSaveFPRegs); |
| 4669 // The results start, value, and temp are unused by going out of | 4673 // The results start, value, and temp are unused by going out of |
| 4670 // scope. | 4674 // scope. |
| 4671 } | 4675 } |
| 4672 | 4676 |
| 4673 exit.Bind(); | 4677 exit.Bind(); |
| 4674 } | 4678 } |
| 4675 } | 4679 } |
| 4676 | 4680 |
| 4677 | 4681 |
| 4678 void CodeGenerator::VisitSlot(Slot* node) { | 4682 void CodeGenerator::VisitSlot(Slot* node) { |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5009 // Get the elements FixedArray. | 5013 // Get the elements FixedArray. |
| 5010 __ movq(elements.reg(), | 5014 __ movq(elements.reg(), |
| 5011 FieldOperand(elements.reg(), JSObject::kElementsOffset)); | 5015 FieldOperand(elements.reg(), JSObject::kElementsOffset)); |
| 5012 | 5016 |
| 5013 // Write to the indexed properties array. | 5017 // Write to the indexed properties array. |
| 5014 int offset = i * kPointerSize + FixedArray::kHeaderSize; | 5018 int offset = i * kPointerSize + FixedArray::kHeaderSize; |
| 5015 __ movq(FieldOperand(elements.reg(), offset), prop_value.reg()); | 5019 __ movq(FieldOperand(elements.reg(), offset), prop_value.reg()); |
| 5016 | 5020 |
| 5017 // Update the write barrier for the array address. | 5021 // Update the write barrier for the array address. |
| 5018 frame_->Spill(prop_value.reg()); // Overwritten by the write barrier. | 5022 frame_->Spill(prop_value.reg()); // Overwritten by the write barrier. |
| 5019 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | |
| 5020 Result scratch = allocator_->Allocate(); | 5023 Result scratch = allocator_->Allocate(); |
| 5021 ASSERT(scratch.is_valid()); | 5024 ASSERT(scratch.is_valid()); |
| 5022 __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg()); | 5025 __ RecordWrite(elements.reg(), |
| 5023 #endif | 5026 offset, |
| 5027 prop_value.reg(), |
| 5028 scratch.reg(), |
| 5029 kDontSaveFPRegs); |
| 5024 } | 5030 } |
| 5025 } | 5031 } |
| 5026 | 5032 |
| 5027 | 5033 |
| 5028 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { | 5034 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { |
| 5029 ASSERT(!in_spilled_code()); | 5035 ASSERT(!in_spilled_code()); |
| 5030 // Call runtime routine to allocate the catch extension object and | 5036 // Call runtime routine to allocate the catch extension object and |
| 5031 // assign the exception value to the catch variable. | 5037 // assign the exception value to the catch variable. |
| 5032 Comment cmnt(masm_, "[ CatchExtensionObject"); | 5038 Comment cmnt(masm_, "[ CatchExtensionObject"); |
| 5033 Load(node->key()); | 5039 Load(node->key()); |
| (...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6341 // Store the value. | 6347 // Store the value. |
| 6342 __ movq(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg()); | 6348 __ movq(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg()); |
| 6343 // Update the write barrier. Save the value as it will be | 6349 // Update the write barrier. Save the value as it will be |
| 6344 // overwritten by the write barrier code and is needed afterward. | 6350 // overwritten by the write barrier code and is needed afterward. |
| 6345 Result duplicate_value = allocator_->Allocate(); | 6351 Result duplicate_value = allocator_->Allocate(); |
| 6346 ASSERT(duplicate_value.is_valid()); | 6352 ASSERT(duplicate_value.is_valid()); |
| 6347 __ movq(duplicate_value.reg(), value.reg()); | 6353 __ movq(duplicate_value.reg(), value.reg()); |
| 6348 // The object register is also overwritten by the write barrier and | 6354 // The object register is also overwritten by the write barrier and |
| 6349 // possibly aliased in the frame. | 6355 // possibly aliased in the frame. |
| 6350 frame_->Spill(object.reg()); | 6356 frame_->Spill(object.reg()); |
| 6351 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | 6357 __ RecordWrite(object.reg(), |
| 6352 __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(), | 6358 JSValue::kValueOffset, |
| 6353 scratch.reg()); | 6359 duplicate_value.reg(), |
| 6354 #endif | 6360 scratch.reg(), |
| 6361 kDontSaveFPRegs); |
| 6355 object.Unuse(); | 6362 object.Unuse(); |
| 6356 scratch.Unuse(); | 6363 scratch.Unuse(); |
| 6357 duplicate_value.Unuse(); | 6364 duplicate_value.Unuse(); |
| 6358 | 6365 |
| 6359 // Leave. | 6366 // Leave. |
| 6360 leave.Bind(&value); | 6367 leave.Bind(&value); |
| 6361 frame_->Push(&value); | 6368 frame_->Push(&value); |
| 6362 } | 6369 } |
| 6363 | 6370 |
| 6364 | 6371 |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6625 FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset), rbx); | 6632 FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset), rbx); |
| 6626 | 6633 |
| 6627 // Update the cache itself. | 6634 // Update the cache itself. |
| 6628 // r9 holds the index as int32. | 6635 // r9 holds the index as int32. |
| 6629 __ bind(&update_cache); | 6636 __ bind(&update_cache); |
| 6630 __ pop(rbx); // restore the key | 6637 __ pop(rbx); // restore the key |
| 6631 __ Integer32ToSmiField( | 6638 __ Integer32ToSmiField( |
| 6632 FieldOperand(rcx, JSFunctionResultCache::kFingerOffset), r9); | 6639 FieldOperand(rcx, JSFunctionResultCache::kFingerOffset), r9); |
| 6633 // Store key. | 6640 // Store key. |
| 6634 __ movq(ArrayElement(rcx, r9), rbx); | 6641 __ movq(ArrayElement(rcx, r9), rbx); |
| 6635 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | 6642 __ RecordWrite(rcx, 0, rbx, r9, kDontSaveFPRegs); |
| 6636 __ RecordWrite(rcx, 0, rbx, r9); | |
| 6637 #endif | |
| 6638 | 6643 |
| 6639 // Store value. | 6644 // Store value. |
| 6640 __ pop(rcx); // restore the cache. | 6645 __ pop(rcx); // restore the cache. |
| 6641 __ SmiToInteger32(rdx, | 6646 __ SmiToInteger32(rdx, |
| 6642 FieldOperand(rcx, JSFunctionResultCache::kFingerOffset)); | 6647 FieldOperand(rcx, JSFunctionResultCache::kFingerOffset)); |
| 6643 __ incl(rdx); | 6648 __ incl(rdx); |
| 6644 // Backup rax, because the RecordWrite macro clobbers its arguments. | 6649 // Backup rax, because the RecordWrite macro clobbers its arguments. |
| 6645 __ movq(rbx, rax); | 6650 __ movq(rbx, rax); |
| 6646 __ movq(ArrayElement(rcx, rdx), rax); | 6651 __ movq(ArrayElement(rcx, rdx), rax); |
| 6647 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | 6652 __ RecordWrite(rcx, 0, rbx, rdx, kDontSaveFPRegs); |
| 6648 __ RecordWrite(rcx, 0, rbx, rdx); | |
| 6649 #endif | |
| 6650 | 6653 |
| 6651 if (!dst_.is(rax)) { | 6654 if (!dst_.is(rax)) { |
| 6652 __ movq(dst_, rax); | 6655 __ movq(dst_, rax); |
| 6653 } | 6656 } |
| 6654 } | 6657 } |
| 6655 | 6658 |
| 6656 | 6659 |
| 6657 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { | 6660 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { |
| 6658 ASSERT_EQ(2, args->length()); | 6661 ASSERT_EQ(2, args->length()); |
| 6659 | 6662 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6812 index2.reg(), | 6815 index2.reg(), |
| 6813 times_pointer_size, | 6816 times_pointer_size, |
| 6814 FixedArray::kHeaderSize)); | 6817 FixedArray::kHeaderSize)); |
| 6815 | 6818 |
| 6816 // Swap elements. | 6819 // Swap elements. |
| 6817 __ movq(object.reg(), Operand(index1.reg(), 0)); | 6820 __ movq(object.reg(), Operand(index1.reg(), 0)); |
| 6818 __ movq(tmp2.reg(), Operand(index2.reg(), 0)); | 6821 __ movq(tmp2.reg(), Operand(index2.reg(), 0)); |
| 6819 __ movq(Operand(index2.reg(), 0), object.reg()); | 6822 __ movq(Operand(index2.reg(), 0), object.reg()); |
| 6820 __ movq(Operand(index1.reg(), 0), tmp2.reg()); | 6823 __ movq(Operand(index1.reg(), 0), tmp2.reg()); |
| 6821 | 6824 |
| 6822 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | |
| 6823 Label done; | 6825 Label done; |
| 6824 __ InNewSpace(tmp1.reg(), tmp2.reg(), equal, &done); | 6826 __ InNewSpace(tmp1.reg(), tmp2.reg(), equal, &done); |
| 6825 // Possible optimization: do a check that both values are Smis | 6827 // Possible optimization: do a check that both values are Smis |
| 6826 // (or them and test against Smi mask.) | 6828 // (or them and test against Smi mask.) |
| 6827 | 6829 |
| 6828 __ movq(tmp2.reg(), tmp1.reg()); | 6830 __ movq(tmp2.reg(), tmp1.reg()); |
| 6829 __ RecordWriteHelper(tmp1.reg(), index1.reg(), object.reg()); | 6831 __ RecordWriteHelper(tmp1.reg(), index1.reg(), object.reg(), kDontSaveFPRegs); |
| 6830 __ RecordWriteHelper(tmp2.reg(), index2.reg(), object.reg()); | 6832 __ RecordWriteHelper(tmp2.reg(), index2.reg(), object.reg(), kDontSaveFPRegs); |
| 6831 __ bind(&done); | 6833 __ bind(&done); |
| 6832 #endif | |
| 6833 | 6834 |
| 6834 deferred->BindExit(); | 6835 deferred->BindExit(); |
| 6835 frame_->Push(Factory::undefined_value()); | 6836 frame_->Push(Factory::undefined_value()); |
| 6836 } | 6837 } |
| 6837 | 6838 |
| 6838 | 6839 |
| 6839 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { | 6840 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { |
| 6840 Comment cmnt(masm_, "[ GenerateCallFunction"); | 6841 Comment cmnt(masm_, "[ GenerateCallFunction"); |
| 6841 | 6842 |
| 6842 ASSERT(args->length() >= 2); | 6843 ASSERT(args->length() >= 2); |
| (...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8317 // If the receiver and the value share a register allocate a new | 8318 // If the receiver and the value share a register allocate a new |
| 8318 // register for the receiver. | 8319 // register for the receiver. |
| 8319 if (receiver.reg().is(value.reg())) { | 8320 if (receiver.reg().is(value.reg())) { |
| 8320 receiver = allocator()->Allocate(); | 8321 receiver = allocator()->Allocate(); |
| 8321 ASSERT(receiver.is_valid()); | 8322 ASSERT(receiver.is_valid()); |
| 8322 __ movq(receiver.reg(), value.reg()); | 8323 __ movq(receiver.reg(), value.reg()); |
| 8323 } | 8324 } |
| 8324 | 8325 |
| 8325 // Update the write barrier. To save instructions in the inlined | 8326 // Update the write barrier. To save instructions in the inlined |
| 8326 // version we do not filter smis. | 8327 // version we do not filter smis. |
| 8327 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | |
| 8328 Label skip_write_barrier; | 8328 Label skip_write_barrier; |
| 8329 __ InNewSpace(receiver.reg(), value.reg(), equal, &skip_write_barrier); | 8329 __ InNewSpace(receiver.reg(), value.reg(), equal, &skip_write_barrier); |
| 8330 int delta_to_record_write = masm_->SizeOfCodeGeneratedSince(&patch_site); | 8330 int delta_to_record_write = masm_->SizeOfCodeGeneratedSince(&patch_site); |
| 8331 __ lea(scratch.reg(), Operand(receiver.reg(), offset)); | 8331 __ lea(scratch.reg(), Operand(receiver.reg(), offset)); |
| 8332 __ RecordWriteHelper(receiver.reg(), scratch.reg(), value.reg()); | 8332 __ RecordWriteHelper(receiver.reg(), |
| 8333 scratch.reg(), |
| 8334 value.reg(), |
| 8335 kDontSaveFPRegs); |
| 8333 if (FLAG_debug_code) { | 8336 if (FLAG_debug_code) { |
| 8334 __ movq(receiver.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); | 8337 __ movq(receiver.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); |
| 8335 __ movq(value.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); | 8338 __ movq(value.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); |
| 8336 __ movq(scratch.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); | 8339 __ movq(scratch.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); |
| 8337 } | 8340 } |
| 8338 __ bind(&skip_write_barrier); | 8341 __ bind(&skip_write_barrier); |
| 8339 #else | |
| 8340 // Use dummy delta to record write value to ensure proper | |
| 8341 // testl encoding. | |
| 8342 int delta_to_record_write = 0x0001; | |
| 8343 #endif | |
| 8344 value.Unuse(); | 8342 value.Unuse(); |
| 8345 scratch.Unuse(); | 8343 scratch.Unuse(); |
| 8346 receiver.Unuse(); | 8344 receiver.Unuse(); |
| 8347 done.Jump(&result); | 8345 done.Jump(&result); |
| 8348 | 8346 |
| 8349 slow.Bind(&value, &receiver); | 8347 slow.Bind(&value, &receiver); |
| 8350 frame()->Push(&receiver); | 8348 frame()->Push(&receiver); |
| 8351 frame()->Push(&value); | 8349 frame()->Push(&value); |
| 8352 result = frame()->CallStoreIC(name, is_contextual); | 8350 result = frame()->CallStoreIC(name, is_contextual); |
| 8353 // Encode the offset to the map check instruction and the offset | 8351 // Encode the offset to the map check instruction and the offset |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8471 // Get the receiver, key and value into registers. | 8469 // Get the receiver, key and value into registers. |
| 8472 result = frame()->Pop(); | 8470 result = frame()->Pop(); |
| 8473 Result key = frame()->Pop(); | 8471 Result key = frame()->Pop(); |
| 8474 Result receiver = frame()->Pop(); | 8472 Result receiver = frame()->Pop(); |
| 8475 | 8473 |
| 8476 Result tmp = allocator_->Allocate(); | 8474 Result tmp = allocator_->Allocate(); |
| 8477 ASSERT(tmp.is_valid()); | 8475 ASSERT(tmp.is_valid()); |
| 8478 Result tmp2 = allocator_->Allocate(); | 8476 Result tmp2 = allocator_->Allocate(); |
| 8479 ASSERT(tmp2.is_valid()); | 8477 ASSERT(tmp2.is_valid()); |
| 8480 | 8478 |
| 8481 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | |
| 8482 // Determine whether the value is a constant before putting it in a | 8479 // Determine whether the value is a constant before putting it in a |
| 8483 // register. | 8480 // register. |
| 8484 bool value_is_constant = result.is_constant(); | 8481 bool value_is_constant = result.is_constant(); |
| 8485 #endif | |
| 8486 | 8482 |
| 8487 // Make sure that value, key and receiver are in registers. | 8483 // Make sure that value, key and receiver are in registers. |
| 8488 result.ToRegister(); | 8484 result.ToRegister(); |
| 8489 key.ToRegister(); | 8485 key.ToRegister(); |
| 8490 receiver.ToRegister(); | 8486 receiver.ToRegister(); |
| 8491 | 8487 |
| 8492 DeferredReferenceSetKeyedValue* deferred = | 8488 DeferredReferenceSetKeyedValue* deferred = |
| 8493 new DeferredReferenceSetKeyedValue(result.reg(), | 8489 new DeferredReferenceSetKeyedValue(result.reg(), |
| 8494 key.reg(), | 8490 key.reg(), |
| 8495 receiver.reg()); | 8491 receiver.reg()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 8515 deferred->Branch(below_equal); | 8511 deferred->Branch(below_equal); |
| 8516 | 8512 |
| 8517 // Get the elements array from the receiver and check that it is not a | 8513 // Get the elements array from the receiver and check that it is not a |
| 8518 // dictionary. | 8514 // dictionary. |
| 8519 __ movq(tmp.reg(), | 8515 __ movq(tmp.reg(), |
| 8520 FieldOperand(receiver.reg(), JSArray::kElementsOffset)); | 8516 FieldOperand(receiver.reg(), JSArray::kElementsOffset)); |
| 8521 | 8517 |
| 8522 // Check whether it is possible to omit the write barrier. If the elements | 8518 // Check whether it is possible to omit the write barrier. If the elements |
| 8523 // array is in new space or the value written is a smi we can safely update | 8519 // array is in new space or the value written is a smi we can safely update |
| 8524 // the elements array without write barrier. | 8520 // the elements array without write barrier. |
| 8525 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | |
| 8526 Label in_new_space; | 8521 Label in_new_space; |
| 8527 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space); | 8522 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space); |
| 8528 if (!value_is_constant) { | 8523 if (!value_is_constant) { |
| 8529 __ JumpIfNotSmi(result.reg(), deferred->entry_label()); | 8524 __ JumpIfNotSmi(result.reg(), deferred->entry_label()); |
| 8530 } | 8525 } |
| 8531 | 8526 |
| 8532 __ bind(&in_new_space); | 8527 __ bind(&in_new_space); |
| 8533 #endif | |
| 8534 | 8528 |
| 8535 // Bind the deferred code patch site to be able to locate the fixed | 8529 // Bind the deferred code patch site to be able to locate the fixed |
| 8536 // array map comparison. When debugging, we patch this comparison to | 8530 // array map comparison. When debugging, we patch this comparison to |
| 8537 // always fail so that we will hit the IC call in the deferred code | 8531 // always fail so that we will hit the IC call in the deferred code |
| 8538 // which will allow the debugger to break for fast case stores. | 8532 // which will allow the debugger to break for fast case stores. |
| 8539 __ bind(deferred->patch_site()); | 8533 __ bind(deferred->patch_site()); |
| 8540 // Avoid using __ to ensure the distance from patch_site | 8534 // Avoid using __ to ensure the distance from patch_site |
| 8541 // to the map address is always the same. | 8535 // to the map address is always the same. |
| 8542 masm()->movq(kScratchRegister, Factory::fixed_array_map(), | 8536 masm()->movq(kScratchRegister, Factory::fixed_array_map(), |
| 8543 RelocInfo::EMBEDDED_OBJECT); | 8537 RelocInfo::EMBEDDED_OBJECT); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8829 } | 8823 } |
| 8830 | 8824 |
| 8831 #endif | 8825 #endif |
| 8832 | 8826 |
| 8833 | 8827 |
| 8834 #undef __ | 8828 #undef __ |
| 8835 | 8829 |
| 8836 } } // namespace v8::internal | 8830 } } // namespace v8::internal |
| 8837 | 8831 |
| 8838 #endif // V8_TARGET_ARCH_X64 | 8832 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |