Backed out changeset 1c27ec193926 (bug 1002271) for B2G build failures

This commit is contained in:
Ed Morley 2014-04-28 15:28:48 +01:00
parent 4ad4a83b07
commit 0e98d692ed
12 changed files with 2636 additions and 29 deletions

View File

@ -1960,8 +1960,7 @@ CheckScriptSize(JSContext *cx, JSScript* script)
return Method_CantCompile;
}
uint32_t numLocalsAndArgs = NumLocalsAndArgs(script);
uint32_t numLocalsAndArgs = analyze::TotalSlots(script);
if (cx->runtime()->isWorkerRuntime()) {
// DOM Workers don't have off thread compilation enabled. Since workers
// don't block the browser's event loop, allow them to compile larger

View File

@ -178,15 +178,6 @@ TooManyArguments(unsigned nargs)
return nargs >= SNAPSHOT_MAX_NARGS || nargs > js_JitOptions.maxStackArgs;
}
inline size_t
NumLocalsAndArgs(JSScript *script)
{
size_t num = 1 /* this */ + script->nfixed();
if (JSFunction *fun = script->functionNonDelazifying())
num += fun->nargs();
return num;
}
void ForbidCompilation(JSContext *cx, JSScript *script);
void ForbidCompilation(JSContext *cx, JSScript *script, ExecutionMode mode);

View File

@ -6,6 +6,8 @@
#include "jit/IonAnalysis.h"
#include "jsanalyze.h"
#include "jit/BaselineInspector.h"
#include "jit/BaselineJIT.h"
#include "jit/Ion.h"

View File

@ -6,6 +6,7 @@
#include "jit/IonOptimizationLevels.h"
#include "jsanalyze.h"
#include "jsscript.h"
using namespace js;
@ -76,7 +77,7 @@ OptimizationInfo::usesBeforeCompile(JSScript *script, jsbytecode *pc) const
if (script->length() > MAX_MAIN_THREAD_SCRIPT_SIZE)
minUses = minUses * (script->length() / (double) MAX_MAIN_THREAD_SCRIPT_SIZE);
uint32_t numLocalsAndArgs = NumLocalsAndArgs(script);
uint32_t numLocalsAndArgs = analyze::TotalSlots(script);
if (numLocalsAndArgs > MAX_MAIN_THREAD_LOCALS_AND_ARGS)
minUses = minUses * (numLocalsAndArgs / (double) MAX_MAIN_THREAD_LOCALS_AND_ARGS);

View File

@ -8,6 +8,8 @@
#include "mozilla/DebugOnly.h"
#include "jsanalyze.h"
#include "jit/IonSpewer.h"
#include "jit/LIR.h"
#include "jit/MIR.h"

View File

@ -8,6 +8,8 @@
#include "mozilla/MathAlgorithms.h"
#include "jsanalyze.h"
#include "jit/Ion.h"
#include "jit/IonAnalysis.h"
#include "jit/IonSpewer.h"

2399
js/src/jsanalyze.cpp Normal file

File diff suppressed because it is too large Load Diff

216
js/src/jsanalyze.h Normal file
View File

@ -0,0 +1,216 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Definitions for javascript analysis. */
#ifndef jsanalyze_h
#define jsanalyze_h
#include "jscompartment.h"
namespace js {
namespace analyze {
class Bytecode;
struct LifetimeVariable;
class SlotValue;
class SSAValue;
struct SSAValueInfo;
class SSAUseChain;
// Common representation of slots between ScriptAnalysis, TypeScript, and in the
// case of TotalSlots, Ion.
static inline uint32_t ThisSlot() {
return 0;
}
static inline uint32_t ArgSlot(uint32_t arg) {
return 1 + arg;
}
static inline uint32_t LocalSlot(JSScript *script, uint32_t local) {
return 1 + local +
(script->functionNonDelazifying() ? script->functionNonDelazifying()->nargs() : 0);
}
static inline uint32_t TotalSlots(JSScript *script) {
return LocalSlot(script, 0) + script->nfixed();
}
// Analysis information about a script. FIXME: At this point, the entire
// purpose of this class is to compute JSScript::needsArgsObj, and to support
// isReachable() in order for jsinfer.cpp:FindPreviousInnerInitializer to get
// the previous opcode. For that purpose, it is completely overkill.
class ScriptAnalysis
{
friend class Bytecode;
JSScript *script_;
Bytecode **codeArray;
uint32_t numSlots;
bool *escapedSlots;
#ifdef DEBUG
/* Whether the compartment was in debug mode when we performed the analysis. */
bool originalDebugMode_: 1;
#endif
/* --------- Bytecode analysis --------- */
bool canTrackVars:1;
bool argumentsContentsObserved_:1;
/* --------- Lifetime analysis --------- */
LifetimeVariable *lifetimes;
public:
ScriptAnalysis(JSScript *script) {
mozilla::PodZero(this);
this->script_ = script;
#ifdef DEBUG
this->originalDebugMode_ = script_->compartment()->debugMode();
#endif
}
MOZ_WARN_UNUSED_RESULT
bool analyzeBytecode(JSContext *cx);
bool isReachable(const jsbytecode *pc) { return maybeCode(pc); }
private:
MOZ_WARN_UNUSED_RESULT
bool analyzeSSA(JSContext *cx);
MOZ_WARN_UNUSED_RESULT
bool analyzeLifetimes(JSContext *cx);
/* Accessors for bytecode information. */
Bytecode& getCode(uint32_t offset) {
JS_ASSERT(offset < script_->length());
JS_ASSERT(codeArray[offset]);
return *codeArray[offset];
}
Bytecode& getCode(const jsbytecode *pc) { return getCode(script_->pcToOffset(pc)); }
Bytecode* maybeCode(uint32_t offset) {
JS_ASSERT(offset < script_->length());
return codeArray[offset];
}
Bytecode* maybeCode(const jsbytecode *pc) { return maybeCode(script_->pcToOffset(pc)); }
inline bool jumpTarget(uint32_t offset);
inline bool jumpTarget(const jsbytecode *pc);
inline const SSAValue &poppedValue(uint32_t offset, uint32_t which);
inline const SSAValue &poppedValue(const jsbytecode *pc, uint32_t which);
inline const SlotValue *newValues(uint32_t offset);
inline const SlotValue *newValues(const jsbytecode *pc);
inline bool trackUseChain(const SSAValue &v);
/*
* Get the use chain for an SSA value.
*/
inline SSAUseChain *& useChain(const SSAValue &v);
/* For a JSOP_CALL* op, get the pc of the corresponding JSOP_CALL/NEW/etc. */
inline jsbytecode *getCallPC(jsbytecode *pc);
/* Accessors for local variable information. */
/*
* Escaping slots include all slots that can be accessed in ways other than
* through the corresponding LOCAL/ARG opcode. This includes all closed
* slots in the script, all slots in scripts which use eval or are in debug
* mode, and slots which are aliased by NAME or similar opcodes in the
* containing script (which does not imply the variable is closed).
*/
inline bool slotEscapes(uint32_t slot);
/*
* Whether we distinguish different writes of this variable while doing
* SSA analysis. Escaping locals can be written in other scripts, and the
* presence of NAME opcodes which could alias local variables or arguments
* keeps us from tracking variable values at each point.
*/
inline bool trackSlot(uint32_t slot);
inline const LifetimeVariable & liveness(uint32_t slot);
void printSSA(JSContext *cx);
void printTypes(JSContext *cx);
/* Bytecode helpers */
MOZ_WARN_UNUSED_RESULT
inline bool addJump(JSContext *cx, unsigned offset,
unsigned *currentOffset, unsigned *forwardJump, unsigned *forwardLoop,
unsigned stackDepth);
/* Lifetime helpers */
MOZ_WARN_UNUSED_RESULT
inline bool addVariable(JSContext *cx, LifetimeVariable &var, unsigned offset,
LifetimeVariable **&saved, unsigned &savedCount);
MOZ_WARN_UNUSED_RESULT
inline bool killVariable(JSContext *cx, LifetimeVariable &var, unsigned offset,
LifetimeVariable **&saved, unsigned &savedCount);
MOZ_WARN_UNUSED_RESULT
inline bool extendVariable(JSContext *cx, LifetimeVariable &var, unsigned start, unsigned end);
inline void ensureVariable(LifetimeVariable &var, unsigned until);
/* SSA helpers */
MOZ_WARN_UNUSED_RESULT
bool makePhi(JSContext *cx, uint32_t slot, uint32_t offset, SSAValue *pv);
MOZ_WARN_UNUSED_RESULT
bool insertPhi(JSContext *cx, SSAValue &phi, const SSAValue &v);
MOZ_WARN_UNUSED_RESULT
bool mergeValue(JSContext *cx, uint32_t offset, const SSAValue &v, SlotValue *pv);
MOZ_WARN_UNUSED_RESULT
bool checkPendingValue(JSContext *cx, const SSAValue &v, uint32_t slot,
Vector<SlotValue> *pending);
MOZ_WARN_UNUSED_RESULT
bool checkBranchTarget(JSContext *cx, uint32_t targetOffset, Vector<uint32_t> &branchTargets,
SSAValueInfo *values, uint32_t stackDepth);
MOZ_WARN_UNUSED_RESULT
bool checkExceptionTarget(JSContext *cx, uint32_t catchOffset,
Vector<uint32_t> &exceptionTargets);
MOZ_WARN_UNUSED_RESULT
bool mergeBranchTarget(JSContext *cx, SSAValueInfo &value, uint32_t slot,
const Vector<uint32_t> &branchTargets, uint32_t currentOffset);
MOZ_WARN_UNUSED_RESULT
bool mergeExceptionTarget(JSContext *cx, const SSAValue &value, uint32_t slot,
const Vector<uint32_t> &exceptionTargets);
MOZ_WARN_UNUSED_RESULT
bool mergeAllExceptionTargets(JSContext *cx, SSAValueInfo *values,
const Vector<uint32_t> &exceptionTargets);
MOZ_WARN_UNUSED_RESULT
bool freezeNewValues(JSContext *cx, uint32_t offset);
typedef Vector<SSAValue, 16> SeenVector;
bool needsArgsObj(JSContext *cx, SeenVector &seen, const SSAValue &v);
bool needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use);
bool needsArgsObj(JSContext *cx);
public:
#ifdef DEBUG
void assertMatchingDebugMode();
void assertMatchingStackDepthAtOffset(uint32_t offset, uint32_t stackDepth);
#else
void assertMatchingDebugMode() { }
void assertMatchingStackDepthAtOffset(uint32_t offset, uint32_t stackDepth) { }
#endif
};
#ifdef DEBUG
void PrintBytecode(JSContext *cx, HandleScript script, jsbytecode *pc);
#endif
} /* namespace analyze */
} /* namespace js */
#endif /* jsanalyze_h */

