source: webkit/trunk/JavaScriptCore/runtime/Structure.cpp@ 40055

Last change on this file since 40055 was 40046, checked in by [email protected], 16 years ago

JavaScriptCore:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • API/JSCallbackFunction.cpp: (JSC::JSCallbackFunction::call):
  • API/JSCallbackObjectFunctions.h: (JSC::::call): (JSC::::toNumber): (JSC::::toString):
  • API/JSObjectRef.cpp: (JSObjectSetPrototype):
  • API/JSValueRef.cpp: (JSValueGetType): (JSValueIsUndefined): (JSValueIsNull): (JSValueIsBoolean): (JSValueIsNumber): (JSValueIsString): (JSValueIsObject): (JSValueIsObjectOfClass): (JSValueToBoolean): (JSValueToNumber): (JSValueToStringCopy): (JSValueToObject):
  • bytecode/CodeBlock.cpp: (JSC::valueToSourceString): (JSC::CodeBlock::mark):
  • bytecode/CodeBlock.h: (JSC::CodeBlock::isKnownNotImmediate):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitEqualityOp): (JSC::keyForImmediateSwitch):
  • interpreter/Interpreter.cpp: (JSC::jsLess): (JSC::jsLessEq): (JSC::jsAddSlowCase): (JSC::jsAdd): (JSC::jsTypeStringForValue): (JSC::jsIsObjectType): (JSC::jsIsFunctionType): (JSC::isNotObject): (JSC::Interpreter::callEval): (JSC::Interpreter::throwException): (JSC::cachePrototypeChain): (JSC::Interpreter::tryCachePutByID): (JSC::countPrototypeChainEntriesAndCheckForProxies): (JSC::Interpreter::tryCacheGetByID): (JSC::Interpreter::privateExecute): (JSC::Interpreter::tryCTICachePutByID): (JSC::Interpreter::tryCTICacheGetByID): (JSC::Interpreter::cti_op_convert_this): (JSC::Interpreter::cti_op_add): (JSC::Interpreter::cti_op_pre_inc): (JSC::Interpreter::cti_op_put_by_id_generic): (JSC::Interpreter::cti_op_get_by_id_generic): (JSC::Interpreter::cti_op_put_by_id): (JSC::Interpreter::cti_op_put_by_id_second): (JSC::Interpreter::cti_op_put_by_id_fail): (JSC::Interpreter::cti_op_get_by_id): (JSC::Interpreter::cti_op_get_by_id_second): (JSC::Interpreter::cti_op_get_by_id_self_fail): (JSC::Interpreter::cti_op_get_by_id_proto_list): (JSC::Interpreter::cti_op_get_by_id_proto_list_full): (JSC::Interpreter::cti_op_get_by_id_proto_fail): (JSC::Interpreter::cti_op_get_by_id_array_fail): (JSC::Interpreter::cti_op_get_by_id_string_fail): (JSC::Interpreter::cti_op_instanceof): (JSC::Interpreter::cti_op_del_by_id): (JSC::Interpreter::cti_op_mul): (JSC::Interpreter::cti_op_call_JSFunction): (JSC::Interpreter::cti_op_call_NotJSFunction): (JSC::Interpreter::cti_op_construct_JSConstruct): (JSC::Interpreter::cti_op_construct_NotJSConstruct): (JSC::Interpreter::cti_op_get_by_val): (JSC::Interpreter::cti_op_get_by_val_byte_array): (JSC::Interpreter::cti_op_sub): (JSC::Interpreter::cti_op_put_by_val): (JSC::Interpreter::cti_op_put_by_val_array): (JSC::Interpreter::cti_op_put_by_val_byte_array): (JSC::Interpreter::cti_op_loop_if_true): (JSC::Interpreter::cti_op_negate): (JSC::Interpreter::cti_op_div): (JSC::Interpreter::cti_op_pre_dec): (JSC::Interpreter::cti_op_not): (JSC::Interpreter::cti_op_jtrue): (JSC::Interpreter::cti_op_post_inc): (JSC::Interpreter::cti_op_lshift): (JSC::Interpreter::cti_op_bitand): (JSC::Interpreter::cti_op_rshift): (JSC::Interpreter::cti_op_bitnot): (JSC::Interpreter::cti_op_mod): (JSC::Interpreter::cti_op_post_dec): (JSC::Interpreter::cti_op_urshift): (JSC::Interpreter::cti_op_bitxor): (JSC::Interpreter::cti_op_bitor): (JSC::Interpreter::cti_op_push_scope): (JSC::Interpreter::cti_op_is_undefined): (JSC::Interpreter::cti_op_is_boolean): (JSC::Interpreter::cti_op_is_number): (JSC::Interpreter::cti_op_to_jsnumber): (JSC::Interpreter::cti_op_in): (JSC::Interpreter::cti_op_put_by_index): (JSC::Interpreter::cti_op_switch_imm): (JSC::Interpreter::cti_op_switch_char): (JSC::Interpreter::cti_op_switch_string): (JSC::Interpreter::cti_op_del_by_val): (JSC::Interpreter::cti_op_put_getter): (JSC::Interpreter::cti_op_put_setter): (JSC::Interpreter::cti_op_new_error):
  • interpreter/Interpreter.h: (JSC::Interpreter::isJSArray): (JSC::Interpreter::isJSString): (JSC::Interpreter::isJSByteArray):
  • interpreter/Register.h: (JSC::Register::marked): (JSC::Register::mark):
  • jit/JITInlineMethods.h: (JSC::JIT::getConstantOperandImmediateInt): (JSC::JIT::isOperandConstantImmediateInt):
  • jsc.cpp: (functionPrint): (functionDebug): (functionRun): (functionLoad): (runWithScripts): (runInteractive):
  • parser/Nodes.cpp: (JSC::processClauseList):
  • profiler/ProfileGenerator.cpp: (JSC::ProfileGenerator::addParentForConsoleStart):
  • profiler/Profiler.cpp: (JSC::Profiler::createCallIdentifier):
  • runtime/ArrayConstructor.cpp: (JSC::constructArrayWithSizeQuirk):
  • runtime/ArrayPrototype.cpp: (JSC::arrayProtoFuncToString): (JSC::arrayProtoFuncToLocaleString): (JSC::arrayProtoFuncJoin): (JSC::arrayProtoFuncConcat): (JSC::arrayProtoFuncPop): (JSC::arrayProtoFuncPush): (JSC::arrayProtoFuncReverse): (JSC::arrayProtoFuncShift): (JSC::arrayProtoFuncSlice): (JSC::arrayProtoFuncSort): (JSC::arrayProtoFuncSplice): (JSC::arrayProtoFuncUnShift): (JSC::arrayProtoFuncFilter): (JSC::arrayProtoFuncMap): (JSC::arrayProtoFuncEvery): (JSC::arrayProtoFuncForEach): (JSC::arrayProtoFuncSome): (JSC::arrayProtoFuncIndexOf): (JSC::arrayProtoFuncLastIndexOf):
  • runtime/BooleanConstructor.cpp: (JSC::constructBoolean): (JSC::callBooleanConstructor):
  • runtime/BooleanPrototype.cpp: (JSC::booleanProtoFuncToString): (JSC::booleanProtoFuncValueOf):
  • runtime/Collector.cpp: (JSC::Heap::protect): (JSC::Heap::unprotect): (JSC::Heap::heap): (JSC::Heap::collect): (JSC::typeName):
  • runtime/Completion.cpp: (JSC::evaluate):
  • runtime/DateConstructor.cpp: (JSC::constructDate): (JSC::dateParse): (JSC::dateUTC):
  • runtime/DateInstance.h: (JSC::DateInstance::internalNumber):
  • runtime/DatePrototype.cpp: (JSC::formatLocaleDate): (JSC::fillStructuresUsingTimeArgs): (JSC::fillStructuresUsingDateArgs): (JSC::dateProtoFuncToString): (JSC::dateProtoFuncToUTCString): (JSC::dateProtoFuncToDateString): (JSC::dateProtoFuncToTimeString): (JSC::dateProtoFuncToLocaleString): (JSC::dateProtoFuncToLocaleDateString): (JSC::dateProtoFuncToLocaleTimeString): (JSC::dateProtoFuncGetTime): (JSC::dateProtoFuncGetFullYear): (JSC::dateProtoFuncGetUTCFullYear): (JSC::dateProtoFuncToGMTString): (JSC::dateProtoFuncGetMonth): (JSC::dateProtoFuncGetUTCMonth): (JSC::dateProtoFuncGetDate): (JSC::dateProtoFuncGetUTCDate): (JSC::dateProtoFuncGetDay): (JSC::dateProtoFuncGetUTCDay): (JSC::dateProtoFuncGetHours): (JSC::dateProtoFuncGetUTCHours): (JSC::dateProtoFuncGetMinutes): (JSC::dateProtoFuncGetUTCMinutes): (JSC::dateProtoFuncGetSeconds): (JSC::dateProtoFuncGetUTCSeconds): (JSC::dateProtoFuncGetMilliSeconds): (JSC::dateProtoFuncGetUTCMilliseconds): (JSC::dateProtoFuncGetTimezoneOffset): (JSC::dateProtoFuncSetTime): (JSC::setNewValueFromTimeArgs): (JSC::setNewValueFromDateArgs): (JSC::dateProtoFuncSetYear): (JSC::dateProtoFuncGetYear):
  • runtime/ErrorConstructor.cpp: (JSC::constructError):
  • runtime/ErrorPrototype.cpp: (JSC::errorProtoFuncToString):
  • runtime/ExceptionHelpers.cpp: (JSC::createError): (JSC::createErrorMessage):
  • runtime/FunctionConstructor.cpp: (JSC::constructFunction):
  • runtime/FunctionPrototype.cpp: (JSC::functionProtoFuncToString): (JSC::functionProtoFuncApply): (JSC::functionProtoFuncCall):
  • runtime/GetterSetter.cpp: (JSC::GetterSetter::toObject):
  • runtime/JSActivation.cpp: (JSC::JSActivation::getOwnPropertySlot):
  • runtime/JSArray.cpp: (JSC::JSArray::put): (JSC::JSArray::mark): (JSC::JSArray::sort): (JSC::AVLTreeAbstractorForArrayCompare::compare_key_key): (JSC::JSArray::compactForSorting):
  • runtime/JSByteArray.h: (JSC::JSByteArray::setIndex):
  • runtime/JSCell.h: (JSC::asCell):
  • runtime/JSFunction.cpp: (JSC::JSFunction::call): (JSC::JSFunction::construct):
  • runtime/JSGlobalObject.cpp: (JSC::markIfNeeded): (JSC::lastInPrototypeChain):
  • runtime/JSGlobalObjectFunctions.cpp: (JSC::encode): (JSC::decode): (JSC::globalFuncEval): (JSC::globalFuncParseInt): (JSC::globalFuncParseFloat): (JSC::globalFuncIsNaN): (JSC::globalFuncIsFinite): (JSC::globalFuncEscape): (JSC::globalFuncUnescape): (JSC::globalFuncJSCPrint):
  • runtime/JSImmediate.cpp: (JSC::JSImmediate::toThisObject): (JSC::JSImmediate::toObject): (JSC::JSImmediate::prototype): (JSC::JSImmediate::toString):
  • runtime/JSImmediate.h:
  • runtime/JSObject.cpp: (JSC::JSObject::mark): (JSC::JSObject::put): (JSC::callDefaultValueFunction): (JSC::JSObject::getPrimitiveNumber): (JSC::JSObject::defineGetter): (JSC::JSObject::defineSetter): (JSC::JSObject::lookupGetter): (JSC::JSObject::lookupSetter): (JSC::JSObject::hasInstance): (JSC::JSObject::toNumber): (JSC::JSObject::toString):
  • runtime/JSObject.h: (JSC::JSObject::JSObject): (JSC::JSObject::inlineGetOwnPropertySlot): (JSC::JSObject::getOwnPropertySlotForWrite): (JSC::JSObject::getPropertySlot): (JSC::JSValuePtr::get):
  • runtime/JSPropertyNameIterator.h: (JSC::JSPropertyNameIterator::create):
  • runtime/JSString.cpp: (JSC::JSString::getOwnPropertySlot):
  • runtime/JSValue.h:
  • runtime/JSWrapperObject.cpp: (JSC::JSWrapperObject::mark):
  • runtime/JSWrapperObject.h: (JSC::JSWrapperObject::setInternalValue):
  • runtime/MathObject.cpp: (JSC::mathProtoFuncAbs): (JSC::mathProtoFuncACos): (JSC::mathProtoFuncASin): (JSC::mathProtoFuncATan): (JSC::mathProtoFuncATan2): (JSC::mathProtoFuncCeil): (JSC::mathProtoFuncCos): (JSC::mathProtoFuncExp): (JSC::mathProtoFuncFloor): (JSC::mathProtoFuncLog): (JSC::mathProtoFuncMax): (JSC::mathProtoFuncMin): (JSC::mathProtoFuncPow): (JSC::mathProtoFuncRound): (JSC::mathProtoFuncSin): (JSC::mathProtoFuncSqrt): (JSC::mathProtoFuncTan):
  • runtime/NativeErrorConstructor.cpp: (JSC::NativeErrorConstructor::NativeErrorConstructor): (JSC::NativeErrorConstructor::construct):
  • runtime/NumberConstructor.cpp: (JSC::constructWithNumberConstructor): (JSC::callNumberConstructor):
  • runtime/NumberPrototype.cpp: (JSC::numberProtoFuncToString): (JSC::numberProtoFuncToLocaleString): (JSC::numberProtoFuncValueOf): (JSC::numberProtoFuncToFixed): (JSC::numberProtoFuncToExponential): (JSC::numberProtoFuncToPrecision):
  • runtime/ObjectConstructor.cpp: (JSC::constructObject):
  • runtime/ObjectPrototype.cpp: (JSC::objectProtoFuncValueOf): (JSC::objectProtoFuncHasOwnProperty): (JSC::objectProtoFuncIsPrototypeOf): (JSC::objectProtoFuncDefineGetter): (JSC::objectProtoFuncDefineSetter): (JSC::objectProtoFuncLookupGetter): (JSC::objectProtoFuncLookupSetter): (JSC::objectProtoFuncPropertyIsEnumerable): (JSC::objectProtoFuncToLocaleString): (JSC::objectProtoFuncToString):
  • runtime/Operations.h: (JSC::JSValuePtr::equalSlowCaseInline): (JSC::JSValuePtr::strictEqual): (JSC::JSValuePtr::strictEqualSlowCaseInline):
  • runtime/Protect.h: (JSC::gcProtect): (JSC::gcUnprotect):
  • runtime/RegExpConstructor.cpp: (JSC::setRegExpConstructorInput): (JSC::setRegExpConstructorMultiline): (JSC::constructRegExp):
  • runtime/RegExpObject.cpp: (JSC::setRegExpObjectLastIndex): (JSC::RegExpObject::match):
  • runtime/RegExpPrototype.cpp: (JSC::regExpProtoFuncTest): (JSC::regExpProtoFuncExec): (JSC::regExpProtoFuncCompile): (JSC::regExpProtoFuncToString):
  • runtime/StringConstructor.cpp: (JSC::stringFromCharCodeSlowCase): (JSC::stringFromCharCode): (JSC::constructWithStringConstructor): (JSC::callStringConstructor):
  • runtime/StringPrototype.cpp: (JSC::stringProtoFuncReplace): (JSC::stringProtoFuncToString): (JSC::stringProtoFuncCharAt): (JSC::stringProtoFuncCharCodeAt): (JSC::stringProtoFuncConcat): (JSC::stringProtoFuncIndexOf): (JSC::stringProtoFuncLastIndexOf): (JSC::stringProtoFuncMatch): (JSC::stringProtoFuncSearch): (JSC::stringProtoFuncSlice): (JSC::stringProtoFuncSplit): (JSC::stringProtoFuncSubstr): (JSC::stringProtoFuncSubstring): (JSC::stringProtoFuncToLowerCase): (JSC::stringProtoFuncToUpperCase): (JSC::stringProtoFuncLocaleCompare): (JSC::stringProtoFuncBig): (JSC::stringProtoFuncSmall): (JSC::stringProtoFuncBlink): (JSC::stringProtoFuncBold): (JSC::stringProtoFuncFixed): (JSC::stringProtoFuncItalics): (JSC::stringProtoFuncStrike): (JSC::stringProtoFuncSub): (JSC::stringProtoFuncSup): (JSC::stringProtoFuncFontcolor): (JSC::stringProtoFuncFontsize): (JSC::stringProtoFuncAnchor): (JSC::stringProtoFuncLink):
  • runtime/Structure.cpp: (JSC::Structure::Structure): (JSC::Structure::getEnumerablePropertyNames): (JSC::Structure::createCachedPrototypeChain):
  • runtime/Structure.h: (JSC::Structure::mark):
  • runtime/StructureChain.cpp: (JSC::StructureChain::StructureChain):

JavaScriptGlue:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • JSUtils.cpp: (KJSValueToJSObject): (KJSValueToCFTypeInternal):
  • JSValueWrapper.cpp: (JSValueWrapper::JSObjectCopyPropertyNames): (JSValueWrapper::JSObjectCopyProperty): (JSValueWrapper::JSObjectSetProperty): (JSValueWrapper::JSObjectCallFunction): (JSValueWrapper::JSObjectMark):
  • UserObjectImp.cpp: (UserObjectImp::getOwnPropertySlot):

WebCore:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • WebCore.xcodeproj/project.pbxproj:
  • bindings/js/JSAudioConstructor.cpp: (WebCore::constructAudio):
  • bindings/js/JSCanvasRenderingContext2DCustom.cpp: (WebCore::toHTMLCanvasStyle): (WebCore::JSCanvasRenderingContext2D::setFillColor): (WebCore::JSCanvasRenderingContext2D::setStrokeColor): (WebCore::JSCanvasRenderingContext2D::strokeRect): (WebCore::JSCanvasRenderingContext2D::drawImage): (WebCore::JSCanvasRenderingContext2D::drawImageFromRect): (WebCore::JSCanvasRenderingContext2D::setShadow): (WebCore::JSCanvasRenderingContext2D::createPattern): (WebCore::JSCanvasRenderingContext2D::putImageData): (WebCore::JSCanvasRenderingContext2D::fillText): (WebCore::JSCanvasRenderingContext2D::strokeText):
  • bindings/js/JSClipboardCustom.cpp: (WebCore::JSClipboard::clearData): (WebCore::JSClipboard::getData): (WebCore::JSClipboard::setData): (WebCore::JSClipboard::setDragImage):
  • bindings/js/JSCustomPositionCallback.cpp: (WebCore::JSCustomPositionCallback::handleEvent):
  • bindings/js/JSCustomPositionErrorCallback.cpp: (WebCore::JSCustomPositionErrorCallback::handleEvent):
  • bindings/js/JSCustomSQLStatementCallback.cpp: (WebCore::JSCustomSQLStatementCallback::handleEvent):
  • bindings/js/JSCustomSQLStatementErrorCallback.cpp: (WebCore::JSCustomSQLStatementErrorCallback::handleEvent):
  • bindings/js/JSCustomSQLTransactionCallback.cpp: (WebCore::JSCustomSQLTransactionCallback::handleEvent):
  • bindings/js/JSCustomSQLTransactionErrorCallback.cpp: (WebCore::JSCustomSQLTransactionErrorCallback::handleEvent):
  • bindings/js/JSCustomVoidCallback.cpp: (WebCore::JSCustomVoidCallback::handleEvent): (WebCore::toVoidCallback):
  • bindings/js/JSCustomXPathNSResolver.cpp: (WebCore::JSCustomXPathNSResolver::create): (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
  • bindings/js/JSDOMApplicationCacheCustom.cpp: (WebCore::JSDOMApplicationCache::hasItem): (WebCore::JSDOMApplicationCache::add): (WebCore::JSDOMApplicationCache::remove): (WebCore::JSDOMApplicationCache::addEventListener): (WebCore::JSDOMApplicationCache::removeEventListener):
  • bindings/js/JSDOMBinding.cpp: (WebCore::valueToStringWithNullCheck): (WebCore::valueToStringWithUndefinedOrNullCheck): (WebCore::reportException):
  • bindings/js/JSDOMGlobalObject.cpp: (WebCore::JSDOMGlobalObject::findJSEventListener): (WebCore::JSDOMGlobalObject::findOrCreateJSEventListener): (WebCore::JSDOMGlobalObject::findJSUnprotectedEventListener): (WebCore::JSDOMGlobalObject::findOrCreateJSUnprotectedEventListener):
  • bindings/js/JSDOMStringListCustom.cpp: (WebCore::JSDOMStringList::item):
  • bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::getOwnPropertySlot): (windowProtoFuncOpen): (WebCore::toJSDOMWindow):
  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::setLocation): (WebCore::JSDOMWindow::postMessage): (WebCore::setTimeoutOrInterval): (WebCore::JSDOMWindow::clearTimeout): (WebCore::JSDOMWindow::clearInterval): (WebCore::JSDOMWindow::atob): (WebCore::JSDOMWindow::btoa): (WebCore::JSDOMWindow::addEventListener): (WebCore::JSDOMWindow::removeEventListener): (WebCore::toDOMWindow):
  • bindings/js/JSDatabaseCustom.cpp: (WebCore::JSDatabase::changeVersion): (WebCore::JSDatabase::transaction):
  • bindings/js/JSDocumentCustom.cpp: (WebCore::JSDocument::setLocation):
  • bindings/js/JSElementCustom.cpp: (WebCore::JSElement::setAttribute): (WebCore::JSElement::setAttributeNS):
  • bindings/js/JSEventListener.cpp: (WebCore::JSAbstractEventListener::handleEvent): (WebCore::JSLazyEventListener::parseCode):
  • bindings/js/JSEventTargetNodeCustom.cpp: (WebCore::JSEventTargetNode::addEventListener): (WebCore::JSEventTargetNode::removeEventListener):
  • bindings/js/JSGeolocationCustom.cpp: (WebCore::createPositionOptions): (WebCore::JSGeolocation::getCurrentPosition): (WebCore::JSGeolocation::watchPosition):
  • bindings/js/JSHTMLCollectionCustom.cpp: (WebCore::callHTMLCollection): (WebCore::JSHTMLCollection::canGetItemsForName): (WebCore::JSHTMLCollection::item): (WebCore::JSHTMLCollection::namedItem):
  • bindings/js/JSHTMLDocumentCustom.cpp: (WebCore::JSHTMLDocument::open): (WebCore::writeHelper):
  • bindings/js/JSHTMLOptionsCollectionCustom.cpp: (WebCore::JSHTMLOptionsCollection::setLength): (WebCore::JSHTMLOptionsCollection::add):
  • bindings/js/JSHTMLSelectElementCustom.cpp: (WebCore::JSHTMLSelectElement::remove): (WebCore::selectIndexSetter):
  • bindings/js/JSImageConstructor.cpp: (WebCore::constructImage):
  • bindings/js/JSInspectedObjectWrapper.cpp: (WebCore::JSInspectedObjectWrapper::wrap): (WebCore::JSInspectedObjectWrapper::prepareIncomingValue):
  • bindings/js/JSInspectorCallbackWrapper.cpp: (WebCore::JSInspectorCallbackWrapper::wrap):
  • bindings/js/JSJavaScriptCallFrameCustom.cpp: (WebCore::JSJavaScriptCallFrame::evaluate):
  • bindings/js/JSLocationCustom.cpp: (WebCore::JSLocation::setHref): (WebCore::JSLocation::setProtocol): (WebCore::JSLocation::setHost): (WebCore::JSLocation::setHostname): (WebCore::JSLocation::setPort): (WebCore::JSLocation::setPathname): (WebCore::JSLocation::setSearch): (WebCore::JSLocation::setHash): (WebCore::JSLocation::replace): (WebCore::JSLocation::assign):
  • bindings/js/JSMessageChannelConstructor.cpp: (WebCore::JSMessageChannelConstructor::mark):
  • bindings/js/JSMessagePortCustom.cpp: (WebCore::JSMessagePort::startConversation): (WebCore::JSMessagePort::addEventListener): (WebCore::JSMessagePort::removeEventListener):
  • bindings/js/JSNodeFilterCondition.cpp: (WebCore::JSNodeFilterCondition::mark): (WebCore::JSNodeFilterCondition::acceptNode):
  • bindings/js/JSNodeFilterCondition.h:
  • bindings/js/JSNodeFilterCustom.cpp: (WebCore::toNodeFilter):
  • bindings/js/JSNodeListCustom.cpp: (WebCore::callNodeList):
  • bindings/js/JSOptionConstructor.cpp: (WebCore::constructHTMLOptionElement):
  • bindings/js/JSQuarantinedObjectWrapper.cpp: (WebCore::JSQuarantinedObjectWrapper::asWrapper): (WebCore::JSQuarantinedObjectWrapper::construct):
  • bindings/js/JSSQLResultSetRowListCustom.cpp: (WebCore::JSSQLResultSetRowList::item):
  • bindings/js/JSSQLTransactionCustom.cpp: (WebCore::JSSQLTransaction::executeSql):
  • bindings/js/JSSVGElementInstanceCustom.cpp: (WebCore::JSSVGElementInstance::addEventListener): (WebCore::JSSVGElementInstance::removeEventListener):
  • bindings/js/JSSVGLengthCustom.cpp: (WebCore::JSSVGLength::convertToSpecifiedUnits):
  • bindings/js/JSSVGMatrixCustom.cpp: (WebCore::JSSVGMatrix::translate): (WebCore::JSSVGMatrix::scale): (WebCore::JSSVGMatrix::scaleNonUniform): (WebCore::JSSVGMatrix::rotate): (WebCore::JSSVGMatrix::rotateFromVector): (WebCore::JSSVGMatrix::skewX): (WebCore::JSSVGMatrix::skewY):
  • bindings/js/JSSVGPathSegListCustom.cpp: (WebCore::JSSVGPathSegList::getItem): (WebCore::JSSVGPathSegList::insertItemBefore): (WebCore::JSSVGPathSegList::replaceItem): (WebCore::JSSVGPathSegList::removeItem):
  • bindings/js/JSSVGPointListCustom.cpp: (WebCore::JSSVGPointList::getItem): (WebCore::JSSVGPointList::insertItemBefore): (WebCore::JSSVGPointList::replaceItem): (WebCore::JSSVGPointList::removeItem):
  • bindings/js/JSSVGTransformListCustom.cpp: (WebCore::JSSVGTransformList::getItem): (WebCore::JSSVGTransformList::insertItemBefore): (WebCore::JSSVGTransformList::replaceItem): (WebCore::JSSVGTransformList::removeItem):
  • bindings/js/JSStorageCustom.cpp: (WebCore::JSStorage::deleteProperty): (WebCore::JSStorage::customPut):
  • bindings/js/JSWebKitCSSMatrixConstructor.cpp: (WebCore::constructWebKitCSSMatrix):
  • bindings/js/JSWorkerConstructor.cpp: (WebCore::constructWorker):
  • bindings/js/JSWorkerContextCustom.cpp: (WebCore::JSWorkerContext::addEventListener): (WebCore::JSWorkerContext::removeEventListener):
  • bindings/js/JSWorkerCustom.cpp: (WebCore::JSWorker::addEventListener): (WebCore::JSWorker::removeEventListener):
  • bindings/js/JSXMLHttpRequestCustom.cpp: (WebCore::JSXMLHttpRequest::open): (WebCore::JSXMLHttpRequest::setRequestHeader): (WebCore::JSXMLHttpRequest::send): (WebCore::JSXMLHttpRequest::getResponseHeader): (WebCore::JSXMLHttpRequest::overrideMimeType): (WebCore::JSXMLHttpRequest::addEventListener): (WebCore::JSXMLHttpRequest::removeEventListener):
  • bindings/js/JSXMLHttpRequestUploadCustom.cpp: (WebCore::JSXMLHttpRequestUpload::addEventListener): (WebCore::JSXMLHttpRequestUpload::removeEventListener):
  • bindings/js/JSXSLTProcessorCustom.cpp: (WebCore::JSXSLTProcessor::importStylesheet): (WebCore::JSXSLTProcessor::transformToFragment): (WebCore::JSXSLTProcessor::transformToDocument): (WebCore::JSXSLTProcessor::setParameter): (WebCore::JSXSLTProcessor::getParameter): (WebCore::JSXSLTProcessor::removeParameter):
  • bindings/js/ScheduledAction.cpp: (WebCore::ScheduledAction::executeFunctionInContext):
  • bindings/js/ScriptCallStack.cpp: (WebCore::ScriptCallStack::initialize):
  • bindings/js/ScriptController.cpp: (WebCore::ScriptController::createScriptObjectForPluginElement):
  • bindings/js/ScriptValue.cpp: (WebCore::ScriptValue::getString): (WebCore::ScriptValue::isNull): (WebCore::ScriptValue::isUndefined):
  • bindings/objc/WebScriptObject.mm: (-[WebScriptObject callWebScriptMethod:withArguments:]): (+[WebScriptObject _convertValueToObjcValue:originRootObject:rootObject:]):
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/NP_jsobject.cpp: (_NPN_InvokeDefault): (_NPN_Invoke): (_NPN_HasMethod): (_NPN_Construct):
  • bridge/c/c_utility.cpp: (JSC::Bindings::convertValueToNPVariant):
  • bridge/jni/jni_instance.cpp: (JavaInstance::invokeMethod):
  • bridge/jni/jni_jsobject.mm: (JavaJSObject::call): (JavaJSObject::convertValueToJObject):
  • bridge/jni/jni_runtime.cpp: (JavaField::dispatchValueFromInstance): (JavaField::valueFromInstance): (JavaField::dispatchSetValueToInstance): (JavaField::setValueToInstance):
  • bridge/jni/jni_utility.cpp: (JSC::Bindings::convertArrayInstanceToJavaArray): (JSC::Bindings::convertValueToJValue):
  • bridge/objc/objc_runtime.mm: (JSC::Bindings::callObjCFallbackObject):
  • bridge/objc/objc_utility.mm: (JSC::Bindings::convertValueToObjcValue):
  • bridge/runtime_method.cpp: (JSC::callRuntimeMethod):
  • bridge/runtime_object.cpp: (JSC::RuntimeObjectImp::getOwnPropertySlot): (JSC::callRuntimeConstructor):

