Commit a6805302 authored by barraclough@apple.com's avatar barraclough@apple.com

Source/JavaScriptCore: GetScopedVar should have value profiling

https://bugs.webkit.org/show_bug.cgi?id=68676

Patch by Filip Pizlo <fpizlo@apple.com> on 2011-09-22
Reviewed by Oliver Hunt.
        
Added GetScopedVar value profiling and predictin propagation.
Added GetScopeChain to CSE.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::predict):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasPrediction):
* dfg/DFGPropagator.cpp:
(JSC::DFG::Propagator::propagateNodePredictions):
(JSC::DFG::Propagator::getScopeChainLoadElimination):
(JSC::DFG::Propagator::performNodeCSE):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_get_scoped_var):

LayoutTests: [Qt] Unreviewed gardening, update expected file after r95745.

Patch by Csaba Osztrogonác <ossy@webkit.org> on 2011-09-22

* platform/qt/editing/deleting/merge-whitespace-pre-expected.png:
* platform/qt/editing/deleting/merge-whitespace-pre-expected.txt:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95787 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b2ad305d
......@@ -91,6 +91,31 @@
* platform/chromium/test_expectations.txt:
2011-09-22 Gavin Barraclough <barraclough@apple.com>
Incorrect this value passed to callbacks.
https://bugs.webkit.org/show_bug.cgi?id=68668
Reviewed by Oliver Hunt.
From Array/String prototype function. Should be undefined, but
global object is passed instead (this is visible for strict callbacks).
* fast/js/array-prototype-properties-expected.txt:
* fast/js/script-tests/strict-callback-this.js: Added.
(strictThrowThisString):
(nonstrictThrowThisString):
(testArrayPrototypeSort):
(testArrayPrototypeFilter):
(testArrayPrototypeMap):
(testArrayPrototypeEvery):
(testArrayPrototypeForEach):
(testArrayPrototypeSome):
(testStringPrototypeReplace):
* fast/js/strict-callback-this-expected.txt: Added.
* fast/js/strict-callback-this.html: Added.
* ietestcenter/Javascript/15.3.4.5-0-2-expected.txt:
2011-09-22 Gavin Barraclough <barraclough@apple.com>
Function.prototype.bind.length shoudl be 1.
......@@ -23,7 +23,7 @@ PASS Array.prototype.indlastIndexOfexOf.call(undefined, 0) threw exception TypeE
FAIL Array.prototype.filter.call(undefined, toString) should throw an exception. Was [object Object].
FAIL Array.prototype.reduce.call(undefined, toString) should throw an exception. Was [object Object].
FAIL Array.prototype.reduceRight.call(undefined, toString) should throw an exception. Was [object Object].
FAIL Array.prototype.map.call(undefined, toString) should throw an exception. Was [object DOMWindow].
FAIL Array.prototype.map.call(undefined, toString) should throw an exception. Was [object Undefined].
PASS successfullyParsed is true
TEST COMPLETE
......
description(
"This tests that a call to array/string prototype methods pass the correct this value (undefined) to strict callees."
);
var undefinedString = String(undefined);
var globalObjectString = String(this);
function strictThrowThisString()
{
"use strict";
throw String(this);
}
function nonstrictThrowThisString()
{
throw String(this);
}
function testArrayPrototypeSort(callback)
{
try {
[1,2].sort(callback);
} catch (e) {
return e;
}
return "FAILED";
}
function testArrayPrototypeFilter(callback)
{
try {
[1,2].filter(callback);
} catch (e) {
return e;
}
return "FAILED";
}
function testArrayPrototypeMap(callback)
{
try {
[1,2].map(callback);
} catch (e) {
return e;
}
return "FAILED";
}
function testArrayPrototypeEvery(callback)
{
try {
[1,2].every(callback);
} catch (e) {
return e;
}
return "FAILED";
}
function testArrayPrototypeForEach(callback)
{
try {
[1,2].forEach(callback);
} catch (e) {
return e;
}
return "FAILED";
}
function testArrayPrototypeSome(callback)
{
try {
[1,2].some(callback);
} catch (e) {
return e;
}
return "FAILED";
}
function testStringPrototypeReplace(callback)
{
try {
"1,2".replace('1', callback);
} catch (e) {
return e;
}
return "FAILED";
}
shouldBe('testArrayPrototypeSort(strictThrowThisString)', 'undefinedString');
shouldBe('testArrayPrototypeFilter(strictThrowThisString)', 'undefinedString');
shouldBe('testArrayPrototypeMap(strictThrowThisString)', 'undefinedString');
shouldBe('testArrayPrototypeEvery(strictThrowThisString)', 'undefinedString');
shouldBe('testArrayPrototypeForEach(strictThrowThisString)', 'undefinedString');
shouldBe('testArrayPrototypeSome(strictThrowThisString)', 'undefinedString');
shouldBe('testStringPrototypeReplace(strictThrowThisString)', 'undefinedString');
shouldBe('testArrayPrototypeSort(nonstrictThrowThisString)', 'globalObjectString');
shouldBe('testArrayPrototypeFilter(nonstrictThrowThisString)', 'globalObjectString');
shouldBe('testArrayPrototypeMap(nonstrictThrowThisString)', 'globalObjectString');
shouldBe('testArrayPrototypeEvery(nonstrictThrowThisString)', 'globalObjectString');
shouldBe('testArrayPrototypeForEach(nonstrictThrowThisString)', 'globalObjectString');
shouldBe('testArrayPrototypeSome(nonstrictThrowThisString)', 'globalObjectString');
shouldBe('testStringPrototypeReplace(nonstrictThrowThisString)', 'globalObjectString');
var successfullyParsed = true;
This tests that a call to array/string prototype methods pass the correct this value (undefined) to strict callees.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS testArrayPrototypeSort(strictThrowThisString) is undefinedString
PASS testArrayPrototypeFilter(strictThrowThisString) is undefinedString
PASS testArrayPrototypeMap(strictThrowThisString) is undefinedString
PASS testArrayPrototypeEvery(strictThrowThisString) is undefinedString
PASS testArrayPrototypeForEach(strictThrowThisString) is undefinedString
PASS testArrayPrototypeSome(strictThrowThisString) is undefinedString
PASS testStringPrototypeReplace(strictThrowThisString) is undefinedString
PASS testArrayPrototypeSort(nonstrictThrowThisString) is globalObjectString
PASS testArrayPrototypeFilter(nonstrictThrowThisString) is globalObjectString
PASS testArrayPrototypeMap(nonstrictThrowThisString) is globalObjectString
PASS testArrayPrototypeEvery(nonstrictThrowThisString) is globalObjectString
PASS testArrayPrototypeForEach(nonstrictThrowThisString) is globalObjectString
PASS testArrayPrototypeSome(nonstrictThrowThisString) is globalObjectString
PASS testStringPrototypeReplace(nonstrictThrowThisString) is globalObjectString
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<link rel="stylesheet" href="resources/js-test-style.css">
<script src="resources/js-test-pre.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script src="script-tests/strict-callback-this.js"></script>
<script src="resources/js-test-post.js"></script>
</body>
</html>
......@@ -44,6 +44,29 @@
* Configurations/FeatureDefines.xcconfig:
2011-09-22 Gavin Barraclough <barraclough@apple.com>
Incorrect this value passed to callbacks.
https://bugs.webkit.org/show_bug.cgi?id=68668
Reviewed by Oliver Hunt.
From Array/String prototype function. Should be undefined, but
global object is passed instead (this is visible for strict callbacks).
* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncSort):
(JSC::arrayProtoFuncFilter):
(JSC::arrayProtoFuncMap):
(JSC::arrayProtoFuncEvery):
(JSC::arrayProtoFuncForEach):
(JSC::arrayProtoFuncSome):
* runtime/JSArray.cpp:
(JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):
(JSC::JSArray::sort):
* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncReplace):
2011-09-22 Gavin Barraclough <barraclough@apple.com>
Function.prototype.bind.length shoudl be 1.
......@@ -543,7 +543,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
MarkedArgumentBuffer l;
l.append(jObj);
l.append(minObj);
compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l).toNumber(exec);
compareResult = call(exec, function, callType, callData, jsUndefined(), l).toNumber(exec);
} else
compareResult = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1;
......@@ -671,7 +671,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
if (callType == CallTypeNone)
return throwVMTypeError(exec);
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
JSValue applyThis = exec->argument(1);
JSArray* resultArray = constructEmptyArray(exec);
unsigned filterIndex = 0;
......@@ -730,7 +730,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
if (callType == CallTypeNone)
return throwVMTypeError(exec);
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
JSValue applyThis = exec->argument(1);
JSArray* resultArray = constructEmptyArray(exec, length);
unsigned k = 0;
......@@ -792,7 +792,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
if (callType == CallTypeNone)
return throwVMTypeError(exec);
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
JSValue applyThis = exec->argument(1);
JSValue result = jsBoolean(true);
......@@ -850,7 +850,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
if (callType == CallTypeNone)
return throwVMTypeError(exec);
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
JSValue applyThis = exec->argument(1);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
......@@ -900,7 +900,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
if (callType == CallTypeNone)
return throwVMTypeError(exec);
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
JSValue applyThis = exec->argument(1);
JSValue result = jsBoolean(false);
......
......@@ -1016,7 +1016,6 @@ struct AVLTreeAbstractorForArrayCompare {
JSValue m_compareFunction;
CallType m_compareCallType;
const CallData* m_compareCallData;
JSValue m_globalThisValue;
OwnPtr<CachedCall> m_cachedCall;
handle get_less(handle h) { return m_nodes[h].lt & 0x7FFFFFFF; }
......@@ -1055,7 +1054,7 @@ struct AVLTreeAbstractorForArrayCompare {
double compareResult;
if (m_cachedCall) {
m_cachedCall->setThis(m_globalThisValue);
m_cachedCall->setThis(jsUndefined());
m_cachedCall->setArgument(0, va);
m_cachedCall->setArgument(1, vb);
compareResult = m_cachedCall->call().toNumber(m_cachedCall->newCallFrame(m_exec));
......@@ -1063,7 +1062,7 @@ struct AVLTreeAbstractorForArrayCompare {
MarkedArgumentBuffer arguments;
arguments.append(va);
arguments.append(vb);
compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments).toNumber(m_exec);
compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, jsUndefined(), arguments).toNumber(m_exec);
}
return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent.
}
......@@ -1099,7 +1098,6 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
tree.abstractor().m_compareFunction = compareFunction;
tree.abstractor().m_compareCallType = callType;
tree.abstractor().m_compareCallData = &callData;
tree.abstractor().m_globalThisValue = exec->globalThisValue();
tree.abstractor().m_nodes.grow(nodeCount);
if (callType == CallTypeJS)
......
......@@ -448,7 +448,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
cachedCall.setArgument(i++, jsNumber(completeMatchStart));
cachedCall.setArgument(i++, sourceVal);
cachedCall.setThis(exec->globalThisValue());
cachedCall.setThis(jsUndefined());
JSValue result = cachedCall.call();
if (LIKELY(result.isString()))
replacements.append(asString(result)->value(exec));
......@@ -495,7 +495,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
args.append(jsNumber(completeMatchStart));
args.append(sourceVal);
replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec));
replacements.append(call(exec, replacement, callType, callData, jsUndefined(), args).toString(exec));
if (exec->hadException())
break;
} else {
......@@ -551,7 +551,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
args.append(jsNumber(matchPos));
args.append(sourceVal);
replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec);
replacementString = call(exec, replacement, callType, callData, jsUndefined(), args).toString(exec);
}
size_t matchEnd = matchPos + matchLen;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment