Ignore:
Timestamp:
Sep 4, 2012, 2:19:25 PM (13 years ago)
Author:
[email protected]
Message:

Improve JSC use of Strings after the UString->String change
https://bugs.webkit.org/show_bug.cgi?id=95633

Patch by Benjamin Poulain <[email protected]> on 2012-09-04
Reviewed by Geoffrey Garen.

This patch improve the use of strings in the JSC runtime.

The initialization of Identifier is left for future patches.

The improvements are the following:
-5% faster to raise one of the modified exception.
-3 times faster to execute Boolean::toString()

Most of the changes are just about using the new methods
for string literals.

With the changes, the binary on x86_64 gets 176 bytes smaller.

  • API/JSCallbackObjectFunctions.h:

(JSC::::staticFunctionGetter):
(JSC::::callbackGetter):

  • API/JSContextRef.cpp:

(JSContextCreateBacktrace):

  • API/JSObjectRef.cpp:

(JSObjectMakeFunctionWithCallback):

  • bytecode/CodeBlock.cpp:

(JSC::valueToSourceString):
(JSC::CodeBlock::nameForRegister):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::addStackTraceIfNecessary):

  • runtime/ArrayConstructor.cpp:

(JSC::constructArrayWithSizeQuirk):

  • runtime/ArrayPrototype.cpp:

(JSC::shift):
(JSC::unshift):
(JSC::arrayProtoFuncPop):
(JSC::arrayProtoFuncReverse):

  • runtime/BooleanPrototype.cpp:

(JSC::booleanProtoFuncToString): Instead of instanciating new strings, reuse the
keywords available in SmallStrings. Avoiding the creation of the JSString and StringImpl
makes the method significantly faster.

  • runtime/DateConversion.cpp:

(JSC::formatDateTime):

  • runtime/DatePrototype.cpp:

(JSC::formatLocaleDate):
(JSC::formateDateInstance):
(JSC::dateProtoFuncToISOString):
Change the way we use snprintf() for clarity and performance.

Instead of allocating one extra byte to put a zero "just in case", we use the size returned
by snprintf().
To prevent any overflow from a programming mistake, we explicitely test for overflow and
return an empty string.

(JSC::dateProtoFuncToJSON):

  • runtime/Error.cpp:

(JSC::createNotEnoughArgumentsError):
(JSC::throwTypeError):
(JSC::throwSyntaxError):

  • runtime/Error.h:

(JSC::StrictModeTypeErrorFunction::create):

  • runtime/ErrorPrototype.cpp:

(JSC::ErrorPrototype::finishCreation):
(JSC::errorProtoFuncToString):
Using a null String is correct because (8) uses jsString(), (9) tests for a length of 0.

  • runtime/ExceptionHelpers.cpp:

(JSC::InterruptedExecutionError::defaultValue):
(JSC::TerminatedExecutionError::defaultValue):
(JSC::createStackOverflowError):
(JSC::createOutOfMemoryError):

  • runtime/Executable.cpp:

(JSC::EvalExecutable::compileInternal):
(JSC::FunctionExecutable::paramString):

  • runtime/FunctionConstructor.cpp:

(JSC::constructFunction):
(JSC::constructFunctionSkippingEvalEnabledCheck):

  • runtime/FunctionPrototype.h:

(JSC::FunctionPrototype::create):
Using a null String for the name is correct because InternalFunction uses jsString()
to create the name value.

  • runtime/InternalFunction.cpp:

(JSC::InternalFunction::finishCreation):
There is no need to create an empty string for a null string, jsString() handle both
cases as empty JSString.

  • runtime/JSArray.cpp:

(JSC::reject):
(JSC::SparseArrayValueMap::put):
(JSC::JSArray::put):
(JSC::JSArray::putByIndexBeyondVectorLength):
(JSC::JSArray::putDirectIndexBeyondVectorLength):
(JSC::JSArray::setLength):
(JSC::JSArray::pop):
(JSC::JSArray::push):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::finishCreation): Same issue as InternalFunction::finishCreation.

(JSC::JSFunction::callerGetter):
(JSC::JSFunction::defineOwnProperty):

  • runtime/JSGlobalData.cpp:

(JSC::enableAssembler): Use CFSTR() instead of CFStringCreateWithCString().
CFStringCreateWithCString() copy the content and may choose to decode the data.
CFSTR() is much more efficient.

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::reset):
JSFunction uses jsString() to create the name, we can use null strings instead
of creating empty strings.

(JSC::JSGlobalObject::createThrowTypeError): ditto.

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::encode):
(JSC::decode):
(JSC::globalFuncEval):

  • runtime/JSONObject.cpp:

(JSC::Stringifier::appendStringifiedValue):
(JSC::Stringifier::Holder::appendNextProperty):
(JSC::JSONProtoFuncParse):
(JSC::JSONProtoFuncStringify):

  • runtime/JSObject.cpp:

(JSC::JSObject::put):
(JSC::JSObject::defaultValue):
(JSC::JSObject::hasInstance):
(JSC::JSObject::defineOwnProperty):

  • runtime/JSString.cpp:

Return an empty JSString to avoid the creation of a temporary empty String.

(JSC::JSRopeString::getIndexSlowCase):

  • runtime/JSString.h:

