Revision: 3680
Author: [email protected]
Date: Fri Jan 22 05:56:12 2010
Log: Make KeyedLoadIC::generic_stub go into slow case if receiver has an
indexed interceptor.
BUG=589,27967.
Review URL: http://codereview.chromium.org/555048
http://code.google.com/p/v8/source/detail?r=3680
Modified:
/branches/bleeding_edge/src/arm/ic-arm.cc
/branches/bleeding_edge/src/ia32/ic-ia32.cc
/branches/bleeding_edge/src/ic.h
/branches/bleeding_edge/src/x64/ic-x64.cc
/branches/bleeding_edge/test/cctest/test-api.cc
=======================================
--- /branches/bleeding_edge/src/arm/ic-arm.cc Thu Jan 7 03:38:43 2010
+++ /branches/bleeding_edge/src/arm/ic-arm.cc Fri Jan 22 05:56:12 2010
@@ -569,11 +569,10 @@
// Get the map of the receiver.
__ ldr(r2, FieldMemOperand(r1, 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.
+
+ // Check bit field.
__ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset));
- __ tst(r3, Operand(1 << Map::kIsAccessCheckNeeded));
+ __ tst(r3, Operand(kSlowCaseBitFieldMask));
__ b(ne, &slow);
// 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,
=======================================
--- /branches/bleeding_edge/src/ia32/ic-ia32.cc Fri Jan 8 01:54:11 2010
+++ /branches/bleeding_edge/src/ia32/ic-ia32.cc Fri Jan 22 05:56:12 2010
@@ -244,11 +244,10 @@
// 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.
+
+ // Check bit field.
__ movzx_b(ebx, FieldOperand(edx, Map::kBitFieldOffset));
- __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
+ __ test(ebx, Immediate(kSlowCaseBitFieldMask));
__ 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,
=======================================
--- /branches/bleeding_edge/src/ic.h Mon Jan 18 06:13:58 2010
+++ /branches/bleeding_edge/src/ic.h Fri Jan 22 05:56:12 2010
@@ -295,6 +295,13 @@
static void ClearInlinedVersion(Address address);
private:
+ // Bit mask to be tested against bit field for the cases when
+ // generic stub should go into slow case.
+ // Access check is necessary explicitly since generic stub does not
perform
+ // map checks.
+ static const int kSlowCaseBitFieldMask =
+ (1 << Map::kIsAccessCheckNeeded) | (1 <<
Map::kHasIndexedInterceptor);
+
static void Generate(MacroAssembler* masm, const ExternalReference& f);
// Update the inline cache.
=======================================
--- /branches/bleeding_edge/src/x64/ic-x64.cc Mon Jan 18 06:09:36 2010
+++ /branches/bleeding_edge/src/x64/ic-x64.cc Fri Jan 22 05:56:12 2010
@@ -271,11 +271,10 @@
ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
__ CmpObjectType(rcx, JS_OBJECT_TYPE, rdx);
__ j(below, &slow);
- // Check that the receiver does not require access checks. We need
- // to check this explicitly since this generic stub does not perform
- // map checks. The map is already in rdx.
+
+ // Check bit field.
__ testb(FieldOperand(rdx, Map::kBitFieldOffset),
- Immediate(1 << Map::kIsAccessCheckNeeded));
+ Immediate(kSlowCaseBitFieldMask));
__ j(not_zero, &slow);
// Check that the key is a smi.
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Wed Jan 20 06:43:12 2010
+++ /branches/bleeding_edge/test/cctest/test-api.cc Fri Jan 22 05:56:12 2010
@@ -61,6 +61,27 @@
namespace i = ::v8::internal;
+static void ExpectString(const char* code, const char* expected) {
+ Local<Value> result = CompileRun(code);
+ CHECK(result->IsString());
+ String::AsciiValue ascii(result);
+ CHECK_EQ(expected, *ascii);
+}
+
+
+static void ExpectBoolean(const char* code, bool expected) {
+ Local<Value> result = CompileRun(code);
+ CHECK(result->IsBoolean());
+ CHECK_EQ(expected, result->BooleanValue());
+}
+
+
+static void ExpectObject(const char* code, Local<Value> expected) {
+ Local<Value> result = CompileRun(code);
+ CHECK(result->Equals(expected));
+}
+
+
static int signature_callback_count;
static v8::Handle<Value> IncrementingSignatureCallback(
const v8::Arguments& args) {
@@ -2379,6 +2400,36 @@
result = interceptor_getter_script->Run();
CHECK_EQ(v8_num(625), result);
}
+
+
+static v8::Handle<Value> IdentityIndexedPropertyGetter(
+ uint32_t index,
+ const AccessorInfo& info) {
+ return v8::Integer::New(index);
+}
+
+
+THREADED_TEST(IndexedInterceptorWithNoSetter) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+ LocalContext context;
+ context->Global()->Set(v8_str("obj"), templ->NewInstance());
+
+ const char* code =
+ "try {"
+ " obj[0] = 239;"
+ " for (var i = 0; i < 100; i++) {"
+ " var v = obj[0];"
+ " if (v != 0) throw 'Wrong value ' + v + ' at iteration ' + i;"
+ " }"
+ " 'PASSED'"
+ "} catch(e) {"
+ " e"
+ "}";
+ ExpectString(code, "PASSED");
+}
THREADED_TEST(MultiContexts) {
@@ -2465,27 +2516,6 @@
Local<Script> script1 = Script::Compile(source);
CHECK_EQ(8901.0, script1->Run()->NumberValue());
}
-
-
-static void ExpectString(const char* code, const char* expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->IsString());
- String::AsciiValue ascii(result);
- CHECK_EQ(0, strcmp(*ascii, expected));
-}
-
-
-static void ExpectBoolean(const char* code, bool expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->IsBoolean());
- CHECK_EQ(expected, result->BooleanValue());
-}
-
-
-static void ExpectObject(const char* code, Local<Value> expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->Equals(expected));
-}
THREADED_TEST(UndetectableObject) {
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev