Index: src/ic-ia32.cc |
=================================================================== |
--- src/ic-ia32.cc (revision 941) |
+++ src/ic-ia32.cc (working copy) |
@@ -215,18 +215,27 @@ |
// ----------------------------------- |
Label slow, fast, check_string, index_int, index_string; |
+ // Load name and receiver. |
__ mov(eax, (Operand(esp, kPointerSize))); |
__ mov(ecx, (Operand(esp, 2 * kPointerSize))); |
// Check that the object isn't a smi. |
__ test(ecx, Immediate(kSmiTagMask)); |
__ j(zero, &slow, not_taken); |
+ |
+ // Get the map of the receiver. |
+ __ mov(edx, FieldOperand(ecx, HeapObject::kMapOffset)); |
+ // Check that the receiver does not require access checks. We need |
+ // to check this explicitly since this generic stub does not perform |
+ // map checks. |
+ __ movzx_b(ebx, FieldOperand(edx, Map::kBitFieldOffset)); |
+ __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); |
+ __ j(not_zero, &slow, not_taken); |
// Check that the object is some kind of JS object EXCEPT JS Value type. |
// In the case that the object is a value-wrapper object, |
// we enter the runtime system to make sure that indexing |
// into string objects work as intended. |
ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); |
- __ mov(edx, FieldOperand(ecx, HeapObject::kMapOffset)); |
__ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset)); |
__ cmp(edx, JS_OBJECT_TYPE); |
__ j(less, &slow, not_taken); |
@@ -268,7 +277,7 @@ |
// bits have been subtracted to allow space for the length and the cached |
// array index. |
ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < |
- (1 << (String::kShortLengthShift - String::kHashShift))); |
+ (1 << (String::kShortLengthShift - String::kHashShift))); |
__ bind(&index_string); |
const int kLengthFieldLimit = |
(String::kMaxCachedArrayIndexLength + 1) << String::kShortLengthShift; |
@@ -298,17 +307,25 @@ |
// -- esp[8] : receiver |
// ----------------------------------- |
Label slow, fast, array, extra; |
- // Get the key and the object from the stack. |
- __ mov(ebx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address |
+ |
+ // Get the receiver from the stack. |
__ mov(edx, Operand(esp, 2 * kPointerSize)); // 2 ~ return address, key |
- // Check that the key is a smi. |
- __ test(ebx, Immediate(kSmiTagMask)); |
- __ j(not_zero, &slow, not_taken); |
// Check that the object isn't a smi. |
__ test(edx, Immediate(kSmiTagMask)); |
__ j(zero, &slow, not_taken); |
- // Get the type of the object from its map. |
+ // Get the map from the receiver. |
__ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
+ // Check that the receiver does not require access checks. We need |
+ // to do this because this generic stub does not perform map checks. |
+ __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset)); |
+ __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); |
+ __ j(not_zero, &slow, not_taken); |
+ // Get the key from the stack. |
+ __ mov(ebx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address |
+ // Check that the key is a smi. |
+ __ test(ebx, Immediate(kSmiTagMask)); |
+ __ j(not_zero, &slow, not_taken); |
+ // Get the instance type from the map of the receiver. |
__ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
// Check if the object is a JS array or not. |
__ cmp(ecx, JS_ARRAY_TYPE); |
@@ -317,7 +334,6 @@ |
__ cmp(ecx, FIRST_JS_OBJECT_TYPE); |
__ j(less, &slow, not_taken); |
- |
// Object case: Check key against length in the elements array. |
// eax: value |
// edx: JSObject |
@@ -515,8 +531,8 @@ |
__ j(zero, &miss, not_taken); |
// Check that the receiver is a valid JS object. |
- __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset)); |
- __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); |
+ __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); |
+ __ movzx_b(eax, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
__ cmp(eax, FIRST_JS_OBJECT_TYPE); |
__ j(less, &miss, not_taken); |
@@ -531,6 +547,10 @@ |
// Accessing global object: Load and invoke. |
__ bind(&global_object); |
+ // Check that the global object does not require access checks. |
+ __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset)); |
+ __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); |
+ __ j(not_equal, &miss, not_taken); |
GenerateNormalHelper(masm, argc, true, &miss); |
// Accessing non-global object: Check for access to global proxy. |
@@ -538,6 +558,11 @@ |
__ bind(&non_global_object); |
__ cmp(eax, JS_GLOBAL_PROXY_TYPE); |
__ j(equal, &global_proxy, not_taken); |
+ // Check that the non-global, non-global-proxy object does not |
+ // require access checks. |
+ __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset)); |
+ __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); |
+ __ j(not_equal, &miss, not_taken); |
__ bind(&invoke); |
GenerateNormalHelper(masm, argc, false, &miss); |
@@ -642,8 +667,8 @@ |
__ j(zero, &miss, not_taken); |
// Check that the receiver is a valid JS object. |
- __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); |
- __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset)); |
+ __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
+ __ movzx_b(edx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
__ cmp(edx, FIRST_JS_OBJECT_TYPE); |
__ j(less, &miss, not_taken); |
@@ -654,6 +679,11 @@ |
__ cmp(edx, JS_GLOBAL_PROXY_TYPE); |
__ j(equal, &global, not_taken); |
+ // Check for non-global object that requires access check. |
+ __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset)); |
+ __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); |
+ __ j(not_zero, &miss, not_taken); |
+ |
// Search the dictionary placing the result in eax. |
__ bind(&probe); |
GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx); |