Changeset 173225 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Sep 3, 2014, 2:01:43 PM (11 years ago)
Author:
[email protected]
Message:

Create tests for type profiling
https://bugs.webkit.org/show_bug.cgi?id=136161

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

The type profiler is now being tested. These are basic tests that don't
check every edge case, but will catch any major failures in the type profiler.
These tests cover:

  • The basic, inheritance-based type system in TypeSet.
  • Function return types.
  • Correct merging of types for multiple assignments to one variable.

This patch also provides an API for writing new tests for
the type profiler. The API works by passing in a function and a
unique substring of an expression contained in that function, and
returns an object representing type information for that expression.

  • jsc.cpp:

(GlobalObject::finishCreation):
(functionFindTypeForExpression):
(functionReturnTypeFor):

  • runtime/TypeProfiler.cpp:

(JSC::TypeProfiler::typeInformationForExpressionAtOffset):

  • runtime/TypeProfiler.h:
  • runtime/TypeProfilerLog.h:
  • runtime/TypeSet.cpp:

(JSC::TypeSet::toJSONString):
(JSC::StructureShape::toJSONString):

  • runtime/TypeSet.h:
  • tests/typeProfiler: Added.
  • tests/typeProfiler.yaml: Added.
  • tests/typeProfiler/basic.js: Added.

(wrapper.foo):
(wrapper):

  • tests/typeProfiler/captured.js: Added.

(wrapper.changeFoo):
(wrapper):

  • tests/typeProfiler/driver: Added.
  • tests/typeProfiler/driver/driver.js: Added.

(assert):

  • tests/typeProfiler/inheritance.js: Added.

(wrapper.A):
(wrapper.B):
(wrapper.C):
(wrapper):

  • tests/typeProfiler/return.js: Added.

(foo):
(Ctor):

Tools:

Have run-javascriptcore-tests run the newly created
tests for the type profiler.

  • Scripts/run-javascriptcore-tests:
  • Scripts/run-jsc-stress-tests:
Location:
trunk/Source/JavaScriptCore
Files:
8 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r173222 r173225  
     12014-09-03  Saam Barati  <[email protected]>
     2
     3        Create tests for type profiling
     4        https://bugs.webkit.org/show_bug.cgi?id=136161
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        The type profiler is now being tested. These are basic tests that don't
     9        check every edge case, but will catch any major failures in the type profiler.
     10        These tests cover:
     11        - The basic, inheritance-based type system in TypeSet.
     12        - Function return types.
     13        - Correct merging of types for multiple assignments to one variable.
     14
     15        This patch also provides an API for writing new tests for
     16        the type profiler. The API works by passing in a function and a
     17        unique substring of an expression contained in that function, and
     18        returns an object representing type information for that expression.
     19
     20        * jsc.cpp:
     21        (GlobalObject::finishCreation):
     22        (functionFindTypeForExpression):
     23        (functionReturnTypeFor):
     24        * runtime/TypeProfiler.cpp:
     25        (JSC::TypeProfiler::typeInformationForExpressionAtOffset):
     26        * runtime/TypeProfiler.h:
     27        * runtime/TypeProfilerLog.h:
     28        * runtime/TypeSet.cpp:
     29        (JSC::TypeSet::toJSONString):
     30        (JSC::StructureShape::toJSONString):
     31        * runtime/TypeSet.h:
     32        * tests/typeProfiler: Added.
     33        * tests/typeProfiler.yaml: Added.
     34        * tests/typeProfiler/basic.js: Added.
     35        (wrapper.foo):
     36        (wrapper):
     37        * tests/typeProfiler/captured.js: Added.
     38        (wrapper.changeFoo):
     39        (wrapper):
     40        * tests/typeProfiler/driver: Added.
     41        * tests/typeProfiler/driver/driver.js: Added.
     42        (assert):
     43        * tests/typeProfiler/inheritance.js: Added.
     44        (wrapper.A):
     45        (wrapper.B):
     46        (wrapper.C):
     47        (wrapper):
     48        * tests/typeProfiler/return.js: Added.
     49        (foo):
     50        (Ctor):
     51
    1522014-09-03  Julien Brianceau   <[email protected]>
    253
  • trunk/Source/JavaScriptCore/jsc.cpp

    r173120 r173225  
    3838#include "JSFunction.h"
    3939#include "JSLock.h"
     40#include "JSONObject.h"
    4041#include "JSProxy.h"
    4142#include "JSString.h"
     
    4647#include "StructureRareDataInlines.h"
    4748#include "TestRunnerUtils.h"
     49#include "TypeProfilerLog.h"
    4850#include <math.h>
    4951#include <stdio.h>
     
    477479static EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState*);
    478480static EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState*);
    479 static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables (ExecState*);
     481static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState*);
     482static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState*);
     483static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState*);
    480484
    481485#if ENABLE(SAMPLING_FLAGS)
     
    628632        addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
    629633        addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
    630         addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 4);
     634
     635        addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 0);
     636        addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);
     637        addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);
    631638       
    632639        JSArray* array = constructEmptyArray(globalExec(), 0);
     
    10641071    exec->vm().dumpTypeProfilerData();
    10651072    return JSValue::encode(jsUndefined());
     1073}
     1074
     1075EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState* exec)
     1076{
     1077    RELEASE_ASSERT(exec->vm().typeProfiler());
     1078    exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionFindTypeForExpression"));
     1079
     1080    JSValue functionValue = exec->argument(0);
     1081    RELEASE_ASSERT(functionValue.isFunction());
     1082    FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(functionValue.asCell()->getObject()))->jsExecutable();
     1083
     1084    RELEASE_ASSERT(exec->argument(1).isString());
     1085    String substring = exec->argument(1).getString(exec);
     1086    String sourceCodeText = executable->source().toString();
     1087    unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
     1088   
     1089    String jsonString = exec->vm().typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID());
     1090    return JSValue::encode(JSONParse(exec, jsonString));
     1091}
     1092
     1093EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState* exec)
     1094{
     1095    RELEASE_ASSERT(exec->vm().typeProfiler());
     1096    exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionReturnTypeFor"));
     1097
     1098    JSValue functionValue = exec->argument(0);
     1099    RELEASE_ASSERT(functionValue.isFunction());
     1100    FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(functionValue.asCell()->getObject()))->jsExecutable();
     1101
     1102    unsigned offset = executable->source().startOffset();
     1103    String jsonString = exec->vm().typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID());
     1104    return JSValue::encode(JSONParse(exec, jsonString));
    10661105}
    10671106
  • trunk/Source/JavaScriptCore/runtime/TypeProfiler.cpp

    r172950 r173225  
    8383}
    8484
     85String TypeProfiler::typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptor descriptor, unsigned offset, intptr_t sourceID)
     86{
     87    // This returns a JSON string representing an Object with the following properties:
     88    //     globalTypeSet: 'JSON<TypeSet> | null'
     89    //     instructionTypeSet: 'JSON<TypeSet>'
     90
     91    TypeLocation* location = findLocation(offset, sourceID, descriptor);
     92    ASSERT(location);
     93
     94    StringBuilder json; 
     95
     96    json.append("{");
     97
     98    json.append("\"globalTypeSet\":");
     99    if (location->m_globalTypeSet && location->m_globalVariableID != TypeProfilerNoGlobalIDExists)
     100        json.append(location->m_globalTypeSet->toJSONString());
     101    else
     102        json.append("null");
     103    json.append(",");
     104
     105    json.append("\"instructionTypeSet\":");
     106    json.append(location->m_instructionTypeSet->toJSONString());
     107
     108    json.append("}");
     109   
     110    return json.toString();
     111}
     112
    85113TypeLocation* TypeProfiler::findLocation(unsigned divot, intptr_t sourceID, TypeProfilerSearchDescriptor descriptor)
    86114{
  • trunk/Source/JavaScriptCore/runtime/TypeProfiler.h

    r172930 r173225  
    9797    void logTypesForTypeLocation(TypeLocation*);
    9898    void getTypesForVariableAtOffsetForInspector(TypeProfilerSearchDescriptor, unsigned divot, intptr_t sourceID, RefPtr<Inspector::Protocol::Runtime::TypeDescription>&);
     99    JS_EXPORT_PRIVATE String typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptor, unsigned offset, intptr_t sourceID);
    99100    void insertNewLocation(TypeLocation*);
    100101    FunctionHasExecutedCache* functionHasExecutedCache() { return &m_functionHasExecutedCache; }
  • trunk/Source/JavaScriptCore/runtime/TypeProfilerLog.h

    r172820 r173225  
    7575    }
    7676
    77     void processLogEntries(String);
     77    JS_EXPORT_PRIVATE void processLogEntries(String);
    7878    LogEntry* logEndPtr() const { return m_logEndPtr; }
    7979
  • trunk/Source/JavaScriptCore/runtime/TypeSet.cpp

    r173120 r173225  
    252252}
    253253
     254String TypeSet::toJSONString() const
     255{
     256    // This returns a JSON string representing an Object with the following properties:
     257    //     displayTypeName: 'String'
     258    //     primitiveTypeNames: 'Array<String>'
     259    //     structures: 'Array<JSON<StructureShape>>'
     260
     261    StringBuilder json;
     262    json.append("{");
     263
     264    json.append("\"displayTypeName\":");
     265    json.append("\"");
     266    json.append(displayName());
     267    json.append("\"");
     268    json.append(",");
     269
     270    json.append("\"primitiveTypeNames\":");
     271    json.append("[");
     272    bool hasAnItem = false;
     273    if (m_seenTypes & TypeUndefined) {
     274        hasAnItem = true;
     275        json.append("\"Undefined\"");
     276    }
     277    if (m_seenTypes & TypeNull) {
     278        if (hasAnItem)
     279            json.append(",");
     280        hasAnItem = true;
     281        json.append("\"Null\"");
     282    }
     283    if (m_seenTypes & TypeBoolean) {
     284        if (hasAnItem)
     285            json.append(",");
     286        hasAnItem = true;
     287        json.append("\"Boolean\"");
     288    }
     289    if (m_seenTypes & TypeMachineInt) {
     290        if (hasAnItem)
     291            json.append(",");
     292        hasAnItem = true;
     293        json.append("\"Integer\"");
     294    }
     295    if (m_seenTypes & TypeNumber) {
     296        if (hasAnItem)
     297            json.append(",");
     298        hasAnItem = true;
     299        json.append("\"Number\"");
     300    }
     301    if (m_seenTypes & TypeString) {
     302        if (hasAnItem)
     303            json.append(",");
     304        hasAnItem = true;
     305        json.append("\"String\"");
     306    }
     307    json.append("]");
     308
     309    json.append(",");
     310
     311    json.append("\"structures\":");
     312    json.append("[");
     313    hasAnItem = false;
     314    for (size_t i = 0; i < m_structureHistory.size(); i++) {
     315        if (hasAnItem)
     316            json.append(",");
     317        hasAnItem = true;
     318        json.append(m_structureHistory[i]->toJSONString());
     319    }
     320    json.append("]");
     321
     322    json.append("}");
     323    return json.toString();
     324}
     325
    254326void TypeSet::dumpSeenTypes()
    255327{
     
    365437}
    366438
     439String StructureShape::toJSONString() const
     440{
     441    // This returns a JSON string representing an Object with the following properties:
     442    //     constructorName: 'String'
     443    //     fields: 'Array<String>'
     444    //     proto: 'JSON<StructureShape> | null'
     445
     446    StringBuilder json;
     447    json.append("{");
     448
     449    json.append("\"constructorName\":");
     450    json.append("\"");
     451    json.append(m_constructorName);
     452    json.append("\"");
     453    json.append(",");
     454
     455    json.append("\"fields\":");
     456    json.append("[");
     457    bool hasAnItem = false;
     458    for (auto it = m_fields.begin(), end = m_fields.end(); it != end; ++it) {
     459        if (hasAnItem)
     460            json.append(",");
     461        hasAnItem = true;
     462
     463        String fieldName((*it).get());
     464        json.append("\"");
     465        json.append(fieldName);
     466        json.append("\"");
     467    }
     468    json.append("]");
     469    json.append(",");
     470
     471    json.append("\"proto\":");
     472    if (m_proto)
     473        json.append(m_proto->toJSONString());
     474    else
     475        json.append("null");
     476
     477    json.append("}");
     478
     479    return json.toString();
     480}
     481
    367482PassRefPtr<Inspector::Protocol::Runtime::StructureDescription> StructureShape::inspectorRepresentation()
    368483{
  • trunk/Source/JavaScriptCore/runtime/TypeSet.h

    r172976 r173225  
    7171    void addProperty(RefPtr<StringImpl>);
    7272    String stringRepresentation();
     73    String toJSONString() const;
    7374    PassRefPtr<Inspector::Protocol::Runtime::StructureDescription> inspectorRepresentation();
    7475    void setConstructorName(String name) { m_constructorName = (name.isEmpty() ? "Object" : name); }
     
    9899    PassRefPtr<Inspector::Protocol::Array<String>> allPrimitiveTypeNames() const;
    99100    PassRefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::StructureDescription>> allStructureRepresentations() const;
     101    String toJSONString() const;
    100102
    101103private:
Note: See TracChangeset for help on using the changeset viewer.