View File

@ -42,6 +42,7 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using namespace js::analyze;
using mozilla::DebugOnly;
using mozilla::Maybe;
@ -4505,14 +4506,7 @@ TypeScript::printTypes(JSContext *cx, HandleScript script) const
fprintf(stderr, "\n");
for (jsbytecode *pc = script->code(); pc < script->codeEnd(); pc += GetBytecodeLength(pc)) {
{
fprintf(stderr, "#%u:", script->id());
Sprinter sprinter(cx);
if (!sprinter.init())
return;
js_Disassemble1(cx, script, pc, script->pcToOffset(pc), true, &sprinter);
fprintf(stderr, "%s", sprinter.string());
}
PrintBytecode(cx, script, pc);
if (js_CodeSpec[*pc].format & JOF_TYPESET) {
StackTypeSet *types = TypeScript::BytecodeTypes(script, pc);

View File

@ -13,6 +13,8 @@
#include "mozilla/PodOperations.h"
#include "jsanalyze.h"
#include "vm/ArrayObject.h"
#include "vm/BooleanObject.h"
#include "vm/NumberObject.h"
@ -541,29 +543,26 @@ extern void TypeDynamicResult(JSContext *cx, JSScript *script, jsbytecode *pc,
/* static */ inline unsigned
TypeScript::NumTypeSets(JSScript *script)
{
size_t num = script->nTypeSets() + 1 /* this */;
if (JSFunction *fun = script->functionNonDelazifying())
num += fun->nargs();
return num;
return script->nTypeSets() + analyze::LocalSlot(script, 0);
}
/* static */ inline StackTypeSet *
TypeScript::ThisTypes(JSScript *script)
{
return script->types->typeArray() + script->nTypeSets();
return script->types->typeArray() + script->nTypeSets() + analyze::ThisSlot();
}
/*
* Note: for non-escaping arguments, argTypes reflect only the initial type of
* the variable (e.g. passed values for argTypes, or undefined for localTypes)
* and not types from subsequent assignments.
* Note: for non-escaping arguments and locals, argTypes/localTypes reflect
* only the initial type of the variable (e.g. passed values for argTypes,
* or undefined for localTypes) and not types from subsequent assignments.
*/
/* static */ inline StackTypeSet *
TypeScript::ArgTypes(JSScript *script, unsigned i)
{
JS_ASSERT(i < script->functionNonDelazifying()->nargs());
return script->types->typeArray() + script->nTypeSets() + 1 + i;
return script->types->typeArray() + script->nTypeSets() + analyze::ArgSlot(i);
}
template <typename TYPESET>

View File

@ -15,6 +15,7 @@
#include <stdio.h>
#include <string.h>
#include "jsanalyze.h"
#include "jsapi.h"
#include "jsatom.h"
#include "jscntxt.h"

View File

@ -123,6 +123,7 @@ UNIFIED_SOURCES += [
'gc/Verifier.cpp',
'gc/Zone.cpp',
'jsalloc.cpp',
'jsanalyze.cpp',
'jsapi.cpp',
'jsbool.cpp',
'jscntxt.cpp',