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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 1559033: Reapply load ICs for nonexistent properties.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 932 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 // Pass the value being stored in the now unused name_reg. 943 // Pass the value being stored in the now unused name_reg.
944 __ mov(name_reg, Operand(eax)); 944 __ mov(name_reg, Operand(eax));
945 __ RecordWrite(scratch, offset, name_reg, receiver_reg); 945 __ RecordWrite(scratch, offset, name_reg, receiver_reg);
946 } 946 }
947 947
948 // Return the value (register eax). 948 // Return the value (register eax).
949 __ ret(0); 949 __ ret(0);
950 } 950 }
951 951
952 952
953 // Generate code to check that a global property cell is empty. Create
954 // the property cell at compilation time if no cell exists for the
955 // property.
956 static Object* GenerateCheckPropertyCell(MacroAssembler* masm,
957 GlobalObject* global,
958 String* name,
959 Register scratch,
960 Label* miss) {
961 Object* probe = global->EnsurePropertyCell(name);
962 if (probe->IsFailure()) return probe;
963 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
964 ASSERT(cell->value()->IsTheHole());
965 __ mov(scratch, Immediate(Handle<Object>(cell)));
966 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
967 Immediate(Factory::the_hole_value()));
968 __ j(not_equal, miss, not_taken);
969 return cell;
970 }
971
972
953 #undef __ 973 #undef __
954 #define __ ACCESS_MASM(masm()) 974 #define __ ACCESS_MASM(masm())
955 975
956 976
957 Register StubCompiler::CheckPrototypes(JSObject* object, 977 Register StubCompiler::CheckPrototypes(JSObject* object,
958 Register object_reg, 978 Register object_reg,
959 JSObject* holder, 979 JSObject* holder,
960 Register holder_reg, 980 Register holder_reg,
961 Register scratch, 981 Register scratch,
962 String* name, 982 String* name,
963 int push_at_depth, 983 int push_at_depth,
964 Label* miss) { 984 Label* miss) {
965 // Check that the maps haven't changed. 985 // Check that the maps haven't changed.
966 Register result = 986 Register result =
967 masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch, 987 masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch,
968 push_at_depth, miss); 988 push_at_depth, miss);
969 989
970 // If we've skipped any global objects, it's not enough to verify 990 // If we've skipped any global objects, it's not enough to verify
971 // that their maps haven't changed. 991 // that their maps haven't changed. We also need to check that the
992 // property cell for the property is still empty.
972 while (object != holder) { 993 while (object != holder) {
973 if (object->IsGlobalObject()) { 994 if (object->IsGlobalObject()) {
974 GlobalObject* global = GlobalObject::cast(object); 995 Object* cell = GenerateCheckPropertyCell(masm(),
975 Object* probe = global->EnsurePropertyCell(name); 996 GlobalObject::cast(object),
976 if (probe->IsFailure()) { 997 name,
977 set_failure(Failure::cast(probe)); 998 scratch,
999 miss);
1000 if (cell->IsFailure()) {
1001 set_failure(Failure::cast(cell));
978 return result; 1002 return result;
979 } 1003 }
980 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
981 ASSERT(cell->value()->IsTheHole());
982 __ mov(scratch, Immediate(Handle<Object>(cell)));
983 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
984 Immediate(Factory::the_hole_value()));
985 __ j(not_equal, miss, not_taken);
986 } 1004 }
987 object = JSObject::cast(object->GetPrototype()); 1005 object = JSObject::cast(object->GetPrototype());
988 } 1006 }
989 1007
990 // Return the register containing the holder. 1008 // Return the register containing the holder.
991 return result; 1009 return result;
992 } 1010 }
993 1011
994 1012
995 void StubCompiler::GenerateLoadField(JSObject* object, 1013 void StubCompiler::GenerateLoadField(JSObject* object,
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after
1941 __ bind(&miss); 1959 __ bind(&miss);
1942 __ DecrementCounter(&Counters::keyed_store_field, 1); 1960 __ DecrementCounter(&Counters::keyed_store_field, 1);
1943 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); 1961 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss));
1944 __ jmp(ic, RelocInfo::CODE_TARGET); 1962 __ jmp(ic, RelocInfo::CODE_TARGET);
1945 1963
1946 // Return the generated code. 1964 // Return the generated code.
1947 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 1965 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
1948 } 1966 }
1949 1967
1950 1968
1969 Object* LoadStubCompiler::CompileLoadNonexistent(String* name,
1970 JSObject* object,
1971 JSObject* last) {
1972 // ----------- S t a t e -------------
1973 // -- eax : receiver
1974 // -- ecx : name
1975 // -- esp[0] : return address
1976 // -----------------------------------
1977 Label miss;
1978
1979 // Check the maps of the full prototype chain. Also check that
1980 // global property cells up to (but not including) the last object
1981 // in the prototype chain are empty.
1982 CheckPrototypes(object, eax, last, ebx, edx, name, &miss);
1983
1984 // If the last object in the prototype chain is a global object,
1985 // check that the global property cell is empty.
1986 if (last->IsGlobalObject()) {
1987 Object* cell = GenerateCheckPropertyCell(masm(),
1988 GlobalObject::cast(last),
1989 name,
1990 edx,
1991 &miss);
1992 if (cell->IsFailure()) return cell;
1993 }
1994
1995 // Return undefined if maps of the full prototype chain is still the
1996 // same and no global property with this name contains a value.
1997 __ mov(eax, Factory::undefined_value());
1998 __ ret(0);
1999
2000 __ bind(&miss);
2001 GenerateLoadMiss(masm(), Code::LOAD_IC);
2002
2003 // Return the generated code.
2004 return GetCode(NONEXISTENT, Heap::empty_string());
2005 }
2006
1951 2007
1952 Object* LoadStubCompiler::CompileLoadField(JSObject* object, 2008 Object* LoadStubCompiler::CompileLoadField(JSObject* object,
1953 JSObject* holder, 2009 JSObject* holder,
1954 int index, 2010 int index,
1955 String* name) { 2011 String* name) {
1956 // ----------- S t a t e ------------- 2012 // ----------- S t a t e -------------
1957 // -- eax : receiver 2013 // -- eax : receiver
1958 // -- ecx : name 2014 // -- ecx : name
1959 // -- esp[0] : return address 2015 // -- esp[0] : return address
1960 // ----------------------------------- 2016 // -----------------------------------
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
2425 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 2481 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
2426 2482
2427 // Return the generated code. 2483 // Return the generated code.
2428 return GetCode(); 2484 return GetCode();
2429 } 2485 }
2430 2486
2431 2487
2432 #undef __ 2488 #undef __
2433 2489
2434 } } // namespace v8::internal 2490 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698