| 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 |
| 265 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; | 266 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
| 266 Result scratch = allocator_->Allocate(); | 267 Result scratch = allocator_->Allocate(); |
| 267 ASSERT(scratch.is_valid()); | 268 ASSERT(scratch.is_valid()); |
| 268 frame_->Spill(context.reg()); | 269 frame_->Spill(context.reg()); |
| 269 frame_->Spill(value.reg()); | 270 frame_->Spill(value.reg()); |
| 270 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg()); | 271 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg()); |
| 272 #endif |
| 271 } | 273 } |
| 272 } | 274 } |
| 273 } | 275 } |
| 274 | 276 |
| 275 // Store the arguments object. This must happen after context | 277 // Store the arguments object. This must happen after context |
| 276 // initialization because the arguments object may be stored in | 278 // initialization because the arguments object may be stored in |
| 277 // the context. | 279 // the context. |
| 278 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { | 280 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { |
| 279 StoreArgumentsObject(true); | 281 StoreArgumentsObject(true); |
| 280 } | 282 } |
| (...skipping 4365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4646 // | 4648 // |
| 4647 // The use of SlotOperand below is safe for an unspilled frame | 4649 // The use of SlotOperand below is safe for an unspilled frame |
| 4648 // because the slot is a context slot. | 4650 // because the slot is a context slot. |
| 4649 ASSERT(slot->type() == Slot::CONTEXT); | 4651 ASSERT(slot->type() == Slot::CONTEXT); |
| 4650 frame_->Dup(); | 4652 frame_->Dup(); |
| 4651 Result value = frame_->Pop(); | 4653 Result value = frame_->Pop(); |
| 4652 value.ToRegister(); | 4654 value.ToRegister(); |
| 4653 Result start = allocator_->Allocate(); | 4655 Result start = allocator_->Allocate(); |
| 4654 ASSERT(start.is_valid()); | 4656 ASSERT(start.is_valid()); |
| 4655 __ movq(SlotOperand(slot, start.reg()), value.reg()); | 4657 __ movq(SlotOperand(slot, start.reg()), value.reg()); |
| 4658 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 4656 // RecordWrite may destroy the value registers. | 4659 // RecordWrite may destroy the value registers. |
| 4657 // | 4660 // |
| 4658 // TODO(204): Avoid actually spilling when the value is not | 4661 // TODO(204): Avoid actually spilling when the value is not |
| 4659 // needed (probably the common case). | 4662 // needed (probably the common case). |
| 4660 frame_->Spill(value.reg()); | 4663 frame_->Spill(value.reg()); |
| 4661 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; | 4664 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
| 4662 Result temp = allocator_->Allocate(); | 4665 Result temp = allocator_->Allocate(); |
| 4663 ASSERT(temp.is_valid()); | 4666 ASSERT(temp.is_valid()); |
| 4664 __ RecordWrite(start.reg(), offset, value.reg(), temp.reg()); | 4667 __ RecordWrite(start.reg(), offset, value.reg(), temp.reg()); |
| 4668 #endif |
| 4665 // The results start, value, and temp are unused by going out of | 4669 // The results start, value, and temp are unused by going out of |
| 4666 // scope. | 4670 // scope. |
| 4667 } | 4671 } |
| 4668 | 4672 |
| 4669 exit.Bind(); | 4673 exit.Bind(); |
| 4670 } | 4674 } |
| 4671 } | 4675 } |
| 4672 | 4676 |
| 4673 | 4677 |
| 4674 void CodeGenerator::VisitSlot(Slot* node) { | 4678 void CodeGenerator::VisitSlot(Slot* node) { |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5005 // Get the elements FixedArray. | 5009 // Get the elements FixedArray. |
| 5006 __ movq(elements.reg(), | 5010 __ movq(elements.reg(), |
| 5007 FieldOperand(elements.reg(), JSObject::kElementsOffset)); | 5011 FieldOperand(elements.reg(), JSObject::kElementsOffset)); |
| 5008 | 5012 |
| 5009 // Write to the indexed properties array. | 5013 // Write to the indexed properties array. |
| 5010 int offset = i * kPointerSize + FixedArray::kHeaderSize; | 5014 int offset = i * kPointerSize + FixedArray::kHeaderSize; |
| 5011 __ movq(FieldOperand(elements.reg(), offset), prop_value.reg()); | 5015 __ movq(FieldOperand(elements.reg(), offset), prop_value.reg()); |
| 5012 | 5016 |
| 5013 // Update the write barrier for the array address. | 5017 // Update the write barrier for the array address. |
| 5014 frame_->Spill(prop_value.reg()); // Overwritten by the write barrier. | 5018 frame_->Spill(prop_value.reg()); // Overwritten by the write barrier. |
| 5019 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 5015 Result scratch = allocator_->Allocate(); | 5020 Result scratch = allocator_->Allocate(); |
| 5016 ASSERT(scratch.is_valid()); | 5021 ASSERT(scratch.is_valid()); |
| 5017 __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg()); | 5022 __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg()); |
| 5023 #endif |
| 5018 } | 5024 } |
| 5019 } | 5025 } |
| 5020 | 5026 |
| 5021 | 5027 |
| 5022 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { | 5028 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { |
| 5023 ASSERT(!in_spilled_code()); | 5029 ASSERT(!in_spilled_code()); |
| 5024 // Call runtime routine to allocate the catch extension object and | 5030 // Call runtime routine to allocate the catch extension object and |
| 5025 // assign the exception value to the catch variable. | 5031 // assign the exception value to the catch variable. |
| 5026 Comment cmnt(masm_, "[ CatchExtensionObject"); | 5032 Comment cmnt(masm_, "[ CatchExtensionObject"); |
| 5027 Load(node->key()); | 5033 Load(node->key()); |
| (...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6335 // Store the value. | 6341 // Store the value. |
| 6336 __ movq(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg()); | 6342 __ movq(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg()); |
| 6337 // Update the write barrier. Save the value as it will be | 6343 // Update the write barrier. Save the value as it will be |
| 6338 // overwritten by the write barrier code and is needed afterward. | 6344 // overwritten by the write barrier code and is needed afterward. |
| 6339 Result duplicate_value = allocator_->Allocate(); | 6345 Result duplicate_value = allocator_->Allocate(); |
| 6340 ASSERT(duplicate_value.is_valid()); | 6346 ASSERT(duplicate_value.is_valid()); |
| 6341 __ movq(duplicate_value.reg(), value.reg()); | 6347 __ movq(duplicate_value.reg(), value.reg()); |
| 6342 // The object register is also overwritten by the write barrier and | 6348 // The object register is also overwritten by the write barrier and |
| 6343 // possibly aliased in the frame. | 6349 // possibly aliased in the frame. |
| 6344 frame_->Spill(object.reg()); | 6350 frame_->Spill(object.reg()); |
| 6351 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 6345 __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(), | 6352 __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(), |
| 6346 scratch.reg()); | 6353 scratch.reg()); |
| 6354 #endif |
| 6347 object.Unuse(); | 6355 object.Unuse(); |
| 6348 scratch.Unuse(); | 6356 scratch.Unuse(); |
| 6349 duplicate_value.Unuse(); | 6357 duplicate_value.Unuse(); |
| 6350 | 6358 |
| 6351 // Leave. | 6359 // Leave. |
| 6352 leave.Bind(&value); | 6360 leave.Bind(&value); |
| 6353 frame_->Push(&value); | 6361 frame_->Push(&value); |
| 6354 } | 6362 } |
| 6355 | 6363 |
| 6356 | 6364 |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6617 FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset), rbx); | 6625 FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset), rbx); |
| 6618 | 6626 |
| 6619 // Update the cache itself. | 6627 // Update the cache itself. |
| 6620 // r9 holds the index as int32. | 6628 // r9 holds the index as int32. |
| 6621 __ bind(&update_cache); | 6629 __ bind(&update_cache); |
| 6622 __ pop(rbx); // restore the key | 6630 __ pop(rbx); // restore the key |
| 6623 __ Integer32ToSmiField( | 6631 __ Integer32ToSmiField( |
| 6624 FieldOperand(rcx, JSFunctionResultCache::kFingerOffset), r9); | 6632 FieldOperand(rcx, JSFunctionResultCache::kFingerOffset), r9); |
| 6625 // Store key. | 6633 // Store key. |
| 6626 __ movq(ArrayElement(rcx, r9), rbx); | 6634 __ movq(ArrayElement(rcx, r9), rbx); |
| 6635 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 6627 __ RecordWrite(rcx, 0, rbx, r9); | 6636 __ RecordWrite(rcx, 0, rbx, r9); |
| 6637 #endif |
| 6628 | 6638 |
| 6629 // Store value. | 6639 // Store value. |
| 6630 __ pop(rcx); // restore the cache. | 6640 __ pop(rcx); // restore the cache. |
| 6631 __ SmiToInteger32(rdx, | 6641 __ SmiToInteger32(rdx, |
| 6632 FieldOperand(rcx, JSFunctionResultCache::kFingerOffset)); | 6642 FieldOperand(rcx, JSFunctionResultCache::kFingerOffset)); |
| 6633 __ incl(rdx); | 6643 __ incl(rdx); |
| 6634 // Backup rax, because the RecordWrite macro clobbers its arguments. | 6644 // Backup rax, because the RecordWrite macro clobbers its arguments. |
| 6635 __ movq(rbx, rax); | 6645 __ movq(rbx, rax); |
| 6636 __ movq(ArrayElement(rcx, rdx), rax); | 6646 __ movq(ArrayElement(rcx, rdx), rax); |
| 6647 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 6637 __ RecordWrite(rcx, 0, rbx, rdx); | 6648 __ RecordWrite(rcx, 0, rbx, rdx); |
| 6649 #endif |
| 6638 | 6650 |
| 6639 if (!dst_.is(rax)) { | 6651 if (!dst_.is(rax)) { |
| 6640 __ movq(dst_, rax); | 6652 __ movq(dst_, rax); |
| 6641 } | 6653 } |
| 6642 } | 6654 } |
| 6643 | 6655 |
| 6644 | 6656 |
| 6645 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { | 6657 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { |
| 6646 ASSERT_EQ(2, args->length()); | 6658 ASSERT_EQ(2, args->length()); |
| 6647 | 6659 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6793 index2.reg(), | 6805 index2.reg(), |
| 6794 times_pointer_size, | 6806 times_pointer_size, |
| 6795 FixedArray::kHeaderSize)); | 6807 FixedArray::kHeaderSize)); |
| 6796 | 6808 |
| 6797 // Swap elements. | 6809 // Swap elements. |
| 6798 __ movq(object.reg(), Operand(index1.reg(), 0)); | 6810 __ movq(object.reg(), Operand(index1.reg(), 0)); |
| 6799 __ movq(tmp2.reg(), Operand(index2.reg(), 0)); | 6811 __ movq(tmp2.reg(), Operand(index2.reg(), 0)); |
| 6800 __ movq(Operand(index2.reg(), 0), object.reg()); | 6812 __ movq(Operand(index2.reg(), 0), object.reg()); |
| 6801 __ movq(Operand(index1.reg(), 0), tmp2.reg()); | 6813 __ movq(Operand(index1.reg(), 0), tmp2.reg()); |
| 6802 | 6814 |
| 6815 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 6803 Label done; | 6816 Label done; |
| 6804 __ InNewSpace(tmp1.reg(), tmp2.reg(), equal, &done); | 6817 __ InNewSpace(tmp1.reg(), tmp2.reg(), equal, &done); |
| 6805 // Possible optimization: do a check that both values are Smis | 6818 // Possible optimization: do a check that both values are Smis |
| 6806 // (or them and test against Smi mask.) | 6819 // (or them and test against Smi mask.) |
| 6807 | 6820 |
| 6808 __ movq(tmp2.reg(), tmp1.reg()); | 6821 __ movq(tmp2.reg(), tmp1.reg()); |
| 6809 RecordWriteStub recordWrite1(tmp2.reg(), index1.reg(), object.reg()); | 6822 RecordWriteStub recordWrite1(tmp2.reg(), index1.reg(), object.reg()); |
| 6810 __ CallStub(&recordWrite1); | 6823 __ CallStub(&recordWrite1); |
| 6811 | 6824 |
| 6812 RecordWriteStub recordWrite2(tmp1.reg(), index2.reg(), object.reg()); | 6825 RecordWriteStub recordWrite2(tmp1.reg(), index2.reg(), object.reg()); |
| 6813 __ CallStub(&recordWrite2); | 6826 __ CallStub(&recordWrite2); |
| 6814 | 6827 |
| 6815 __ bind(&done); | 6828 __ bind(&done); |
| 6829 #endif |
| 6816 | 6830 |
| 6817 deferred->BindExit(); | 6831 deferred->BindExit(); |
| 6818 frame_->Push(Factory::undefined_value()); | 6832 frame_->Push(Factory::undefined_value()); |
| 6819 } | 6833 } |
| 6820 | 6834 |
| 6821 | 6835 |
| 6822 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { | 6836 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { |
| 6823 Comment cmnt(masm_, "[ GenerateCallFunction"); | 6837 Comment cmnt(masm_, "[ GenerateCallFunction"); |
| 6824 | 6838 |
| 6825 ASSERT(args->length() >= 2); | 6839 ASSERT(args->length() >= 2); |
| (...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8300 // If the receiver and the value share a register allocate a new | 8314 // If the receiver and the value share a register allocate a new |
| 8301 // register for the receiver. | 8315 // register for the receiver. |
| 8302 if (receiver.reg().is(value.reg())) { | 8316 if (receiver.reg().is(value.reg())) { |
| 8303 receiver = allocator()->Allocate(); | 8317 receiver = allocator()->Allocate(); |
| 8304 ASSERT(receiver.is_valid()); | 8318 ASSERT(receiver.is_valid()); |
| 8305 __ movq(receiver.reg(), value.reg()); | 8319 __ movq(receiver.reg(), value.reg()); |
| 8306 } | 8320 } |
| 8307 | 8321 |
| 8308 // Update the write barrier. To save instructions in the inlined | 8322 // Update the write barrier. To save instructions in the inlined |
| 8309 // version we do not filter smis. | 8323 // version we do not filter smis. |
| 8324 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 8310 Label skip_write_barrier; | 8325 Label skip_write_barrier; |
| 8311 __ InNewSpace(receiver.reg(), value.reg(), equal, &skip_write_barrier); | 8326 __ InNewSpace(receiver.reg(), value.reg(), equal, &skip_write_barrier); |
| 8312 int delta_to_record_write = masm_->SizeOfCodeGeneratedSince(&patch_site); | 8327 int delta_to_record_write = masm_->SizeOfCodeGeneratedSince(&patch_site); |
| 8313 __ lea(scratch.reg(), Operand(receiver.reg(), offset)); | 8328 __ lea(scratch.reg(), Operand(receiver.reg(), offset)); |
| 8314 __ RecordWriteHelper(receiver.reg(), scratch.reg(), value.reg()); | 8329 __ RecordWriteHelper(receiver.reg(), scratch.reg(), value.reg()); |
| 8315 if (FLAG_debug_code) { | 8330 if (FLAG_debug_code) { |
| 8316 __ movq(receiver.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); | 8331 __ movq(receiver.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); |
| 8317 __ movq(value.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); | 8332 __ movq(value.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); |
| 8318 __ movq(scratch.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); | 8333 __ movq(scratch.reg(), BitCast<int64_t>(kZapValue), RelocInfo::NONE); |
| 8319 } | 8334 } |
| 8320 __ bind(&skip_write_barrier); | 8335 __ bind(&skip_write_barrier); |
| 8336 #else |
| 8337 // Use dummy delta to record write value to ensure proper |
| 8338 // testl encoding. |
| 8339 int delta_to_record_write = 0x0001; |
| 8340 #endif |
| 8321 value.Unuse(); | 8341 value.Unuse(); |
| 8322 scratch.Unuse(); | 8342 scratch.Unuse(); |
| 8323 receiver.Unuse(); | 8343 receiver.Unuse(); |
| 8324 done.Jump(&result); | 8344 done.Jump(&result); |
| 8325 | 8345 |
| 8326 slow.Bind(&value, &receiver); | 8346 slow.Bind(&value, &receiver); |
| 8327 frame()->Push(&receiver); | 8347 frame()->Push(&receiver); |
| 8328 frame()->Push(&value); | 8348 frame()->Push(&value); |
| 8329 result = frame()->CallStoreIC(name, is_contextual); | 8349 result = frame()->CallStoreIC(name, is_contextual); |
| 8330 // Encode the offset to the map check instruction and the offset | 8350 // Encode the offset to the map check instruction and the offset |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8448 // Get the receiver, key and value into registers. | 8468 // Get the receiver, key and value into registers. |
| 8449 result = frame()->Pop(); | 8469 result = frame()->Pop(); |
| 8450 Result key = frame()->Pop(); | 8470 Result key = frame()->Pop(); |
| 8451 Result receiver = frame()->Pop(); | 8471 Result receiver = frame()->Pop(); |
| 8452 | 8472 |
| 8453 Result tmp = allocator_->Allocate(); | 8473 Result tmp = allocator_->Allocate(); |
| 8454 ASSERT(tmp.is_valid()); | 8474 ASSERT(tmp.is_valid()); |
| 8455 Result tmp2 = allocator_->Allocate(); | 8475 Result tmp2 = allocator_->Allocate(); |
| 8456 ASSERT(tmp2.is_valid()); | 8476 ASSERT(tmp2.is_valid()); |
| 8457 | 8477 |
| 8478 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 8458 // 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 |
| 8459 // register. | 8480 // register. |
| 8460 bool value_is_constant = result.is_constant(); | 8481 bool value_is_constant = result.is_constant(); |
| 8482 #endif |
| 8461 | 8483 |
| 8462 // Make sure that value, key and receiver are in registers. | 8484 // Make sure that value, key and receiver are in registers. |
| 8463 result.ToRegister(); | 8485 result.ToRegister(); |
| 8464 key.ToRegister(); | 8486 key.ToRegister(); |
| 8465 receiver.ToRegister(); | 8487 receiver.ToRegister(); |
| 8466 | 8488 |
| 8467 DeferredReferenceSetKeyedValue* deferred = | 8489 DeferredReferenceSetKeyedValue* deferred = |
| 8468 new DeferredReferenceSetKeyedValue(result.reg(), | 8490 new DeferredReferenceSetKeyedValue(result.reg(), |
| 8469 key.reg(), | 8491 key.reg(), |
| 8470 receiver.reg()); | 8492 receiver.reg()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 8490 deferred->Branch(below_equal); | 8512 deferred->Branch(below_equal); |
| 8491 | 8513 |
| 8492 // Get the elements array from the receiver and check that it is not a | 8514 // Get the elements array from the receiver and check that it is not a |
| 8493 // dictionary. | 8515 // dictionary. |
| 8494 __ movq(tmp.reg(), | 8516 __ movq(tmp.reg(), |
| 8495 FieldOperand(receiver.reg(), JSArray::kElementsOffset)); | 8517 FieldOperand(receiver.reg(), JSArray::kElementsOffset)); |
| 8496 | 8518 |
| 8497 // Check whether it is possible to omit the write barrier. If the elements | 8519 // Check whether it is possible to omit the write barrier. If the elements |
| 8498 // array is in new space or the value written is a smi we can safely update | 8520 // array is in new space or the value written is a smi we can safely update |
| 8499 // the elements array without write barrier. | 8521 // the elements array without write barrier. |
| 8522 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 8500 Label in_new_space; | 8523 Label in_new_space; |
| 8501 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space); | 8524 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space); |
| 8502 if (!value_is_constant) { | 8525 if (!value_is_constant) { |
| 8503 __ JumpIfNotSmi(result.reg(), deferred->entry_label()); | 8526 __ JumpIfNotSmi(result.reg(), deferred->entry_label()); |
| 8504 } | 8527 } |
| 8505 | 8528 |
| 8506 __ bind(&in_new_space); | 8529 __ bind(&in_new_space); |
| 8530 #endif |
| 8531 |
| 8507 // Bind the deferred code patch site to be able to locate the fixed | 8532 // Bind the deferred code patch site to be able to locate the fixed |
| 8508 // array map comparison. When debugging, we patch this comparison to | 8533 // array map comparison. When debugging, we patch this comparison to |
| 8509 // always fail so that we will hit the IC call in the deferred code | 8534 // always fail so that we will hit the IC call in the deferred code |
| 8510 // which will allow the debugger to break for fast case stores. | 8535 // which will allow the debugger to break for fast case stores. |
| 8511 __ bind(deferred->patch_site()); | 8536 __ bind(deferred->patch_site()); |
| 8512 // Avoid using __ to ensure the distance from patch_site | 8537 // Avoid using __ to ensure the distance from patch_site |
| 8513 // to the map address is always the same. | 8538 // to the map address is always the same. |
| 8514 masm()->movq(kScratchRegister, Factory::fixed_array_map(), | 8539 masm()->movq(kScratchRegister, Factory::fixed_array_map(), |
| 8515 RelocInfo::EMBEDDED_OBJECT); | 8540 RelocInfo::EMBEDDED_OBJECT); |
| 8516 __ cmpq(FieldOperand(tmp.reg(), HeapObject::kMapOffset), | 8541 __ cmpq(FieldOperand(tmp.reg(), HeapObject::kMapOffset), |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8799 // Call the function from C++. | 8824 // Call the function from C++. |
| 8800 return FUNCTION_CAST<ModuloFunction>(buffer); | 8825 return FUNCTION_CAST<ModuloFunction>(buffer); |
| 8801 } | 8826 } |
| 8802 | 8827 |
| 8803 #endif | 8828 #endif |
| 8804 | 8829 |
| 8805 | 8830 |
| 8806 #undef __ | 8831 #undef __ |
| 8807 | 8832 |
| 8808 void RecordWriteStub::Generate(MacroAssembler* masm) { | 8833 void RecordWriteStub::Generate(MacroAssembler* masm) { |
| 8834 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 8809 masm->RecordWriteHelper(object_, addr_, scratch_); | 8835 masm->RecordWriteHelper(object_, addr_, scratch_); |
| 8836 #endif |
| 8810 masm->ret(0); | 8837 masm->ret(0); |
| 8811 } | 8838 } |
| 8812 | 8839 |
| 8813 } } // namespace v8::internal | 8840 } } // namespace v8::internal |
| 8814 | 8841 |
| 8815 #endif // V8_TARGET_ARCH_X64 | 8842 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |