diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-10-11 15:06:25 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-10-19 20:48:25 +0200 |
commit | 7dc5973bf12919d2d35230844beabe558d4faa00 (patch) | |
tree | 88d6128a911d2ec3b9a72d8e45d56fc2b250c714 /src/v8/0008-Add-custom-object-compare-callback.patch | |
parent | 4dc25c1f2995a5e02da47f0f6f3522af9eb6f78c (diff) |
Diffstat (limited to 'src/v8/0008-Add-custom-object-compare-callback.patch')
-rw-r--r-- | src/v8/0008-Add-custom-object-compare-callback.patch | 489 |
1 files changed, 0 insertions, 489 deletions
diff --git a/src/v8/0008-Add-custom-object-compare-callback.patch b/src/v8/0008-Add-custom-object-compare-callback.patch deleted file mode 100644 index 125668805e..0000000000 --- a/src/v8/0008-Add-custom-object-compare-callback.patch +++ /dev/null @@ -1,489 +0,0 @@ -From a7c491e6e533110a17fe9f7d47cf92a1b2263180 Mon Sep 17 00:00:00 2001 -From: Aaron Kennedy <aaron.kennedy@nokia.com> -Date: Mon, 27 Jun 2011 14:57:28 +1000 -Subject: [PATCH 08/16] Add custom object compare callback - -A global custom object comparison callback can be set with: - V8::SetUserObjectComparisonCallbackFunction() -When two JSObjects are compared (== or !=), if either one has -the MarkAsUseUserObjectComparison() bit set, the custom comparison -callback is invoked to do the actual comparison. - -This is useful when you have "value" objects that you want to -compare as equal, even though they are actually different JS object -instances. ---- - include/v8.h | 13 +++++++++++++ - src/api.cc | 19 +++++++++++++++++++ - src/arm/code-stubs-arm.cc | 42 ++++++++++++++++++++++++++++++++++++++++-- - src/factory.cc | 8 ++++++++ - src/ia32/code-stubs-ia32.cc | 40 ++++++++++++++++++++++++++++++++++++++++ - src/isolate.h | 8 ++++++++ - src/objects-inl.h | 15 +++++++++++++++ - src/objects.h | 10 +++++++++- - src/runtime.cc | 23 +++++++++++++++++++++++ - src/runtime.h | 1 + - src/top.cc | 5 +++++ - src/x64/code-stubs-x64.cc | 37 +++++++++++++++++++++++++++++++++++++ - 12 files changed, 218 insertions(+), 3 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 99f4b9a..7544deb 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -2366,6 +2366,12 @@ class V8EXPORT ObjectTemplate : public Template { - bool HasExternalResource(); - void SetHasExternalResource(bool value); - -+ /** -+ * Mark object instances of the template as using the user object -+ * comparison callback. -+ */ -+ void MarkAsUseUserObjectComparison(); -+ - private: - ObjectTemplate(); - static Local<ObjectTemplate> New(Handle<FunctionTemplate> constructor); -@@ -2566,6 +2572,10 @@ typedef void (*FailedAccessCheckCallback)(Local<Object> target, - AccessType type, - Local<Value> data); - -+// --- U s e r O b j e c t C o m p a r i s o n C a l l b a c k --- -+typedef bool (*UserObjectComparisonCallback)(Local<Object> lhs, -+ Local<Object> rhs); -+ - // --- G a r b a g e C o l l e c t i o n C a l l b a c k s - - /** -@@ -2816,6 +2826,9 @@ class V8EXPORT V8 { - /** Callback function for reporting failed access checks.*/ - static void SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback); - -+ /** Callback for user object comparisons */ -+ static void SetUserObjectComparisonCallbackFunction(UserObjectComparisonCallback); -+ - /** - * Enables the host application to receive a notification before a - * garbage collection. Allocations are not allowed in the -diff --git a/src/api.cc b/src/api.cc -index ff74efb..2436031 100644 ---- a/src/api.cc -+++ b/src/api.cc -@@ -1321,6 +1321,16 @@ void ObjectTemplate::SetHasExternalResource(bool value) - } - } - -+void ObjectTemplate::MarkAsUseUserObjectComparison() -+{ -+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); -+ if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUseUserObjectComparison()")) { -+ return; -+ } -+ ENTER_V8(isolate); -+ EnsureConstructor(this); -+ Utils::OpenHandle(this)->set_use_user_object_comparison(i::Smi::FromInt(1)); -+} - - // --- S c r i p t D a t a --- - -@@ -4632,6 +4642,15 @@ void V8::SetFailedAccessCheckCallbackFunction( - isolate->SetFailedAccessCheckCallback(callback); - } - -+void V8::SetUserObjectComparisonCallbackFunction( -+ UserObjectComparisonCallback callback) { -+ i::Isolate* isolate = i::Isolate::Current(); -+ if (IsDeadCheck(isolate, "v8::V8::SetUserObjectComparisonCallbackFunction()")) { -+ return; -+ } -+ isolate->SetUserObjectComparisonCallback(callback); -+} -+ - void V8::AddObjectGroup(Persistent<Value>* objects, - size_t length, - RetainedObjectInfo* info) { -diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc -index a2626bf..749c9be 100644 ---- a/src/arm/code-stubs-arm.cc -+++ b/src/arm/code-stubs-arm.cc -@@ -1563,6 +1563,36 @@ void CompareStub::Generate(MacroAssembler* masm) { - // NOTICE! This code is only reached after a smi-fast-case check, so - // it is certain that at least one operand isn't a smi. - -+ { -+ Label not_user_equal, user_equal; -+ __ and_(r2, r1, Operand(r0)); -+ __ tst(r2, Operand(kSmiTagMask)); -+ __ b(eq, ¬_user_equal); -+ -+ __ CompareObjectType(r0, r2, r4, JS_OBJECT_TYPE); -+ __ b(ne, ¬_user_equal); -+ -+ __ CompareObjectType(r1, r3, r4, JS_OBJECT_TYPE); -+ __ b(ne, ¬_user_equal); -+ -+ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField3Offset)); -+ __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison)); -+ __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison)); -+ __ b(eq, &user_equal); -+ -+ __ ldrb(r3, FieldMemOperand(r3, Map::kBitField3Offset)); -+ __ and_(r3, r3, Operand(1 << Map::kUseUserObjectComparison)); -+ __ cmp(r3, Operand(1 << Map::kUseUserObjectComparison)); -+ __ b(ne, ¬_user_equal); -+ -+ __ bind(&user_equal); -+ -+ __ Push(r0, r1); -+ __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1); -+ -+ __ bind(¬_user_equal); -+ } -+ - // Handle the case where the objects are identical. Either returns the answer - // or goes to slow. Only falls through if the objects were not identical. - EmitIdenticalObjectComparison(masm, &slow, cc_, never_nan_nan_); -@@ -5802,10 +5832,18 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) { - __ tst(r2, Operand(kSmiTagMask)); - __ b(eq, &miss); - -- __ CompareObjectType(r0, r2, r2, JS_OBJECT_TYPE); -+ __ CompareObjectType(r0, r2, r3, JS_OBJECT_TYPE); - __ b(ne, &miss); -- __ CompareObjectType(r1, r2, r2, JS_OBJECT_TYPE); -+ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField3Offset)); -+ __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison)); -+ __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison)); -+ __ b(eq, &miss); -+ __ CompareObjectType(r1, r2, r3, JS_OBJECT_TYPE); - __ b(ne, &miss); -+ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField3Offset)); -+ __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison)); -+ __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison)); -+ __ b(eq, &miss); - - ASSERT(GetCondition() == eq); - __ sub(r0, r0, Operand(r1)); -diff --git a/src/factory.cc b/src/factory.cc -index d530a75..6f8c7de 100644 ---- a/src/factory.cc -+++ b/src/factory.cc -@@ -998,6 +998,7 @@ Handle<JSFunction> Factory::CreateApiFunction( - - int internal_field_count = 0; - bool has_external_resource = false; -+ bool use_user_object_comparison = false; - - if (!obj->instance_template()->IsUndefined()) { - Handle<ObjectTemplateInfo> instance_template = -@@ -1007,6 +1008,8 @@ Handle<JSFunction> Factory::CreateApiFunction( - Smi::cast(instance_template->internal_field_count())->value(); - has_external_resource = - !instance_template->has_external_resource()->IsUndefined(); -+ use_user_object_comparison = -+ !instance_template->use_user_object_comparison()->IsUndefined(); - } - - int instance_size = kPointerSize * internal_field_count; -@@ -1051,6 +1054,11 @@ Handle<JSFunction> Factory::CreateApiFunction( - map->set_has_external_resource(true); - } - -+ // Mark as using user object comparison if needed -+ if (use_user_object_comparison) { -+ map->set_use_user_object_comparison(true); -+ } -+ - // Mark as undetectable if needed. - if (obj->undetectable()) { - map->set_is_undetectable(); -diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc -index afa599e..0964ab9 100644 ---- a/src/ia32/code-stubs-ia32.cc -+++ b/src/ia32/code-stubs-ia32.cc -@@ -3447,6 +3447,40 @@ void CompareStub::Generate(MacroAssembler* masm) { - __ Assert(not_zero, "Unexpected smi operands."); - } - -+ { -+ NearLabel not_user_equal, user_equal; -+ __ test(eax, Immediate(kSmiTagMask)); -+ __ j(zero, ¬_user_equal); -+ __ test(edx, Immediate(kSmiTagMask)); -+ __ j(zero, ¬_user_equal); -+ -+ __ CmpObjectType(eax, JS_OBJECT_TYPE, ebx); -+ __ j(not_equal, ¬_user_equal); -+ -+ __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx); -+ __ j(not_equal, ¬_user_equal); -+ -+ __ test_b(FieldOperand(ebx, Map::kBitField3Offset), -+ 1 << Map::kUseUserObjectComparison); -+ __ j(not_zero, &user_equal); -+ __ test_b(FieldOperand(ecx, Map::kBitField3Offset), -+ 1 << Map::kUseUserObjectComparison); -+ __ j(not_zero, &user_equal); -+ -+ __ jmp(¬_user_equal); -+ -+ __ bind(&user_equal); -+ -+ __ pop(ebx); // Return address. -+ __ push(eax); -+ __ push(edx); -+ __ push(ebx); -+ __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1); -+ -+ __ bind(¬_user_equal); -+ } -+ -+ - // NOTICE! This code is only reached after a smi-fast-case check, so - // it is certain that at least one operand isn't a smi. - -@@ -5592,8 +5626,14 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) { - - __ CmpObjectType(eax, JS_OBJECT_TYPE, ecx); - __ j(not_equal, &miss, not_taken); -+ __ test_b(FieldOperand(ecx, Map::kBitField3Offset), -+ 1 << Map::kUseUserObjectComparison); -+ __ j(not_zero, &miss); - __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx); - __ j(not_equal, &miss, not_taken); -+ __ test_b(FieldOperand(ecx, Map::kBitField3Offset), -+ 1 << Map::kUseUserObjectComparison); -+ __ j(not_zero, &miss); - - ASSERT(GetCondition() == equal); - __ sub(eax, Operand(edx)); -diff --git a/src/isolate.h b/src/isolate.h -index 35ffcb4..8130397 100644 ---- a/src/isolate.h -+++ b/src/isolate.h -@@ -267,6 +267,9 @@ class ThreadLocalTop BASE_EMBEDDED { - // Call back function to report unsafe JS accesses. - v8::FailedAccessCheckCallback failed_access_check_callback_; - -+ // Call back function for user object comparisons -+ v8::UserObjectComparisonCallback user_object_comparison_callback_; -+ - private: - void InitializeInternal(); - -@@ -699,6 +702,11 @@ class Isolate { - void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback); - void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type); - -+ void SetUserObjectComparisonCallback(v8::UserObjectComparisonCallback callback); -+ inline v8::UserObjectComparisonCallback UserObjectComparisonCallback() { -+ return thread_local_top()->user_object_comparison_callback_; -+ } -+ - // Exception throwing support. The caller should use the result - // of Throw() as its return value. - Failure* Throw(Object* exception, MessageLocation* location = NULL); -diff --git a/src/objects-inl.h b/src/objects-inl.h -index 1c7f83e..1765441 100644 ---- a/src/objects-inl.h -+++ b/src/objects-inl.h -@@ -2552,6 +2552,19 @@ bool Map::has_external_resource() - } - - -+void Map::set_use_user_object_comparison(bool value) { -+ if (value) { -+ set_bit_field3(bit_field3() | (1 << kUseUserObjectComparison)); -+ } else { -+ set_bit_field3(bit_field3() & ~(1 << kUseUserObjectComparison)); -+ } -+} -+ -+bool Map::use_user_object_comparison() { -+ return ((1 << kUseUserObjectComparison) & bit_field3()) != 0; -+} -+ -+ - void Map::set_named_interceptor_is_fallback(bool value) - { - if (value) { -@@ -3050,6 +3063,8 @@ ACCESSORS(ObjectTemplateInfo, internal_field_count, Object, - kInternalFieldCountOffset) - ACCESSORS(ObjectTemplateInfo, has_external_resource, Object, - kHasExternalResourceOffset) -+ACCESSORS(ObjectTemplateInfo, use_user_object_comparison, Object, -+ kUseUserObjectComparisonOffset) - - ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset) - ACCESSORS(SignatureInfo, args, Object, kArgsOffset) -diff --git a/src/objects.h b/src/objects.h -index edbc47a..e75e9f1 100644 ---- a/src/objects.h -+++ b/src/objects.h -@@ -3724,6 +3724,11 @@ class Map: public HeapObject { - inline void set_has_external_resource(bool value); - inline bool has_external_resource(); - -+ -+ // Tells whether the user object comparison callback should be used for -+ // comparisons involving this object -+ inline void set_use_user_object_comparison(bool value); -+ inline bool use_user_object_comparison(); - - // Whether the named interceptor is a fallback interceptor or not - inline void set_named_interceptor_is_fallback(bool value); -@@ -3922,6 +3927,7 @@ class Map: public HeapObject { - // Bit positions for bit field 3 - static const int kNamedInterceptorIsFallback = 0; - static const int kHasExternalResource = 1; -+ static const int kUseUserObjectComparison = 2; - - // Layout of the default cache. It holds alternating name and code objects. - static const int kCodeCacheEntrySize = 2; -@@ -6442,6 +6448,7 @@ class ObjectTemplateInfo: public TemplateInfo { - DECL_ACCESSORS(constructor, Object) - DECL_ACCESSORS(internal_field_count, Object) - DECL_ACCESSORS(has_external_resource, Object) -+ DECL_ACCESSORS(use_user_object_comparison, Object) - - static inline ObjectTemplateInfo* cast(Object* obj); - -@@ -6459,7 +6466,8 @@ class ObjectTemplateInfo: public TemplateInfo { - static const int kInternalFieldCountOffset = - kConstructorOffset + kPointerSize; - static const int kHasExternalResourceOffset = kInternalFieldCountOffset + kPointerSize; -- static const int kSize = kHasExternalResourceOffset + kPointerSize; -+ static const int kUseUserObjectComparisonOffset = kHasExternalResourceOffset + kPointerSize; -+ static const int kSize = kUseUserObjectComparisonOffset + kPointerSize; - }; - - -diff --git a/src/runtime.cc b/src/runtime.cc -index c13f92d..b50de80 100644 ---- a/src/runtime.cc -+++ b/src/runtime.cc -@@ -6279,6 +6279,29 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) { - } - - -+RUNTIME_FUNCTION(MaybeObject*, Runtime_UserObjectEquals) { -+ NoHandleAllocation ha; -+ ASSERT(args.length() == 2); -+ -+ CONVERT_CHECKED(JSObject, lhs, args[1]); -+ CONVERT_CHECKED(JSObject, rhs, args[0]); -+ -+ bool result; -+ -+ v8::UserObjectComparisonCallback callback = isolate->UserObjectComparisonCallback(); -+ if (callback) { -+ HandleScope scope(isolate); -+ Handle<JSObject> lhs_handle(lhs); -+ Handle<JSObject> rhs_handle(rhs); -+ result = callback(v8::Utils::ToLocal(lhs_handle), v8::Utils::ToLocal(rhs_handle)); -+ } else { -+ result = (lhs == rhs); -+ } -+ -+ return Smi::FromInt(result?0:1); -+} -+ -+ - RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) { - NoHandleAllocation ha; - ASSERT(args.length() == 3); -diff --git a/src/runtime.h b/src/runtime.h -index 5e97173..0d754f9 100644 ---- a/src/runtime.h -+++ b/src/runtime.h -@@ -146,6 +146,7 @@ namespace internal { - /* Comparisons */ \ - F(NumberEquals, 2, 1) \ - F(StringEquals, 2, 1) \ -+ F(UserObjectEquals, 2, 1) \ - \ - F(NumberCompare, 3, 1) \ - F(SmiLexicographicCompare, 2, 1) \ -diff --git a/src/top.cc b/src/top.cc -index e078ee9..c345383 100644 ---- a/src/top.cc -+++ b/src/top.cc -@@ -68,6 +68,7 @@ void ThreadLocalTop::InitializeInternal() { - thread_id_ = ThreadId::Invalid(); - external_caught_exception_ = false; - failed_access_check_callback_ = NULL; -+ user_object_comparison_callback_ = NULL; - save_context_ = NULL; - catcher_ = NULL; - } -@@ -387,6 +388,10 @@ void Isolate::SetFailedAccessCheckCallback( - thread_local_top()->failed_access_check_callback_ = callback; - } - -+void Isolate::SetUserObjectComparisonCallback( -+ v8::UserObjectComparisonCallback callback) { -+ thread_local_top()->user_object_comparison_callback_ = callback; -+} - - void Isolate::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) { - if (!thread_local_top()->failed_access_check_callback_) return; -diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc -index d923494..10b9b56 100644 ---- a/src/x64/code-stubs-x64.cc -+++ b/src/x64/code-stubs-x64.cc -@@ -2443,6 +2443,37 @@ void CompareStub::Generate(MacroAssembler* masm) { - __ bind(&ok); - } - -+ { -+ NearLabel not_user_equal, user_equal; -+ __ JumpIfSmi(rax, ¬_user_equal); -+ __ JumpIfSmi(rdx, ¬_user_equal); -+ -+ __ CmpObjectType(rax, JS_OBJECT_TYPE, rbx); -+ __ j(not_equal, ¬_user_equal); -+ -+ __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx); -+ __ j(not_equal, ¬_user_equal); -+ -+ __ testb(FieldOperand(rbx, Map::kBitField3Offset), -+ Immediate(1 << Map::kUseUserObjectComparison)); -+ __ j(not_zero, &user_equal); -+ __ testb(FieldOperand(rcx, Map::kBitField3Offset), -+ Immediate(1 << Map::kUseUserObjectComparison)); -+ __ j(not_zero, &user_equal); -+ -+ __ jmp(¬_user_equal); -+ -+ __ bind(&user_equal); -+ -+ __ pop(rbx); // Return address. -+ __ push(rax); -+ __ push(rdx); -+ __ push(rbx); -+ __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1); -+ -+ __ bind(¬_user_equal); -+ } -+ - // The compare stub returns a positive, negative, or zero 64-bit integer - // value in rax, corresponding to result of comparing the two inputs. - // NOTICE! This code is only reached after a smi-fast-case check, so -@@ -4471,8 +4502,14 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) { - - __ CmpObjectType(rax, JS_OBJECT_TYPE, rcx); - __ j(not_equal, &miss, not_taken); -+ __ testb(FieldOperand(rcx, Map::kBitField3Offset), -+ Immediate(1 << Map::kUseUserObjectComparison)); -+ __ j(not_zero, &miss); - __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx); - __ j(not_equal, &miss, not_taken); -+ __ testb(FieldOperand(rcx, Map::kBitField3Offset), -+ Immediate(1 << Map::kUseUserObjectComparison)); -+ __ j(not_zero, &miss); - - ASSERT(GetCondition() == equal); - __ subq(rax, rdx); --- -1.7.4.4 - |