From d25d40aa5c6e8f35dd297a418b218a613f12895d Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Thu, 5 Aug 2010 10:45:07 +0000 Subject: [PATCH] Modify polymorphic keyed load IC stub to load cached properties from the property array of a fast-case JSObject. Review URL: http://codereview.chromium.org/3053042 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5175 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/ic-arm.cc | 17 ++++++++++++----- src/ia32/ic-ia32.cc | 14 +++++++++++--- src/x64/ic-x64.cc | 15 +++++++++++---- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc index e7e3de3cdb..1fd7098254 100644 --- a/src/arm/ic-arm.cc +++ b/src/arm/ic-arm.cc @@ -1105,7 +1105,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // -- r0 : key // -- r1 : receiver // ----------------------------------- - Label slow, check_string, index_smi, index_string; + Label slow, check_string, index_smi, index_string, property_array_property; Label check_pixel_array, probe_dictionary, check_number_dictionary; Register key = r0; @@ -1193,7 +1193,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ cmp(r0, r5); __ b(ne, &slow); - // Get field offset and check that it is an in-object property. + // Get field offset. // r0 : key // r1 : receiver // r2 : receiver's map @@ -1203,11 +1203,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ mov(r4, Operand(cache_field_offsets)); __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2)); __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset)); - __ cmp(r5, r6); - __ b(ge, &slow); + __ sub(r5, r5, r6, SetCC); + __ b(ge, &property_array_property); // Load in-object property. - __ sub(r5, r5, r6); // Index from end of object. __ ldrb(r6, FieldMemOperand(r2, Map::kInstanceSizeOffset)); __ add(r6, r6, r5); // Index from start of object. __ sub(r1, r1, Operand(kHeapObjectTag)); // Remove the heap tag. @@ -1215,6 +1214,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1, r2, r3); __ Ret(); + // Load property array property. + __ bind(&property_array_property); + __ ldr(r1, FieldMemOperand(r1, JSObject::kPropertiesOffset)); + __ add(r1, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); + __ ldr(r0, MemOperand(r1, r5, LSL, kPointerSizeLog2)); + __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1, r2, r3); + __ Ret(); + // Do a quick inline probe of the receiver's dictionary, if it // exists. __ bind(&probe_dictionary); diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc index cbf710c5de..2cd41a15bb 100644 --- a/src/ia32/ic-ia32.cc +++ b/src/ia32/ic-ia32.cc @@ -545,7 +545,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // -- edx : receiver // -- esp[0] : return address // ----------------------------------- - Label slow, check_string, index_smi, index_string; + Label slow, check_string, index_smi, index_string, property_array_property; Label check_pixel_array, probe_dictionary, check_number_dictionary; // Check that the key is a smi. @@ -652,7 +652,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ cmp(eax, Operand::StaticArray(edi, times_1, cache_keys)); __ j(not_equal, &slow); - // Get field offset and check that it is an in-object property. + // Get field offset. // edx : receiver // ebx : receiver's map // eax : key @@ -663,7 +663,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets)); __ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset)); __ sub(edi, Operand(ecx)); - __ j(above_equal, &slow); + __ j(above_equal, &property_array_property); // Load in-object property. __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset)); @@ -672,6 +672,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1); __ ret(0); + // Load property array property. + __ bind(&property_array_property); + __ mov(eax, FieldOperand(edx, JSObject::kPropertiesOffset)); + __ mov(eax, FieldOperand(eax, edi, times_pointer_size, + FixedArray::kHeaderSize)); + __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1); + __ ret(0); + // Do a quick inline probe of the receiver's dictionary, if it // exists. __ bind(&probe_dictionary); diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc index b6957b2d48..a8971f5b4a 100644 --- a/src/x64/ic-x64.cc +++ b/src/x64/ic-x64.cc @@ -599,7 +599,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // -- rdx : receiver // -- rsp[0] : return address // ----------------------------------- - Label slow, check_string, index_smi, index_string; + Label slow, check_string, index_smi, index_string, property_array_property; Label check_pixel_array, probe_dictionary, check_number_dictionary; // Check that the key is a smi. @@ -692,15 +692,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ cmpq(rax, Operand(kScratchRegister, rdi, times_1, kPointerSize)); __ j(not_equal, &slow); - // Get field offset which is a 32-bit integer and check that it is - // an in-object property. + // Get field offset, which is a 32-bit integer. ExternalReference cache_field_offsets = ExternalReference::keyed_lookup_cache_field_offsets(); __ movq(kScratchRegister, cache_field_offsets); __ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0)); __ movzxbq(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset)); __ subq(rdi, rcx); - __ j(above_equal, &slow); + __ j(above_equal, &property_array_property); // Load in-object property. __ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset)); @@ -709,6 +708,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1); __ ret(0); + // Load property array property. + __ bind(&property_array_property); + __ movq(rax, FieldOperand(rdx, JSObject::kPropertiesOffset)); + __ movq(rax, FieldOperand(rax, rdi, times_pointer_size, + FixedArray::kHeaderSize)); + __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1); + __ ret(0); + // Do a quick inline probe of the receiver's dictionary, if it // exists. __ bind(&probe_dictionary);