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

Unified Diff: src/x64/ic-x64.cc

Issue 2804029: Implement IC for storing to dictionary case objects.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/v8-counters.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/ic-x64.cc
===================================================================
--- src/x64/ic-x64.cc (revision 4975)
+++ src/x64/ic-x64.cc (working copy)
@@ -61,11 +61,11 @@
// Generated code falls through if the receiver is a regular non-global
// JS object with slow properties and no interceptors.
-static void GenerateDictionaryLoadReceiverCheck(MacroAssembler* masm,
- Register receiver,
- Register r0,
- Register r1,
- Label* miss) {
+static void GenerateStringDictionaryReceiverCheck(MacroAssembler* masm,
+ Register receiver,
+ Register r0,
+ Register r1,
+ Label* miss) {
// Register usage:
// receiver: holds the receiver on entry and is unchanged.
// r0: used to hold receiver instance type.
@@ -98,34 +98,17 @@
}
-// Helper function used to load a property from a dictionary backing storage.
-// This function may return false negatives, so miss_label
-// must always call a backup property load that is complete.
-// This function is safe to call if name is not a symbol, and will jump to
-// the miss_label in that case.
-// The generated code assumes that the receiver has slow properties,
-// is not a global object and does not have interceptors.
-static void GenerateDictionaryLoad(MacroAssembler* masm,
- Label* miss_label,
- Register elements,
- Register name,
- Register r0,
- Register r1,
- Register result) {
- // Register use:
- //
- // elements - holds the property dictionary on entry and is unchanged.
- //
- // name - holds the name of the property on entry and is unchanged.
- //
- // r0 - used to hold the capacity of the property dictionary.
- //
- // r1 - used to hold the index into the property dictionary.
- //
- // result - holds the result on exit if the load succeeded.
-
- Label done;
-
+// Probe the string dictionary in the |elements| register. Jump to the
+// |done| label if a property with the given name is found leaving the
+// index into the dictionary in |r1|. Jump to the |miss| label
+// otherwise.
+static void GenerateStringDictionaryProbes(MacroAssembler* masm,
+ Label* miss,
+ Label* done,
+ Register elements,
+ Register name,
+ Register r0,
+ Register r1) {
// Compute the capacity mask.
const int kCapacityOffset =
StringDictionary::kHeaderSize +
@@ -157,14 +140,58 @@
__ cmpq(name, Operand(elements, r1, times_pointer_size,
kElementsStartOffset - kHeapObjectTag));
if (i != kProbes - 1) {
- __ j(equal, &done);
+ __ j(equal, done);
} else {
- __ j(not_equal, miss_label);
+ __ j(not_equal, miss);
}
}
+}
- // Check that the value is a normal property.
+
+// Helper function used to load a property from a dictionary backing storage.
+// This function may return false negatives, so miss_label
+// must always call a backup property load that is complete.
+// This function is safe to call if name is not a symbol, and will jump to
+// the miss_label in that case.
+// The generated code assumes that the receiver has slow properties,
+// is not a global object and does not have interceptors.
+static void GenerateDictionaryLoad(MacroAssembler* masm,
+ Label* miss_label,
+ Register elements,
+ Register name,
+ Register r0,
+ Register r1,
+ Register result) {
+ // Register use:
+ //
+ // elements - holds the property dictionary on entry and is unchanged.
+ //
+ // name - holds the name of the property on entry and is unchanged.
+ //
+ // r0 - used to hold the capacity of the property dictionary.
+ //
+ // r1 - used to hold the index into the property dictionary.
+ //
+ // result - holds the result on exit if the load succeeded.
+
+ Label done;
+
+ // Probe the dictionary.
+ GenerateStringDictionaryProbes(masm,
+ miss_label,
+ &done,
+ elements,
+ name,
+ r0,
+ r1);
+
+ // If probing finds an entry in the dictionary, r0 contains the
+ // index into the dictionary. Check that the value is a normal
+ // property.
__ bind(&done);
+ const int kElementsStartOffset =
+ StringDictionary::kHeaderSize +
+ StringDictionary::kElementsStartIndex * kPointerSize;
const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
__ Test(Operand(elements, r1, times_pointer_size,
kDetailsOffset - kHeapObjectTag),
@@ -179,6 +206,75 @@
}
+// Helper function used to store a property to a dictionary backing
+// storage. This function may fail to store a property even though it
+// is in the dictionary, so code at miss_label must always call a
+// backup property store that is complete. This function is safe to
+// call if name is not a symbol, and will jump to the miss_label in
+// that case. The generated code assumes that the receiver has slow
+// properties, is not a global object and does not have interceptors.
+static void GenerateDictionaryStore(MacroAssembler* masm,
+ Label* miss_label,
+ Register elements,
+ Register name,
+ Register value,
+ Register scratch0,
+ Register scratch1) {
+ // Register use:
+ //
+ // elements - holds the property dictionary on entry and is clobbered.
+ //
+ // name - holds the name of the property on entry and is unchanged.
+ //
+ // value - holds the value to store and is unchanged.
+ //
+ // scratch0 - used for index into the property dictionary and is clobbered.
+ //
+ // scratch1 - used to hold the capacity of the property dictionary and is
+ // clobbered.
+ Label done;
+
+ // Probe the dictionary.
+ GenerateStringDictionaryProbes(masm,
+ miss_label,
+ &done,
+ elements,
+ name,
+ scratch0,
+ scratch1);
+
+ // If probing finds an entry in the dictionary, scratch0 contains the
+ // index into the dictionary. Check that the value is a normal
+ // property that is not read only.
+ __ bind(&done);
+ const int kElementsStartOffset =
+ StringDictionary::kHeaderSize +
+ StringDictionary::kElementsStartIndex * kPointerSize;
+ const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
+ const int kTypeAndReadOnlyMask
+ = (PropertyDetails::TypeField::mask() |
+ PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize;
+ __ Test(Operand(elements,
+ scratch1,
+ times_pointer_size,
+ kDetailsOffset - kHeapObjectTag),
+ Smi::FromInt(kTypeAndReadOnlyMask));
+ __ j(not_zero, miss_label);
+
+ // Store the value at the masked, scaled index.
+ const int kValueOffset = kElementsStartOffset + kPointerSize;
+ __ lea(scratch1, Operand(elements,
+ scratch1,
+ times_pointer_size,
+ kValueOffset - kHeapObjectTag));
+ __ movq(Operand(scratch1, 0), value);
+
+ // Update write barrier. Make sure not to clobber the value.
+ __ movq(scratch0, value);
+ __ RecordWrite(elements, scratch1, scratch0);
+}
+
+
static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
Label* miss,
Register elements,
@@ -1332,7 +1428,7 @@
// Get the receiver of the function from the stack.
__ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
- GenerateDictionaryLoadReceiverCheck(masm, rdx, rax, rbx, &miss);
+ GenerateStringDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss);
// rax: elements
// Search the dictionary placing the result in rdi.
@@ -1616,7 +1712,7 @@
// -----------------------------------
Label miss;
- GenerateDictionaryLoadReceiverCheck(masm, rax, rdx, rbx, &miss);
+ GenerateStringDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss);
// rdx: elements
// Search the dictionary placing the result in rax.
@@ -1760,6 +1856,28 @@
}
+void StoreIC::GenerateNormal(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- rax : value
+ // -- rcx : name
+ // -- rdx : receiver
+ // -- rsp[0] : return address
+ // -----------------------------------
+
+ Label miss, restore_miss;
+
+ GenerateStringDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss);
+
+ GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9);
+ __ IncrementCounter(&Counters::store_normal_hit, 1);
+ __ ret(0);
+
+ __ bind(&miss);
+ __ IncrementCounter(&Counters::store_normal_miss, 1);
+ GenerateMiss(masm);
+}
+
+
#undef __
« no previous file with comments | « src/v8-counters.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698