Changeset 241956 in webkit
- Timestamp:
- Feb 22, 2019 12:20:49 PM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/APIUtils.h
r235254 r241956 58 58 *returnedExceptionRef = toRef(exec, exception); 59 59 #if ENABLE(REMOTE_INSPECTOR) 60 VM& vm = exec->vm();60 JSC::VM& vm = exec->vm(); 61 61 vm.vmEntryGlobalObject(exec)->inspectorController().reportAPIException(exec, JSC::Exception::create(vm, exception)); 62 62 #endif -
trunk/Source/JavaScriptCore/API/JSWrapperMap.mm
r237607 r241956 29 29 #if JSC_OBJC_API_ENABLED 30 30 #import "APICast.h" 31 #import "APIUtils.h" 31 32 #import "JSAPIWrapperObject.h" 32 33 #import "JSCInlines.h" … … 179 180 } 180 181 181 inline void putNonEnumerable(JSValue *base, NSString *propertyName, JSValue *value) 182 { 183 [base defineProperty:propertyName descriptor:@{ 184 JSPropertyDescriptorValueKey: value, 185 JSPropertyDescriptorWritableKey: @YES, 186 JSPropertyDescriptorEnumerableKey: @NO, 187 JSPropertyDescriptorConfigurableKey: @YES 188 }]; 182 inline void putNonEnumerable(JSContext *context, JSValue *base, NSString *propertyName, JSValue *value) 183 { 184 if (![base isObject]) 185 return; 186 JSC::ExecState* exec = toJS([context JSGlobalContextRef]); 187 JSC::VM& vm = exec->vm(); 188 JSC::JSLockHolder locker(vm); 189 auto scope = DECLARE_CATCH_SCOPE(vm); 190 191 JSC::JSObject* baseObject = JSC::asObject(toJS(exec, [base JSValueRef])); 192 auto name = OpaqueJSString::tryCreate(propertyName); 193 if (!name) 194 return; 195 196 JSC::PropertyDescriptor descriptor; 197 descriptor.setValue(toJS(exec, [value JSValueRef])); 198 descriptor.setEnumerable(false); 199 descriptor.setConfigurable(true); 200 descriptor.setWritable(true); 201 bool shouldThrow = false; 202 baseObject->methodTable(vm)->defineOwnProperty(baseObject, exec, name->identifier(&vm), descriptor, shouldThrow); 203 204 JSValueRef exception = 0; 205 if (handleExceptionIfNeeded(scope, exec, &exception) == ExceptionStatus::DidThrow) 206 [context valueFromNotifyException:exception]; 189 207 } 190 208 … … 255 273 JSObjectRef method = objCCallbackFunctionForMethod(context, objcClass, protocol, isInstanceMethod, sel, types); 256 274 if (method) 257 putNonEnumerable( object, name, [JSValue valueWithJSValueRef:method inContext:context]);275 putNonEnumerable(context, object, name, [JSValue valueWithJSValueRef:method inContext:context]); 258 276 } 259 277 }); … … 485 503 JSValue* prototype = [JSValue valueWithJSValueRef:toRef(jsPrototype) inContext:context]; 486 504 JSValue* constructor = [JSValue valueWithJSValueRef:toRef(jsConstructor) inContext:context]; 487 putNonEnumerable(prototype, @"constructor", constructor); 488 putNonEnumerable(constructor, @"prototype", prototype); 505 506 putNonEnumerable(context, prototype, @"constructor", constructor); 507 putNonEnumerable(context, constructor, @"prototype", prototype); 489 508 490 509 Protocol *exportProtocol = getJSExportProtocol(); … … 512 531 JSValue *constructor = [JSValue valueWithJSValueRef:method inContext:context]; 513 532 JSValue *prototype = [JSValue valueWithNewObjectInContext:context]; 514 putNonEnumerable(con structor, @"prototype", prototype);515 putNonEnumerable( prototype, @"constructor", constructor);533 putNonEnumerable(context, constructor, @"prototype", prototype); 534 putNonEnumerable(context, prototype, @"constructor", constructor); 516 535 return toJS(method); 517 536 } -
trunk/Source/JavaScriptCore/ChangeLog
r241955 r241956 1 2019-02-22 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] putNonEnumerable in JSWrapperMap is too costly 4 https://bugs.webkit.org/show_bug.cgi?id=194935 5 6 Reviewed by Mark Lam. 7 8 When we convert Objective-C blocks to JS objects, we need to set up a corresponding function object correctly. 9 During this allocation, we call [JSValue defineProperty:descriptor] to connect a "prototype" object and "constructor" object. 10 The problem is that this API has a particularly costly implementation: 11 12 [[_context globalObject][@"Object"] invokeMethod:@"defineProperty" withArguments:@[ self, key, descriptor ]]; 13 14 This wraps each JS objects appear in this code with Objective-C wrapper. And we convert a NSDictionary to JSObject, which 15 has "writable", "enumerable", "configurable", "value" fields, and call the "defineProperty" JS function through Objective-C wrapper. 16 This allocates many Objective-C wrappers and JS objects for descriptors. Since JSC has a direct C++ API "defineOwnProperty", we should 17 bypass these Objective-C APIs and call JSC's code directly. 18 19 This patch changes `putNonEnumerable` implementation, from calling [JSValue defineProperty:descriptor] to calling JSC C++ code directly. 20 We do not change [JSValue defineProperty:descriptor] implementation for now because of two reasons. (1) This is not used in our benchmarks 21 except for this (converting an Objective-C block to a JS object) one path. And (2) even if we were to re-write [JSValue defineProperty:descriptor] 22 to be more optimized, we would still want to call the JSC C++ version of defineProperty directly here to avoid NSDictionary allocation for a descriptor. 23 24 * API/APIUtils.h: 25 (setException): 26 * API/JSWrapperMap.mm: 27 (putNonEnumerable): 28 (copyMethodsToObject): 29 (-[JSObjCClassInfo allocateConstructorAndPrototypeInContext:]): 30 (-[JSObjCClassInfo wrapperForObject:inContext:]): 31 1 32 2019-02-22 Yusuke Suzuki <ysuzuki@apple.com> 2 33
Note: See TracChangeset
for help on using the changeset viewer.