Bug 507053: fix on-trace scope chain computation for JSOP_BINDNAME, r=gal

This commit is contained in:
David Mandelin 2009-07-30 11:34:35 -07:00
Родитель 702f3daabf
Коммит 4b86791b27
3 изменённых файлов: 100 добавлений и 8 удалений

Просмотреть файл

@ -11389,14 +11389,19 @@ TraceRecorder::record_JSOP_BINDNAME()
}
}
/*
* If obj is a js_CallClass object, then we are tracing a reference to an
* upvar in a heavyweight function. We cannot reach this point of the trace
* with a different call object because of the guard on the function call,
* so we can assume the result of the bindname is constant on this trace.
*/
if (obj != globalObj && OBJ_GET_CLASS(cx, obj) != &js_CallClass)
ABORT_TRACE("Can only trace JSOP_BINDNAME with global or call object");
if (obj != globalObj) {
if (OBJ_GET_CLASS(cx, obj) != &js_CallClass)
ABORT_TRACE("Can only trace JSOP_BINDNAME with global or call object");
/*
* The interpreter version of JSOP_BINDNAME does the full lookup. We
* don't need to do that on trace because we will leave trace if the
* scope ever changes, so the result of the lookup cannot change.
*/
JS_ASSERT(obj == cx->fp->scopeChain);
stack(0, stobj_get_parent(get(&cx->fp->argv[-2])));
return JSRS_CONTINUE;
}
/*
* The trace is specialized to this global object. Furthermore, we know it

Просмотреть файл

@ -729,11 +729,17 @@ class TraceRecorder : public avmplus::GCObject {
nanojit::LIns*& dslots_ins);
nanojit::LIns* stobj_get_slot(nanojit::LIns* obj_ins, unsigned slot,
nanojit::LIns*& dslots_ins);
nanojit::LIns* stobj_get_private(nanojit::LIns* obj_ins, jsval mask=JSVAL_INT) {
return lir->ins2(nanojit::LIR_piand,
stobj_get_fslot(obj_ins, JSSLOT_PRIVATE),
lir->insImmPtr((void*) ~mask));
}
nanojit::LIns* stobj_get_parent(nanojit::LIns* obj_ins) {
return stobj_get_fslot(obj_ins, JSSLOT_PARENT);
}
JSRecordingStatus native_get(nanojit::LIns* obj_ins, nanojit::LIns* pobj_ins,
JSScopeProperty* sprop, nanojit::LIns*& dslots_ins,
nanojit::LIns*& v_ins);

Просмотреть файл

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is JavaScript Engine testing utilities.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): Dave Mandelin
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var gTestfile = 'regress-507053.js';
//-----------------------------------------------------------------------------
var BUGNUMBER = 507053;
var summary = 'TM: invalid results with setting a closure variable in a loop'
var actual = '';
var expect = '2,4,8,16,32,2,4,8,16,32,2,4,8,16,32,2,4,8,16,32,2,4,8,16,32,';
//-----------------------------------------------------------------------------
start_test();
jit(true);
var f = function() {
var p = 1;
function g() {
for (var i = 0; i < 5; ++i) {
p = p * 2;
actual += p + ',';
}
}
g();
}
for (var i = 0; i < 5; ++i) {
f();
}
jit(false);
finish_test();
//-----------------------------------------------------------------------------
function start_test()
{
enterFunc ('test');
printBugNumber(BUGNUMBER);
printStatus (summary);
}
function finish_test()
{
reportCompare(expect, actual, summary);
exitFunc ('test');
}