(JSC): Remove the versions of jsNontrivialString() taking a char*. All the callers
have been replaced by calls using ASCIILiteral.

  • runtime/JSValue.cpp:

(JSC::JSValue::putToPrimitive):

  • runtime/LiteralParser.cpp:

(JSC::::Lexer::lex):
(JSC::::Lexer::lexString):
(JSC::::Lexer::lexNumber):
(JSC::::parse):

  • runtime/LiteralParser.h:

(JSC::LiteralParser::getErrorMessage):

  • runtime/NumberPrototype.cpp:

(JSC::numberProtoFuncToExponential):
(JSC::numberProtoFuncToFixed):
(JSC::numberProtoFuncToPrecision):
(JSC::numberProtoFuncToString):

  • runtime/ObjectConstructor.cpp:

(JSC::objectConstructorGetPrototypeOf):
(JSC::objectConstructorGetOwnPropertyDescriptor):
(JSC::objectConstructorGetOwnPropertyNames):
(JSC::objectConstructorKeys):
(JSC::toPropertyDescriptor):
(JSC::objectConstructorDefineProperty):
(JSC::objectConstructorDefineProperties):
(JSC::objectConstructorCreate):
(JSC::objectConstructorSeal):
(JSC::objectConstructorFreeze):
(JSC::objectConstructorPreventExtensions):
(JSC::objectConstructorIsSealed):
(JSC::objectConstructorIsFrozen):
(JSC::objectConstructorIsExtensible):

  • runtime/ObjectPrototype.cpp:

(JSC::objectProtoFuncDefineGetter):
(JSC::objectProtoFuncDefineSetter):
(JSC::objectProtoFuncToString):

  • runtime/RegExpConstructor.cpp:

(JSC::constructRegExp):

  • runtime/RegExpObject.cpp:

(JSC::reject):
(JSC::regExpObjectSource):

  • runtime/RegExpPrototype.cpp:

(JSC::regExpProtoFuncCompile):

  • runtime/StringObject.cpp:

(JSC::StringObject::defineOwnProperty):

  • runtime/StringPrototype.cpp:

(JSC::jsSpliceSubstrings):
(JSC::jsSpliceSubstringsWithSeparators):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r127191 r127505  
    183183            if (prototype.isNull()) {
    184184                if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode())
    185                     throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
     185                    throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError));
    186186                return;
    187187            }
     
    196196            if (attributes & ReadOnly) {
    197197                if (slot.isStrictMode())
    198                     throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
     198                    throwError(exec, createTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)));
    199199                return;
    200200            }
     
    205205                if (!setterFunc) {
    206206                    if (slot.isStrictMode())
    207                         throwError(exec, createTypeError(exec, "setting a property that has only a getter"));
     207                        throwError(exec, createTypeError(exec, ASCIILiteral("setting a property that has only a getter")));
    208208                    return;
    209209                }
     
    230230   
    231231    if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode())
    232         throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
     232        throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError));
    233233    return;
    234234}
     
    390390    ASSERT(!exec->hadException());
    391391
    392     return throwError(exec, createTypeError(exec, "No default value"));
     392    return throwError(exec, createTypeError(exec, ASCIILiteral("No default value")));
    393393}
    394394
     
    410410
    411411    if (!proto.isObject()) {
    412         throwError(exec, createTypeError(exec, "instanceof called on an object with an invalid prototype property."));
     412        throwError(exec, createTypeError(exec, ASCIILiteral("instanceof called on an object with an invalid prototype property.")));
    413413        return false;
    414414    }
     
    719719        if (!object->isExtensible()) {
    720720            if (throwException)
    721                 throwError(exec, createTypeError(exec, "Attempting to define property on object that is not extensible."));
     721                throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible.")));
    722722            return false;
    723723        }
     
    737737        if (descriptor.configurable()) {
    738738            if (throwException)
    739                 throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property."));
     739                throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
    740740            return false;
    741741        }
    742742        if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) {
    743743            if (throwException)
    744                 throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property."));
     744                throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
    745745            return false;
    746746        }
     
    760760        if (!current.configurable()) {
    761761            if (throwException)
    762                 throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property."));
     762                throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
    763763            return false;
    764764        }
     
    772772            if (!current.writable() && descriptor.writable()) {
    773773                if (throwException)
    774                     throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property."));
     774                    throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
    775775                return false;
    776776            }
     
    778778                if (descriptor.value() && !sameValue(exec, current.value(), descriptor.value())) {
    779779                    if (throwException)
    780                         throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property."));
     780                        throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
    781781                    return false;
    782782                }
     
    794794        if (descriptor.setterPresent() && !(current.setterPresent() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) {
    795795            if (throwException)
    796                 throwError(exec, createTypeError(exec, "Attempting to change the setter of an unconfigurable property."));
     796                throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change the setter of an unconfigurable property.")));
    797797            return false;
    798798        }
    799799        if (descriptor.getterPresent() && !(current.getterPresent() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) {
    800800            if (throwException)
    801                 throwError(exec, createTypeError(exec, "Attempting to change the getter of an unconfigurable property."));
     801                throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change the getter of an unconfigurable property.")));
    802802            return false;
    803803        }
Note: See TracChangeset for help on using the changeset viewer.