Commit dffb7533 authored by kasperl@chromium.org's avatar kasperl@chromium.org

Implement for-in cache validity checking in the full codegen on IA-32.

Review URL: http://codereview.chromium.org/3376003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5445 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 666b98fb
......@@ -744,11 +744,10 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ bind(&done_convert);
__ push(r0);
// TODO(kasperl): Check cache validity in generated code. This is a
// fast case for the JSObject::IsSimpleEnum cache validity
// checks. If we cannot guarantee cache validity, call the runtime
// system to check cache validity or get the property names in a
// fixed array.
// BUG(867): Check cache validity in generated code. This is a fast
// case for the JSObject::IsSimpleEnum cache validity checks. If we
// cannot guarantee cache validity, call the runtime system to check
// cache validity or get the property names in a fixed array.
// Get the set of properties to enumerate.
__ push(r0); // Duplicate the enumerable object on the stack.
......
......@@ -756,13 +756,57 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ bind(&done_convert);
__ push(eax);
// TODO(kasperl): Check cache validity in generated code. This is a
// fast case for the JSObject::IsSimpleEnum cache validity
// checks. If we cannot guarantee cache validity, call the runtime
// system to check cache validity or get the property names in a
// fixed array.
// Check cache validity in generated code. This is a fast case for
// the JSObject::IsSimpleEnum cache validity checks. If we cannot
// guarantee cache validity, call the runtime system to check cache
// validity or get the property names in a fixed array.
Label next, call_runtime;
__ mov(ecx, eax);
__ bind(&next);
// Check that there are no elements. Register ecx contains the
// current JS object we've reached through the prototype chain.
__ cmp(FieldOperand(ecx, JSObject::kElementsOffset),
Factory::empty_fixed_array());
__ j(not_equal, &call_runtime);
// Check that instance descriptors are not empty so that we can
// check for an enum cache. Leave the map in ebx for the subsequent
// prototype load.
__ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset));
__ mov(edx, FieldOperand(ebx, Map::kInstanceDescriptorsOffset));
__ cmp(edx, Factory::empty_descriptor_array());
__ j(equal, &call_runtime);
// Check that there in an enum cache in the non-empty instance
// descriptors (edx). This is the case if the next enumeration
// index field does not contain a smi.
__ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset));
__ test(edx, Immediate(kSmiTagMask));
__ j(zero, &call_runtime);
// For all objects but the receiver, check that the cache is empty.
Label check_prototype;
__ cmp(ecx, Operand(eax));
__ j(equal, &check_prototype);
__ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset));
__ cmp(edx, Factory::empty_fixed_array());
__ j(not_equal, &call_runtime);
// Load the prototype from the map and loop if non-null.
__ bind(&check_prototype);
__ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
__ cmp(ecx, Factory::null_value());
__ j(not_equal, &next);
// The enum cache is valid. Load the map of the object being
// iterated over and use the cache for the iteration.
Label use_cache;
__ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
__ jmp(&use_cache);
// Get the set of properties to enumerate.
__ bind(&call_runtime);
__ push(eax); // Duplicate the enumerable object on the stack.
__ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
......@@ -774,6 +818,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ j(not_equal, &fixed_array);
// We got a map in register eax. Get the enumeration cache from it.
__ bind(&use_cache);
__ mov(ecx, FieldOperand(eax, Map::kInstanceDescriptorsOffset));
__ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumerationIndexOffset));
__ mov(edx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset));
......
......@@ -746,11 +746,10 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ bind(&done_convert);
__ push(rax);
// TODO(kasperl): Check cache validity in generated code. This is a
// fast case for the JSObject::IsSimpleEnum cache validity
// checks. If we cannot guarantee cache validity, call the runtime
// system to check cache validity or get the property names in a
// fixed array.
// BUG(867): Check cache validity in generated code. This is a fast
// case for the JSObject::IsSimpleEnum cache validity checks. If we
// cannot guarantee cache validity, call the runtime system to check
// cache validity or get the property names in a fixed array.
// Get the set of properties to enumerate.
__ push(rax); // Duplicate the enumerable object on the stack.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment