Changeset 146089 in webkit


Ignore:
Timestamp:
Mar 18, 2013 11:09:22 AM (11 years ago)
Author:
fpizlo@apple.com
Message:

DFG string conversions and allocations should be inlined
https://bugs.webkit.org/show_bug.cgi?id=112376

Source/JavaScriptCore:

Reviewed by Geoffrey Garen.

This turns new String(), String(), String.prototype.valueOf(), and
String.prototype.toString() into intrinsics. It gives the DFG the ability to handle
conversions from StringObject to JSString and vice-versa, and also gives it the
ability to handle cases where a variable may be either a StringObject or a JSString.
To do this, I added StringObject to value profiling (and removed the stale
distinction between Myarguments and Foreignarguments). I also cleaned up ToPrimitive
handling, using some of the new functionality but also taking advantage of the
existence of Identity(String:@a).

This is a 2% SunSpider speed-up. Also there are some speed-ups on V8v7 and Kraken.
On microbenchmarks that stress new String() this is a 14x speed-up.

  • CMakeLists.txt:
  • DerivedSources.make:
  • DerivedSources.pri:
  • GNUmakefile.list.am:
  • bytecode/CodeBlock.h:

(CodeBlock):
(JSC::CodeBlock::hasExitSite):
(JSC):

  • bytecode/DFGExitProfile.cpp:

(JSC::DFG::ExitProfile::hasExitSite):
(DFG):

  • bytecode/DFGExitProfile.h:

(ExitProfile):
(JSC::DFG::ExitProfile::hasExitSite):

  • bytecode/ExitKind.cpp:

(JSC::exitKindToString):

  • bytecode/ExitKind.h:
  • bytecode/SpeculatedType.cpp:

(JSC::dumpSpeculation):
(JSC::speculationToAbbreviatedString):
(JSC::speculationFromClassInfo):

  • bytecode/SpeculatedType.h:

(JSC):
(JSC::isStringObjectSpeculation):
(JSC::isStringOrStringObjectSpeculation):

  • create_hash_table:
  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::executeEffects):

  • dfg/DFGAbstractState.h:

(JSC::DFG::AbstractState::filterEdgeByUse):

  • dfg/DFGByteCodeParser.cpp:

(ByteCodeParser):
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::emitArgumentPhantoms):
(DFG):
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::putStructureStoreElimination):

  • dfg/DFGEdge.h:

(JSC::DFG::Edge::shift):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
(FixupPhase):
(JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
(JSC::DFG::FixupPhase::observeUseKindOnNode):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::hasGlobalExitSite):
(Graph):
(JSC::DFG::Graph::hasExitSite):
(JSC::DFG::Graph::clobbersWorld):

  • dfg/DFGNode.h:

(JSC::DFG::Node::convertToToString):
(Node):
(JSC::DFG::Node::hasStructure):
(JSC::DFG::Node::shouldSpeculateStringObject):
(JSC::DFG::Node::shouldSpeculateStringOrStringObject):

  • dfg/DFGNodeType.h:

(DFG):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileToStringOnCell):
(DFG):
(JSC::DFG::SpeculativeJIT::compileNewStringObject):
(JSC::DFG::SpeculativeJIT::speculateObject):
(JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
(JSC::DFG::SpeculativeJIT::speculateString):
(JSC::DFG::SpeculativeJIT::speculateStringObject):
(JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
(JSC::DFG::SpeculativeJIT::speculate):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):
(SpeculativeJIT):
(JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
(DFG):
(JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGUseKind.cpp:

(WTF::printInternal):

  • dfg/DFGUseKind.h:

(JSC::DFG::typeFilterFor):

  • interpreter/CallFrame.h:

(JSC::ExecState::regExpPrototypeTable):

  • runtime/CommonIdentifiers.h:
  • runtime/Intrinsic.h:
  • runtime/JSDestructibleObject.h:

(JSDestructibleObject):
(JSC::JSDestructibleObject::classInfoOffset):

  • runtime/JSGlobalData.cpp:

(JSC):
(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::~JSGlobalData):

  • runtime/JSGlobalData.h:

(JSGlobalData):

  • runtime/JSObject.cpp:
  • runtime/JSObject.h:

(JSC):

  • runtime/JSWrapperObject.h:

(JSC::JSWrapperObject::allocationSize):
(JSWrapperObject):
(JSC::JSWrapperObject::internalValueOffset):
(JSC::JSWrapperObject::internalValueCellOffset):

  • runtime/StringPrototype.cpp:

(JSC):
(JSC::StringPrototype::finishCreation):
(JSC::StringPrototype::create):

  • runtime/StringPrototype.h:

(StringPrototype):

LayoutTests:

Reviewed by Geoffrey Garen.

  • fast/js/dfg-to-string-bad-toString-expected.txt: Added.
  • fast/js/dfg-to-string-bad-toString.html: Added.
  • fast/js/dfg-to-string-bad-valueOf-expected.txt: Added.
  • fast/js/dfg-to-string-bad-valueOf.html: Added.
  • fast/js/dfg-to-string-int-expected.txt: Added.
  • fast/js/dfg-to-string-int-or-string-expected.txt: Added.
  • fast/js/dfg-to-string-int-or-string.html: Added.
  • fast/js/dfg-to-string-int.html: Added.
  • fast/js/dfg-to-string-side-effect-clobbers-toString-expected.txt: Added.
  • fast/js/dfg-to-string-side-effect-clobbers-toString.html: Added.
  • fast/js/dfg-to-string-side-effect-expected.txt: Added.
  • fast/js/dfg-to-string-side-effect.html: Added.
  • fast/js/dfg-to-string-toString-becomes-bad-expected.txt: Added.
  • fast/js/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype-expected.txt: Added.
  • fast/js/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype.html: Added.
  • fast/js/dfg-to-string-toString-becomes-bad.html: Added.
  • fast/js/dfg-to-string-toString-in-string-expected.txt: Added.
  • fast/js/dfg-to-string-toString-in-string.html: Added.
  • fast/js/dfg-to-string-valueOf-becomes-bad-expected.txt: Added.
  • fast/js/dfg-to-string-valueOf-becomes-bad.html: Added.
  • fast/js/dfg-to-string-valueOf-in-string-expected.txt: Added.
  • fast/js/dfg-to-string-valueOf-in-string.html: Added.
  • fast/js/jsc-test-list:
  • fast/js/regress/script-tests/string-concat-object.js: Added.

(foo):

  • fast/js/regress/script-tests/string-concat-pair-object.js: Added.

(foo):

  • fast/js/regress/script-tests/string-concat-pair-simple.js: Added.

(foo):

  • fast/js/regress/script-tests/string-concat-simple.js: Added.

(foo):

  • fast/js/regress/script-tests/string-cons-repeat.js: Added.

(foo):

  • fast/js/regress/script-tests/string-cons-tower.js: Added.

(foo):

  • fast/js/regress/string-concat-object-expected.txt: Added.
  • fast/js/regress/string-concat-object.html: Added.
  • fast/js/regress/string-concat-pair-object-expected.txt: Added.
  • fast/js/regress/string-concat-pair-object.html: Added.
  • fast/js/regress/string-concat-pair-simple-expected.txt: Added.
  • fast/js/regress/string-concat-pair-simple.html: Added.
  • fast/js/regress/string-concat-simple-expected.txt: Added.
  • fast/js/regress/string-concat-simple.html: Added.
  • fast/js/regress/string-cons-repeat-expected.txt: Added.
  • fast/js/regress/string-cons-repeat.html: Added.
  • fast/js/regress/string-cons-tower-expected.txt: Added.
  • fast/js/regress/string-cons-tower.html: Added.
  • fast/js/script-tests/dfg-to-string-bad-toString.js: Added.

(String.prototype.toString):
(foo):

  • fast/js/script-tests/dfg-to-string-bad-valueOf.js: Added.

(String.prototype.valueOf):
(foo):

  • fast/js/script-tests/dfg-to-string-int-or-string.js: Added.

(foo):

  • fast/js/script-tests/dfg-to-string-int.js: Added.

(foo):

  • fast/js/script-tests/dfg-to-string-side-effect-clobbers-toString.js: Added.

(foo):

  • fast/js/script-tests/dfg-to-string-side-effect.js: Added.

(foo):

  • fast/js/script-tests/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype.js: Added.

(foo):
(.String.prototype.toString):

  • fast/js/script-tests/dfg-to-string-toString-becomes-bad.js: Added.

(foo):
(.String.prototype.toString):

  • fast/js/script-tests/dfg-to-string-toString-in-string.js: Added.

(foo):
(.argument.toString):

  • fast/js/script-tests/dfg-to-string-valueOf-becomes-bad.js: Added.

(foo):
(.String.prototype.valueOf):

  • fast/js/script-tests/dfg-to-string-valueOf-in-string.js: Added.

(foo):
(.argument.valueOf):

Location:
trunk
Files:
51 added
43 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r146087 r146089  
     12013-03-18  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG string conversions and allocations should be inlined
     4        https://bugs.webkit.org/show_bug.cgi?id=112376
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * fast/js/dfg-to-string-bad-toString-expected.txt: Added.
     9        * fast/js/dfg-to-string-bad-toString.html: Added.
     10        * fast/js/dfg-to-string-bad-valueOf-expected.txt: Added.
     11        * fast/js/dfg-to-string-bad-valueOf.html: Added.
     12        * fast/js/dfg-to-string-int-expected.txt: Added.
     13        * fast/js/dfg-to-string-int-or-string-expected.txt: Added.
     14        * fast/js/dfg-to-string-int-or-string.html: Added.
     15        * fast/js/dfg-to-string-int.html: Added.
     16        * fast/js/dfg-to-string-side-effect-clobbers-toString-expected.txt: Added.
     17        * fast/js/dfg-to-string-side-effect-clobbers-toString.html: Added.
     18        * fast/js/dfg-to-string-side-effect-expected.txt: Added.
     19        * fast/js/dfg-to-string-side-effect.html: Added.
     20        * fast/js/dfg-to-string-toString-becomes-bad-expected.txt: Added.
     21        * fast/js/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype-expected.txt: Added.
     22        * fast/js/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype.html: Added.
     23        * fast/js/dfg-to-string-toString-becomes-bad.html: Added.
     24        * fast/js/dfg-to-string-toString-in-string-expected.txt: Added.
     25        * fast/js/dfg-to-string-toString-in-string.html: Added.
     26        * fast/js/dfg-to-string-valueOf-becomes-bad-expected.txt: Added.
     27        * fast/js/dfg-to-string-valueOf-becomes-bad.html: Added.
     28        * fast/js/dfg-to-string-valueOf-in-string-expected.txt: Added.
     29        * fast/js/dfg-to-string-valueOf-in-string.html: Added.
     30        * fast/js/jsc-test-list:
     31        * fast/js/regress/script-tests/string-concat-object.js: Added.
     32        (foo):
     33        * fast/js/regress/script-tests/string-concat-pair-object.js: Added.
     34        (foo):
     35        * fast/js/regress/script-tests/string-concat-pair-simple.js: Added.
     36        (foo):
     37        * fast/js/regress/script-tests/string-concat-simple.js: Added.
     38        (foo):
     39        * fast/js/regress/script-tests/string-cons-repeat.js: Added.
     40        (foo):
     41        * fast/js/regress/script-tests/string-cons-tower.js: Added.
     42        (foo):
     43        * fast/js/regress/string-concat-object-expected.txt: Added.
     44        * fast/js/regress/string-concat-object.html: Added.
     45        * fast/js/regress/string-concat-pair-object-expected.txt: Added.
     46        * fast/js/regress/string-concat-pair-object.html: Added.
     47        * fast/js/regress/string-concat-pair-simple-expected.txt: Added.
     48        * fast/js/regress/string-concat-pair-simple.html: Added.
     49        * fast/js/regress/string-concat-simple-expected.txt: Added.
     50        * fast/js/regress/string-concat-simple.html: Added.
     51        * fast/js/regress/string-cons-repeat-expected.txt: Added.
     52        * fast/js/regress/string-cons-repeat.html: Added.
     53        * fast/js/regress/string-cons-tower-expected.txt: Added.
     54        * fast/js/regress/string-cons-tower.html: Added.
     55        * fast/js/script-tests/dfg-to-string-bad-toString.js: Added.
     56        (String.prototype.toString):
     57        (foo):
     58        * fast/js/script-tests/dfg-to-string-bad-valueOf.js: Added.
     59        (String.prototype.valueOf):
     60        (foo):
     61        * fast/js/script-tests/dfg-to-string-int-or-string.js: Added.
     62        (foo):
     63        * fast/js/script-tests/dfg-to-string-int.js: Added.
     64        (foo):
     65        * fast/js/script-tests/dfg-to-string-side-effect-clobbers-toString.js: Added.
     66        (foo):
     67        * fast/js/script-tests/dfg-to-string-side-effect.js: Added.
     68        (foo):
     69        * fast/js/script-tests/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype.js: Added.
     70        (foo):
     71        (.String.prototype.toString):
     72        * fast/js/script-tests/dfg-to-string-toString-becomes-bad.js: Added.
     73        (foo):
     74        (.String.prototype.toString):
     75        * fast/js/script-tests/dfg-to-string-toString-in-string.js: Added.
     76        (foo):
     77        (.argument.toString):
     78        * fast/js/script-tests/dfg-to-string-valueOf-becomes-bad.js: Added.
     79        (foo):
     80        (.String.prototype.valueOf):
     81        * fast/js/script-tests/dfg-to-string-valueOf-in-string.js: Added.
     82        (foo):
     83        (.argument.valueOf):
     84
    1852013-03-18  Dean Jackson  <dino@apple.com>
    286
  • trunk/LayoutTests/fast/js/jsc-test-list

    r145828 r146089  
    195195fast/js/dfg-string-stricteq
    196196fast/js/dfg-tear-off-arguments-not-activation
     197fast/js/dfg-to-string-bad-toString
     198fast/js/dfg-to-string-bad-valueOf
     199fast/js/dfg-to-string-int-or-string
     200fast/js/dfg-to-string-int
     201fast/js/dfg-to-string-side-effect
     202fast/js/dfg-to-string-side-effect-clobbers-toString
     203fast/js/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype
     204fast/js/dfg-to-string-toString-becomes-bad
     205fast/js/dfg-to-string-toString-in-string
     206fast/js/dfg-to-string-valueOf-becomes-bad
     207fast/js/dfg-to-string-valueOf-in-string
    197208fast/js/dfg-uint16array
    198209fast/js/dfg-uint32-to-number-in-middle-of-copy-propagation
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r146071 r146089  
    334334    runtime/RegExpPrototype.cpp
    335335    runtime/StringConstructor.cpp
    336     runtime/StringPrototype.cpp
    337336)
    338337
  • trunk/Source/JavaScriptCore/ChangeLog

    r146071 r146089  
     12013-03-15  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG string conversions and allocations should be inlined
     4        https://bugs.webkit.org/show_bug.cgi?id=112376
     5
     6        Reviewed by Geoffrey Garen.
     7       
     8        This turns new String(), String(), String.prototype.valueOf(), and
     9        String.prototype.toString() into intrinsics. It gives the DFG the ability to handle
     10        conversions from StringObject to JSString and vice-versa, and also gives it the
     11        ability to handle cases where a variable may be either a StringObject or a JSString.
     12        To do this, I added StringObject to value profiling (and removed the stale
     13        distinction between Myarguments and Foreignarguments). I also cleaned up ToPrimitive
     14        handling, using some of the new functionality but also taking advantage of the
     15        existence of Identity(String:@a).
     16       
     17        This is a 2% SunSpider speed-up. Also there are some speed-ups on V8v7 and Kraken.
     18        On microbenchmarks that stress new String() this is a 14x speed-up.
     19
     20        * CMakeLists.txt:
     21        * DerivedSources.make:
     22        * DerivedSources.pri:
     23        * GNUmakefile.list.am:
     24        * bytecode/CodeBlock.h:
     25        (CodeBlock):
     26        (JSC::CodeBlock::hasExitSite):
     27        (JSC):
     28        * bytecode/DFGExitProfile.cpp:
     29        (JSC::DFG::ExitProfile::hasExitSite):
     30        (DFG):
     31        * bytecode/DFGExitProfile.h:
     32        (ExitProfile):
     33        (JSC::DFG::ExitProfile::hasExitSite):
     34        * bytecode/ExitKind.cpp:
     35        (JSC::exitKindToString):
     36        * bytecode/ExitKind.h:
     37        * bytecode/SpeculatedType.cpp:
     38        (JSC::dumpSpeculation):
     39        (JSC::speculationToAbbreviatedString):
     40        (JSC::speculationFromClassInfo):
     41        * bytecode/SpeculatedType.h:
     42        (JSC):
     43        (JSC::isStringObjectSpeculation):
     44        (JSC::isStringOrStringObjectSpeculation):
     45        * create_hash_table:
     46        * dfg/DFGAbstractState.cpp:
     47        (JSC::DFG::AbstractState::executeEffects):
     48        * dfg/DFGAbstractState.h:
     49        (JSC::DFG::AbstractState::filterEdgeByUse):
     50        * dfg/DFGByteCodeParser.cpp:
     51        (ByteCodeParser):
     52        (JSC::DFG::ByteCodeParser::handleCall):
     53        (JSC::DFG::ByteCodeParser::emitArgumentPhantoms):
     54        (DFG):
     55        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
     56        * dfg/DFGCSEPhase.cpp:
     57        (JSC::DFG::CSEPhase::putStructureStoreElimination):
     58        * dfg/DFGEdge.h:
     59        (JSC::DFG::Edge::shift):
     60        * dfg/DFGFixupPhase.cpp:
     61        (JSC::DFG::FixupPhase::fixupNode):
     62        (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
     63        (FixupPhase):
     64        (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
     65        (JSC::DFG::FixupPhase::observeUseKindOnNode):
     66        * dfg/DFGGraph.h:
     67        (JSC::DFG::Graph::hasGlobalExitSite):
     68        (Graph):
     69        (JSC::DFG::Graph::hasExitSite):
     70        (JSC::DFG::Graph::clobbersWorld):
     71        * dfg/DFGNode.h:
     72        (JSC::DFG::Node::convertToToString):
     73        (Node):
     74        (JSC::DFG::Node::hasStructure):
     75        (JSC::DFG::Node::shouldSpeculateStringObject):
     76        (JSC::DFG::Node::shouldSpeculateStringOrStringObject):
     77        * dfg/DFGNodeType.h:
     78        (DFG):
     79        * dfg/DFGOperations.cpp:
     80        * dfg/DFGOperations.h:
     81        * dfg/DFGPredictionPropagationPhase.cpp:
     82        (JSC::DFG::PredictionPropagationPhase::propagate):
     83        * dfg/DFGSpeculativeJIT.cpp:
     84        (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
     85        (DFG):
     86        (JSC::DFG::SpeculativeJIT::compileNewStringObject):
     87        (JSC::DFG::SpeculativeJIT::speculateObject):
     88        (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
     89        (JSC::DFG::SpeculativeJIT::speculateString):
     90        (JSC::DFG::SpeculativeJIT::speculateStringObject):
     91        (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
     92        (JSC::DFG::SpeculativeJIT::speculate):
     93        * dfg/DFGSpeculativeJIT.h:
     94        (JSC::DFG::SpeculativeJIT::callOperation):
     95        (SpeculativeJIT):
     96        (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
     97        (DFG):
     98        (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
     99        * dfg/DFGSpeculativeJIT32_64.cpp:
     100        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
     101        (JSC::DFG::SpeculativeJIT::compile):
     102        * dfg/DFGSpeculativeJIT64.cpp:
     103        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
     104        (JSC::DFG::SpeculativeJIT::compile):
     105        * dfg/DFGUseKind.cpp:
     106        (WTF::printInternal):
     107        * dfg/DFGUseKind.h:
     108        (JSC::DFG::typeFilterFor):
     109        * interpreter/CallFrame.h:
     110        (JSC::ExecState::regExpPrototypeTable):
     111        * runtime/CommonIdentifiers.h:
     112        * runtime/Intrinsic.h:
     113        * runtime/JSDestructibleObject.h:
     114        (JSDestructibleObject):
     115        (JSC::JSDestructibleObject::classInfoOffset):
     116        * runtime/JSGlobalData.cpp:
     117        (JSC):
     118        (JSC::JSGlobalData::JSGlobalData):
     119        (JSC::JSGlobalData::~JSGlobalData):
     120        * runtime/JSGlobalData.h:
     121        (JSGlobalData):
     122        * runtime/JSObject.cpp:
     123        * runtime/JSObject.h:
     124        (JSC):
     125        * runtime/JSWrapperObject.h:
     126        (JSC::JSWrapperObject::allocationSize):
     127        (JSWrapperObject):
     128        (JSC::JSWrapperObject::internalValueOffset):
     129        (JSC::JSWrapperObject::internalValueCellOffset):
     130        * runtime/StringPrototype.cpp:
     131        (JSC):
     132        (JSC::StringPrototype::finishCreation):
     133        (JSC::StringPrototype::create):
     134        * runtime/StringPrototype.h:
     135        (StringPrototype):
     136
    11372013-03-18  Filip Pizlo  <fpizlo@apple.com>
    2138
  • trunk/Source/JavaScriptCore/DerivedSources.make

    r146071 r146089  
    1 # Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
     1# Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 Apple Inc. All rights reserved.
    22#
    33# Redistribution and use in source and binary forms, with or without
     
    5656    RegExpObject.lut.h \
    5757    StringConstructor.lut.h \
    58     StringPrototype.lut.h \
    5958    docs/bytecode.html \
    6059    udis86_itab.h \
  • trunk/Source/JavaScriptCore/DerivedSources.pri

    r146071 r146089  
    2525    runtime/RegExpPrototype.cpp \
    2626    runtime/StringConstructor.cpp \
    27     runtime/StringPrototype.cpp \
    2827
    2928KEYWORDLUT_FILES += \
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r146071 r146089  
    2929        DerivedSources/JavaScriptCore/RegExpPrototype.lut.h \
    3030        DerivedSources/JavaScriptCore/StringConstructor.lut.h \
    31         DerivedSources/JavaScriptCore/StringPrototype.lut.h \
    3231        DerivedSources/JavaScriptCore/LLIntDesiredOffsets.h \
    3332        DerivedSources/JavaScriptCore/LLIntAssembly.h
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r145000 r146089  
    788788            return m_exitProfile.add(site);
    789789        }
     790       
     791        bool hasExitSite(const DFG::FrequentExitSite& site) const { return m_exitProfile.hasExitSite(site); }
    790792
    791793        DFG::ExitProfile& exitProfile() { return m_exitProfile; }
     
    13901392        return baselineCodeBlock;
    13911393    }
    1392    
     1394
    13931395    inline int CodeBlock::argumentIndexAfterCapture(size_t argument)
    13941396    {
  • trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.cpp

    r139021 r146089  
    7171}
    7272
     73bool ExitProfile::hasExitSite(const FrequentExitSite& site) const
     74{
     75    if (!m_frequentExitSites)
     76        return false;
     77   
     78    for (unsigned i = m_frequentExitSites->size(); i--;) {
     79        if (m_frequentExitSites->at(i) == site)
     80            return true;
     81    }
     82    return false;
     83}
     84
    7385QueryableExitProfile::QueryableExitProfile(const ExitProfile& profile)
    7486{
  • trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.h

    r139021 r146089  
    134134    Vector<FrequentExitSite> exitSitesFor(unsigned bytecodeIndex);
    135135   
     136    // This is O(n) and should be called on less-frequently executed code paths
     137    // in the compiler. It should be strictly cheaper than building a
     138    // QueryableExitProfile, if you really expect this to be called infrequently
     139    // and you believe that there are few exit sites.
     140    bool hasExitSite(const FrequentExitSite&) const;
     141    bool hasExitSite(ExitKind kind) const
     142    {
     143        return hasExitSite(FrequentExitSite(kind));
     144    }
     145    bool hasExitSite(unsigned bytecodeIndex, ExitKind kind) const
     146    {
     147        return hasExitSite(FrequentExitSite(bytecodeIndex, kind));
     148    }
     149   
    136150private:
    137151    friend class QueryableExitProfile;
  • trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp

    r140594 r146089  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6565    case ArgumentsEscaped:
    6666        return "ArgumentsEscaped";
     67    case NotStringObject:
     68        return "NotStringObject";
    6769    case Uncountable:
    6870        return "Uncountable";
  • trunk/Source/JavaScriptCore/bytecode/ExitKind.h

    r138871 r146089  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4545    InadequateCoverage, // We exited because we ended up in code that didn't have profiling coverage.
    4646    ArgumentsEscaped, // We exited because arguments escaped but we didn't expect them to.
     47    NotStringObject, // We exited because we shouldn't have attempted to optimize string object access.
    4748    Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
    4849    UncountableWatchpoint // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves.
  • trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp

    r139541 r146089  
    11/*
    2  * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3434#include "JSFunction.h"
    3535#include "Operations.h"
     36#include "StringObject.h"
    3637#include "ValueProfile.h"
    3738#include <wtf/BoundsCheckedPointer.h>
     
    121122        isTop = false;
    122123   
    123     if (value & SpecMyArguments)
    124         myOut.print("Myarguments");
    125     else
    126         isTop = false;
    127    
    128     if (value & SpecForeignArguments)
    129         myOut.print("Foreignarguments");
     124    if (value & SpecArguments)
     125        myOut.print("Arguments");
    130126    else
    131127        isTop = false;
     
    133129    if (value & SpecString)
    134130        myOut.print("String");
     131    else
     132        isTop = false;
     133   
     134    if (value & SpecStringObject)
     135        myOut.print("Stringobject");
    135136    else
    136137        isTop = false;
     
    198199    if (isFloat64ArraySpeculation(prediction))
    199200        return "<Float64array>";
    200     if (isMyArgumentsSpeculation(prediction))
    201         return "<Myarguments>";
    202201    if (isArgumentsSpeculation(prediction))
    203202        return "<Arguments>";
     203    if (isStringObjectSpeculation(prediction))
     204        return "<StringObject>";
     205    if (isStringOrStringObjectSpeculation(prediction))
     206        return "<StringOrStringObject>";
    204207    if (isObjectSpeculation(prediction))
    205208        return "<Object>";
     
    233236   
    234237    if (classInfo == &Arguments::s_info)
    235         return SpecArguments; // Cannot distinguish between MyArguments and ForeignArguments at this stage. That happens in the flow analysis.
     238        return SpecArguments;
     239   
     240    if (classInfo == &StringObject::s_info)
     241        return SpecStringObject;
    236242   
    237243    if (classInfo->isSubClassOf(&JSFunction::s_info))
    238244        return SpecFunction;
    239 
    240245   
    241246    if (classInfo->typedArrayStorageType != TypedArrayNone) {
  • trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h

    r142695 r146089  
    11/*
    2  * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5050static const SpeculatedType SpecFloat32Array      = 0x00000800; // It's definitely an Uint16Array or one of its subclasses.
    5151static const SpeculatedType SpecFloat64Array      = 0x00001000; // It's definitely an Uint16Array or one of its subclasses.
    52 static const SpeculatedType SpecMyArguments       = 0x00002000; // It's definitely an Arguments object, and it's definitely the one for my current frame.
    53 static const SpeculatedType SpecForeignArguments  = 0x00004000; // It's definitely an Arguments object, and it's definitely not mine.
    54 static const SpeculatedType SpecArguments         = 0x00006000; // It's definitely an Arguments object.
     52static const SpeculatedType SpecArguments         = 0x00002000; // It's definitely an Arguments object.
     53static const SpeculatedType SpecStringObject      = 0x00004000; // It's definitely a StringObject.
    5554static const SpeculatedType SpecObjectOther       = 0x00008000; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
    5655static const SpeculatedType SpecObject            = 0x0000ffff; // Bitmask used for testing for any kind of object prediction.
     
    215214}
    216215
    217 inline bool isMyArgumentsSpeculation(SpeculatedType value)
    218 {
    219     return value == SpecMyArguments;
     216inline bool isStringObjectSpeculation(SpeculatedType value)
     217{
     218    return value == SpecStringObject;
     219}
     220
     221inline bool isStringOrStringObjectSpeculation(SpeculatedType value)
     222{
     223    return !!value && !(value & ~(SpecString | SpecStringObject));
    220224}
    221225
  • trunk/Source/JavaScriptCore/create_hash_table

    r111129 r146089  
    272272
    273273        my $intrinsic = "NoIntrinsic";
    274         $intrinsic = "CharCodeAtIntrinsic" if ($key eq "charCodeAt");
    275         $intrinsic = "CharAtIntrinsic" if ($key eq "charAt");
    276274        $intrinsic = "FromCharCodeIntrinsic" if ($key eq "fromCharCode");
    277275        if ($name eq "mathTable") {
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp

    r145052 r146089  
    3434#include "Operations.h"
    3535#include "PutByIdStatus.h"
     36#include "StringObject.h"
    3637
    3738namespace JSC { namespace DFG {
     
    770771            break;
    771772        }
    772         forNode(node).set(SpecString);
     773        forNode(node).set(m_graph.m_globalData.stringStructure.get());
    773774        break;
    774775    }
     
    858859    case StringCharAt:
    859860        node->setCanExit(true);
    860         forNode(node).set(SpecString);
     861        forNode(node).set(m_graph.m_globalData.stringStructure.get());
    861862        break;
    862863           
     
    877878            break;
    878879        case Array::String:
    879             forNode(node).set(SpecString);
     880            forNode(node).set(m_graph.m_globalData.stringStructure.get());
    880881            break;
    881882        case Array::Arguments:
     
    10321033        }
    10331034       
    1034         if (node->child1().useKind() == Int32Use) {
    1035             forNode(node).set(SpecInt32);
    1036             break;
    1037         }
    1038 
     1035        ASSERT(node->child1().useKind() == UntypedUse);
     1036       
    10391037        AbstractValue& source = forNode(node->child1());
    10401038        AbstractValue& destination = forNode(node);
     
    10611059        // deal since we don't do any optimization on those currently.
    10621060       
     1061        clobberWorld(node->codeOrigin, indexInBlock);
     1062       
    10631063        SpeculatedType type = source.m_type;
    10641064        if (type & ~(SpecNumber | SpecString | SpecBoolean)) {
     
    10691069        break;
    10701070    }
     1071       
     1072    case ToString: {
     1073        switch (node->child1().useKind()) {
     1074        case StringObjectUse:
     1075            // This also filters that the StringObject has the primordial StringObject
     1076            // structure.
     1077            forNode(node->child1()).filter(m_graph.globalObjectFor(node->codeOrigin)->stringObjectStructure());
     1078            node->setCanExit(true); // We could be more precise but it's likely not worth it.
     1079            break;
     1080        case StringOrStringObjectUse:
     1081            node->setCanExit(true); // We could be more precise but it's likely not worth it.
     1082            break;
     1083        case CellUse:
     1084        case UntypedUse:
     1085            clobberWorld(node->codeOrigin, indexInBlock);
     1086            break;
     1087        default:
     1088            RELEASE_ASSERT_NOT_REACHED();
     1089            break;
     1090        }
     1091        forNode(node).set(m_graph.m_globalData.stringStructure.get());
     1092        break;
     1093    }
     1094       
     1095    case NewStringObject: {
     1096        ASSERT(node->structure()->classInfo() == &StringObject::s_info);
     1097        forNode(node).set(node->structure());
     1098        break;
     1099    }
    10711100           
    10721101    case StrCat:
    1073         forNode(node).set(SpecString);
     1102        forNode(node).set(m_graph.m_globalData.stringStructure.get());
    10741103        break;
    10751104           
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractState.h

    r144991 r146089  
    191191        case KnownNumberUse:
    192192        case KnownCellUse:
     193        case KnownStringUse:
    193194            ASSERT(!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())));
    194195            break;
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r145828 r146089  
    4040#include "PutByIdStatus.h"
    4141#include "ResolveGlobalStatus.h"
     42#include "StringConstructor.h"
    4243#include <wtf/CommaPrinter.h>
    4344#include <wtf/HashMap.h>
     
    165166    void handleCall(Interpreter*, Instruction* currentInstruction, NodeType op, CodeSpecializationKind);
    166167    void emitFunctionChecks(const CallLinkStatus&, Node* callTarget, int registerOffset, CodeSpecializationKind);
     168    void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind);
    167169    // Handle inlining. Return true if it succeeded, false if we need to plant a call.
    168170    bool handleInlining(bool usesResult, Node* callTargetNode, int resultOperand, const CallLinkStatus&, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, CodeSpecializationKind);
     
    12071209
    12081210    if (InternalFunction* function = callLinkStatus.internalFunction()) {
    1209         if (handleConstantInternalFunction(usesResult, resultOperand, function, registerOffset, argumentCountIncludingThis, prediction, kind))
     1211        if (handleConstantInternalFunction(usesResult, resultOperand, function, registerOffset, argumentCountIncludingThis, prediction, kind)) {
     1212            // This phantoming has to be *after* the code for the intrinsic, to signify that
     1213            // the inputs must be kept alive whatever exits the intrinsic may do.
     1214            addToGraph(Phantom, callTarget);
     1215            emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, kind);
    12101216            return;
    1211            
     1217        }
     1218       
    12121219        // Can only handle this using the generic call handler.
    12131220        addCall(interpreter, currentInstruction, op);
     
    12201227           
    12211228        if (handleIntrinsic(usesResult, resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction)) {
    1222             // Need to keep all inputs alive for OSR, and need to ensure that we get
    1223             // backwards propagation of NodeUsedAsValue. Note that inlining doesn't
    1224             // need to do this because it already Flushes the arguments, which has a
    1225             // similar effect.
     1229            // This phantoming has to be *after* the code for the intrinsic, to signify that
     1230            // the inputs must be kept alive whatever exits the intrinsic may do.
    12261231            addToGraph(Phantom, callTarget);
    1227             for (int i = 0; i < argumentCountIncludingThis; ++i)
    1228                 addToGraph(Phantom, get(registerOffset + argumentToOperand(i)));
    1229            
     1232            emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, kind);
    12301233            return;
    12311234        }
     
    12601263        addToGraph(CheckExecutable, OpInfo(callLinkStatus.executable()), callTarget, thisArgument);
    12611264    }
     1265}
     1266
     1267void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind kind)
     1268{
     1269    for (int i = kind == CodeForCall ? 0 : 1; i < argumentCountIncludingThis; ++i)
     1270        addToGraph(Phantom, get(registerOffset + argumentToOperand(i)));
    12621271}
    12631272
     
    16291638   
    16301639    UNUSED_PARAM(prediction); // Remove this once we do more things.
    1631     UNUSED_PARAM(kind); // Remove this once we do more things.
    16321640   
    16331641    if (function->classInfo() == &ArrayConstructor::s_info) {
     
    16441652            usesResult, resultOperand,
    16451653            addToGraph(Node::VarArg, NewArray, OpInfo(ArrayWithUndecided), OpInfo(0)));
     1654        return true;
     1655    } else if (function->classInfo() == &StringConstructor::s_info) {
     1656        Node* result;
     1657       
     1658        if (argumentCountIncludingThis <= 1)
     1659            result = cellConstant(m_globalData->smallStrings.emptyString());
     1660        else
     1661            result = addToGraph(ToString, get(registerOffset + argumentToOperand(1)));
     1662       
     1663        if (kind == CodeForConstruct)
     1664            result = addToGraph(NewStringObject, OpInfo(function->globalObject()->stringObjectStructure()), result);
     1665       
     1666        setIntrinsicResult(usesResult, resultOperand, result);
    16461667        return true;
    16471668    }
  • trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

    r144973 r146089  
    577577            case ReallocatePropertyStorage:
    578578            case TypeOf:
     579            case ToString:
     580            case NewStringObject:
    579581                return 0;
    580582               
  • trunk/Source/JavaScriptCore/dfg/DFGEdge.h

    r144452 r146089  
    149149   
    150150#if USE(JSVALUE64)
    151     static uint32_t shift() { return 5; }
     151    static uint32_t shift() { return 6; }
    152152   
    153153    static uintptr_t makeWord(Node* node, UseKind useKind, ProofStatus proofStatus)
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r145578 r146089  
    527527           
    528528        case ToPrimitive: {
    529             if (node->child1()->shouldSpeculateInteger())
     529            if (node->child1()->shouldSpeculateInteger()) {
    530530                setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
     531                node->convertToIdentity();
     532                break;
     533            }
     534           
     535            if (node->child1()->shouldSpeculateString()) {
     536                setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
     537                node->convertToIdentity();
     538                break;
     539            }
     540           
     541            if (node->child1()->shouldSpeculateStringObject()
     542                && canOptimizeStringObjectAccess(node->codeOrigin)) {
     543                setUseKindAndUnboxIfProfitable<StringObjectUse>(node->child1());
     544                node->convertToToString();
     545                break;
     546            }
     547           
     548            if (node->child1()->shouldSpeculateStringOrStringObject()
     549                && canOptimizeStringObjectAccess(node->codeOrigin)) {
     550                setUseKindAndUnboxIfProfitable<StringOrStringObjectUse>(node->child1());
     551                node->convertToToString();
     552                break;
     553            }
     554           
    531555            // FIXME: Add string speculation here.
    532556            // https://bugs.webkit.org/show_bug.cgi?id=110175
     557            break;
     558        }
     559           
     560        case ToString: {
     561            if (node->child1()->shouldSpeculateString()) {
     562                setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
     563                node->convertToIdentity();
     564                break;
     565            }
     566           
     567            if (node->child1()->shouldSpeculateStringObject()
     568                && canOptimizeStringObjectAccess(node->codeOrigin)) {
     569                setUseKindAndUnboxIfProfitable<StringObjectUse>(node->child1());
     570                break;
     571            }
     572           
     573            if (node->child1()->shouldSpeculateStringOrStringObject()
     574                && canOptimizeStringObjectAccess(node->codeOrigin)) {
     575                setUseKindAndUnboxIfProfitable<StringOrStringObjectUse>(node->child1());
     576                break;
     577            }
     578           
     579            if (node->child1()->shouldSpeculateCell()) {
     580                setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
     581                break;
     582            }
     583           
     584            break;
     585        }
     586           
     587        case NewStringObject: {
     588            setUseKindAndUnboxIfProfitable<KnownStringUse>(node->child1());
    533589            break;
    534590        }
     
    807863    }
    808864   
     865    bool isStringPrototypeMethodSane(Structure* stringPrototypeStructure, const Identifier& ident)
     866    {
     867        unsigned attributesUnused;
     868        JSCell* specificValue;
     869        PropertyOffset offset = stringPrototypeStructure->get(
     870            globalData(), ident, attributesUnused, specificValue);
     871        if (!isValidOffset(offset))
     872            return false;
     873       
     874        if (!specificValue)
     875            return false;
     876       
     877        if (!specificValue->inherits(&JSFunction::s_info))
     878            return false;
     879       
     880        JSFunction* function = jsCast<JSFunction*>(specificValue);
     881        if (function->executable()->intrinsicFor(CodeForCall) != StringPrototypeValueOfIntrinsic)
     882            return false;
     883       
     884        return true;
     885    }
     886   
     887    bool canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin)
     888    {
     889        if (m_graph.hasExitSite(codeOrigin, NotStringObject))
     890            return false;
     891       
     892        Structure* stringObjectStructure = m_graph.globalObjectFor(codeOrigin)->stringObjectStructure();
     893        ASSERT(stringObjectStructure->storedPrototype().isObject());
     894        ASSERT(stringObjectStructure->storedPrototype().asCell()->classInfo() == &StringPrototype::s_info);
     895       
     896        JSObject* stringPrototypeObject = asObject(stringObjectStructure->storedPrototype());
     897        Structure* stringPrototypeStructure = stringPrototypeObject->structure();
     898        if (stringPrototypeStructure->transitionWatchpointSetHasBeenInvalidated())
     899            return false;
     900       
     901        if (stringPrototypeStructure->isDictionary())
     902            return false;
     903       
     904        // We're being conservative here. We want DFG's ToString on StringObject to be
     905        // used in both numeric contexts (that would call valueOf()) and string contexts
     906        // (that would call toString()). We don't want the DFG to have to distinguish
     907        // between the two, just because that seems like it would get confusing. So we
     908        // just require both methods to be sane.
     909        if (!isStringPrototypeMethodSane(stringPrototypeStructure, globalData().propertyNames->valueOf))
     910            return false;
     911        if (!isStringPrototypeMethodSane(stringPrototypeStructure, globalData().propertyNames->toString))
     912            return false;
     913       
     914        return true;
     915    }
     916   
    809917    void fixupSetLocalsInBlock(BasicBlock* block)
    810918    {
     
    9751083        case ObjectUse:
    9761084        case StringUse:
     1085        case KnownStringUse:
     1086        case StringObjectUse:
     1087        case StringOrStringObjectUse:
    9771088            if (alwaysUnboxSimplePrimitives()
    9781089                || isCellSpeculation(variable->prediction()))
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r145052 r146089  
    377377    }
    378378   
     379    bool hasGlobalExitSite(const CodeOrigin& codeOrigin, ExitKind exitKind)
     380    {
     381        return baselineCodeBlockFor(codeOrigin)->hasExitSite(FrequentExitSite(exitKind));
     382    }
     383   
     384    bool hasExitSite(const CodeOrigin& codeOrigin, ExitKind exitKind)
     385    {
     386        return baselineCodeBlockFor(codeOrigin)->hasExitSite(FrequentExitSite(codeOrigin.bytecodeIndex, exitKind));
     387    }
     388   
    379389    int argumentsRegisterFor(const CodeOrigin& codeOrigin)
    380390    {
     
    523533        case PutByValAlias:
    524534            return !byValIsPure(node);
     535        case ToString:
     536            switch (node->child1().useKind()) {
     537            case StringObjectUse:
     538            case StringOrStringObjectUse:
     539                return false;
     540            case CellUse:
     541            case UntypedUse:
     542                return true;
     543            default:
     544                RELEASE_ASSERT_NOT_REACHED();
     545                return true;
     546            }
    525547        default:
    526548            RELEASE_ASSERT_NOT_REACHED();
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r145052 r146089  
    350350    }
    351351   
     352    void convertToToString()
     353    {
     354        ASSERT(m_op == ToPrimitive);
     355        m_op = ToString;
     356    }
     357   
    352358    JSCell* weakConstant()
    353359    {
     
    845851        case ArrayifyToStructure:
    846852        case NewObject:
     853        case NewStringObject:
    847854            return true;
    848855        default:
     
    11211128    }
    11221129 
     1130    bool shouldSpeculateStringObject()
     1131    {
     1132        return isStringObjectSpeculation(prediction());
     1133    }
     1134   
     1135    bool shouldSpeculateStringOrStringObject()
     1136    {
     1137        return isStringOrStringObjectSpeculation(prediction());
     1138    }
     1139   
    11231140    bool shouldSpeculateFinalObject()
    11241141    {
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r144862 r146089  
    223223    macro(LogicalNot, NodeResultBoolean) \
    224224    macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
     225    macro(ToString, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
     226    macro(NewStringObject, NodeResultJS) \
    225227    macro(StrCat, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
    226228    \
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r145945 r146089  
    15461546
    15471547    return string->value(exec).impl();
     1548}
     1549
     1550JSCell* DFG_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
     1551{
     1552    JSGlobalData& globalData = exec->globalData();
     1553    NativeCallFrameTracer tracer(&globalData, exec);
     1554   
     1555    return StringObject::create(exec, structure, string);
     1556}
     1557
     1558JSCell* DFG_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
     1559{
     1560    JSGlobalData& globalData = exec->globalData();
     1561    NativeCallFrameTracer tracer(&globalData, exec);
     1562   
     1563    return JSValue(cell).toString(exec);
     1564}
     1565
     1566JSCell* DFG_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
     1567{
     1568    JSGlobalData& globalData = exec->globalData();
     1569    NativeCallFrameTracer tracer(&globalData, exec);
     1570
     1571    return JSValue::decode(value).toString(exec);
    15481572}
    15491573
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r143165 r146089  
    8686typedef JSCell* DFG_OPERATION (*C_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*);
    8787typedef JSCell* DFG_OPERATION (*C_DFGOperation_EIcf)(ExecState*, InlineCallFrame*);
     88typedef JSCell* DFG_OPERATION (*C_DFGOperation_EJ)(ExecState*, EncodedJSValue);
     89typedef JSCell* DFG_OPERATION (*C_DFGOperation_EJssSt)(ExecState*, JSString*, Structure*);
    8890typedef JSCell* DFG_OPERATION (*C_DFGOperation_EOZ)(ExecState*, JSObject*, int32_t);
    8991typedef JSCell* DFG_OPERATION (*C_DFGOperation_ESt)(ExecState*, Structure*);
     
    213215char* DFG_OPERATION operationEnsureArrayStorage(ExecState*, JSCell*);
    214216StringImpl* DFG_OPERATION operationResolveRope(ExecState*, JSString*);
     217JSCell* DFG_OPERATION operationNewStringObject(ExecState*, JSString*, Structure*);
     218JSCell* DFG_OPERATION operationToStringOnCell(ExecState*, JSCell*);
     219JSCell* DFG_OPERATION operationToString(ExecState*, EncodedJSValue);
    215220
    216221// This method is used to lookup an exception hander, keyed by faultLocation, which is
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r145491 r146089  
    414414       
    415415        case StringCharAt:
    416         case StrCat: {
     416        case StrCat:
     417        case ToString: {
    417418            changed |= setPrediction(SpecString);
    418419            break;
     
    437438                    changed |= mergePrediction(child);
    438439            }
     440            break;
     441        }
     442           
     443        case NewStringObject: {
     444            changed |= setPrediction(SpecStringObject);
    439445            break;
    440446        }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r145933 r146089  
    39233923}
    39243924
     3925void SpeculativeJIT::compileToStringOnCell(Node* node)
     3926{
     3927    SpeculateCellOperand op1(this, node->child1());
     3928    GPRReg op1GPR = op1.gpr();
     3929   
     3930    switch (node->child1().useKind()) {
     3931    case StringObjectUse: {
     3932        GPRTemporary result(this);
     3933        GPRReg resultGPR = result.gpr();
     3934       
     3935        if (!m_state.forNode(node->child1()).m_currentKnownStructure.isSubsetOf(StructureSet(m_jit.globalObjectFor(node->codeOrigin)->stringObjectStructure()))) {
     3936            speculateStringObject(op1GPR);
     3937            m_state.forNode(node->child1()).filter(SpecStringObject);
     3938        }
     3939        m_jit.loadPtr(JITCompiler::Address(op1GPR, JSWrapperObject::internalValueCellOffset()), resultGPR);
     3940        cellResult(resultGPR, node);
     3941        break;
     3942    }
     3943       
     3944    case StringOrStringObjectUse: {
     3945        GPRTemporary result(this);
     3946        GPRReg resultGPR = result.gpr();
     3947       
     3948        m_jit.loadPtr(JITCompiler::Address(op1GPR, JSCell::structureOffset()), resultGPR);
     3949        JITCompiler::Jump isString = m_jit.branchPtr(
     3950            JITCompiler::Equal, resultGPR, TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
     3951       
     3952        speculateStringObjectForStructure(resultGPR);
     3953       
     3954        m_jit.loadPtr(JITCompiler::Address(op1GPR, JSWrapperObject::internalValueCellOffset()), resultGPR);
     3955       
     3956        JITCompiler::Jump done = m_jit.jump();
     3957        isString.link(&m_jit);
     3958        m_jit.move(op1GPR, resultGPR);
     3959        done.link(&m_jit);
     3960       
     3961        m_state.forNode(node->child1()).filter(SpecString | SpecStringObject);
     3962       
     3963        cellResult(resultGPR, node);
     3964        break;
     3965    }
     3966       
     3967    case CellUse: {
     3968        GPRResult result(this);
     3969        GPRReg resultGPR = result.gpr();
     3970       
     3971        // We flush registers instead of silent spill/fill because in this mode we
     3972        // believe that most likely the input is not a string, and we need to take
     3973        // slow path.
     3974        flushRegisters();
     3975        JITCompiler::Jump done;
     3976        if (node->child1()->prediction() & SpecString) {
     3977            done = m_jit.branchPtr(
     3978                JITCompiler::Equal,
     3979                JITCompiler::Address(op1GPR, JSCell::structureOffset()),
     3980                TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
     3981        }
     3982        callOperation(operationToStringOnCell, resultGPR, op1GPR);
     3983        if (done.isSet())
     3984            done.link(&m_jit);
     3985        cellResult(resultGPR, node);
     3986        break;
     3987    }
     3988       
     3989    default:
     3990        RELEASE_ASSERT_NOT_REACHED();
     3991    }
     3992}
     3993
     3994void SpeculativeJIT::compileNewStringObject(Node* node)
     3995{
     3996    SpeculateCellOperand operand(this, node->child1());
     3997   
     3998    GPRTemporary result(this);
     3999    GPRTemporary scratch1(this);
     4000    GPRTemporary scratch2(this);
     4001
     4002    GPRReg operandGPR = operand.gpr();
     4003    GPRReg resultGPR = result.gpr();
     4004    GPRReg scratch1GPR = scratch1.gpr();
     4005    GPRReg scratch2GPR = scratch2.gpr();
     4006   
     4007    JITCompiler::JumpList slowPath;
     4008   
     4009    emitAllocateJSObject<StringObject>(
     4010        resultGPR, TrustedImmPtr(node->structure()), TrustedImmPtr(0), scratch1GPR, scratch2GPR,
     4011        slowPath);
     4012   
     4013    m_jit.storePtr(
     4014        TrustedImmPtr(&StringObject::s_info),
     4015        JITCompiler::Address(resultGPR, JSDestructibleObject::classInfoOffset()));
     4016#if USE(JSVALUE64)
     4017    m_jit.store64(
     4018        operandGPR, JITCompiler::Address(resultGPR, JSWrapperObject::internalValueOffset()));
     4019#else
     4020    m_jit.store32(
     4021        TrustedImm32(JSValue::CellTag),
     4022        JITCompiler::Address(resultGPR, JSWrapperObject::internalValueOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
     4023    m_jit.store32(
     4024        operandGPR,
     4025        JITCompiler::Address(resultGPR, JSWrapperObject::internalValueOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
     4026#endif
     4027   
     4028    addSlowPathGenerator(slowPathCall(
     4029        slowPath, this, operationNewStringObject, resultGPR, operandGPR, node->structure()));
     4030   
     4031    cellResult(resultGPR, node);
     4032}
     4033
    39254034void SpeculativeJIT::speculateInt32(Edge edge)
    39264035{
     
    39744083   
    39754084    SpeculateCellOperand operand(this, edge);
     4085    GPRReg gpr = operand.gpr();
    39764086    DFG_TYPE_CHECK(
    3977         JSValueSource::unboxedCell(operand.gpr()), edge, SpecObject, m_jit.branchPtr(
     4087        JSValueSource::unboxedCell(gpr), edge, SpecObject, m_jit.branchPtr(
    39784088            MacroAssembler::Equal,
    3979             MacroAssembler::Address(operand.gpr(), JSCell::structureOffset()),
     4089            MacroAssembler::Address(gpr, JSCell::structureOffset()),
    39804090            MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
    39814091}
     
    39944104        MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister);
    39954105    DFG_TYPE_CHECK(
    3996         JSValueRegs(operand.gpr()), edge, (~SpecCell) | SpecObject, m_jit.branchPtr(
     4106        JSValueRegs(gpr), edge, (~SpecCell) | SpecObject, m_jit.branchPtr(
    39974107            MacroAssembler::Equal,
    39984108            MacroAssembler::Address(gpr, JSCell::structureOffset()),
     
    40434153   
    40444154    SpeculateCellOperand operand(this, edge);
     4155    GPRReg gpr = operand.gpr();
    40454156    DFG_TYPE_CHECK(
    4046         JSValueSource::unboxedCell(operand.gpr()), edge, SpecString, m_jit.branchPtr(
     4157        JSValueSource::unboxedCell(gpr), edge, SpecString, m_jit.branchPtr(
    40474158            MacroAssembler::NotEqual,
    4048             MacroAssembler::Address(operand.gpr(), JSCell::structureOffset()),
     4159            MacroAssembler::Address(gpr, JSCell::structureOffset()),
    40494160            MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
     4161}
     4162
     4163void SpeculativeJIT::speculateStringObject(GPRReg gpr)
     4164{
     4165    speculateStringObjectForStructure(JITCompiler::Address(gpr, JSCell::structureOffset()));
     4166}
     4167
     4168void SpeculativeJIT::speculateStringObject(Edge edge)
     4169{
     4170    if (!needsTypeCheck(edge, SpecStringObject))
     4171        return;
     4172   
     4173    SpeculateCellOperand operand(this, edge);
     4174    GPRReg gpr = operand.gpr();
     4175    if (!needsTypeCheck(edge, SpecStringObject))
     4176        return;
     4177   
     4178    speculateStringObject(gpr);
     4179    m_state.forNode(edge).filter(SpecStringObject);
     4180}
     4181
     4182void SpeculativeJIT::speculateStringOrStringObject(Edge edge)
     4183{
     4184    if (!needsTypeCheck(edge, SpecString | SpecStringObject))
     4185        return;
     4186   
     4187    SpeculateCellOperand operand(this, edge);
     4188    GPRReg gpr = operand.gpr();
     4189    if (!needsTypeCheck(edge, SpecString | SpecStringObject))
     4190        return;
     4191   
     4192    GPRTemporary structure(this);
     4193    GPRReg structureGPR = structure.gpr();
     4194   
     4195    m_jit.loadPtr(JITCompiler::Address(gpr, JSCell::structureOffset()), structureGPR);
     4196   
     4197    JITCompiler::Jump isString = m_jit.branchPtr(
     4198        JITCompiler::Equal, structureGPR, TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
     4199   
     4200    speculateStringObjectForStructure(structureGPR);
     4201   
     4202    isString.link(&m_jit);
     4203   
     4204    m_state.forNode(edge).filter(SpecString | SpecStringObject);
    40504205}
    40514206
     
    41084263        ASSERT(!needsTypeCheck(edge, SpecCell));
    41094264        break;
     4265    case KnownStringUse:
     4266        ASSERT(!needsTypeCheck(edge, SpecString));
     4267        break;
    41104268    case Int32Use:
    41114269        speculateInt32(edge);
     
    41324290        speculateString(edge);
    41334291        break;
     4292    case StringObjectUse:
     4293        speculateStringObject(edge);
     4294        break;
     4295    case StringOrStringObjectUse:
     4296        speculateStringOrStringObject(edge);
     4297        break;
    41344298    case NotCellUse:
    41354299        speculateNotCell(edge);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r145931 r146089  
    10861086        return appendCallWithExceptionCheckSetResult(operation, result);
    10871087    }
     1088    JITCompiler::Call callOperation(C_DFGOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
     1089    {
     1090        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
     1091        return appendCallWithExceptionCheckSetResult(operation, result);
     1092    }
     1093    JITCompiler::Call callOperation(C_DFGOperation_EJ operation, GPRReg result, GPRReg arg1)
     1094    {
     1095        m_jit.setupArgumentsWithExecState(arg1);
     1096        return appendCallWithExceptionCheckSetResult(operation, result);
     1097    }
    10881098    JITCompiler::Call callOperation(S_DFGOperation_J operation, GPRReg result, GPRReg arg1)
    10891099    {
     
    14721482    {
    14731483        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
     1484        return appendCallWithExceptionCheckSetResult(operation, result);
     1485    }
     1486    JITCompiler::Call callOperation(C_DFGOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
     1487    {
     1488        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
     1489        return appendCallWithExceptionCheckSetResult(operation, result);
     1490    }
     1491    JITCompiler::Call callOperation(C_DFGOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
     1492    {
     1493        m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag);
    14741494        return appendCallWithExceptionCheckSetResult(operation, result);
    14751495    }
     
    20312051    void emitObjectOrOtherBranch(Edge value, BlockIndex taken, BlockIndex notTaken);
    20322052    void emitBranch(Node*);
     2053   
     2054    void compileToStringOnCell(Node*);
     2055    void compileNewStringObject(Node*);
    20332056   
    20342057    void compileIntegerCompare(Node*, MacroAssembler::RelationalCondition);
     
    22052228    void speculateObjectOrOther(Edge);
    22062229    void speculateString(Edge);
     2230    template<typename StructureLocationType>
     2231    void speculateStringObjectForStructure(StructureLocationType);
     2232    void speculateStringObject(GPRReg);
     2233    void speculateStringObject(Edge);
     2234    void speculateStringOrStringObject(Edge);
    22072235    void speculateNotCell(Edge);
    22082236    void speculateOther(Edge);
     
    28392867    {
    28402868        ASSERT(m_jit);
    2841         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == CellUse || edge.useKind() == KnownCellUse || edge.useKind() == ObjectUse || edge.useKind() == StringUse));
     2869        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == CellUse || edge.useKind() == KnownCellUse || edge.useKind() == ObjectUse || edge.useKind() == StringUse || edge.useKind() == KnownStringUse || edge.useKind() == StringObjectUse || edge.useKind() == StringOrStringObjectUse));
    28422870        if (jit->isFilled(node()))
    28432871            gpr();
     
    29252953};
    29262954
     2955template<typename StructureLocationType>
     2956void SpeculativeJIT::speculateStringObjectForStructure(StructureLocationType structureLocation)
     2957{
     2958    Structure* stringObjectStructure =
     2959        m_jit.globalObjectFor(m_currentNode->codeOrigin)->stringObjectStructure();
     2960    Structure* stringPrototypeStructure = stringObjectStructure->storedPrototype().asCell()->structure();
     2961    ASSERT(stringPrototypeStructure->transitionWatchpointSetIsStillValid());
     2962   
     2963    speculationCheck(
     2964        NotStringObject, JSValueRegs(), 0,
     2965        m_jit.branchPtr(
     2966            JITCompiler::NotEqual, structureLocation, TrustedImmPtr(stringObjectStructure)));
     2967    stringPrototypeStructure->addTransitionWatchpoint(speculationWatchpoint(NotStringObject));
     2968}
     2969
    29272970#define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \
    29282971        if (!needsTypeCheck((edge), (typesPassedThrough)))              \
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r145931 r146089  
    11001100    AbstractValue& value = m_state.forNode(edge);
    11011101    SpeculatedType type = value.m_type;
    1102     ASSERT(edge.useKind() != KnownCellUse || !(value.m_type & ~SpecCell));
     1102    ASSERT((edge.useKind() != KnownCellUse && edge.useKind() != KnownStringUse) || !(value.m_type & ~SpecCell));
    11031103    value.filter(SpecCell);
    11041104    VirtualRegister virtualRegister = edge->virtualRegister();
     
    32593259       
    32603260    case ToPrimitive: {
    3261         switch (node->child1().useKind()) {
    3262         case Int32Use: {
    3263             // It's really profitable to speculate integer, since it's really cheap,
    3264             // it means we don't have to do any real work, and we emit a lot less code.
    3265            
    3266             SpeculateIntegerOperand op1(this, node->child1());
    3267             GPRTemporary result(this, op1);
    3268            
    3269             ASSERT(op1.format() == DataFormatInteger);
    3270             m_jit.move(op1.gpr(), result.gpr());
    3271            
    3272             integerResult(result.gpr(), node);
    3273             break;
    3274         }
    3275 
    3276         case UntypedUse: {
     3261        RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
     3262        JSValueOperand op1(this, node->child1());
     3263        GPRTemporary resultTag(this, op1);
     3264        GPRTemporary resultPayload(this, op1, false);
     3265       
     3266        GPRReg op1TagGPR = op1.tagGPR();
     3267        GPRReg op1PayloadGPR = op1.payloadGPR();
     3268        GPRReg resultTagGPR = resultTag.gpr();
     3269        GPRReg resultPayloadGPR = resultPayload.gpr();
     3270       
     3271        op1.use();
     3272       
     3273        if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean))) {
     3274            m_jit.move(op1TagGPR, resultTagGPR);
     3275            m_jit.move(op1PayloadGPR, resultPayloadGPR);
     3276        } else {
     3277            MacroAssembler::Jump alreadyPrimitive = m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag));
     3278            MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1PayloadGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
     3279           
     3280            alreadyPrimitive.link(&m_jit);
     3281            m_jit.move(op1TagGPR, resultTagGPR);
     3282            m_jit.move(op1PayloadGPR, resultPayloadGPR);
     3283           
     3284            addSlowPathGenerator(
     3285                slowPathCall(
     3286                    notPrimitive, this, operationToPrimitive,
     3287                    JSValueRegs(resultTagGPR, resultPayloadGPR), op1TagGPR, op1PayloadGPR));
     3288        }
     3289       
     3290        jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
     3291        break;
     3292    }
     3293       
     3294    case ToString: {
     3295        if (node->child1().useKind() == UntypedUse) {
    32773296            JSValueOperand op1(this, node->child1());
    3278             GPRTemporary resultTag(this, op1);
    3279             GPRTemporary resultPayload(this, op1, false);
    3280        
     3297            GPRReg op1PayloadGPR = op1.payloadGPR();
    32813298            GPRReg op1TagGPR = op1.tagGPR();
    3282             GPRReg op1PayloadGPR = op1.payloadGPR();
    3283             GPRReg resultTagGPR = resultTag.gpr();
    3284             GPRReg resultPayloadGPR = resultPayload.gpr();
    3285        
    3286             op1.use();
    3287        
    3288             if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean))) {
    3289                 m_jit.move(op1TagGPR, resultTagGPR);
    3290                 m_jit.move(op1PayloadGPR, resultPayloadGPR);
    3291             } else {
    3292                 MacroAssembler::Jump alreadyPrimitive = m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag));
    3293                 MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1PayloadGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
    3294            
    3295                 alreadyPrimitive.link(&m_jit);
    3296                 m_jit.move(op1TagGPR, resultTagGPR);
    3297                 m_jit.move(op1PayloadGPR, resultPayloadGPR);
    3298            
    3299                 addSlowPathGenerator(
    3300                     slowPathCall(
    3301                         notPrimitive, this, operationToPrimitive,
    3302                         JSValueRegs(resultTagGPR, resultPayloadGPR), op1TagGPR, op1PayloadGPR));
     3299           
     3300            GPRResult result(this);
     3301            GPRReg resultGPR = result.gpr();
     3302           
     3303            flushRegisters();
     3304           
     3305            JITCompiler::Jump done;
     3306            if (node->child1()->prediction() & SpecString) {
     3307                JITCompiler::Jump slowPath = m_jit.branch32(
     3308                    JITCompiler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag));
     3309                done = m_jit.branchPtr(
     3310                    JITCompiler::Equal,
     3311                    JITCompiler::Address(op1PayloadGPR, JSCell::structureOffset()),
     3312                    TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
     3313                slowPath.link(&m_jit);
    33033314            }
    3304        
    3305             jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
    3306             break;
    3307         }
    3308            
    3309         default:
    3310             RELEASE_ASSERT_NOT_REACHED();
    3311             break;
    3312         }
     3315            callOperation(operationToString, resultGPR, op1TagGPR, op1PayloadGPR);
     3316            if (done.isSet())
     3317                done.link(&m_jit);
     3318            cellResult(resultGPR, node);
     3319            break;
     3320        }
     3321       
     3322        compileToStringOnCell(node);
     3323        break;
     3324    }
     3325       
     3326    case NewStringObject: {
     3327        compileNewStringObject(node);
    33133328        break;
    33143329    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r145931 r146089  
    11261126    AbstractValue& value = m_state.forNode(edge);
    11271127    SpeculatedType type = value.m_type;
    1128     ASSERT(edge.useKind() != KnownCellUse || !(value.m_type & ~SpecCell));
     1128    ASSERT((edge.useKind() != KnownCellUse && edge.useKind() != KnownStringUse) || !(value.m_type & ~SpecCell));
    11291129    value.filter(SpecCell);
    11301130    VirtualRegister virtualRegister = edge->virtualRegister();
     
    31893189       
    31903190    case ToPrimitive: {
    3191         switch (node->child1().useKind()) {
    3192         case Int32Use: {
    3193             // It's really profitable to speculate integer, since it's really cheap,
    3194             // it means we don't have to do any real work, and we emit a lot less code.
    3195            
    3196             SpeculateIntegerOperand op1(this, node->child1());
    3197             GPRTemporary result(this, op1);
    3198            
    3199             m_jit.move(op1.gpr(), result.gpr());
    3200             if (op1.format() == DataFormatInteger)
    3201                 m_jit.or64(GPRInfo::tagTypeNumberRegister, result.gpr());
    3202            
    3203             jsValueResult(result.gpr(), node);
    3204             break;
    3205         }
    3206        
    3207         case UntypedUse: {
     3191        RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
     3192        JSValueOperand op1(this, node->child1());
     3193        GPRTemporary result(this, op1);
     3194       
     3195        GPRReg op1GPR = op1.gpr();
     3196        GPRReg resultGPR = result.gpr();
     3197       
     3198        op1.use();
     3199       
     3200        if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean)))
     3201            m_jit.move(op1GPR, resultGPR);
     3202        else {
     3203            MacroAssembler::Jump alreadyPrimitive = m_jit.branchTest64(MacroAssembler::NonZero, op1GPR, GPRInfo::tagMaskRegister);
     3204            MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
     3205           
     3206            alreadyPrimitive.link(&m_jit);
     3207            m_jit.move(op1GPR, resultGPR);
     3208           
     3209            addSlowPathGenerator(
     3210                slowPathCall(notPrimitive, this, operationToPrimitive, resultGPR, op1GPR));
     3211        }
     3212       
     3213        jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
     3214        break;
     3215    }
     3216       
     3217    case ToString: {
     3218        if (node->child1().useKind() == UntypedUse) {
    32083219            JSValueOperand op1(this, node->child1());
    3209             GPRTemporary result(this, op1);
    3210        
    32113220            GPRReg op1GPR = op1.gpr();
     3221           
     3222            GPRResult result(this);
    32123223            GPRReg resultGPR = result.gpr();
    3213        
    3214             op1.use();
    3215        
    3216             if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean)))
    3217                 m_jit.move(op1GPR, resultGPR);
    3218             else {
    3219                 MacroAssembler::Jump alreadyPrimitive = m_jit.branchTest64(MacroAssembler::NonZero, op1GPR, GPRInfo::tagMaskRegister);
    3220                 MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
    3221            
    3222                 alreadyPrimitive.link(&m_jit);
    3223                 m_jit.move(op1GPR, resultGPR);
    3224            
    3225                 addSlowPathGenerator(
    3226                     slowPathCall(notPrimitive, this, operationToPrimitive, resultGPR, op1GPR));
     3224           
     3225            flushRegisters();
     3226           
     3227            JITCompiler::Jump done;
     3228            if (node->child1()->prediction() & SpecString) {
     3229                JITCompiler::Jump slowPath = m_jit.branchTest64(
     3230                    JITCompiler::NonZero, op1GPR, GPRInfo::tagMaskRegister);
     3231                done = m_jit.branchPtr(
     3232                    JITCompiler::Equal,
     3233                    JITCompiler::Address(op1GPR, JSCell::structureOffset()),
     3234                    TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
     3235                slowPath.link(&m_jit);
    32273236            }
    3228        
    3229             jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
    3230             break;
    3231         }
    3232            
    3233         default:
    3234             RELEASE_ASSERT_NOT_REACHED();
    3235             break;
    3236         }
     3237            callOperation(operationToString, resultGPR, op1GPR);
     3238            if (done.isSet())
     3239                done.link(&m_jit);
     3240            cellResult(resultGPR, node);
     3241            break;
     3242        }
     3243       
     3244        compileToStringOnCell(node);
     3245        break;
     3246    }
     3247       
     3248    case NewStringObject: {
     3249        compileNewStringObject(node);
    32373250        break;
    32383251    }
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp

    r143654 r146089  
    7272        out.print("String");
    7373        break;
     74    case KnownStringUse:
     75        out.print("KnownString");
     76        break;
     77    case StringObjectUse:
     78        out.print("StringObject");
     79        break;
     80    case StringOrStringObjectUse:
     81        out.print("StringOrStringObject");
     82        break;
    7483    case NotCellUse:
    7584        out.print("NotCell");
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.h

    r143654 r146089  
    4949    ObjectOrOtherUse,
    5050    StringUse,
     51    KnownStringUse,
     52    StringObjectUse,
     53    StringOrStringObjectUse,
    5154    NotCellUse,
    5255    OtherUse,
     
    7780        return SpecObject | SpecOther;
    7881    case StringUse:
     82    case KnownStringUse:
    7983        return SpecString;
     84    case StringObjectUse:
     85        return SpecStringObject;
     86    case StringOrStringObjectUse:
     87        return SpecString | SpecStringObject;
    8088    case NotCellUse:
    8189        return ~SpecCell;
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r146071 r146089  
    9595        static const HashTable* regExpConstructorTable(CallFrame* callFrame) { return callFrame->globalData().regExpConstructorTable; }
    9696        static const HashTable* regExpPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().regExpPrototypeTable; }
    97         static const HashTable* stringTable(CallFrame* callFrame) { return callFrame->globalData().stringTable; }
    9897        static const HashTable* stringConstructorTable(CallFrame* callFrame) { return callFrame->globalData().stringConstructorTable; }
    9998
  • trunk/Source/JavaScriptCore/runtime/Intrinsic.h

    r111129 r146089  
    4848    RegExpExecIntrinsic,
    4949    RegExpTestIntrinsic,
     50    StringPrototypeValueOfIntrinsic
    5051};
    5152
  • trunk/Source/JavaScriptCore/runtime/JSDestructibleObject.h

    r130303 r146089  
    1515
    1616    const ClassInfo* classInfo() const { return m_classInfo; }
     17   
     18    static ptrdiff_t classInfoOffset() { return OBJECT_OFFSETOF(JSDestructibleObject, m_classInfo); }
    1719
    1820protected:
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.cpp

    r146071 r146089  
    9898extern const HashTable regExpConstructorTable;
    9999extern const HashTable regExpPrototypeTable;
    100 extern const HashTable stringTable;
    101100extern const HashTable stringConstructorTable;
    102101
     
    159158    , regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
    160159    , regExpPrototypeTable(fastNew<HashTable>(JSC::regExpPrototypeTable))
    161     , stringTable(fastNew<HashTable>(JSC::stringTable))
    162160    , stringConstructorTable(fastNew<HashTable>(JSC::stringConstructorTable))
    163161    , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
     
    289287    regExpConstructorTable->deleteTable();
    290288    regExpPrototypeTable->deleteTable();
    291     stringTable->deleteTable();
    292289    stringConstructorTable->deleteTable();
    293290
     
    308305    fastDelete(const_cast<HashTable*>(regExpConstructorTable));
    309306    fastDelete(const_cast<HashTable*>(regExpPrototypeTable));
    310     fastDelete(const_cast<HashTable*>(stringTable));
    311307    fastDelete(const_cast<HashTable*>(stringConstructorTable));
    312308
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.h

    r146071 r146089  
    231231        const HashTable* regExpConstructorTable;
    232232        const HashTable* regExpPrototypeTable;
    233         const HashTable* stringTable;
    234233        const HashTable* stringConstructorTable;
    235234       
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r146071 r146089  
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    33 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    4  *  Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2012 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
    55 *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
    66 *
     
    3131#include "DatePrototype.h"
    3232#include "ErrorConstructor.h"
     33#include "Executable.h"
    3334#include "GetterSetter.h"
    3435#include "IndexingHeaderInlines.h"
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r146071 r146089  
    14551455// Use this macro from within finishCreation() methods in prototypes. This assumes
    14561456// you've defined variables called exec, globalObject, and globalData, and they
    1457 // have the expected meanings. This also assumes that the function you're defining
    1458 // doesn't have an intrinsic.
     1457// have the expected meanings.
     1458#define JSC_NATIVE_INTRINSIC_FUNCTION(jsName, cppName, attributes, length, intrinsic) \
     1459    putDirectNativeFunction(\
     1460        exec, globalObject, Identifier(exec, #jsName), (length), cppName, \
     1461        (intrinsic), (attributes))
     1462
     1463// As above, but this assumes that the function you're defining doesn't have an
     1464// intrinsic.
    14591465#define JSC_NATIVE_FUNCTION(jsName, cppName, attributes, length) \
    1460     putDirectNativeFunction(exec, globalObject, globalData.propertyNames->jsName, (length), cppName, NoIntrinsic, (attributes))
     1466    JSC_NATIVE_INTRINSIC_FUNCTION(jsName, cppName, (attributes), (length), NoIntrinsic)
    14611467
    14621468} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSWrapperObject.h

    r130303 r146089  
    3333        typedef JSDestructibleObject Base;
    3434
     35        static size_t allocationSize(size_t inlineCapacity)
     36        {
     37            ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
     38            return sizeof(JSWrapperObject);
     39        }
     40
    3541        JSValue internalValue() const;
    3642        void setInternalValue(JSGlobalData&, JSValue);
     
    3945        {
    4046            return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
     47        }
     48       
     49        static ptrdiff_t internalValueOffset() { return OBJECT_OFFSETOF(JSWrapperObject, m_internalValue); }
     50        static ptrdiff_t internalValueCellOffset()
     51        {
     52#if USE(JSVALUE64)
     53            return internalValueOffset();
     54#else
     55            return internalValueOffset() + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload);
     56#endif
    4157        }
    4258
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp

    r135800 r146089  
    11/*
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
    44 *  Copyright (C) 2009 Torch Mobile, Inc.
    55 *
     
    8383static EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState*);
    8484
    85 }
    86 
    87 #include "StringPrototype.lut.h"
    88 
    89 namespace JSC {
    90 
    91 const ClassInfo StringPrototype::s_info = { "String", &StringObject::s_info, 0, ExecState::stringTable, CREATE_METHOD_TABLE(StringPrototype) };
    92 
    93 /* Source for StringPrototype.lut.h
    94 @begin stringTable 26
    95     toString              stringProtoFuncToString          DontEnum|Function       0
    96     valueOf               stringProtoFuncToString          DontEnum|Function       0
    97     charAt                stringProtoFuncCharAt            DontEnum|Function       1
    98     charCodeAt            stringProtoFuncCharCodeAt        DontEnum|Function       1
    99     concat                stringProtoFuncConcat            DontEnum|Function       1
    100     indexOf               stringProtoFuncIndexOf           DontEnum|Function       1
    101     lastIndexOf           stringProtoFuncLastIndexOf       DontEnum|Function       1
    102     match                 stringProtoFuncMatch             DontEnum|Function       1
    103     replace               stringProtoFuncReplace           DontEnum|Function       2
    104     search                stringProtoFuncSearch            DontEnum|Function       1
    105     slice                 stringProtoFuncSlice             DontEnum|Function       2
    106     split                 stringProtoFuncSplit             DontEnum|Function       2
    107     substr                stringProtoFuncSubstr            DontEnum|Function       2
    108     substring             stringProtoFuncSubstring         DontEnum|Function       2
    109     toLowerCase           stringProtoFuncToLowerCase       DontEnum|Function       0
    110     toUpperCase           stringProtoFuncToUpperCase       DontEnum|Function       0
    111     localeCompare         stringProtoFuncLocaleCompare     DontEnum|Function       1
    112 
    113     # toLocaleLowerCase and toLocaleUpperCase are currently identical to toLowerCase and toUpperCase
    114     toLocaleLowerCase     stringProtoFuncToLowerCase       DontEnum|Function       0
    115     toLocaleUpperCase     stringProtoFuncToUpperCase       DontEnum|Function       0
    116 
    117     big                   stringProtoFuncBig               DontEnum|Function       0
    118     small                 stringProtoFuncSmall             DontEnum|Function       0
    119     blink                 stringProtoFuncBlink             DontEnum|Function       0
    120     bold                  stringProtoFuncBold              DontEnum|Function       0
    121     fixed                 stringProtoFuncFixed             DontEnum|Function       0
    122     italics               stringProtoFuncItalics           DontEnum|Function       0
    123     strike                stringProtoFuncStrike            DontEnum|Function       0
    124     sub                   stringProtoFuncSub               DontEnum|Function       0
    125     sup                   stringProtoFuncSup               DontEnum|Function       0
    126     fontcolor             stringProtoFuncFontcolor         DontEnum|Function       1
    127     fontsize              stringProtoFuncFontsize          DontEnum|Function       1
    128     anchor                stringProtoFuncAnchor            DontEnum|Function       1
    129     link                  stringProtoFuncLink              DontEnum|Function       1
    130     trim                  stringProtoFuncTrim              DontEnum|Function       0
    131     trimLeft              stringProtoFuncTrimLeft          DontEnum|Function       0
    132     trimRight             stringProtoFuncTrimRight         DontEnum|Function       0
    133 @end
    134 */
     85const ClassInfo StringPrototype::s_info = { "String", &StringObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringPrototype) };
    13586
    13687// ECMA 15.5.4
     
    14091}
    14192
    142 void StringPrototype::finishCreation(ExecState* exec, JSGlobalObject*, JSString* nameAndMessage)
    143 {
    144     Base::finishCreation(exec->globalData(), nameAndMessage);
     93void StringPrototype::finishCreation(ExecState* exec, JSGlobalObject* globalObject, JSString* nameAndMessage)
     94{
     95    JSGlobalData& globalData = exec->globalData();
     96   
     97    Base::finishCreation(globalData, nameAndMessage);
    14598    ASSERT(inherits(&s_info));
     99
     100    JSC_NATIVE_INTRINSIC_FUNCTION(toString, stringProtoFuncToString, DontEnum, 0, StringPrototypeValueOfIntrinsic);
     101    JSC_NATIVE_INTRINSIC_FUNCTION(valueOf, stringProtoFuncToString, DontEnum, 0, StringPrototypeValueOfIntrinsic);
     102    JSC_NATIVE_INTRINSIC_FUNCTION(charAt, stringProtoFuncCharAt, DontEnum, 1, CharAtIntrinsic);
     103    JSC_NATIVE_INTRINSIC_FUNCTION(charCodeAt, stringProtoFuncCharCodeAt, DontEnum, 1, CharCodeAtIntrinsic);
     104    JSC_NATIVE_FUNCTION(concat, stringProtoFuncConcat, DontEnum, 1);
     105    JSC_NATIVE_FUNCTION(indexOf, stringProtoFuncIndexOf, DontEnum, 1);
     106    JSC_NATIVE_FUNCTION(lastIndexOf, stringProtoFuncLastIndexOf, DontEnum, 1);
     107    JSC_NATIVE_FUNCTION(match, stringProtoFuncMatch, DontEnum, 1);
     108    JSC_NATIVE_FUNCTION(replace, stringProtoFuncReplace, DontEnum, 2);
     109    JSC_NATIVE_FUNCTION(search, stringProtoFuncSearch, DontEnum, 1);
     110    JSC_NATIVE_FUNCTION(slice, stringProtoFuncSlice, DontEnum, 2);
     111    JSC_NATIVE_FUNCTION(split, stringProtoFuncSplit, DontEnum, 2);
     112    JSC_NATIVE_FUNCTION(substr, stringProtoFuncSubstr, DontEnum, 2);
     113    JSC_NATIVE_FUNCTION(substring, stringProtoFuncSubstring, DontEnum, 2);
     114    JSC_NATIVE_FUNCTION(toLowerCase, stringProtoFuncToLowerCase, DontEnum, 0);
     115    JSC_NATIVE_FUNCTION(toUpperCase, stringProtoFuncToUpperCase, DontEnum, 0);
     116    JSC_NATIVE_FUNCTION(localeCompare, stringProtoFuncLocaleCompare, DontEnum, 1);
     117    JSC_NATIVE_FUNCTION(toLocaleLowerCase, stringProtoFuncToLowerCase, DontEnum, 0);
     118    JSC_NATIVE_FUNCTION(toLocaleUpperCase, stringProtoFuncToUpperCase, DontEnum, 0);
     119    JSC_NATIVE_FUNCTION(big, stringProtoFuncBig, DontEnum, 0);
     120    JSC_NATIVE_FUNCTION(small, stringProtoFuncSmall, DontEnum, 0);
     121    JSC_NATIVE_FUNCTION(blink, stringProtoFuncBlink, DontEnum, 0);
     122    JSC_NATIVE_FUNCTION(bold, stringProtoFuncBold, DontEnum, 0);
     123    JSC_NATIVE_FUNCTION(fixed, stringProtoFuncFixed, DontEnum, 0);
     124    JSC_NATIVE_FUNCTION(italics, stringProtoFuncItalics, DontEnum, 0);
     125    JSC_NATIVE_FUNCTION(strike, stringProtoFuncStrike, DontEnum, 0);
     126    JSC_NATIVE_FUNCTION(sub, stringProtoFuncSub, DontEnum, 0);
     127    JSC_NATIVE_FUNCTION(sup, stringProtoFuncSup, DontEnum, 0);
     128    JSC_NATIVE_FUNCTION(fontcolor, stringProtoFuncFontcolor, DontEnum, 1);
     129    JSC_NATIVE_FUNCTION(fontsize, stringProtoFuncFontsize, DontEnum, 1);
     130    JSC_NATIVE_FUNCTION(anchor, stringProtoFuncAnchor, DontEnum, 1);
     131    JSC_NATIVE_FUNCTION(link, stringProtoFuncLink, DontEnum, 1);
     132    JSC_NATIVE_FUNCTION(trim, stringProtoFuncTrim, DontEnum, 0);
     133    JSC_NATIVE_FUNCTION(trimLeft, stringProtoFuncTrimLeft, DontEnum, 0);
     134    JSC_NATIVE_FUNCTION(trimRight, stringProtoFuncTrimRight, DontEnum, 0);
    146135
    147136    // The constructor will be added later, after StringConstructor has been built
     
    149138}
    150139
    151 bool StringPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
    152 {
    153     return getStaticFunctionSlot<StringObject>(exec, ExecState::stringTable(exec), jsCast<StringPrototype*>(cell), propertyName, slot);
    154 }
    155 
    156 bool StringPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
    157 {
    158     return getStaticFunctionDescriptor<StringObject>(exec, ExecState::stringTable(exec), jsCast<StringPrototype*>(object), propertyName, descriptor);
     140StringPrototype* StringPrototype::create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
     141{
     142    JSString* empty = jsEmptyString(exec);
     143    StringPrototype* prototype = new (NotNull, allocateCell<StringPrototype>(*exec->heap())) StringPrototype(exec, structure);
     144    prototype->finishCreation(exec, globalObject, empty);
     145    return prototype;
    159146}
    160147
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.h

    r116828 r146089  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    3535        typedef StringObject Base;
    3636
    37         static StringPrototype* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
    38         {
    39             JSString* empty = jsEmptyString(exec);
    40             StringPrototype* prototype = new (NotNull, allocateCell<StringPrototype>(*exec->heap())) StringPrototype(exec, structure);
    41             prototype->finishCreation(exec, globalObject, empty);
    42             return prototype;
    43         }
    44 
    45         static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
    46         static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
     37        static StringPrototype* create(ExecState*, JSGlobalObject*, Structure*);
    4738
    4839        static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
     
    5546    protected:
    5647        void finishCreation(ExecState*, JSGlobalObject*, JSString*);
    57         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | StringObject::StructureFlags;
     48        static const unsigned StructureFlags = StringObject::StructureFlags;
    5849
    5950    };
Note: See TracChangeset for help on using the changeset viewer.