WebKit/mac:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • Plugins/Hosted/NetscapePluginInstanceProxy.mm: (WebKit::NetscapePluginInstanceProxy::invoke): (WebKit::NetscapePluginInstanceProxy::hasMethod): (WebKit::NetscapePluginInstanceProxy::marshalValue):
  • WebView/WebFrame.mm: (-[WebFrame _stringByEvaluatingJavaScriptFromString:forceUserGesture:]):
  • WebView/WebView.mm: (aeDescFromJSValue):

WebKit/win:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • WebScriptCallFrame.cpp: (WebScriptCallFrame::jsValueToString):
  • WebView.cpp: (WebView::stringByEvaluatingJavaScriptFromString):

WebKit/wx:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • WebFrame.cpp: (wxWebFrame::RunScript):
File size: 33.6 KB
Line 
1/*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "Structure.h"
28
29#include "Identifier.h"
30#include "JSObject.h"
31#include "PropertyNameArray.h"
32#include "StructureChain.h"
33#include "Lookup.h"
34#include <wtf/RefCountedLeakCounter.h>
35#include <wtf/RefPtr.h>
36
37#if ENABLE(JSC_MULTIPLE_THREADS)
38#include <wtf/Threading.h>
39#endif
40
41#define DUMP_STRUCTURE_ID_STATISTICS 0
42
43#ifndef NDEBUG
44#define DO_PROPERTYMAP_CONSTENCY_CHECK 0
45#else
46#define DO_PROPERTYMAP_CONSTENCY_CHECK 0
47#endif
48
49using namespace std;
50using namespace WTF;
51
52namespace JSC {
53
54// Choose a number for the following so that most property maps are smaller,
55// but it's not going to blow out the stack to allocate this number of pointers.
56static const int smallMapThreshold = 1024;
57
58// The point at which the function call overhead of the qsort implementation
59// becomes small compared to the inefficiency of insertion sort.
60static const unsigned tinyMapThreshold = 20;
61
62static const unsigned newTableSize = 16;
63
64#ifndef NDEBUG
65static WTF::RefCountedLeakCounter structureCounter("Structure");
66
67#if ENABLE(JSC_MULTIPLE_THREADS)
68static Mutex ignoreSetMutex;
69#endif
70
71static bool shouldIgnoreLeaks;
72static HashSet<Structure*> ignoreSet;
73#endif
74
75#if DUMP_STRUCTURE_ID_STATISTICS
76static HashSet<Structure*> liveStructureSet;
77#endif
78
79void Structure::dumpStatistics()
80{
81#if DUMP_STRUCTURE_ID_STATISTICS
82 unsigned numberLeaf = 0;
83 unsigned numberUsingSingleSlot = 0;
84 unsigned numberSingletons = 0;
85 unsigned numberWithPropertyMaps = 0;
86 unsigned totalPropertyMapsSize = 0;
87
88 HashSet<Structure*>::const_iterator end = liveStructureSet.end();
89 for (HashSet<Structure*>::const_iterator it = liveStructureSet.begin(); it != end; ++it) {
90 Structure* structure = *it;
91 if (structure->m_usingSingleTransitionSlot) {
92 if (!structure->m_transitions.singleTransition)
93 ++numberLeaf;
94 else
95 ++numberUsingSingleSlot;
96
97 if (!structure->m_previous && !structure->m_transitions.singleTransition)
98 ++numberSingletons;
99 }
100
101 if (structure->m_propertyTable) {
102 ++numberWithPropertyMaps;
103 totalPropertyMapsSize += PropertyMapHashTable::allocationSize(structure->m_propertyTable->size);
104 if (structure->m_propertyTable->deletedOffsets)
105 totalPropertyMapsSize += (structure->m_propertyTable->deletedOffsets->capacity() * sizeof(unsigned));
106 }
107 }
108
109 printf("Number of live Structures: %d\n", liveStructureSet.size());
110 printf("Number of Structures using the single item optimization for transition map: %d\n", numberUsingSingleSlot);
111 printf("Number of Structures that are leaf nodes: %d\n", numberLeaf);
112 printf("Number of Structures that singletons: %d\n", numberSingletons);
113 printf("Number of Structures with PropertyMaps: %d\n", numberWithPropertyMaps);
114
115 printf("Size of a single Structures: %d\n", static_cast<unsigned>(sizeof(Structure)));
116 printf("Size of sum of all property maps: %d\n", totalPropertyMapsSize);
117 printf("Size of average of all property maps: %f\n", static_cast<double>(totalPropertyMapsSize) / static_cast<double>(liveStructureSet.size()));
118#else
119 printf("Dumping Structure statistics is not enabled.\n");
120#endif
121}
122
123Structure::Structure(JSValuePtr prototype, const TypeInfo& typeInfo)
124 : m_typeInfo(typeInfo)
125 , m_prototype(prototype)
126 , m_cachedPrototypeChain(0)
127 , m_previous(0)
128 , m_nameInPrevious(0)
129 , m_propertyTable(0)
130 , m_propertyStorageCapacity(JSObject::inlineStorageCapacity)
131 , m_offset(noOffset)
132 , m_isDictionary(false)
133 , m_isPinnedPropertyTable(false)
134 , m_hasGetterSetterProperties(false)
135 , m_usingSingleTransitionSlot(true)
136 , m_attributesInPrevious(0)
137{
138 ASSERT(m_prototype);
139 ASSERT(m_prototype.isObject() || m_prototype.isNull());
140
141 m_transitions.singleTransition = 0;
142
143#ifndef NDEBUG
144#if ENABLE(JSC_MULTIPLE_THREADS)
145 MutexLocker protect(ignoreSetMutex);
146#endif
147 if (shouldIgnoreLeaks)
148 ignoreSet.add(this);
149 else
150 structureCounter.increment();
151#endif
152
153#if DUMP_STRUCTURE_ID_STATISTICS
154 liveStructureSet.add(this);
155#endif
156}
157
158Structure::~Structure()
159{
160 if (m_previous) {
161 if (m_previous->m_usingSingleTransitionSlot) {
162 m_previous->m_transitions.singleTransition = 0;
163 } else {
164 ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious.get(), m_attributesInPrevious)));
165 m_previous->m_transitions.table->remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious));
166 }
167 }
168
169 if (m_cachedPropertyNameArrayData)
170 m_cachedPropertyNameArrayData->setCachedStructure(0);
171
172 if (!m_usingSingleTransitionSlot)
173 delete m_transitions.table;
174
175 if (m_propertyTable) {
176 unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
177 for (unsigned i = 1; i <= entryCount; i++) {
178 if (UString::Rep* key = m_propertyTable->entries()[i].key)
179 key->deref();
180 }
181 fastFree(m_propertyTable);
182 }
183
184#ifndef NDEBUG
185#if ENABLE(JSC_MULTIPLE_THREADS)
186 MutexLocker protect(ignoreSetMutex);
187#endif
188 HashSet<Structure*>::iterator it = ignoreSet.find(this);
189 if (it != ignoreSet.end())
190 ignoreSet.remove(it);
191 else
192 structureCounter.decrement();
193#endif
194
195#if DUMP_STRUCTURE_ID_STATISTICS
196 liveStructureSet.remove(this);
197#endif
198}
199
200void Structure::startIgnoringLeaks()
201{
202#ifndef NDEBUG
203 shouldIgnoreLeaks = true;
204#endif
205}
206
207void Structure::stopIgnoringLeaks()
208{
209#ifndef NDEBUG
210 shouldIgnoreLeaks = false;
211#endif
212}
213
214static bool isPowerOf2(unsigned v)
215{
216 // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
217
218 return !(v & (v - 1)) && v;
219}
220
221static unsigned nextPowerOf2(unsigned v)
222{
223 // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
224 // Devised by Sean Anderson, Sepember 14, 2001
225
226 v--;
227 v |= v >> 1;
228 v |= v >> 2;
229 v |= v >> 4;
230 v |= v >> 8;
231 v |= v >> 16;
232 v++;
233
234 return v;
235}
236
237static unsigned sizeForKeyCount(size_t keyCount)
238{
239 if (keyCount == notFound)
240 return newTableSize;
241
242 if (keyCount < 8)
243 return newTableSize;
244
245 if (isPowerOf2(keyCount))
246 return keyCount * 4;
247
248 return nextPowerOf2(keyCount) * 2;
249}
250
251void Structure::materializePropertyMap()
252{
253 ASSERT(!m_propertyTable);
254
255 Vector<Structure*, 8> structures;
256 structures.append(this);
257
258 Structure* structure = this;
259
260 // Search for the last Structure with a property table.
261 while ((structure = structure->previousID())) {
262 if (structure->m_isPinnedPropertyTable) {
263 ASSERT(structure->m_propertyTable);
264 ASSERT(!structure->m_previous);
265
266 m_propertyTable = structure->copyPropertyTable();
267 break;
268 }
269
270 structures.append(structure);
271 }
272
273 if (!m_propertyTable)
274 createPropertyMapHashTable(sizeForKeyCount(m_offset + 1));
275 else {
276 if (sizeForKeyCount(m_offset + 1) > m_propertyTable->size)
277 rehashPropertyMapHashTable(sizeForKeyCount(m_offset + 1)); // This could be made more efficient by combining with the copy above.
278 }
279
280 for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) {
281 structure = structures[i];
282 structure->m_nameInPrevious->ref();
283 PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, ++m_propertyTable->lastIndexUsed);
284 insertIntoPropertyMapHashTable(entry);
285 }
286}
287
288void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
289{
290 bool shouldCache = propertyNames.cacheable() && !(propertyNames.size() || m_isDictionary);
291
292 if (shouldCache) {
293 if (m_cachedPropertyNameArrayData) {
294 if (structureChainsAreEqual(m_cachedPropertyNameArrayData->cachedPrototypeChain(), cachedPrototypeChain())) {
295 propertyNames.setData(m_cachedPropertyNameArrayData);
296 return;
297 }
298 }
299 propertyNames.setCacheable(false);
300 }
301
302 getEnumerablePropertyNamesInternal(propertyNames);
303
304 // Add properties from the static hashtables of properties
305 for (const ClassInfo* info = baseObject->classInfo(); info; info = info->parentClass) {
306 const HashTable* table = info->propHashTable(exec);
307 if (!table)
308 continue;
309 table->initializeIfNeeded(exec);
310 ASSERT(table->table);
311#if ENABLE(PERFECT_HASH_SIZE)
312 int hashSizeMask = table->hashSizeMask;
313#else
314 int hashSizeMask = table->compactSize - 1;
315#endif
316 const HashEntry* entry = table->table;
317 for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
318 if (entry->key() && !(entry->attributes() & DontEnum))
319 propertyNames.add(entry->key());
320 }
321 }
322
323 if (m_prototype.isObject())
324 asObject(m_prototype)->getPropertyNames(exec, propertyNames);
325
326 if (shouldCache) {
327 if (m_cachedPropertyNameArrayData)
328 m_cachedPropertyNameArrayData->setCachedStructure(0);
329
330 m_cachedPropertyNameArrayData = propertyNames.data();
331
332 StructureChain* chain = cachedPrototypeChain();
333 if (!chain)
334 chain = createCachedPrototypeChain();
335 m_cachedPropertyNameArrayData->setCachedPrototypeChain(chain);
336 m_cachedPropertyNameArrayData->setCachedStructure(this);
337 }
338}
339
340void Structure::clearEnumerationCache()
341{
342 if (m_cachedPropertyNameArrayData)
343 m_cachedPropertyNameArrayData->setCachedStructure(0);
344 m_cachedPropertyNameArrayData.clear();
345}
346
347void Structure::growPropertyStorageCapacity()
348{
349 if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity)
350 m_propertyStorageCapacity = JSObject::nonInlineBaseStorageCapacity;
351 else
352 m_propertyStorageCapacity *= 2;
353}
354
355PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset)
356{
357 ASSERT(!structure->m_isDictionary);
358 ASSERT(structure->typeInfo().type() == ObjectType);
359
360 if (structure->m_usingSingleTransitionSlot) {
361 Structure* existingTransition = structure->m_transitions.singleTransition;
362 if (existingTransition && existingTransition->m_nameInPrevious.get() == propertyName.ustring().rep() && existingTransition->m_attributesInPrevious == attributes) {
363 ASSERT(structure->m_transitions.singleTransition->m_offset != noOffset);
364 offset = structure->m_transitions.singleTransition->m_offset;
365 return existingTransition;
366 }
367 } else {
368 if (Structure* existingTransition = structure->m_transitions.table->get(make_pair(propertyName.ustring().rep(), attributes))) {
369 ASSERT(existingTransition->m_offset != noOffset);
370 offset = existingTransition->m_offset;
371 return existingTransition;
372 }
373 }
374
375 return 0;
376}
377
378PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset)
379{
380 ASSERT(!structure->m_isDictionary);
381 ASSERT(structure->typeInfo().type() == ObjectType);
382 ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, offset));
383
384 if (structure->transitionCount() > s_maxTransitionLength) {
385 RefPtr<Structure> transition = toDictionaryTransition(structure);
386 offset = transition->put(propertyName, attributes);
387 if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
388 transition->growPropertyStorageCapacity();
389 return transition.release();
390 }
391
392 RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
393 transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain;
394 transition->m_previous = structure;
395 transition->m_nameInPrevious = propertyName.ustring().rep();
396 transition->m_attributesInPrevious = attributes;
397 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
398 transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
399
400 if (structure->m_propertyTable) {
401 if (structure->m_isPinnedPropertyTable)
402 transition->m_propertyTable = structure->copyPropertyTable();
403 else {
404 transition->m_propertyTable = structure->m_propertyTable;
405 structure->m_propertyTable = 0;
406 }
407 } else {
408 if (structure->m_previous)
409 transition->materializePropertyMap();
410 else
411 transition->createPropertyMapHashTable();
412 }
413
414 offset = transition->put(propertyName, attributes);
415 if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
416 transition->growPropertyStorageCapacity();
417
418 transition->m_offset = offset;
419
420 if (structure->m_usingSingleTransitionSlot) {
421 if (!structure->m_transitions.singleTransition) {
422 structure->m_transitions.singleTransition = transition.get();
423 return transition.release();
424 }
425
426 Structure* existingTransition = structure->m_transitions.singleTransition;
427 structure->m_usingSingleTransitionSlot = false;
428 StructureTransitionTable* transitionTable = new StructureTransitionTable;
429 structure->m_transitions.table = transitionTable;
430 transitionTable->add(make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition);
431 }
432 structure->m_transitions.table->add(make_pair(propertyName.ustring().rep(), attributes), transition.get());
433 return transition.release();
434}
435
436PassRefPtr<Structure> Structure::removePropertyTransition(Structure* structure, const Identifier& propertyName, size_t& offset)
437{
438 ASSERT(!structure->m_isDictionary);
439
440 RefPtr<Structure> transition = toDictionaryTransition(structure);
441
442 offset = transition->remove(propertyName);
443
444 return transition.release();
445}
446
447PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, JSValuePtr prototype)
448{
449 RefPtr<Structure> transition = create(prototype, structure->typeInfo());
450
451 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
452 transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
453
454 // Don't set m_offset, as one can not transition to this.
455
456 structure->materializePropertyMapIfNecessary();
457 transition->m_propertyTable = structure->copyPropertyTable();
458 transition->m_isPinnedPropertyTable = true;
459
460 return transition.release();
461}
462
463PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
464{
465 RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
466 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
467 transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties;
468
469 // Don't set m_offset, as one can not transition to this.
470
471 structure->materializePropertyMapIfNecessary();
472 transition->m_propertyTable = structure->copyPropertyTable();
473 transition->m_isPinnedPropertyTable = true;
474
475 return transition.release();
476}
477
478PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure)
479{
480 ASSERT(!structure->m_isDictionary);
481
482 RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
483 transition->m_isDictionary = true;
484 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
485 transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
486
487 structure->materializePropertyMapIfNecessary();
488 transition->m_propertyTable = structure->copyPropertyTable();
489 transition->m_isPinnedPropertyTable = true;
490
491 return transition.release();
492}
493
494PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure)
495{
496 ASSERT(structure->m_isDictionary);
497
498 // Since dictionary Structures are not shared, and no opcodes specialize
499 // for them, we don't need to allocate a new Structure when transitioning
500 // to non-dictionary status.
501
502 // FIMXE: We can make this more efficient by canonicalizing the Structure (draining the
503 // deleted offsets vector) before transitioning from dictionary.
504 if (!structure->m_propertyTable || !structure->m_propertyTable->deletedOffsets || structure->m_propertyTable->deletedOffsets->isEmpty())
505 structure->m_isDictionary = false;
506
507 return structure;
508}
509
510size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes)
511{
512 ASSERT(!m_transitions.singleTransition);
513
514 materializePropertyMapIfNecessary();
515
516 m_isPinnedPropertyTable = true;
517 size_t offset = put(propertyName, attributes);
518 if (propertyStorageSize() > propertyStorageCapacity())
519 growPropertyStorageCapacity();
520 clearEnumerationCache();
521 return offset;
522}
523
524size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName)
525{
526 ASSERT(!m_transitions.singleTransition);
527 ASSERT(m_isDictionary);
528
529 materializePropertyMapIfNecessary();
530
531 m_isPinnedPropertyTable = true;
532 size_t offset = remove(propertyName);
533 clearEnumerationCache();
534 return offset;
535}
536
537StructureChain* Structure::createCachedPrototypeChain()
538{
539 ASSERT(typeInfo().type() == ObjectType);
540 ASSERT(!m_cachedPrototypeChain);
541
542 JSValuePtr prototype = storedPrototype();
543 if (!prototype.isCell())
544 return 0;
545
546 RefPtr<StructureChain> chain = StructureChain::create(asObject(prototype)->structure());
547 setCachedPrototypeChain(chain.release());
548 return cachedPrototypeChain();
549}
550
551#if DUMP_PROPERTYMAP_STATS
552
553static int numProbes;
554static int numCollisions;
555static int numRehashes;
556static int numRemoves;
557
558struct PropertyMapStatisticsExitLogger {
559 ~PropertyMapStatisticsExitLogger();
560};
561
562static PropertyMapStatisticsExitLogger logger;
563
564PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger()
565{
566 printf("\nJSC::PropertyMap statistics\n\n");
567 printf("%d probes\n", numProbes);
568 printf("%d collisions (%.1f%%)\n", numCollisions, 100.0 * numCollisions / numProbes);
569 printf("%d rehashes\n", numRehashes);
570 printf("%d removes\n", numRemoves);
571}
572
573#endif
574
575static const unsigned deletedSentinelIndex = 1;
576
577#if !DO_PROPERTYMAP_CONSTENCY_CHECK
578
579inline void Structure::checkConsistency()
580{
581}
582
583#endif
584
585PropertyMapHashTable* Structure::copyPropertyTable()
586{
587 if (!m_propertyTable)
588 return 0;
589
590 size_t tableSize = PropertyMapHashTable::allocationSize(m_propertyTable->size);
591 PropertyMapHashTable* newTable = static_cast<PropertyMapHashTable*>(fastMalloc(tableSize));
592 memcpy(newTable, m_propertyTable, tableSize);
593
594 unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
595 for (unsigned i = 1; i <= entryCount; ++i) {
596 if (UString::Rep* key = newTable->entries()[i].key)
597 key->ref();
598 }
599
600 // Copy the deletedOffsets vector.
601 if (m_propertyTable->deletedOffsets)
602 newTable->deletedOffsets = new Vector<unsigned>(*m_propertyTable->deletedOffsets);
603
604 return newTable;
605}
606
607size_t Structure::get(const Identifier& propertyName, unsigned& attributes)
608{
609 ASSERT(!propertyName.isNull());
610
611 materializePropertyMapIfNecessary();
612 if (!m_propertyTable)
613 return notFound;
614
615 UString::Rep* rep = propertyName._ustring.rep();
616
617 unsigned i = rep->computedHash();
618
619#if DUMP_PROPERTYMAP_STATS
620 ++numProbes;
621#endif
622
623 unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
624 if (entryIndex == emptyEntryIndex)
625 return notFound;
626
627 if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
628 attributes = m_propertyTable->entries()[entryIndex - 1].attributes;
629 return m_propertyTable->entries()[entryIndex - 1].offset;
630 }
631
632#if DUMP_PROPERTYMAP_STATS
633 ++numCollisions;
634#endif
635
636 unsigned k = 1 | doubleHash(rep->computedHash());
637
638 while (1) {
639 i += k;
640
641#if DUMP_PROPERTYMAP_STATS
642 ++numRehashes;
643#endif
644
645 entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
646 if (entryIndex == emptyEntryIndex)
647 return notFound;
648
649 if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
650 attributes = m_propertyTable->entries()[entryIndex - 1].attributes;
651 return m_propertyTable->entries()[entryIndex - 1].offset;
652 }
653 }
654}
655
656size_t Structure::put(const Identifier& propertyName, unsigned attributes)
657{
658 ASSERT(!propertyName.isNull());
659 ASSERT(get(propertyName) == notFound);
660
661 checkConsistency();
662
663 UString::Rep* rep = propertyName._ustring.rep();
664
665 if (!m_propertyTable)
666 createPropertyMapHashTable();
667
668 // FIXME: Consider a fast case for tables with no deleted sentinels.
669
670 unsigned i = rep->computedHash();
671 unsigned k = 0;
672 bool foundDeletedElement = false;
673 unsigned deletedElementIndex = 0; // initialize to make the compiler happy
674
675#if DUMP_PROPERTYMAP_STATS
676 ++numProbes;
677#endif
678
679 while (1) {
680 unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
681 if (entryIndex == emptyEntryIndex)
682 break;
683
684 if (entryIndex == deletedSentinelIndex) {
685 // If we find a deleted-element sentinel, remember it for use later.
686 if (!foundDeletedElement) {
687 foundDeletedElement = true;
688 deletedElementIndex = i;
689 }
690 }
691
692 if (k == 0) {
693 k = 1 | doubleHash(rep->computedHash());
694#if DUMP_PROPERTYMAP_STATS
695 ++numCollisions;
696#endif
697 }
698
699 i += k;
700
701#if DUMP_PROPERTYMAP_STATS
702 ++numRehashes;
703#endif
704 }
705
706 // Figure out which entry to use.
707 unsigned entryIndex = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount + 2;
708 if (foundDeletedElement) {
709 i = deletedElementIndex;
710 --m_propertyTable->deletedSentinelCount;
711
712 // Since we're not making the table bigger, we can't use the entry one past
713 // the end that we were planning on using, so search backwards for the empty
714 // slot that we can use. We know it will be there because we did at least one
715 // deletion in the past that left an entry empty.
716 while (m_propertyTable->entries()[--entryIndex - 1].key) { }
717 }
718
719 // Create a new hash table entry.
720 m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = entryIndex;
721
722 // Create a new hash table entry.
723 rep->ref();
724 m_propertyTable->entries()[entryIndex - 1].key = rep;
725 m_propertyTable->entries()[entryIndex - 1].attributes = attributes;
726 m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed;
727
728 unsigned newOffset;
729 if (m_propertyTable->deletedOffsets && !m_propertyTable->deletedOffsets->isEmpty()) {
730 newOffset = m_propertyTable->deletedOffsets->last();
731 m_propertyTable->deletedOffsets->removeLast();
732 } else
733 newOffset = m_propertyTable->keyCount;
734 m_propertyTable->entries()[entryIndex - 1].offset = newOffset;
735
736 ++m_propertyTable->keyCount;
737
738 if ((m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount) * 2 >= m_propertyTable->size)
739 expandPropertyMapHashTable();
740
741 checkConsistency();
742 return newOffset;
743}
744
745size_t Structure::remove(const Identifier& propertyName)
746{
747 ASSERT(!propertyName.isNull());
748
749 checkConsistency();
750
751 UString::Rep* rep = propertyName._ustring.rep();
752
753 if (!m_propertyTable)
754 return notFound;
755
756#if DUMP_PROPERTYMAP_STATS
757 ++numProbes;
758 ++numRemoves;
759#endif
760
761 // Find the thing to remove.
762 unsigned i = rep->computedHash();
763 unsigned k = 0;
764 unsigned entryIndex;
765 UString::Rep* key = 0;
766 while (1) {
767 entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
768 if (entryIndex == emptyEntryIndex)
769 return notFound;
770
771 key = m_propertyTable->entries()[entryIndex - 1].key;
772 if (rep == key)
773 break;
774
775 if (k == 0) {
776 k = 1 | doubleHash(rep->computedHash());
777#if DUMP_PROPERTYMAP_STATS
778 ++numCollisions;
779#endif
780 }
781
782 i += k;
783
784#if DUMP_PROPERTYMAP_STATS
785 ++numRehashes;
786#endif
787 }
788
789 // Replace this one element with the deleted sentinel. Also clear out
790 // the entry so we can iterate all the entries as needed.
791 m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = deletedSentinelIndex;
792
793 size_t offset = m_propertyTable->entries()[entryIndex - 1].offset;
794
795 key->deref();
796 m_propertyTable->entries()[entryIndex - 1].key = 0;
797 m_propertyTable->entries()[entryIndex - 1].attributes = 0;
798 m_propertyTable->entries()[entryIndex - 1].offset = 0;
799
800 if (!m_propertyTable->deletedOffsets)
801 m_propertyTable->deletedOffsets = new Vector<unsigned>;
802 m_propertyTable->deletedOffsets->append(offset);
803
804 ASSERT(m_propertyTable->keyCount >= 1);
805 --m_propertyTable->keyCount;
806 ++m_propertyTable->deletedSentinelCount;
807
808 if (m_propertyTable->deletedSentinelCount * 4 >= m_propertyTable->size)
809 rehashPropertyMapHashTable();
810
811 checkConsistency();
812 return offset;
813}
814
815void Structure::insertIntoPropertyMapHashTable(const PropertyMapEntry& entry)
816{
817 ASSERT(m_propertyTable);
818
819 unsigned i = entry.key->computedHash();
820 unsigned k = 0;
821
822#if DUMP_PROPERTYMAP_STATS
823 ++numProbes;
824#endif
825
826 while (1) {
827 unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
828 if (entryIndex == emptyEntryIndex)
829 break;
830
831 if (k == 0) {
832 k = 1 | doubleHash(entry.key->computedHash());
833#if DUMP_PROPERTYMAP_STATS
834 ++numCollisions;
835#endif
836 }
837
838 i += k;
839
840#if DUMP_PROPERTYMAP_STATS
841 ++numRehashes;
842#endif
843 }
844
845 unsigned entryIndex = m_propertyTable->keyCount + 2;
846 m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = entryIndex;
847 m_propertyTable->entries()[entryIndex - 1] = entry;
848
849 ++m_propertyTable->keyCount;
850}
851
852void Structure::createPropertyMapHashTable()
853{
854 ASSERT(sizeForKeyCount(7) == newTableSize);
855 createPropertyMapHashTable(newTableSize);
856}
857
858void Structure::createPropertyMapHashTable(unsigned newTableSize)
859{
860 ASSERT(!m_propertyTable);
861 ASSERT(isPowerOf2(newTableSize));
862
863 checkConsistency();
864
865 m_propertyTable = static_cast<PropertyMapHashTable*>(fastZeroedMalloc(PropertyMapHashTable::allocationSize(newTableSize)));
866 m_propertyTable->size = newTableSize;
867 m_propertyTable->sizeMask = newTableSize - 1;
868
869 checkConsistency();
870}
871
872void Structure::expandPropertyMapHashTable()
873{
874 ASSERT(m_propertyTable);
875 rehashPropertyMapHashTable(m_propertyTable->size * 2);
876}
877
878void Structure::rehashPropertyMapHashTable()
879{
880 ASSERT(m_propertyTable);
881 ASSERT(m_propertyTable->size);
882 rehashPropertyMapHashTable(m_propertyTable->size);
883}
884
885void Structure::rehashPropertyMapHashTable(unsigned newTableSize)
886{
887 ASSERT(m_propertyTable);
888 ASSERT(isPowerOf2(newTableSize));
889
890 checkConsistency();
891
892 PropertyMapHashTable* oldTable = m_propertyTable;
893
894 m_propertyTable = static_cast<PropertyMapHashTable*>(fastZeroedMalloc(PropertyMapHashTable::allocationSize(newTableSize)));
895 m_propertyTable->size = newTableSize;
896 m_propertyTable->sizeMask = newTableSize - 1;
897
898 unsigned lastIndexUsed = 0;
899 unsigned entryCount = oldTable->keyCount + oldTable->deletedSentinelCount;
900 for (unsigned i = 1; i <= entryCount; ++i) {
901 if (oldTable->entries()[i].key) {
902 lastIndexUsed = max(oldTable->entries()[i].index, lastIndexUsed);
903 insertIntoPropertyMapHashTable(oldTable->entries()[i]);
904 }
905 }
906 m_propertyTable->lastIndexUsed = lastIndexUsed;
907 m_propertyTable->deletedOffsets = oldTable->deletedOffsets;
908
909 fastFree(oldTable);
910
911 checkConsistency();
912}
913
914static int comparePropertyMapEntryIndices(const void* a, const void* b)
915{
916 unsigned ia = static_cast<PropertyMapEntry* const*>(a)[0]->index;
917 unsigned ib = static_cast<PropertyMapEntry* const*>(b)[0]->index;
918 if (ia < ib)
919 return -1;
920 if (ia > ib)
921 return +1;
922 return 0;
923}
924
925void Structure::getEnumerablePropertyNamesInternal(PropertyNameArray& propertyNames)
926{
927 materializePropertyMapIfNecessary();
928 if (!m_propertyTable)
929 return;
930
931 if (m_propertyTable->keyCount < tinyMapThreshold) {
932 PropertyMapEntry* a[tinyMapThreshold];
933 int i = 0;
934 unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
935 for (unsigned k = 1; k <= entryCount; k++) {
936 if (m_propertyTable->entries()[k].key && !(m_propertyTable->entries()[k].attributes & DontEnum)) {
937 PropertyMapEntry* value = &m_propertyTable->entries()[k];
938 int j;
939 for (j = i - 1; j >= 0 && a[j]->index > value->index; --j)
940 a[j + 1] = a[j];
941 a[j + 1] = value;
942 ++i;
943 }
944 }
945 if (!propertyNames.size()) {
946 for (int k = 0; k < i; ++k)
947 propertyNames.addKnownUnique(a[k]->key);
948 } else {
949 for (int k = 0; k < i; ++k)
950 propertyNames.add(a[k]->key);
951 }
952
953 return;
954 }
955
956 // Allocate a buffer to use to sort the keys.
957 Vector<PropertyMapEntry*, smallMapThreshold> sortedEnumerables(m_propertyTable->keyCount);
958
959 // Get pointers to the enumerable entries in the buffer.
960 PropertyMapEntry** p = sortedEnumerables.data();
961 unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
962 for (unsigned i = 1; i <= entryCount; i++) {
963 if (m_propertyTable->entries()[i].key && !(m_propertyTable->entries()[i].attributes & DontEnum))
964 *p++ = &m_propertyTable->entries()[i];
965 }
966
967 size_t enumerableCount = p - sortedEnumerables.data();
968 // Sort the entries by index.
969 qsort(sortedEnumerables.data(), enumerableCount, sizeof(PropertyMapEntry*), comparePropertyMapEntryIndices);
970 sortedEnumerables.resize(enumerableCount);
971
972 // Put the keys of the sorted entries into the list.
973 if (!propertyNames.size()) {
974 for (size_t i = 0; i < sortedEnumerables.size(); ++i)
975 propertyNames.addKnownUnique(sortedEnumerables[i]->key);
976 } else {
977 for (size_t i = 0; i < sortedEnumerables.size(); ++i)
978 propertyNames.add(sortedEnumerables[i]->key);
979 }
980}
981
982#if DO_PROPERTYMAP_CONSTENCY_CHECK
983
984void Structure::checkConsistency()
985{
986 if (!m_propertyTable)
987 return;
988
989 ASSERT(m_propertyTable->size >= newTableSize);
990 ASSERT(m_propertyTable->sizeMask);
991 ASSERT(m_propertyTable->size == m_propertyTable->sizeMask + 1);
992 ASSERT(!(m_propertyTable->size & m_propertyTable->sizeMask));
993
994 ASSERT(m_propertyTable->keyCount <= m_propertyTable->size / 2);
995 ASSERT(m_propertyTable->deletedSentinelCount <= m_propertyTable->size / 4);
996
997 ASSERT(m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount <= m_propertyTable->size / 2);
998
999 unsigned indexCount = 0;
1000 unsigned deletedIndexCount = 0;
1001 for (unsigned a = 0; a != m_propertyTable->size; ++a) {
1002 unsigned entryIndex = m_propertyTable->entryIndices[a];
1003 if (entryIndex == emptyEntryIndex)
1004 continue;
1005 if (entryIndex == deletedSentinelIndex) {
1006 ++deletedIndexCount;
1007 continue;
1008 }
1009 ASSERT(entryIndex > deletedSentinelIndex);
1010 ASSERT(entryIndex - 1 <= m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount);
1011 ++indexCount;
1012
1013 for (unsigned b = a + 1; b != m_propertyTable->size; ++b)
1014 ASSERT(m_propertyTable->entryIndices[b] != entryIndex);
1015 }
1016 ASSERT(indexCount == m_propertyTable->keyCount);
1017 ASSERT(deletedIndexCount == m_propertyTable->deletedSentinelCount);
1018
1019 ASSERT(m_propertyTable->entries()[0].key == 0);
1020
1021 unsigned nonEmptyEntryCount = 0;
1022 for (unsigned c = 1; c <= m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; ++c) {
1023 UString::Rep* rep = m_propertyTable->entries()[c].key;
1024 if (!rep)
1025 continue;
1026 ++nonEmptyEntryCount;
1027 unsigned i = rep->computedHash();
1028 unsigned k = 0;
1029 unsigned entryIndex;
1030 while (1) {
1031 entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
1032 ASSERT(entryIndex != emptyEntryIndex);
1033 if (rep == m_propertyTable->entries()[entryIndex - 1].key)
1034 break;
1035 if (k == 0)
1036 k = 1 | doubleHash(rep->computedHash());
1037 i += k;
1038 }
1039 ASSERT(entryIndex == c + 1);
1040 }
1041
1042 ASSERT(nonEmptyEntryCount == m_propertyTable->keyCount);
1043}
1044
1045#endif // DO_PROPERTYMAP_CONSTENCY_CHECK
1046
1047} // namespace JSC
Note: See TracBrowser for help on using the repository browser.