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

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

Issue 1695007: Moving more code to lookup an item from the native cache into code generator. (Closed)
Patch Set: Next round of Lasse's comments Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 6562 matching lines...) Expand 10 before | Expand all | Expand 10 after
6573 class DeferredSearchCache: public DeferredCode { 6573 class DeferredSearchCache: public DeferredCode {
6574 public: 6574 public:
6575 DeferredSearchCache(Register dst, Register cache, Register key) 6575 DeferredSearchCache(Register dst, Register cache, Register key)
6576 : dst_(dst), cache_(cache), key_(key) { 6576 : dst_(dst), cache_(cache), key_(key) {
6577 set_comment("[ DeferredSearchCache"); 6577 set_comment("[ DeferredSearchCache");
6578 } 6578 }
6579 6579
6580 virtual void Generate(); 6580 virtual void Generate();
6581 6581
6582 private: 6582 private:
6583 Register dst_, cache_, key_; 6583 Register dst_; // on invocation Smi index of finger, on exit
6584 // holds value being looked up.
6585 Register cache_; // instance of JSFunctionResultCache.
6586 Register key_; // key being looked up.
6584 }; 6587 };
6585 6588
6586 6589
6590 // Return a position of the element at |index_as_smi| + |additional_offset|
6591 // in FixedArray pointer to which is held in |array|. |index_as_smi| is Smi.
6592 static Operand ArrayElement(Register array,
6593 Register index_as_smi,
6594 int additional_offset = 0) {
6595 int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize;
6596 return FieldOperand(array, index_as_smi, times_half_pointer_size, offset);
6597 }
6598
6599
6587 void DeferredSearchCache::Generate() { 6600 void DeferredSearchCache::Generate() {
6588 __ push(cache_); 6601 Label first_loop, search_further, second_loop, cache_miss;
6602
6603 // Smi-tagging is equivalent to multiplying by 2.
6604 STATIC_ASSERT(kSmiTag == 0);
6605 STATIC_ASSERT(kSmiTagSize == 1);
6606
6607 Smi* kEntrySizeSmi = Smi::FromInt(JSFunctionResultCache::kEntrySize);
6608 Smi* kEntriesIndexSmi = Smi::FromInt(JSFunctionResultCache::kEntriesIndex);
6609
6610 // Check the cache from finger to start of the cache.
6611 __ bind(&first_loop);
6612 __ sub(Operand(dst_), Immediate(kEntrySizeSmi));
6613 __ cmp(Operand(dst_), Immediate(kEntriesIndexSmi));
6614 __ j(less, &search_further);
6615
6616 __ cmp(key_, ArrayElement(cache_, dst_));
6617 __ j(not_equal, &first_loop);
6618
6619 __ mov(FieldOperand(cache_, JSFunctionResultCache::kFingerOffset), dst_);
6620 __ mov(dst_, ArrayElement(cache_, dst_, 1));
6621 __ jmp(exit_label());
6622
6623 __ bind(&search_further);
6624
6625 // Check the cache from end of cache up to finger.
6626 __ mov(dst_, FieldOperand(cache_, JSFunctionResultCache::kCacheSizeOffset));
6627
6628 __ bind(&second_loop);
6629 __ sub(Operand(dst_), Immediate(kEntrySizeSmi));
6630 // Consider prefetching into some reg.
6631 __ cmp(dst_, FieldOperand(cache_, JSFunctionResultCache::kFingerOffset));
6632 __ j(less_equal, &cache_miss);
6633
6634 __ cmp(key_, ArrayElement(cache_, dst_));
6635 __ j(not_equal, &second_loop);
6636
6637 __ mov(FieldOperand(cache_, JSFunctionResultCache::kFingerOffset), dst_);
6638 __ mov(dst_, ArrayElement(cache_, dst_, 1));
6639 __ jmp(exit_label());
6640
6641 __ bind(&cache_miss);
6642 __ push(cache_); // store a reference to cache
6643 __ push(key_); // store a key
6644 Handle<Object> receiver(Top::global_context()->global());
6645 __ push(Immediate(receiver));
6589 __ push(key_); 6646 __ push(key_);
6590 __ CallRuntime(Runtime::kGetFromCache, 2); 6647 // On ia32 function must be in edi.
6648 __ mov(edi, FieldOperand(cache_, JSFunctionResultCache::kFactoryOffset));
6649 ParameterCount expected(1);
6650 __ InvokeFunction(edi, expected, CALL_FUNCTION);
6651
6652 // Find a place to put new cached value into.
6653 Label add_new_entry, update_cache;
6654 __ mov(ecx, Operand(esp, kPointerSize)); // restore the cache
6655 // Possible optimization: cache size is constant for the given cache
6656 // so technically we could use a constant here. However, if we have
6657 // cache miss this optimization would hardly matter much.
6658
6659 // Check if we could add new entry to cache.
6660 __ mov(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
6661 __ SmiTag(ebx);
6662 __ cmp(ebx, FieldOperand(ecx, JSFunctionResultCache::kCacheSizeOffset));
6663 __ j(greater, &add_new_entry);
6664
6665 // Check if we could evict entry after finger.
6666 __ mov(edx, FieldOperand(ecx, JSFunctionResultCache::kFingerOffset));
6667 __ add(Operand(edx), Immediate(kEntrySizeSmi));
6668 __ cmp(ebx, Operand(edx));
6669 __ j(greater, &update_cache);
6670
6671 // Need to wrap over the cache.
6672 __ mov(edx, Immediate(kEntriesIndexSmi));
6673 __ jmp(&update_cache);
6674
6675 __ bind(&add_new_entry);
6676 __ mov(edx, FieldOperand(ecx, JSFunctionResultCache::kCacheSizeOffset));
6677 __ lea(ebx, Operand(edx, JSFunctionResultCache::kEntrySize << 1));
6678 __ mov(FieldOperand(ecx, JSFunctionResultCache::kCacheSizeOffset), ebx);
6679
6680 // Update the cache itself.
6681 // edx holds the index.
6682 __ bind(&update_cache);
6683 __ pop(ebx); // restore the key
6684 __ mov(FieldOperand(ecx, JSFunctionResultCache::kFingerOffset), edx);
6685 // Store key.
6686 __ mov(ArrayElement(ecx, edx), ebx);
6687 __ RecordWrite(ecx, 0, ebx, edx);
6688
6689 // Store value.
6690 __ pop(ecx); // restore the cache.
6691 __ mov(edx, FieldOperand(ecx, JSFunctionResultCache::kFingerOffset));
6692 __ add(Operand(edx), Immediate(Smi::FromInt(1)));
6693 __ mov(ebx, eax);
6694 __ mov(ArrayElement(ecx, edx), ebx);
6695 __ RecordWrite(ecx, 0, ebx, edx);
6696
6591 if (!dst_.is(eax)) { 6697 if (!dst_.is(eax)) {
6592 __ mov(dst_, eax); 6698 __ mov(dst_, eax);
6593 } 6699 }
6594 } 6700 }
6595 6701
6596 6702
6597 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { 6703 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) {
6598 ASSERT_EQ(2, args->length()); 6704 ASSERT_EQ(2, args->length());
6599 6705
6600 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 6706 ASSERT_NE(NULL, args->at(0)->AsLiteral());
(...skipping 21 matching lines...) Expand all
6622 __ mov(cache.reg(), 6728 __ mov(cache.reg(),
6623 FieldOperand(cache.reg(), FixedArray::OffsetOfElementAt(cache_id))); 6729 FieldOperand(cache.reg(), FixedArray::OffsetOfElementAt(cache_id)));
6624 6730
6625 Result tmp = allocator()->Allocate(); 6731 Result tmp = allocator()->Allocate();
6626 ASSERT(tmp.is_valid()); 6732 ASSERT(tmp.is_valid());
6627 6733
6628 DeferredSearchCache* deferred = new DeferredSearchCache(tmp.reg(), 6734 DeferredSearchCache* deferred = new DeferredSearchCache(tmp.reg(),
6629 cache.reg(), 6735 cache.reg(),
6630 key.reg()); 6736 key.reg());
6631 6737
6632 const int kFingerOffset =
6633 FixedArray::OffsetOfElementAt(JSFunctionResultCache::kFingerIndex);
6634 // tmp.reg() now holds finger offset as a smi. 6738 // tmp.reg() now holds finger offset as a smi.
6635 ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 6739 ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
6636 __ mov(tmp.reg(), FieldOperand(cache.reg(), kFingerOffset)); 6740 __ mov(tmp.reg(), FieldOperand(cache.reg(),
6637 __ cmp(key.reg(), FieldOperand(cache.reg(), 6741 JSFunctionResultCache::kFingerOffset));
6638 tmp.reg(), // as smi 6742 __ cmp(key.reg(), ArrayElement(cache.reg(), tmp.reg()));
6639 times_half_pointer_size,
6640 FixedArray::kHeaderSize));
6641 deferred->Branch(not_equal); 6743 deferred->Branch(not_equal);
6642 6744
6643 __ mov(tmp.reg(), FieldOperand(cache.reg(), 6745 __ mov(tmp.reg(), ArrayElement(cache.reg(), tmp.reg(), 1));
6644 tmp.reg(), // as smi
6645 times_half_pointer_size,
6646 kPointerSize + FixedArray::kHeaderSize));
6647 6746
6648 deferred->BindExit(); 6747 deferred->BindExit();
6649 frame_->Push(&tmp); 6748 frame_->Push(&tmp);
6650 } 6749 }
6651 6750
6652 6751
6653 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) { 6752 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
6654 ASSERT_EQ(args->length(), 1); 6753 ASSERT_EQ(args->length(), 1);
6655 6754
6656 // Load the argument on the stack and call the stub. 6755 // Load the argument on the stack and call the stub.
(...skipping 6486 matching lines...) Expand 10 before | Expand all | Expand 10 after
13143 13242
13144 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 13243 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
13145 // tagged as a small integer. 13244 // tagged as a small integer.
13146 __ bind(&runtime); 13245 __ bind(&runtime);
13147 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 13246 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
13148 } 13247 }
13149 13248
13150 #undef __ 13249 #undef __
13151 13250
13152 } } // namespace v8::internal 13251 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698