mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 1c27ec193926 (bug 1002271) for B2G build failures
This commit is contained in:
parent
4ad4a83b07
commit
0e98d692ed
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "jit/IonAnalysis.h"
|
||||
|
||||
#include "jsanalyze.h"
|
||||
|
||||
#include "jit/BaselineInspector.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/Ion.h"
|
||||
|
@ -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);
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "jsanalyze.h"
|
||||
|
||||
#include "jit/IonSpewer.h"
|
||||
#include "jit/LIR.h"
|
||||
#include "jit/MIR.h"
|
||||
|
@ -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
2399
js/src/jsanalyze.cpp
Normal file
File diff suppressed because it is too large
Load Diff
216
js/src/jsanalyze.h
Normal file
216
js/src/jsanalyze.h
Normal 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 */
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsanalyze.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
|
@ -123,6 +123,7 @@ UNIFIED_SOURCES += [
|
||||
'gc/Verifier.cpp',
|
||||
'gc/Zone.cpp',
|
||||
'jsalloc.cpp',
|
||||
'jsanalyze.cpp',
|
||||
'jsapi.cpp',
|
||||
'jsbool.cpp',
|
||||
'jscntxt.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user