Bug 854050. (r=dvander)

This commit is contained in:
Shu-yu Guo 2013-03-26 15:23:12 -07:00
parent 04bae7d956
commit d732995def
9 changed files with 53 additions and 28 deletions

View File

@ -1198,17 +1198,6 @@ CodeGenerator::emitCallInvokeFunction(LInstruction *call, Register calleereg,
return true;
}
static inline int32_t ionOffset(ExecutionMode executionMode)
{
switch (executionMode) {
case SequentialExecution: return offsetof(JSScript, ion);
case ParallelExecution: return offsetof(JSScript, parallelIon);
}
JS_ASSERT(false);
return offsetof(JSScript, ion);
}
bool
CodeGenerator::visitCallGeneric(LCallGeneric *call)
{
@ -1224,7 +1213,7 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call)
// Generate an ArgumentsRectifier.
IonCompartment *ion = gen->ionCompartment();
IonCode *argumentsRectifier = ion->getArgumentsRectifier();
IonCode *argumentsRectifier = ion->getArgumentsRectifier(executionMode);
masm.checkStackAlignment();
@ -1239,7 +1228,7 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call)
// Knowing that calleereg is a non-native function, load the JSScript.
masm.loadPtr(Address(calleereg, offsetof(JSFunction, u.i.script_)), objreg);
masm.loadPtr(Address(objreg, ionOffset(executionMode)), objreg);
masm.loadPtr(Address(objreg, OffsetOfIonInJSScript(executionMode)), objreg);
// Guard that the IonScript has been compiled.
masm.branchPtr(Assembler::BelowOrEqual, objreg, ImmWord(ION_COMPILING_SCRIPT), &uncompiled);
@ -1378,7 +1367,7 @@ CodeGenerator::visitCallKnown(LCallKnown *call)
// Knowing that calleereg is a non-native function, load the JSScript.
masm.loadPtr(Address(calleereg, offsetof(JSFunction, u.i.script_)), objreg);
masm.loadPtr(Address(objreg, ionOffset(executionMode)), objreg);
masm.loadPtr(Address(objreg, OffsetOfIonInJSScript(executionMode)), objreg);
// Guard that the IonScript has been compiled.
masm.branchPtr(Assembler::BelowOrEqual, objreg, ImmWord(ION_COMPILING_SCRIPT), &uncompiled);
@ -1586,7 +1575,7 @@ CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric *apply)
// Knowing that calleereg is a non-native function, load the JSScript.
masm.loadPtr(Address(calleereg, offsetof(JSFunction, u.i.script_)), objreg);
masm.loadPtr(Address(objreg, ionOffset(executionMode)), objreg);
masm.loadPtr(Address(objreg, OffsetOfIonInJSScript(executionMode)), objreg);
// Guard that the IonScript has been compiled.
masm.branchPtr(Assembler::BelowOrEqual, objreg, ImmWord(ION_COMPILING_SCRIPT), &invoke);
@ -1630,7 +1619,7 @@ CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric *apply)
// Hardcode the address of the argumentsRectifier code.
IonCompartment *ion = gen->ionCompartment();
IonCode *argumentsRectifier = ion->getArgumentsRectifier();
IonCode *argumentsRectifier = ion->getArgumentsRectifier(executionMode);
JS_ASSERT(ArgumentsRectifierReg != objreg);
masm.movePtr(ImmGCPtr(argumentsRectifier), objreg); // Necessary for GC marking.

View File

@ -21,7 +21,7 @@ CountArgSlots(JSFunction *fun)
enum ExecutionMode {
// Normal JavaScript execution
SequentialExecution,
SequentialExecution = 0,
// JavaScript code to be executed in parallel worker threads,
// e.g. by ParallelArray

View File

@ -40,6 +40,15 @@ static inline void SetIonScript(RawScript script, ExecutionMode cmode, IonScript
JS_NOT_REACHED("No such execution mode");
}
static inline size_t OffsetOfIonInJSScript(ExecutionMode cmode)
{
switch (cmode) {
case SequentialExecution: return offsetof(JSScript, ion);
case ParallelExecution: return offsetof(JSScript, parallelIon);
}
JS_NOT_REACHED("No such execution mode");
}
static inline bool CanIonCompile(RawScript script, ExecutionMode cmode)
{
switch (cmode) {

View File

@ -160,6 +160,7 @@ IonRuntime::IonRuntime()
enterJIT_(NULL),
bailoutHandler_(NULL),
argumentsRectifier_(NULL),
parallelArgumentsRectifier_(NULL),
invalidator_(NULL),
functionWrappers_(NULL),
flusher_(NULL)
@ -207,10 +208,16 @@ IonRuntime::initialize(JSContext *cx)
if (!bailoutHandler_)
return false;
argumentsRectifier_ = generateArgumentsRectifier(cx);
argumentsRectifier_ = generateArgumentsRectifier(cx, SequentialExecution);
if (!argumentsRectifier_)
return false;
#ifdef JS_THREADSAFE
parallelArgumentsRectifier_ = generateArgumentsRectifier(cx, ParallelExecution);
if (!parallelArgumentsRectifier_)
return false;
#endif
invalidator_ = generateInvalidator(cx);
if (!invalidator_)
return false;

View File

@ -13,6 +13,7 @@
#include "js/Value.h"
#include "vm/Stack.h"
#include "IonFrames.h"
#include "CompileInfo.h"
namespace js {
namespace ion {
@ -44,9 +45,12 @@ class IonRuntime
IonCode *bailoutHandler_;
// Argument-rectifying thunk, in the case of insufficient arguments passed
// to a function call site. Pads with |undefined|.
// to a function call site.
IonCode *argumentsRectifier_;
// Arguments-rectifying thunk which loads |parallelIon| instead of |ion|.
IonCode *parallelArgumentsRectifier_;
// Thunk that invalides an (Ion compiled) caller on the Ion stack.
IonCode *invalidator_;
@ -63,7 +67,7 @@ class IonRuntime
private:
IonCode *generateEnterJIT(JSContext *cx);
IonCode *generateArgumentsRectifier(JSContext *cx);
IonCode *generateArgumentsRectifier(JSContext *cx, ExecutionMode mode);
IonCode *generateBailoutTable(JSContext *cx, uint32_t frameClass);
IonCode *generateBailoutHandler(JSContext *cx);
IonCode *generateInvalidator(JSContext *cx);
@ -124,8 +128,12 @@ class IonCompartment
IonCode *getBailoutTable(const FrameSizeClass &frameClass);
IonCode *getArgumentsRectifier() {
return rt->argumentsRectifier_;
IonCode *getArgumentsRectifier(ExecutionMode mode) {
switch (mode) {
case SequentialExecution: return rt->argumentsRectifier_;
case ParallelExecution: return rt->parallelArgumentsRectifier_;
default: JS_NOT_REACHED("No such execution mode");
}
}
IonCode *getInvalidationThunk() {

View File

@ -14,6 +14,7 @@
#include "ion/IonSpewer.h"
#include "ion/Bailouts.h"
#include "ion/VMFunctions.h"
#include "ion/ExecutionModeInlines.h"
using namespace js;
using namespace js::ion;
@ -248,7 +249,7 @@ IonRuntime::generateInvalidator(JSContext *cx)
}
IonCode *
IonRuntime::generateArgumentsRectifier(JSContext *cx)
IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode)
{
MacroAssembler masm(cx);
// ArgumentsRectifierReg contains the |nargs| pushed onto the current frame.
@ -310,7 +311,7 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx)
// Call the target function.
// Note that this code assumes the function is JITted.
masm.ma_ldr(DTRAddr(r1, DtrOffImm(offsetof(JSFunction, u.i.script_))), r3);
masm.ma_ldr(DTRAddr(r3, DtrOffImm(offsetof(JSScript, ion))), r3);
masm.ma_ldr(DTRAddr(r3, DtrOffImm(OffsetOfIonInJSScript(mode))), r3);
masm.ma_ldr(DTRAddr(r3, DtrOffImm(IonScript::offsetOfMethod())), r3);
masm.ma_ldr(DTRAddr(r3, DtrOffImm(IonCode::offsetOfCode())), r3);
masm.ma_callIonHalfPush(r3);

View File

@ -13,6 +13,7 @@
#include "ion/Bailouts.h"
#include "ion/VMFunctions.h"
#include "ion/IonSpewer.h"
#include "ion/ExecutionModeInlines.h"
#include "jsscriptinlines.h"
@ -222,7 +223,7 @@ IonRuntime::generateInvalidator(JSContext *cx)
}
IonCode *
IonRuntime::generateArgumentsRectifier(JSContext *cx)
IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode)
{
// Do not erase the frame pointer in this function.
@ -289,7 +290,7 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx)
// Call the target function.
// Note that this code assumes the function is JITted.
masm.movq(Operand(rax, offsetof(JSFunction, u.i.script_)), rax);
masm.movq(Operand(rax, offsetof(JSScript, ion)), rax);
masm.movq(Operand(rax, OffsetOfIonInJSScript(mode)), rax);
masm.movq(Operand(rax, IonScript::offsetOfMethod()), rax);
masm.movq(Operand(rax, IonCode::offsetOfCode()), rax);
masm.call(rax);

View File

@ -13,6 +13,7 @@
#include "ion/IonSpewer.h"
#include "ion/Bailouts.h"
#include "ion/VMFunctions.h"
#include "ion/ExecutionModeInlines.h"
#include "jsscriptinlines.h"
@ -211,7 +212,7 @@ IonRuntime::generateInvalidator(JSContext *cx)
}
IonCode *
IonRuntime::generateArgumentsRectifier(JSContext *cx)
IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode)
{
MacroAssembler masm(cx);
@ -282,7 +283,7 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx)
// Call the target function.
// Note that this assumes the function is JITted.
masm.movl(Operand(eax, offsetof(JSFunction, u.i.script_)), eax);
masm.movl(Operand(eax, offsetof(JSScript, ion)), eax);
masm.movl(Operand(eax, OffsetOfIonInJSScript(mode)), eax);
masm.movl(Operand(eax, IonScript::offsetOfMethod()), eax);
masm.movl(Operand(eax, IonCode::offsetOfCode()), eax);
masm.call(eax);

View File

@ -0,0 +1,9 @@
function bug854050() {
// Shouldn't crash. Tests Ion's argumentsRectifier loading the right
// IonScript depending on execution mode.
for (z = 0; z < 1; z++)
function x(b, x) {}
ParallelArray(47, x);
}
bug854050();