Changeset 173225 in webkit for trunk/Source/JavaScriptCore
- Timestamp:
- Sep 3, 2014, 2:01:43 PM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r173222 r173225 1 2014-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 1 52 2014-09-03 Julien Brianceau <[email protected]> 2 53 -
trunk/Source/JavaScriptCore/jsc.cpp
r173120 r173225 38 38 #include "JSFunction.h" 39 39 #include "JSLock.h" 40 #include "JSONObject.h" 40 41 #include "JSProxy.h" 41 42 #include "JSString.h" … … 46 47 #include "StructureRareDataInlines.h" 47 48 #include "TestRunnerUtils.h" 49 #include "TypeProfilerLog.h" 48 50 #include <math.h> 49 51 #include <stdio.h> … … 477 479 static EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState*); 478 480 static EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState*); 479 static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables (ExecState*); 481 static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState*); 482 static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState*); 483 static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState*); 480 484 481 485 #if ENABLE(SAMPLING_FLAGS) … … 628 632 addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1); 629 633 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); 631 638 632 639 JSArray* array = constructEmptyArray(globalExec(), 0); … … 1064 1071 exec->vm().dumpTypeProfilerData(); 1065 1072 return JSValue::encode(jsUndefined()); 1073 } 1074 1075 EncodedJSValue 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 1093 EncodedJSValue 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)); 1066 1105 } 1067 1106 -
trunk/Source/JavaScriptCore/runtime/TypeProfiler.cpp
r172950 r173225 83 83 } 84 84 85 String 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 85 113 TypeLocation* TypeProfiler::findLocation(unsigned divot, intptr_t sourceID, TypeProfilerSearchDescriptor descriptor) 86 114 { -
trunk/Source/JavaScriptCore/runtime/TypeProfiler.h
r172930 r173225 97 97 void logTypesForTypeLocation(TypeLocation*); 98 98 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); 99 100 void insertNewLocation(TypeLocation*); 100 101 FunctionHasExecutedCache* functionHasExecutedCache() { return &m_functionHasExecutedCache; } -
trunk/Source/JavaScriptCore/runtime/TypeProfilerLog.h
r172820 r173225 75 75 } 76 76 77 void processLogEntries(String);77 JS_EXPORT_PRIVATE void processLogEntries(String); 78 78 LogEntry* logEndPtr() const { return m_logEndPtr; } 79 79 -
trunk/Source/JavaScriptCore/runtime/TypeSet.cpp
r173120 r173225 252 252 } 253 253 254 String 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 254 326 void TypeSet::dumpSeenTypes() 255 327 { … … 365 437 } 366 438 439 String 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 367 482 PassRefPtr<Inspector::Protocol::Runtime::StructureDescription> StructureShape::inspectorRepresentation() 368 483 { -
trunk/Source/JavaScriptCore/runtime/TypeSet.h
r172976 r173225 71 71 void addProperty(RefPtr<StringImpl>); 72 72 String stringRepresentation(); 73 String toJSONString() const; 73 74 PassRefPtr<Inspector::Protocol::Runtime::StructureDescription> inspectorRepresentation(); 74 75 void setConstructorName(String name) { m_constructorName = (name.isEmpty() ? "Object" : name); } … … 98 99 PassRefPtr<Inspector::Protocol::Array<String>> allPrimitiveTypeNames() const; 99 100 PassRefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::StructureDescription>> allStructureRepresentations() const; 101 String toJSONString() const; 100 102 101 103 private:
Note:
See TracChangeset
for help on using the changeset viewer.