This commit is contained in:
Phil Ringnalda 2013-09-22 09:13:14 -07:00
Родитель 272d3b9cf1 50a9eb0861
Коммит f156befe0b
132 изменённых файлов: 1835 добавлений и 429 удалений

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

@ -798,3 +798,7 @@ bin/libfreebl_32int64_3.so
@BINPATH@/metro/defaults
@BINPATH@/metro/modules
#endif
#ifdef MOZ_ASAN
@BINPATH@/llvm-symbolizer
#endif

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

@ -24,7 +24,7 @@ dnl If this is a mozilla-central, we'll find the virtualenv in the top
dnl source directory. If this is a SpiderMonkey build, we assume we're at
dnl js/src and try to find the virtualenv from the mozilla-central root.
for base in $MOZILLA_CENTRAL_PATH $_topsrcdir $_topsrcdir/../..; do
possible=$base/build/virtualenv/populate_virtualenv.py
possible=$base/python/mozbuild/mozbuild/virtualenv.py
if test -e $possible; then
_virtualenv_topsrcdir=$base
@ -53,7 +53,8 @@ if test -z $DONT_POPULATE_VIRTUALENV; then
dnl virtualenv is present and up to date. It sanitizes the environment
dnl for us, so we don't need to clean anything out.
$PYTHON $_virtualenv_populate_path \
$_virtualenv_topsrcdir $MOZ_BUILD_ROOT $MOZ_BUILD_ROOT/_virtualenv || exit 1
$_virtualenv_topsrcdir $MOZ_BUILD_ROOT $MOZ_BUILD_ROOT/_virtualenv \
$_virtualenv_topsrcdir/build/virtualenv_packages.txt || exit 1
case "$host_os" in
mingw*)

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

@ -512,6 +512,12 @@ class Automation(object):
# ASan specific environment stuff
if self.IS_ASAN and (self.IS_LINUX or self.IS_MAC):
# Symbolizer support
llvmsym = os.path.join(xrePath, "llvm-symbolizer")
if os.path.isfile(llvmsym):
env["ASAN_SYMBOLIZER_PATH"] = llvmsym
self.log.info("INFO | automation.py | ASan using symbolizer at %s", llvmsym)
try:
totalMemory = int(os.popen("free").readlines()[1].split()[1])

49
build/docs/conf.py Normal file
Просмотреть файл

@ -0,0 +1,49 @@
# 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/.
from __future__ import unicode_literals
import os
import re
from datetime import datetime
here = os.path.abspath(os.path.dirname(__file__))
mozilla_dir = os.path.normpath(os.path.join(here, '..', '..'))
import mdn_theme
extensions = [
'sphinx.ext.autodoc',
]
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
project = u'Mozilla Build System'
year = datetime.now().year
copyright = u'%s, Mozilla Foundation, CC BY-SA 3.0' % year
# Grab the version from the source tree's milestone.
with open(os.path.join(mozilla_dir, 'config', 'milestone.txt'), 'rt') as fh:
for line in fh:
line = line.strip()
if not line or line.startswith('#'):
continue
release = line
break
version = re.sub(r'[ab]\d+$', '', release)
exclude_patterns = ['_build']
pygments_style = 'sphinx'
html_theme_path = [mdn_theme.get_theme_dir()]
html_theme = 'mdn'
html_static_path = ['_static']
htmlhelp_basename = 'MozillaBuildSystemdoc'

28
build/docs/glossary.rst Normal file
Просмотреть файл

@ -0,0 +1,28 @@
========
Glossary
========
.. glossary::
:sorted:
object directory
A directory holding the output of the build system. The build
system attempts to isolate all file modifications to this
directory. By convention, object directories are commonly
directories under the source directory prefixed with **obj-**.
e.g. **obj-firefox**.
mozconfig
A shell script used to configure the build system.
configure
A generated shell script which detects the current system
environment, applies a requested set of build configuration
options, and writes out metadata to be consumed by the build
system.
config.status
An executable file produced by **configure** that takes the
generated build config and writes out files used to build the
tree. Traditionally, config.status writes out a bunch of
Makefiles.

41
build/docs/index.rst Normal file
Просмотреть файл

@ -0,0 +1,41 @@
==================================
Mozilla Build System Documentation
==================================
Overview
========
.. toctree::
:maxdepth: 1
glossary
Important Concepts
==================
.. toctree::
:maxdepth: 1
Mozconfig Files <mozconfigs>
Profile Guided Optimization <pgo>
mozbuild
========
mozbuild is a Python package containing a lot of the code for the
Mozilla build system.
.. toctree::
:maxdepth: 1
mozbuild/index
mozbuild/frontend
mozbuild/dumbmake
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

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

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

68
build/docs/mozconfigs.rst Normal file
Просмотреть файл

@ -0,0 +1,68 @@
===============
mozconfig Files
===============
mozconfig files are used to configure how a build works.
mozconfig files are actually shell scripts. They are executed in a
special context with specific variables and functions exposed to them.
API
===
Functions
---------
The following special functions are available to a mozconfig script.
ac_add_options
^^^^^^^^^^^^^^
This function is used to declare extra options/arguments to pass into
configure.
e.g.::
ac_add_options --disable-tests
ac_add_options --enable-optimize
mk_add_options
^^^^^^^^^^^^^^
This function is used to inject statements into client.mk for execution.
It is typically used to define variables, notably the object directory.
e.g.::
mk_add_options AUTOCLOBBER=1
ac_add_options
^^^^^^^^^^^^^^
This is a variant of ac_add_options() which only adds configure options
for a specified application. This is only used when building multiple
applications through client.mk. This function is typically not needed.
Special mk_add_options Variables
--------------------------------
For historical reasons, the method for communicating certain
well-defined variables is via mk_add_options(). In this section, we
document what those special variables are.
MOZ_OBJDIR
^^^^^^^^^^
This variable is used to define the :term:`object directory` for the current
build.
Finding the active mozconfig
============================
Multiple mozconfig files can exist to provide different configuration
options for different tasks. The rules for finding the active mozconfig
are defined in the
:py:func:`mozbuild.mozconfig.MozconfigLoader.find_mozconfig` method:
.. autoclass:: mozbuild.mozconfig.MozconfigLoader
:members: find_mozconfig

40
build/docs/pgo.rst Normal file
Просмотреть файл

@ -0,0 +1,40 @@
.. _pgo:
===========================
Profile Guided Optimization
===========================
:abbr:`PGO (Profile Guided Optimization)` is the process of adding
probes to a compiled binary, running said binary, then using the
run-time information to *recompile* the binary to (hopefully) make it
faster.
How PGO Builds Work
===================
The supported interface for invoking a PGO build is to evaluate the
*build* target of client.mk with *MOZ_PGO* defined. e.g.::
$ make -f client.mk MOZ_PGO=1
This is equivalent to::
$ make -f client.mk profiledbuild
Which is roughly equivalent to:
#. Perform a build with *MOZ_PROFILE_GENERATE=1* and *MOZ_PGO_INSTRUMENTED=1*
#. Package with *MOZ_PGO_INSTRUMENTED=1*
#. Performing a run of the instrumented binaries
#. $ make maybe_clobber_profiledbuild
#. Perform a build with *MOZ_PROFILE_USE=1*
Differences between toolchains
==============================
There are some implementation differences depending on the compiler
toolchain being used.
The *maybe_clobber_profiledbuild* step gets its name because of a
difference. On Windows, this step merely moves some *.pgc* files around.
Using GCC or Clang, it is equivalent to a *make clean*.

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

@ -6,6 +6,14 @@
SDK_BINARY = run-mozilla.sh
ifneq ($(LLVM_SYMBOLIZER),)
# Install a copy of the llvm-symbolizer binary to dist/bin, so it can
# be used for symbolizing traces for e.g. AddressSanitizer
LLVMSYM_EXECUTABLES=$(LLVM_SYMBOLIZER)
LLVMSYM_DEST=$(FINAL_TARGET)
INSTALL_TARGETS += LLVMSYM
endif
include $(topsrcdir)/config/rules.mk
libs:: $(srcdir)/run-mozilla.sh

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

@ -3,6 +3,7 @@
# Use Clang as specified in manifest
export CC="$topsrcdir/clang/bin/clang -fgnu89-inline"
export CXX="$topsrcdir/clang/bin/clang++"
export LLVM_SYMBOLIZER="$topsrcdir/clang/bin/llvm-symbolizer"
# Mandatory flags for ASan
export ASANFLAGS="-fsanitize=address -Dxmalloc=myxmalloc -fPIC"

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

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

@ -325,8 +325,8 @@ CONFIG_STATUS_DEPS := \
$(TOPSRCDIR)/config/milestone.txt \
$(TOPSRCDIR)/js/src/config/milestone.txt \
$(TOPSRCDIR)/browser/config/version.txt \
$(TOPSRCDIR)/build/virtualenv/packages.txt \
$(TOPSRCDIR)/build/virtualenv/populate_virtualenv.py \
$(TOPSRCDIR)/build/virtualenv_packages.txt \
$(TOPSRCDIR)/python/mozbuild/mozbuild/virtualenv.py \
$(TOPSRCDIR)/testing/mozbase/packages.txt \
$(NULL)

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

@ -1212,8 +1212,10 @@ MOZ_ARG_ENABLE_BOOL(address-sanitizer,
if test -n "$MOZ_ASAN"; then
MOZ_LLVM_HACKS=1
AC_DEFINE(MOZ_ASAN)
MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
fi
AC_SUBST(MOZ_ASAN)
AC_SUBST(LLVM_SYMBOLIZER)
dnl ========================================================
dnl = Enable hacks required for LLVM instrumentations
@ -1235,7 +1237,12 @@ dnl ========================================================
if test "$GNU_CC"; then
# Per bug 719659 comment 2, some of the headers on ancient build machines
# may require gnu89 inline semantics. But otherwise, we use C99.
CFLAGS="$CFLAGS -std=gnu99 -fgnu89-inline"
# But on OS X we just use C99 plus GNU extensions, in order to fix
# bug 917526.
CFLAGS="$CFLAGS -std=gnu99"
if test "${OS_ARCH}" != Darwin; then
CFLAGS="$CFLAGS -fgnu89-inline"
fi
# FIXME: Let us build with strict aliasing. bug 414641.
CFLAGS="$CFLAGS -fno-strict-aliasing"
MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(notdir $@) -o $@'

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

@ -9,6 +9,7 @@
#include "nsIFile.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
#include "nsDataHashtable.h"
#endif
namespace mozilla {

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

@ -298,11 +298,18 @@ JITTEST_VALGRIND_FLAG = --valgrind
endif
endif
ifdef MOZ_ASAN
ifneq ($(LLVM_SYMBOLIZER),)
# Use the LLVM symbolizer when running jit-tests under ASan, if available
JITTEST_ASAN_ENV=ASAN_SYMBOLIZER_PATH='$(LLVM_SYMBOLIZER)'
endif
endif
check-style::
(cd $(srcdir) && $(PYTHON) config/check_spidermonkey_style.py);
check-jit-test::
$(wildcard $(RUN_TEST_PROGRAM)) $(PYTHON) -u $(srcdir)/jit-test/jit_test.py \
$(JITTEST_ASAN_ENV) $(wildcard $(RUN_TEST_PROGRAM)) $(PYTHON) -u $(srcdir)/jit-test/jit_test.py \
--no-slow --no-progress --tinderbox --tbpl $(JITTEST_VALGRIND_FLAG) \
$(DIST)/bin/$(JS_SHELL_NAME)$(BIN_SUFFIX)

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

@ -24,7 +24,7 @@ dnl If this is a mozilla-central, we'll find the virtualenv in the top
dnl source directory. If this is a SpiderMonkey build, we assume we're at
dnl js/src and try to find the virtualenv from the mozilla-central root.
for base in $MOZILLA_CENTRAL_PATH $_topsrcdir $_topsrcdir/../..; do
possible=$base/build/virtualenv/populate_virtualenv.py
possible=$base/python/mozbuild/mozbuild/virtualenv.py
if test -e $possible; then
_virtualenv_topsrcdir=$base
@ -53,7 +53,8 @@ if test -z $DONT_POPULATE_VIRTUALENV; then
dnl virtualenv is present and up to date. It sanitizes the environment
dnl for us, so we don't need to clean anything out.
$PYTHON $_virtualenv_populate_path \
$_virtualenv_topsrcdir $MOZ_BUILD_ROOT $MOZ_BUILD_ROOT/_virtualenv || exit 1
$_virtualenv_topsrcdir $MOZ_BUILD_ROOT $MOZ_BUILD_ROOT/_virtualenv \
$_virtualenv_topsrcdir/build/virtualenv_packages.txt || exit 1
case "$host_os" in
mingw*)

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

@ -260,7 +260,7 @@ StructTypeRepresentation::init(JSContext *cx,
JSObject *
TypeRepresentation::addToTableOrFree(JSContext *cx,
TypeRepresentationSet::AddPtr &p)
TypeRepresentationHash::AddPtr &p)
{
JS_ASSERT(!ownerObject_);
@ -298,7 +298,7 @@ ScalarTypeRepresentation::Create(JSContext *cx,
JSCompartment *comp = cx->compartment();
ScalarTypeRepresentation sample(type);
TypeRepresentationSet::AddPtr p = comp->typeReprs.lookupForAdd(&sample);
TypeRepresentationHash::AddPtr p = comp->typeReprs.lookupForAdd(&sample);
if (p)
return (*p)->ownerObject();
@ -332,7 +332,7 @@ ArrayTypeRepresentation::Create(JSContext *cx,
}
ArrayTypeRepresentation sample(element, length);
TypeRepresentationSet::AddPtr p = comp->typeReprs.lookupForAdd(&sample);
TypeRepresentationHash::AddPtr p = comp->typeReprs.lookupForAdd(&sample);
if (p)
return (*p)->ownerObject();
@ -364,7 +364,7 @@ StructTypeRepresentation::Create(JSContext *cx,
if (!ptr->init(cx, ids, typeReprOwners))
return NULL;
TypeRepresentationSet::AddPtr p = comp->typeReprs.lookupForAdd(ptr);
TypeRepresentationHash::AddPtr p = comp->typeReprs.lookupForAdd(ptr);
if (p) {
js_free(ptr); // do not finalize, not present in the table
return (*p)->ownerObject();
@ -540,10 +540,10 @@ StructTypeRepresentation::appendStringStruct(JSContext *cx, StringBuffer &conten
// Misc
const StructField *
StructTypeRepresentation::fieldNamed(HandleId id) const
StructTypeRepresentation::fieldNamed(jsid id) const
{
for (size_t i = 0; i < fieldCount(); i++) {
if (field(i).id.get() == id.get())
if (field(i).id.get() == id)
return &field(i);
}
return NULL;

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

@ -85,7 +85,7 @@ struct TypeRepresentationHasher
typedef js::HashSet<TypeRepresentation *,
TypeRepresentationHasher,
RuntimeAllocPolicy> TypeRepresentationSet;
RuntimeAllocPolicy> TypeRepresentationHash;
class TypeRepresentation {
public:
@ -102,7 +102,7 @@ class TypeRepresentation {
size_t alignment_;
Kind kind_;
JSObject *addToTableOrFree(JSContext *cx, TypeRepresentationSet::AddPtr &p);
JSObject *addToTableOrFree(JSContext *cx, TypeRepresentationHash::AddPtr &p);
private:
static const Class class_;
@ -290,7 +290,7 @@ class StructTypeRepresentation : public TypeRepresentation {
return fields()[i];
}
const StructField *fieldNamed(HandleId id) const;
const StructField *fieldNamed(jsid id) const;
static JSObject *Create(JSContext *cx,
AutoIdVector &ids,

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

@ -2366,3 +2366,10 @@ BinaryBlock::obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
return true;
}
/* static */ size_t
BinaryBlock::dataOffset()
{
return JSObject::getPrivateDataOffset(BLOCK_RESERVED_SLOTS + 1);
}

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

@ -197,6 +197,10 @@ class BinaryBlock
public:
static const Class class_;
// Returns the offset in bytes within the object where the `void*`
// pointer can be found.
static size_t dataOffset();
static bool isBlock(HandleObject val);
static uint8_t *mem(HandleObject val);

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

@ -1061,7 +1061,12 @@ dnl ========================================================
if test "$GNU_CC"; then
# Per bug 719659 comment 2, some of the headers on ancient build machines
# may require gnu89 inline semantics. But otherwise, we use C99.
CFLAGS="$CFLAGS -std=gnu99 -fgnu89-inline"
# But on OS X we just use C99 plus GNU extensions, in order to fix
# bug 917526.
CFLAGS="$CFLAGS -std=gnu99"
if test "${OS_ARCH}" != Darwin; then
CFLAGS="$CFLAGS -fgnu89-inline"
fi
MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(notdir $@) -o $@'
MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(notdir $@) -o $@'
DSO_LDOPTS='-shared'

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

@ -134,16 +134,10 @@ class gcstats::StatisticsSerializer
return NULL;
}
size_t outlen = nchars;
bool ok = InflateStringToBuffer(NULL, buf, nchars, out, &outlen);
InflateStringToBuffer(buf, nchars, out);
js_free(buf);
if (!ok) {
oom_ = true;
js_free(out);
return NULL;
}
out[nchars] = 0;
out[nchars] = 0;
return out;
}

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

@ -0,0 +1,30 @@
// Test that we can optimize stuff like line.target.x without
// creating an intermediate object.
if (!this.hasOwnProperty("Type"))
quit();
var PointType = new StructType({x: float64,
y: float64});
var LineType = new StructType({source: PointType,
target: PointType});
function manhattenDistance(line) {
return (Math.abs(line.target.x - line.source.x) +
Math.abs(line.target.y - line.source.y));
}
function foo() {
var N = 30000;
var points = [];
var obj;
var s;
var fromAToB = new LineType({source: {x: 22, y: 44},
target: {x: 66, y: 88}});
for (var i = 0; i < N; i++)
assertEq(manhattenDistance(fromAToB), 88);
}
foo();

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

@ -12,16 +12,25 @@ function xPlusY(p) {
return p.x + p.y;
}
function xPlusYTweak(p) {
p.x = 22;
return xPlusY(p);
}
function foo() {
var N = 30000;
var points = [];
var obj;
var s;
for (var i = 0; i < N; i++) {
var s;
if ((i % 2) == 0 || true)
s = xPlusY(new PointType2({x: i, y: i+1}));
obj = new PointType2({x: i, y: i+1});
else
s = xPlusY(new PointType3({x: i, y: i+1, z: i+2}));
assertEq(s, i + i + 1);
obj = new PointType3({x: i, y: i+1, z: i+2});
assertEq(xPlusY(obj), i + i + 1);
assertEq(xPlusYTweak(obj), 22 + i + 1);
}
}

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

@ -16,6 +16,7 @@
#include "jsnum.h"
#include "builtin/Eval.h"
#include "builtin/TypedObject.h"
#include "gc/Nursery.h"
#include "jit/ExecutionModeInlines.h"
#include "jit/IonLinker.h"
@ -2861,6 +2862,25 @@ CodeGenerator::visitNewArrayCallVM(LNewArray *lir)
return true;
}
typedef JSObject *(*NewDerivedTypedObjectFn)(JSContext *,
HandleObject type,
HandleObject owner,
int32_t offset);
static const VMFunction CreateDerivedTypedObjInfo =
FunctionInfo<NewDerivedTypedObjectFn>(CreateDerivedTypedObj);
bool
CodeGenerator::visitNewDerivedTypedObject(LNewDerivedTypedObject *lir)
{
// Not yet made safe for par exec:
JS_ASSERT(gen->info().executionMode() == SequentialExecution);
pushArg(ToRegister(lir->offset()));
pushArg(ToRegister(lir->owner()));
pushArg(ToRegister(lir->type()));
return callVM(CreateDerivedTypedObjInfo, lir);
}
bool
CodeGenerator::visitNewSlots(LNewSlots *lir)
{
@ -3577,6 +3597,15 @@ CodeGenerator::visitTypedArrayElements(LTypedArrayElements *lir)
return true;
}
bool
CodeGenerator::visitTypedObjectElements(LTypedObjectElements *lir)
{
Register obj = ToRegister(lir->object());
Register out = ToRegister(lir->output());
masm.loadPtr(Address(obj, BinaryBlock::dataOffset()), out);
return true;
}
bool
CodeGenerator::visitStringLength(LStringLength *lir)
{

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

@ -132,6 +132,7 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitNewStringObject(LNewStringObject *lir);
bool visitNewPar(LNewPar *lir);
bool visitNewDenseArrayPar(LNewDenseArrayPar *lir);
bool visitNewDerivedTypedObject(LNewDerivedTypedObject *lir);
bool visitAbortPar(LAbortPar *lir);
bool visitInitElem(LInitElem *lir);
bool visitInitElemGetterSetter(LInitElemGetterSetter *lir);
@ -148,6 +149,7 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitArrayLength(LArrayLength *lir);
bool visitTypedArrayLength(LTypedArrayLength *lir);
bool visitTypedArrayElements(LTypedArrayElements *lir);
bool visitTypedObjectElements(LTypedObjectElements *lir);
bool visitStringLength(LStringLength *lir);
bool visitInitializedLength(LInitializedLength *lir);
bool visitSetInitializedLength(LSetInitializedLength *lir);

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

@ -11,6 +11,7 @@
#include "jsautooplen.h"
#include "builtin/Eval.h"
#include "builtin/TypedObject.h"
#include "builtin/TypeRepresentation.h"
#include "frontend/SourceNotes.h"
#include "jit/BaselineFrame.h"
@ -1186,7 +1187,15 @@ IonBuilder::traverseBytecode()
// FALL THROUGH
default:
JS_ASSERT(popped[i]->isFolded() || popped[i]->defUseCount() > poppedUses[i]);
JS_ASSERT(popped[i]->isFolded() ||
// MNewDerivedTypedObject instances are
// often dead unless they escape from the
// fn. See IonBuilder::loadTypedObjectData()
// for more details.
popped[i]->isNewDerivedTypedObject() ||
popped[i]->defUseCount() > poppedUses[i]);
break;
}
}
@ -7001,6 +7010,28 @@ IonBuilder::convertShiftToMaskForStaticTypedArray(MDefinition *id,
return ptr;
}
static MIRType
MIRTypeForTypedArrayRead(ScalarTypeRepresentation::Type arrayType,
bool observedDouble)
{
switch (arrayType) {
case ScalarTypeRepresentation::TYPE_INT8:
case ScalarTypeRepresentation::TYPE_UINT8:
case ScalarTypeRepresentation::TYPE_UINT8_CLAMPED:
case ScalarTypeRepresentation::TYPE_INT16:
case ScalarTypeRepresentation::TYPE_UINT16:
case ScalarTypeRepresentation::TYPE_INT32:
return MIRType_Int32;
case ScalarTypeRepresentation::TYPE_UINT32:
return observedDouble ? MIRType_Double : MIRType_Int32;
case ScalarTypeRepresentation::TYPE_FLOAT32:
return (LIRGenerator::allowFloat32Optimizations()) ? MIRType_Float32 : MIRType_Double;
case ScalarTypeRepresentation::TYPE_FLOAT64:
return MIRType_Double;
}
MOZ_ASSUME_UNREACHABLE("Unknown typed array type");
}
bool
IonBuilder::jsop_getelem_typed(MDefinition *obj, MDefinition *index,
ScalarTypeRepresentation::Type arrayType)
@ -7027,28 +7058,7 @@ IonBuilder::jsop_getelem_typed(MDefinition *obj, MDefinition *index,
// the array type to determine the result type, even if the opcode has
// never executed. The known pushed type is only used to distinguish
// uint32 reads that may produce either doubles or integers.
MIRType knownType;
switch (arrayType) {
case ScalarTypeRepresentation::TYPE_INT8:
case ScalarTypeRepresentation::TYPE_UINT8:
case ScalarTypeRepresentation::TYPE_UINT8_CLAMPED:
case ScalarTypeRepresentation::TYPE_INT16:
case ScalarTypeRepresentation::TYPE_UINT16:
case ScalarTypeRepresentation::TYPE_INT32:
knownType = MIRType_Int32;
break;
case ScalarTypeRepresentation::TYPE_UINT32:
knownType = allowDouble ? MIRType_Double : MIRType_Int32;
break;
case ScalarTypeRepresentation::TYPE_FLOAT32:
knownType = (LIRGenerator::allowFloat32Optimizations()) ? MIRType_Float32 : MIRType_Double;
break;
case ScalarTypeRepresentation::TYPE_FLOAT64:
knownType = MIRType_Double;
break;
default:
MOZ_ASSUME_UNREACHABLE("Unknown typed array type");
}
MIRType knownType = MIRTypeForTypedArrayRead(arrayType, allowDouble);
// Get the length.
MInstruction *length = getTypedArrayLength(obj);
@ -8150,6 +8160,10 @@ IonBuilder::jsop_getprop(PropertyName *name)
return resumeAfter(call);
}
// Try to emit loads from known binary data blocks
if (!getPropTryTypedObject(&emitted, id, types) || emitted)
return emitted;
// Try to emit loads from definite slots.
if (!getPropTryDefiniteSlot(&emitted, name, barrier, types) || emitted)
return emitted;
@ -8231,6 +8245,121 @@ IonBuilder::getPropTryConstant(bool *emitted, jsid id, types::TemporaryTypeSet *
return true;
}
bool
IonBuilder::getPropTryTypedObject(bool *emitted,
jsid id,
types::TemporaryTypeSet *resultTypes)
{
TypeRepresentationSet fieldTypeReprs;
int32_t fieldOffset;
size_t fieldIndex;
if (!lookupTypedObjectField(current->peek(-1), id, &fieldOffset,
&fieldTypeReprs, &fieldIndex))
return false;
if (fieldTypeReprs.empty())
return true;
switch (fieldTypeReprs.kind()) {
case TypeRepresentation::Struct:
case TypeRepresentation::Array:
return getPropTryComplexPropOfTypedObject(emitted,
fieldOffset,
fieldTypeReprs,
fieldIndex,
resultTypes);
case TypeRepresentation::Scalar:
return getPropTryScalarPropOfTypedObject(emitted,
fieldOffset,
fieldTypeReprs,
resultTypes);
}
MOZ_ASSUME_UNREACHABLE("Bad kind");
}
bool
IonBuilder::getPropTryScalarPropOfTypedObject(bool *emitted,
int32_t fieldOffset,
TypeRepresentationSet fieldTypeReprs,
types::TemporaryTypeSet *resultTypes)
{
// Must always be loading the same scalar type
if (fieldTypeReprs.length() != 1)
return true;
ScalarTypeRepresentation *fieldTypeRepr = fieldTypeReprs.get(0)->asScalar();
// OK!
*emitted = true;
MDefinition *typedObj = current->pop();
// Find location within the owner object.
MDefinition *owner, *ownerOffset;
loadTypedObjectData(typedObj, fieldOffset, &owner, &ownerOffset);
// Load the element data.
MTypedObjectElements *elements = MTypedObjectElements::New(owner);
current->add(elements);
// Reading from an Uint32Array will result in a double for values
// that don't fit in an int32. We have to bailout if this happens
// and the instruction is not known to return a double.
bool allowDouble = resultTypes->hasType(types::Type::DoubleType());
MIRType knownType = MIRTypeForTypedArrayRead(fieldTypeRepr->type(), allowDouble);
// Typed array offsets are expressed in units of the alignment,
// and the binary data API guarantees all offsets are properly
// aligned. So just do the divide.
MConstant *alignment = MConstant::New(Int32Value(fieldTypeRepr->alignment()));
current->add(alignment);
MDiv *scaledOffset = MDiv::NewAsmJS(ownerOffset, alignment, MIRType_Int32);
current->add(scaledOffset);
MLoadTypedArrayElement *load =
MLoadTypedArrayElement::New(elements, scaledOffset,
fieldTypeRepr->type());
load->setResultType(knownType);
load->setResultTypeSet(resultTypes);
current->add(load);
current->push(load);
return true;
}
bool
IonBuilder::getPropTryComplexPropOfTypedObject(bool *emitted,
int32_t fieldOffset,
TypeRepresentationSet fieldTypeReprs,
size_t fieldIndex,
types::TemporaryTypeSet *resultTypes)
{
// Must know the field index so that we can load the new type
// object for the derived value
if (fieldIndex == SIZE_MAX)
return true;
*emitted = true;
MDefinition *typedObj = current->pop();
// Identify the type object for the field.
MDefinition *type = loadTypedObjectType(typedObj);
MDefinition *fieldType = typeObjectForFieldFromStructType(type, fieldIndex);
// Find location within the owner object.
MDefinition *owner, *ownerOffset;
loadTypedObjectData(typedObj, fieldOffset, &owner, &ownerOffset);
// Create the derived type object.
MInstruction *derived = new MNewDerivedTypedObject(fieldTypeReprs,
fieldType,
owner,
ownerOffset);
derived->setResultTypeSet(resultTypes);
current->add(derived);
current->push(derived);
return true;
}
bool
IonBuilder::getPropTryDefiniteSlot(bool *emitted, PropertyName *name,
bool barrier, types::TemporaryTypeSet *types)
@ -8521,6 +8650,10 @@ IonBuilder::jsop_setprop(PropertyName *name)
return false;
}
// Try to emit stores to known binary data blocks
if (!setPropTryTypedObject(&emitted, obj, id, value) || emitted)
return emitted;
// Try to emit store from definite slots.
if (!setPropTryDefiniteSlot(&emitted, obj, name, value, barrier, objTypes) || emitted)
return emitted;
@ -8653,6 +8786,66 @@ IonBuilder::setPropTryCommonDOMSetter(bool *emitted, MDefinition *obj,
return true;
}
bool
IonBuilder::setPropTryTypedObject(bool *emitted, MDefinition *obj,
jsid id, MDefinition *value)
{
TypeRepresentationSet fieldTypeReprs;
int32_t fieldOffset;
size_t fieldIndex;
if (!lookupTypedObjectField(obj, id, &fieldOffset, &fieldTypeReprs,
&fieldIndex))
return false;
if (fieldTypeReprs.empty())
return true;
switch (fieldTypeReprs.kind()) {
case TypeRepresentation::Struct:
case TypeRepresentation::Array:
// For now, only optimize storing scalars.
return true;
case TypeRepresentation::Scalar:
break;
}
// Must always be storing the same scalar type
if (fieldTypeReprs.length() != 1)
return true;
ScalarTypeRepresentation *fieldTypeRepr = fieldTypeReprs.get(0)->asScalar();
// OK!
*emitted = true;
MTypedObjectElements *elements = MTypedObjectElements::New(obj);
current->add(elements);
// Typed array offsets are expressed in units of the alignment,
// and the binary data API guarantees all offsets are properly
// aligned.
JS_ASSERT(fieldOffset % fieldTypeRepr->alignment() == 0);
int32_t scaledFieldOffset = fieldOffset / fieldTypeRepr->alignment();
MConstant *offset = MConstant::New(Int32Value(scaledFieldOffset));
current->add(offset);
// Clamp value to [0, 255] for Uint8ClampedArray.
MDefinition *toWrite = value;
if (fieldTypeRepr->type() == ScalarTypeRepresentation::TYPE_UINT8_CLAMPED) {
toWrite = MClampToUint8::New(value);
current->add(toWrite->toInstruction());
}
MStoreTypedArrayElement *store =
MStoreTypedArrayElement::New(elements, offset, toWrite,
fieldTypeRepr->type());
current->add(store);
current->push(value);
return true;
}
bool
IonBuilder::setPropTryDefiniteSlot(bool *emitted, MDefinition *obj,
PropertyName *name, MDefinition *value,
@ -9325,3 +9518,172 @@ IonBuilder::cloneTypeSet(types::StackTypeSet *types)
// after bug 804676 this code can be removed.
return types->clone(GetIonContext()->temp->lifoAlloc());
}
TypeRepresentationSetHash *
IonBuilder::getOrCreateReprSetHash()
{
if (!reprSetHash_) {
TypeRepresentationSetHash* hash =
cx->new_<TypeRepresentationSetHash>();
if (!hash || !hash->init()) {
js_delete(hash);
return NULL;
}
reprSetHash_ = hash;
}
return reprSetHash_.get();
}
bool
IonBuilder::lookupTypeRepresentationSet(MDefinition *typedObj,
TypeRepresentationSet *out)
{
*out = TypeRepresentationSet(); // default to unknown
// Extract TypeRepresentationSet directly if we can
if (typedObj->isNewDerivedTypedObject()) {
*out = typedObj->toNewDerivedTypedObject()->set();
return true;
}
// Extract TypeRepresentationSet directly if we can
types::TemporaryTypeSet *types = typedObj->resultTypeSet();
if (!types || types->getKnownTypeTag() != JSVAL_TYPE_OBJECT)
return true;
// And only known objects.
if (types->unknownObject())
return true;
TypeRepresentationSetBuilder set;
for (uint32_t i = 0; i < types->getObjectCount(); i++) {
types::TypeObject *type = types->getTypeObject(0);
if (!type || type->unknownProperties())
return true;
if (!type->hasTypedObject())
return true;
TypeRepresentation *typeRepr = type->typedObject()->typeRepr;
if (!set.insert(typeRepr))
return false;
}
return set.build(*this, out);
}
MDefinition *
IonBuilder::loadTypedObjectType(MDefinition *typedObj)
{
// Shortcircuit derived type objects, meaning the intermediate
// objects created to represent `a.b` in an expression like
// `a.b.c`. In that case, the type object can be simply pulled
// from the operands of that instruction.
if (typedObj->isNewDerivedTypedObject())
return typedObj->toNewDerivedTypedObject()->type();
MInstruction *load = MLoadFixedSlot::New(typedObj, js::SLOT_DATATYPE);
current->add(load);
return load;
}
// Given a typed object `typedObj` and an offset `offset` into that
// object's data, returns another typed object and adusted offset
// where the data can be found. Often, these returned values are the
// same as the inputs, but in cases where intermediate derived type
// objects have been created, the return values will remove
// intermediate layers (often rendering those derived type objects
// into dead code).
void
IonBuilder::loadTypedObjectData(MDefinition *typedObj,
int32_t offset,
MDefinition **owner,
MDefinition **ownerOffset)
{
MConstant *offsetDef = MConstant::New(Int32Value(offset));
current->add(offsetDef);
// Shortcircuit derived type objects, meaning the intermediate
// objects created to represent `a.b` in an expression like
// `a.b.c`. In that case, the owned and a base offset can be
// pulled from the operands of the instruction and combined with
// `offset`.
if (typedObj->isNewDerivedTypedObject()) {
// If we see that the
MNewDerivedTypedObject *ins = typedObj->toNewDerivedTypedObject();
MAdd *offsetAdd = MAdd::NewAsmJS(ins->offset(), offsetDef,
MIRType_Int32);
current->add(offsetAdd);
*owner = ins->owner();
*ownerOffset = offsetAdd;
return;
}
*owner = typedObj;
*ownerOffset = offsetDef;
}
// Looks up the offset/type-repr-set of the field `id`, given the type
// set `objTypes` of the field owner. Note that even when true is
// returned, `*fieldTypeReprs` might be empty if no useful type/offset
// pair could be determined.
bool
IonBuilder::lookupTypedObjectField(MDefinition *typedObj,
jsid id,
int32_t *fieldOffset,
TypeRepresentationSet *fieldTypeReprs,
size_t *fieldIndex)
{
TypeRepresentationSet objTypeReprs;
if (!lookupTypeRepresentationSet(typedObj, &objTypeReprs))
return false;
// Must be accessing a struct.
if (!objTypeReprs.allOfKind(TypeRepresentation::Struct))
return true;
// Determine the type/offset of the field `id`, if any.
size_t offset;
if (!objTypeReprs.fieldNamed(*this, id, &offset,
fieldTypeReprs, fieldIndex))
return false;
if (fieldTypeReprs->empty())
return false;
// Field offset must be representable as signed integer.
if (offset >= size_t(INT_MAX)) {
*fieldTypeReprs = TypeRepresentationSet();
return true;
}
*fieldOffset = int32_t(offset);
JS_ASSERT(*fieldOffset >= 0);
return true;
}
MDefinition *
IonBuilder::typeObjectForFieldFromStructType(MDefinition *typeObj,
size_t fieldIndex)
{
// Load list of field type objects.
MInstruction *fieldTypes = MLoadFixedSlot::New(typeObj, SLOT_STRUCT_FIELD_TYPES);
current->add(fieldTypes);
// Index into list with index of field.
MInstruction *fieldTypesElements = MElements::New(fieldTypes);
current->add(fieldTypesElements);
MConstant *fieldIndexDef = MConstant::New(Int32Value(fieldIndex));
current->add(fieldIndexDef);
MInstruction *fieldType = MLoadElement::New(fieldTypesElements, fieldIndexDef, false, false);
current->add(fieldType);
return fieldType;
}

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

@ -15,6 +15,7 @@
#include "jit/BytecodeAnalysis.h"
#include "jit/MIR.h"
#include "jit/MIRGraph.h"
#include "jit/TypeRepresentationSet.h"
namespace js {
namespace jit {
@ -363,6 +364,17 @@ class IonBuilder : public MIRGenerator
bool barrier, types::TemporaryTypeSet *types);
bool getPropTryInlineAccess(bool *emitted, PropertyName *name, jsid id,
bool barrier, types::TemporaryTypeSet *types);
bool getPropTryTypedObject(bool *emitted, jsid id,
types::TemporaryTypeSet *resultTypes);
bool getPropTryScalarPropOfTypedObject(bool *emitted,
int32_t fieldOffset,
TypeRepresentationSet fieldTypeReprs,
types::TemporaryTypeSet *resultTypes);
bool getPropTryComplexPropOfTypedObject(bool *emitted,
int32_t fieldOffset,
TypeRepresentationSet fieldTypeReprs,
size_t fieldIndex,
types::TemporaryTypeSet *resultTypes);
bool getPropTryCache(bool *emitted, PropertyName *name, jsid id,
bool barrier, types::TemporaryTypeSet *types);
bool needsToMonitorMissingProperties(types::TemporaryTypeSet *types);
@ -381,10 +393,28 @@ class IonBuilder : public MIRGenerator
PropertyName *name, jsid id,
MDefinition *value, bool barrier,
types::TemporaryTypeSet *objTypes);
bool setPropTryTypedObject(bool *emitted, MDefinition *obj,
jsid id, MDefinition *value);
bool setPropTryCache(bool *emitted, MDefinition *obj,
PropertyName *name, MDefinition *value,
bool barrier, types::TemporaryTypeSet *objTypes);
// binary data lookup helpers.
bool lookupTypeRepresentationSet(MDefinition *typedObj,
TypeRepresentationSet *out);
bool lookupTypedObjectField(MDefinition *typedObj,
jsid id,
int32_t *fieldOffset,
TypeRepresentationSet *fieldTypeReprs,
size_t *fieldIndex);
MDefinition *loadTypedObjectType(MDefinition *value);
void loadTypedObjectData(MDefinition *inOwner,
int32_t inOffset,
MDefinition **outOwner,
MDefinition **outOffset);
MDefinition *typeObjectForFieldFromStructType(MDefinition *type,
size_t fieldIndex);
// jsop_setelem() helpers.
bool setElemTryTyped(bool *emitted, MDefinition *object,
MDefinition *index, MDefinition *value);
@ -641,12 +671,15 @@ class IonBuilder : public MIRGenerator
AbortReason abortReason() { return abortReason_; }
TypeRepresentationSetHash *getOrCreateReprSetHash(); // fallible
private:
bool init();
JSContext *cx;
BaselineFrame *baselineFrame_;
AbortReason abortReason_;
ScopedJSDeletePtr<TypeRepresentationSetHash> reprSetHash_;
// Basic analysis information about the script.
BytecodeAnalysis analysis_;

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

@ -501,6 +501,32 @@ public:
}
};
class LNewDerivedTypedObject : public LCallInstructionHelper<1, 3, 0>
{
public:
LIR_HEADER(NewDerivedTypedObject);
LNewDerivedTypedObject(const LAllocation &type,
const LAllocation &owner,
const LAllocation &offset) {
setOperand(0, type);
setOperand(1, owner);
setOperand(2, offset);
}
const LAllocation *type() {
return getOperand(0);
}
const LAllocation *owner() {
return getOperand(1);
}
const LAllocation *offset() {
return getOperand(2);
}
};
class LNewStringObject : public LInstructionHelper<1, 1, 1>
{
public:
@ -3042,6 +3068,20 @@ class LTypedArrayElements : public LInstructionHelper<1, 1, 0>
}
};
// Load a typed array's elements vector.
class LTypedObjectElements : public LInstructionHelper<1, 1, 0>
{
public:
LIR_HEADER(TypedObjectElements)
LTypedObjectElements(const LAllocation &object) {
setOperand(0, object);
}
const LAllocation *object() {
return getOperand(0);
}
};
// Bailout if index >= length.
class LBoundsCheck : public LInstructionHelper<0, 2, 0>
{

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

@ -32,6 +32,7 @@
_(NewPar) \
_(NewDenseArrayPar) \
_(NewCallObjectPar) \
_(NewDerivedTypedObject) \
_(AbortPar) \
_(InitElem) \
_(InitElemGetterSetter) \
@ -221,6 +222,7 @@
_(ArrayLength) \
_(TypedArrayLength) \
_(TypedArrayElements) \
_(TypedObjectElements) \
_(StringLength) \
_(ArgumentsLength) \
_(GetArgument) \

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

@ -207,6 +207,16 @@ LIRGenerator::visitNewCallObject(MNewCallObject *ins)
return true;
}
bool
LIRGenerator::visitNewDerivedTypedObject(MNewDerivedTypedObject *ins)
{
LNewDerivedTypedObject *lir =
new LNewDerivedTypedObject(useRegisterAtStart(ins->type()),
useRegisterAtStart(ins->owner()),
useRegisterAtStart(ins->offset()));
return defineReturn(lir, ins) && assignSafepoint(lir, ins);
}
bool
LIRGenerator::visitNewCallObjectPar(MNewCallObjectPar *ins)
{
@ -2068,6 +2078,13 @@ LIRGenerator::visitTypedArrayElements(MTypedArrayElements *ins)
return define(new LTypedArrayElements(useRegisterAtStart(ins->object())), ins);
}
bool
LIRGenerator::visitTypedObjectElements(MTypedObjectElements *ins)
{
JS_ASSERT(ins->type() == MIRType_Elements);
return define(new LTypedObjectElements(useRegisterAtStart(ins->object())), ins);
}
bool
LIRGenerator::visitInitializedLength(MInitializedLength *ins)
{

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

@ -89,6 +89,7 @@ class LIRGenerator : public LIRGeneratorSpecific
bool visitNewDeclEnvObject(MNewDeclEnvObject *ins);
bool visitNewCallObject(MNewCallObject *ins);
bool visitNewStringObject(MNewStringObject *ins);
bool visitNewDerivedTypedObject(MNewDerivedTypedObject *ins);
bool visitNewPar(MNewPar *ins);
bool visitNewCallObjectPar(MNewCallObjectPar *ins);
bool visitNewDenseArrayPar(MNewDenseArrayPar *ins);
@ -182,6 +183,7 @@ class LIRGenerator : public LIRGeneratorSpecific
bool visitArrayLength(MArrayLength *ins);
bool visitTypedArrayLength(MTypedArrayLength *ins);
bool visitTypedArrayElements(MTypedArrayElements *ins);
bool visitTypedObjectElements(MTypedObjectElements *ins);
bool visitInitializedLength(MInitializedLength *ins);
bool visitSetInitializedLength(MSetInitializedLength *ins);
bool visitNot(MNot *ins);

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

@ -539,6 +539,13 @@ MConstantElements::printOpcode(FILE *fp) const
fprintf(fp, " %p", value());
}
void
MLoadTypedArrayElement::printOpcode(FILE *fp) const
{
MDefinition::printOpcode(fp);
fprintf(fp, " %s", ScalarTypeRepresentation::typeName(arrayType()));
}
MParameter *
MParameter::New(int32_t index, types::TemporaryTypeSet *types)
{

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

@ -24,6 +24,7 @@
#include "jit/IonMacroAssembler.h"
#include "jit/MOpcodes.h"
#include "jit/TypePolicy.h"
#include "jit/TypeRepresentationSet.h"
#include "vm/ScopeObject.h"
namespace js {
@ -1487,6 +1488,66 @@ class MNewPar : public MUnaryInstruction
}
};
// Creates a new derived type object. At runtime, this is just a call
// to `BinaryBlock::createDerived()`. That is, the MIR itself does not
// compile to particularly optimized code. However, using a distinct
// MIR for creating derived type objects allows the compiler to
// optimize ephemeral typed objects as would be created for a
// reference like `a.b.c` -- here, the `a.b` will create an ephemeral
// derived type object that aliases the memory of `a` itself. The
// specific nature of `a.b` is revealed by using
// `MNewDerivedTypedObject` rather than `MGetProperty` or what have
// you. Moreover, the compiler knows that there are no side-effects,
// so `MNewDerivedTypedObject` instructions can be reordered or pruned
// as dead code.
class MNewDerivedTypedObject
: public MTernaryInstruction,
public Mix3Policy<ObjectPolicy<0>,
ObjectPolicy<1>,
IntPolicy<2> >
{
private:
TypeRepresentationSet set_;
public:
INSTRUCTION_HEADER(NewDerivedTypedObject);
MNewDerivedTypedObject(TypeRepresentationSet set,
MDefinition *type,
MDefinition *owner,
MDefinition *offset)
: MTernaryInstruction(type, owner, offset),
set_(set)
{
setMovable();
setResultType(MIRType_Object);
}
TypeRepresentationSet set() const {
return set_;
}
MDefinition *type() const {
return getOperand(0);
}
MDefinition *owner() const {
return getOperand(1);
}
MDefinition *offset() const {
return getOperand(2);
}
TypePolicy *typePolicy() {
return this;
}
virtual AliasSet getAliasSet() const {
return AliasSet::None();
}
};
// Abort parallel execution.
class MAbortPar : public MAryControlInstruction<0, 0>
{
@ -4882,6 +4943,42 @@ class MTypedArrayElements
}
};
// Load a binary data object's "elements", which is just its opaque
// binary data space. Eventually this should probably be
// unified with `MTypedArrayElements`.
class MTypedObjectElements
: public MUnaryInstruction,
public SingleObjectPolicy
{
private:
MTypedObjectElements(MDefinition *object)
: MUnaryInstruction(object)
{
setResultType(MIRType_Elements);
setMovable();
}
public:
INSTRUCTION_HEADER(TypedObjectElements)
static MTypedObjectElements *New(MDefinition *object) {
return new MTypedObjectElements(object);
}
TypePolicy *typePolicy() {
return this;
}
MDefinition *object() const {
return getOperand(0);
}
bool congruentTo(MDefinition *ins) const {
return congruentIfOperandsEqual(ins);
}
AliasSet getAliasSet() const {
return AliasSet::Load(AliasSet::ObjectFields);
}
};
// Perform !-operation
class MNot
: public MUnaryInstruction,
@ -5423,6 +5520,8 @@ class MLoadTypedArrayElement
return AliasSet::Load(AliasSet::TypedArrayElement);
}
void printOpcode(FILE *fp) const;
void computeRange();
bool canProduceFloat32() const { return arrayType_ == ScalarTypeRepresentation::TYPE_FLOAT32; }

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

@ -123,6 +123,7 @@ namespace jit {
_(ArrayLength) \
_(TypedArrayLength) \
_(TypedArrayElements) \
_(TypedObjectElements) \
_(InitializedLength) \
_(SetInitializedLength) \
_(Not) \
@ -197,6 +198,7 @@ namespace jit {
_(NewCallObjectPar) \
_(NewPar) \
_(NewDenseArrayPar) \
_(NewDerivedTypedObject) \
_(AbortPar) \
_(LambdaPar) \
_(RestPar) \

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

@ -175,6 +175,7 @@ class ParallelSafetyVisitor : public MInstructionVisitor
CUSTOM_OP(NewObject)
CUSTOM_OP(NewCallObject)
CUSTOM_OP(NewParallelArray)
UNSAFE_OP(NewDerivedTypedObject)
UNSAFE_OP(InitElem)
UNSAFE_OP(InitElemGetterSetter)
UNSAFE_OP(InitProp)
@ -207,6 +208,7 @@ class ParallelSafetyVisitor : public MInstructionVisitor
SAFE_OP(ArrayLength)
SAFE_OP(TypedArrayLength)
SAFE_OP(TypedArrayElements)
SAFE_OP(TypedObjectElements)
SAFE_OP(InitializedLength)
WRITE_GUARDED_OP(SetInitializedLength, elements)
SAFE_OP(Not)

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

@ -416,6 +416,7 @@ IntPolicy<Op>::staticAdjustInputs(MInstruction *def)
template bool IntPolicy<0>::staticAdjustInputs(MInstruction *def);
template bool IntPolicy<1>::staticAdjustInputs(MInstruction *def);
template bool IntPolicy<2>::staticAdjustInputs(MInstruction *def);
template <unsigned Op>
bool

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

@ -0,0 +1,278 @@
/* -*- 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/. */
#include "jit/TypeRepresentationSet.h"
#include "mozilla/HashFunctions.h"
#include "jit/IonBuilder.h"
#include "jsinferinlines.h"
using namespace js;
using namespace jit;
///////////////////////////////////////////////////////////////////////////
// TypeRepresentationSet hasher
HashNumber
TypeRepresentationSetHasher::hash(TypeRepresentationSet key)
{
HashNumber hn = mozilla::HashGeneric(key.length());
for (size_t i = 0; i < key.length(); i++)
hn = mozilla::AddToHash(hn, uintptr_t(key.get(i)));
return hn;
}
bool
TypeRepresentationSetHasher::match(TypeRepresentationSet key1,
TypeRepresentationSet key2)
{
if (key1.length() != key2.length())
return false;
// Note: entries are always sorted
for (size_t i = 0; i < key1.length(); i++) {
if (key1.get(i) != key2.get(i))
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////
// TypeRepresentationSetBuilder
TypeRepresentationSetBuilder::TypeRepresentationSetBuilder()
: invalid_(false)
{}
bool
TypeRepresentationSetBuilder::insert(TypeRepresentation *typeRepr)
{
if (invalid_)
return true;
if (entries_.length() == 0)
return entries_.append(typeRepr);
// Check that this new type repr is of the same basic kind as the
// ones we have seen thus far. If not, for example if we have an
// `int` and a `struct`, then convert this set to the invalid set.
TypeRepresentation *entry0 = entries_[0];
if (typeRepr->kind() != entry0->kind()) {
invalid_ = true;
entries_.clear();
return true;
}
// Otherwise, use binary search to find the right place to insert
// the type descriptor. We keep list sorted by the *address* of
// the type representations within.
uintptr_t typeReprAddr = (uintptr_t) typeRepr;
size_t min = 0;
size_t max = entries_.length();
while (min != max) {
size_t i = min + ((max - min) >> 1); // average w/o fear of overflow
uintptr_t entryiaddr = (uintptr_t) entries_[i];
if (entryiaddr == typeReprAddr)
return true; // typeRepr already present in the set
if (entryiaddr < typeReprAddr) {
// typeRepr lies to the right of entry i
min = i;
} else {
// typeRepr lies to the left of entry i
max = i;
}
}
// As a sanity check, give up if the TypeRepresentationSet grows too large.
if (entries_.length() >= 512) {
invalid_ = true;
entries_.clear();
return true;
}
// Not present. Insert at position `min`.
if (min == entries_.length())
return entries_.append(typeRepr);
TypeRepresentation **insertLoc = &entries_[min];
return entries_.insert(insertLoc, typeRepr) != NULL;
}
bool
TypeRepresentationSetBuilder::build(IonBuilder &builder,
TypeRepresentationSet *out)
{
if (invalid_) {
*out = TypeRepresentationSet();
return true;
}
TypeRepresentationSetHash *table = builder.getOrCreateReprSetHash();
if (!table)
return false;
// Check if there is already a copy in the hashtable.
size_t length = entries_.length();
TypeRepresentationSet tempSet(length, entries_.begin());
TypeRepresentationSetHash::AddPtr p = table->lookupForAdd(tempSet);
if (p) {
*out = *p;
return true;
}
// If not, allocate a permanent copy in Ion temp memory and add it.
size_t space = sizeof(TypeRepresentation*) * length;
TypeRepresentation **array = (TypeRepresentation**)
GetIonContext()->temp->allocate(space);
if (!array)
return false;
memcpy(array, entries_.begin(), space);
TypeRepresentationSet permSet(length, array);
if (!table->add(p, permSet))
return false;
*out = permSet;
return true;
}
///////////////////////////////////////////////////////////////////////////
// TypeRepresentationSet
TypeRepresentationSet::TypeRepresentationSet(const TypeRepresentationSet &c)
: length_(c.length_),
entries_(c.entries_)
{}
TypeRepresentationSet::TypeRepresentationSet(size_t length,
TypeRepresentation **entries)
: length_(length),
entries_(entries)
{}
TypeRepresentationSet::TypeRepresentationSet()
: length_(0),
entries_(NULL)
{}
bool
TypeRepresentationSet::empty()
{
return length() == 0;
}
size_t
TypeRepresentationSet::length()
{
return length_;
}
TypeRepresentation *
TypeRepresentationSet::get(size_t i)
{
JS_ASSERT(i < length());
return entries_[i];
}
bool
TypeRepresentationSet::allOfKind(TypeRepresentation::Kind aKind)
{
if (empty())
return false;
return kind() == aKind;
}
TypeRepresentation::Kind
TypeRepresentationSet::kind()
{
JS_ASSERT(!empty());
return get(0)->kind();
}
size_t
TypeRepresentationSet::arrayLength()
{
JS_ASSERT(kind() == TypeRepresentation::Array);
const size_t result = get(0)->asArray()->length();
for (size_t i = 1; i < length(); i++) {
if (get(i)->asArray()->length() != result)
return SIZE_MAX;
}
return result;
}
bool
TypeRepresentationSet::arrayElementType(IonBuilder &builder,
TypeRepresentationSet *out)
{
JS_ASSERT(kind() == TypeRepresentation::Array);
TypeRepresentationSetBuilder elementTypes;
for (size_t i = 0; i < length(); i++) {
if (!elementTypes.insert(get(i)->asArray()->element()))
return false;
}
return elementTypes.build(builder, out);
}
bool
TypeRepresentationSet::fieldNamed(IonBuilder &builder,
jsid id,
size_t *offset,
TypeRepresentationSet *out,
size_t *index)
{
JS_ASSERT(kind() == TypeRepresentation::Struct);
// Initialize `*offset` and `*out` for the case where incompatible
// or absent fields are found.
*offset = SIZE_MAX;
*index = SIZE_MAX;
*out = TypeRepresentationSet();
// Remember offset of the first field.
size_t offset0;
size_t index0;
TypeRepresentationSetBuilder fieldTypes;
{
const StructField *field = get(0)->asStruct()->fieldNamed(id);
if (!field)
return true;
offset0 = field->offset;
index0 = field->index;
if (!fieldTypes.insert(field->typeRepr))
return false;
}
// Check that all subsequent fields are at the same offset
// and compute the union of their types.
for (size_t i = 1; i < length(); i++) {
const StructField *field = get(i)->asStruct()->fieldNamed(id);
if (!field)
return true;
if (field->offset != offset0)
return true;
if (field->index != index0)
index0 = SIZE_MAX;
if (!fieldTypes.insert(field->typeRepr))
return false;
}
// All struct types had a field named `id` at the same offset
// (though it's still possible that the types are incompatible and
// that the indices disagree).
*offset = offset0;
*index = index0;
return fieldTypes.build(builder, out);
}

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

@ -0,0 +1,146 @@
/* -*- 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/. */
#ifndef jit_TypeRepresentationSet_h
#define jit_TypeRepresentationSet_h
#include "builtin/TypeRepresentation.h"
#include "jit/IonAllocPolicy.h"
#include "js/HashTable.h"
// TypeRepresentationSet stores a set of TypeRepresentation* objects,
// representing the possible types of the binary data associated with
// a typed object value. Often TypeRepresentationSets will be
// singleton sets, but it is also possible to have cases where many
// type representations flow into a single point. In such cases, the
// various type representations may differ in their details but often
// have a common prefix. We try to optimize this case as well.
//
// So, for example, consider some code like:
//
// var Point2Type = new StructType({x: uint8, y: uint8});
// var Point3Type = new StructType({x: uint8, y: uint8, z: uint8});
//
// function distance2d(pnt) {
// return Math.sqrt(pnt.x * pnt.x + pnt.y * pnt.y);
// }
//
// Even if the function `distance2d()` were used with instances of
// both Point2Type and Point3Type, we can still generate optimal code,
// because both of those types contain fields named `x` and `y` with
// the same types at the same offset.
namespace js {
namespace jit {
class IonBuilder;
class TypeRepresentationSet;
class TypeRepresentationSetBuilder {
private:
Vector<TypeRepresentation *, 4, SystemAllocPolicy> entries_;
bool invalid_;
bool overlaps(TypeRepresentation *a, TypeRepresentation *b);
public:
TypeRepresentationSetBuilder();
bool insert(TypeRepresentation *typeRepr);
bool build(IonBuilder &builder, TypeRepresentationSet *out);
};
class TypeRepresentationSet {
private:
friend class TypeRepresentationSetBuilder;
size_t length_;
TypeRepresentation **entries_; // Allocated using temp policy
TypeRepresentationSet(size_t length, TypeRepresentation **entries);
public:
//////////////////////////////////////////////////////////////////////
// Constructors
//
// For more flexible constructors, see
// TypeRepresentationSetBuilder above.
TypeRepresentationSet(const TypeRepresentationSet &c);
TypeRepresentationSet(); // empty set
//////////////////////////////////////////////////////////////////////
// Query the set
bool empty();
size_t length();
TypeRepresentation *get(size_t i);
bool allOfKind(TypeRepresentation::Kind kind);
//////////////////////////////////////////////////////////////////////
// The following operations are only valid on a non-empty set:
TypeRepresentation::Kind kind();
//////////////////////////////////////////////////////////////////////
// Array operations
//
// Only valid when `kind() == TypeRepresentation::Array`
// Returns the length of the arrays in this set, or SIZE_MAX
// if they are not all the same.
size_t arrayLength();
// Returns a `TypeRepresentationSet` representing the element
// types of the various array types in this set. The returned set
// may be the empty set.
bool arrayElementType(IonBuilder &builder, TypeRepresentationSet *out);
//////////////////////////////////////////////////////////////////////
// Struct operations
//
// Only valid when `kind() == TypeRepresentation::Struct`
// Searches the type in the set for a field named `id`. All
// possible types must agree on the offset of the field within the
// structure and the possible types of the field must be
// compatible. If any pair of types disagree on the offset or have
// incompatible types for the field, then `*out` will be set to
// the empty set.
//
// Upon success, `out` will be set to the set of possible types of
// the field and `offset` will be set to the field's offset within
// the struct (measured in bytes).
//
// The parameter `*index` is special. If all types agree on the
// index of the field, then `*index` is set to the field index.
// Otherwise, it is set to SIZE_MAX. Note that two types may agree
// on the type and offset of a field but disagree about its index,
// e.g. the field `c` in `new StructType({a: uint8, b: uint8, c:
// uint16})` and `new StructType({a: uint16, c: uint16})`.
bool fieldNamed(IonBuilder &builder,
jsid id,
size_t *offset,
TypeRepresentationSet *out,
size_t *index);
};
struct TypeRepresentationSetHasher
{
typedef TypeRepresentationSet Lookup;
static HashNumber hash(TypeRepresentationSet key);
static bool match(TypeRepresentationSet key1,
TypeRepresentationSet key2);
};
typedef js::HashSet<TypeRepresentationSet,
TypeRepresentationSetHasher,
IonAllocPolicy> TypeRepresentationSetHash;
} // namespace jit
} // namespace js
#endif

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

@ -7,6 +7,7 @@
#include "jit/VMFunctions.h"
#include "builtin/ParallelArray.h"
#include "builtin/TypedObject.h"
#include "frontend/BytecodeCompiler.h"
#include "jit/BaselineIC.h"
#include "jit/Ion.h"
@ -872,5 +873,12 @@ InitBaselineFrameForOsr(BaselineFrame *frame, StackFrame *interpFrame, uint32_t
return frame->initForOsr(interpFrame, numStackValues);
}
JSObject *CreateDerivedTypedObj(JSContext *cx, HandleObject type,
HandleObject owner, int32_t offset)
{
return BinaryBlock::createDerived(cx, type, owner, offset);
}
} // namespace jit
} // namespace js

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

@ -665,6 +665,9 @@ bool LeaveBlock(JSContext *cx, BaselineFrame *frame);
bool InitBaselineFrameForOsr(BaselineFrame *frame, StackFrame *interpFrame,
uint32_t numStackValues);
JSObject *CreateDerivedTypedObj(JSContext *cx, HandleObject type,
HandleObject owner, int32_t offset);
} // namespace jit
} // namespace js

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

@ -5463,7 +5463,25 @@ JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst, size_
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return InflateStringToBuffer(cx, src, srclen, dst, dstlenp);
if (!dst) {
*dstlenp = srclen;
return true;
}
size_t dstlen = *dstlenp;
if (srclen > dstlen) {
InflateStringToBuffer(src, dstlen, dst);
AutoSuppressGC suppress(cx);
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BUFFER_TOO_SMALL);
return false;
}
InflateStringToBuffer(src, srclen, dst);
*dstlenp = srclen;
return true;
}
JS_PUBLIC_API(char *)

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

@ -388,13 +388,8 @@ js::AtomizeMaybeGC(ExclusiveContext *cx, const char *bytes, size_t length, Inter
* js::AtomizeString rarely has to copy the temp string we make.
*/
jschar inflated[ATOMIZE_BUF_MAX];
size_t inflatedLength = ATOMIZE_BUF_MAX - 1;
if (!InflateStringToBuffer(cx->maybeJSContext(),
bytes, length, inflated, &inflatedLength))
{
return NULL;
}
return AtomizeAndCopyChars<allowGC>(cx, inflated, inflatedLength, ib);
InflateStringToBuffer(bytes, length, inflated);
return AtomizeAndCopyChars<allowGC>(cx, inflated, length, ib);
}
jschar *tbcharsZ = InflateString(cx, bytes, &length);

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

@ -204,7 +204,7 @@ struct JSCompartment
js::RegExpCompartment regExps;
/* Set of all currently living type representations. */
js::TypeRepresentationSet typeReprs;
js::TypeRepresentationHash typeReprs;
private:
void sizeOfTypeInferenceData(JS::TypeInferenceSizes *stats, mozilla::MallocSizeOf mallocSizeOf);

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

@ -46,7 +46,7 @@ PerThreadDataFriendFields::PerThreadDataFriendFields()
}
JS_FRIEND_API(void)
JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook)
js::SetSourceHook(JSRuntime *rt, SourceHook *hook)
{
rt->sourceHook = hook;
}

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

@ -203,14 +203,34 @@ struct JSFunctionSpecWithHelp {
extern JS_FRIEND_API(bool)
JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj, const JSFunctionSpecWithHelp *fs);
typedef bool (* JS_SourceHook)(JSContext *cx, const char *filename,
jschar **src, uint32_t *length);
extern JS_FRIEND_API(void)
JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook);
namespace js {
/*
* A class of objects that return source code on demand.
*
* When code is compiled with CompileOptions::LAZY_SOURCE, SpiderMonkey
* doesn't retain the source code (and doesn't do lazy bytecode
* generation). If we ever need the source code, say, in response to a call
* to Function.prototype.toSource or Debugger.Source.prototype.text, then
* we call the 'load' member function of the instance of this class that
* has hopefully been registered with the runtime, passing the code's URL,
* and hope that it will be able to find the source.
*/
class SourceHook {
public:
virtual ~SourceHook() { }
/* Set |*src| and |*length| to refer to the source code for |filename|. */
virtual bool load(JSContext *cx, const char *filename, jschar **src, size_t *length) = 0;
};
/*
* Have |rt| use |hook| to retrieve LAZY_SOURCE source code.
* See the comments for SourceHook.
*/
extern JS_FRIEND_API(void)
SetSourceHook(JSRuntime *rt, SourceHook *hook);
inline JSRuntime *
GetRuntime(const JSContext *cx)
{

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

@ -650,11 +650,12 @@ js::Int32ToAtom<NoGC>(ExclusiveContext *cx, int32_t si);
/* Returns a non-NULL pointer to inside cbuf. */
static char *
IntToCString(ToCStringBuf *cbuf, int i, int base = 10)
IntToCString(ToCStringBuf *cbuf, int i, size_t *len, int base = 10)
{
unsigned u = (i < 0) ? -i : i;
RangedPtr<char> cp(cbuf->sbuf + cbuf->sbufSize - 1, cbuf->sbuf, cbuf->sbufSize);
RangedPtr<char> cp(cbuf->sbuf + ToCStringBuf::sbufSize - 1, cbuf->sbuf, ToCStringBuf::sbufSize);
char *end = cp.get();
*cp = '\0';
/* Build the string from behind. */
@ -681,6 +682,7 @@ IntToCString(ToCStringBuf *cbuf, int i, int base = 10)
if (i < 0)
*--cp = '-';
*len = end - cp.get();
return cp.get();
}
@ -1309,8 +1311,9 @@ char *
js::NumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base/* = 10*/)
{
int32_t i;
size_t len;
return mozilla::DoubleIsInt32(d, &i)
? IntToCString(cbuf, i, base)
? IntToCString(cbuf, i, &len, base)
: FracNumberToCString(cx, cbuf, d, base);
}
@ -1350,7 +1353,8 @@ js_NumberToStringWithBase(ThreadSafeContext *cx, double d, int base)
return str;
}
numStr = IntToCString(&cbuf, i, base);
size_t len;
numStr = IntToCString(&cbuf, i, &len, base);
JS_ASSERT(!cbuf.dbuf && numStr >= cbuf.sbuf && numStr < cbuf.sbuf + cbuf.sbufSize);
} else {
if (comp) {
@ -1466,21 +1470,23 @@ js::NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb)
/* Convert to C-string. */
ToCStringBuf cbuf;
const char *cstr;
size_t cstrlen;
if (v.isInt32()) {
cstr = IntToCString(&cbuf, v.toInt32());
cstr = IntToCString(&cbuf, v.toInt32(), &cstrlen);
JS_ASSERT(cstrlen == strlen(cstr));
} else {
cstr = NumberToCString(cx, &cbuf, v.toDouble());
if (!cstr) {
JS_ReportOutOfMemory(cx);
return false;
}
cstrlen = strlen(cstr);
}
/*
* Inflate to jschar string. The input C-string characters are < 127, so
* even if jschars are UTF-8, all chars should map to one jschar.
*/
size_t cstrlen = strlen(cstr);
JS_ASSERT(!cbuf.dbuf && cstrlen < cbuf.sbufSize);
return sb.appendInflated(cstr, cstrlen);
}

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

@ -998,8 +998,8 @@ JSScript::loadSource(JSContext *cx, ScriptSource *ss, bool *worked)
if (!cx->runtime()->sourceHook || !ss->sourceRetrievable())
return true;
jschar *src = NULL;
uint32_t length;
if (!cx->runtime()->sourceHook(cx, ss->filename(), &src, &length))
size_t length;
if (!cx->runtime()->sourceHook->load(cx, ss->filename(), &src, &length))
return false;
if (!src)
return true;
@ -1124,7 +1124,7 @@ ScriptSource::setSourceCopy(ExclusiveContext *cx, const jschar *src, uint32_t le
}
void
ScriptSource::setSource(const jschar *src, uint32_t length)
ScriptSource::setSource(const jschar *src, size_t length)
{
JS_ASSERT(!hasSourceData());
length_ = length;

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

@ -341,7 +341,7 @@ class ScriptSource
uint32_t length,
bool argumentsNotIncluded,
SourceCompressionTask *tok);
void setSource(const jschar *src, uint32_t length);
void setSource(const jschar *src, size_t length);
bool ready() const { return ready_; }
void setSourceRetrievable() { sourceRetrievable_ = true; }
bool sourceRetrievable() const { return sourceRetrievable_; }

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

@ -4164,29 +4164,6 @@ js::DeflateStringToBuffer(JSContext *maybecx, const jschar *src, size_t srclen,
return true;
}
bool
js::InflateStringToBuffer(JSContext *maybecx, const char *src, size_t srclen,
jschar *dst, size_t *dstlenp)
{
if (dst) {
size_t dstlen = *dstlenp;
if (srclen > dstlen) {
for (size_t i = 0; i < dstlen; i++)
dst[i] = (unsigned char) src[i];
if (maybecx) {
AutoSuppressGC suppress(maybecx);
JS_ReportErrorNumber(maybecx, js_GetErrorMessage, NULL,
JSMSG_BUFFER_TOO_SMALL);
}
return false;
}
for (size_t i = 0; i < srclen; i++)
dst[i] = (unsigned char) src[i];
}
*dstlenp = srclen;
return true;
}
#define ____ false
/*

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

@ -249,15 +249,15 @@ extern jschar *
InflateString(ThreadSafeContext *cx, const char *bytes, size_t *length);
/*
* Inflate bytes to JS chars in an existing buffer. 'chars' must be large
* enough for 'length' jschars. The buffer is NOT null-terminated.
*
* charsLength must be be initialized with the destination buffer size and, on
* return, will contain on return the number of copied chars.
* Inflate bytes to JS chars in an existing buffer. 'dst' must be large
* enough for 'srclen' jschars. The buffer is NOT null-terminated.
*/
extern bool
InflateStringToBuffer(JSContext *maybecx, const char *bytes, size_t length,
jschar *chars, size_t *charsLength);
inline void
InflateStringToBuffer(const char *src, size_t srclen, jschar *dst)
{
for (size_t i = 0; i < srclen; i++)
dst[i] = (unsigned char) src[i];
}
/*
* Deflate JS chars to bytes into a buffer. 'bytes' must be large enough for

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

@ -248,6 +248,7 @@ if CONFIG['ENABLE_ION']:
'Snapshots.cpp',
'StupidAllocator.cpp',
'TypePolicy.cpp',
'TypeRepresentationSet.cpp',
'UnreachableCodeElimination.cpp',
'VMFunctions.cpp',
'ValueNumbering.cpp',

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

@ -234,7 +234,6 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
negativeInfinityValue(DoubleValue(NegativeInfinity())),
positiveInfinityValue(DoubleValue(PositiveInfinity())),
emptyString(NULL),
sourceHook(NULL),
debugMode(false),
spsProfiler(thisFromCtor()),
profilingScripts(false),
@ -399,6 +398,9 @@ JSRuntime::~JSRuntime()
{
JS_ASSERT(!isHeapBusy());
/* Free source hook early, as its destructor may want to delete roots. */
sourceHook = NULL;
/* Off thread compilation and parsing depend on atoms still existing. */
for (CompartmentsIter comp(this); !comp.done(); comp.next())
CancelOffThreadIonCompile(comp, NULL);

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

@ -11,6 +11,7 @@
#include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/PodOperations.h"
#include "mozilla/Scoped.h"
#include "mozilla/ThreadLocal.h"
#include <setjmp.h>
@ -1275,7 +1276,7 @@ struct JSRuntime : public JS::shadow::Runtime,
return !contextList.isEmpty();
}
JS_SourceHook sourceHook;
mozilla::ScopedDeletePtr<js::SourceHook> sourceHook;
/* Per runtime debug hooks -- see js/OldDebugAPI.h. */
JSDebugHooks debugHooks;

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

@ -122,10 +122,7 @@ StringBuffer::appendInflated(const char *cstr, size_t cstrlen)
size_t lengthBefore = length();
if (!cb.growByUninitialized(cstrlen))
return false;
mozilla::DebugOnly<size_t> oldcstrlen = cstrlen;
mozilla::DebugOnly<bool> ok = InflateStringToBuffer(NULL, cstr, cstrlen,
begin() + lengthBefore, &cstrlen);
JS_ASSERT(ok && oldcstrlen == cstrlen);
InflateStringToBuffer(cstr, cstrlen, begin() + lengthBefore);
return true;
}

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

@ -2774,100 +2774,103 @@ PreserveWrapper(JSContext *cx, JSObject *obj)
}
static nsresult
ReadSourceFromFilename(JSContext *cx, const char *filename, jschar **src, uint32_t *len)
ReadSourceFromFilename(JSContext *cx, const char *filename, jschar **src, size_t *len)
{
nsresult rv;
nsresult rv;
// mozJSSubScriptLoader prefixes the filenames of the scripts it loads with
// the filename of its caller. Axe that if present.
const char *arrow;
while ((arrow = strstr(filename, " -> ")))
filename = arrow + strlen(" -> ");
// mozJSSubScriptLoader prefixes the filenames of the scripts it loads with
// the filename of its caller. Axe that if present.
const char *arrow;
while ((arrow = strstr(filename, " -> ")))
filename = arrow + strlen(" -> ");
// Get the URI.
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), filename);
NS_ENSURE_SUCCESS(rv, rv);
// Get the URI.
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), filename);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> scriptChannel;
rv = NS_NewChannel(getter_AddRefs(scriptChannel), uri);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> scriptChannel;
rv = NS_NewChannel(getter_AddRefs(scriptChannel), uri);
NS_ENSURE_SUCCESS(rv, rv);
// Only allow local reading.
nsCOMPtr<nsIURI> actualUri;
rv = scriptChannel->GetURI(getter_AddRefs(actualUri));
NS_ENSURE_SUCCESS(rv, rv);
nsCString scheme;
rv = actualUri->GetScheme(scheme);
NS_ENSURE_SUCCESS(rv, rv);
if (!scheme.EqualsLiteral("file") && !scheme.EqualsLiteral("jar"))
return NS_OK;
nsCOMPtr<nsIInputStream> scriptStream;
rv = scriptChannel->Open(getter_AddRefs(scriptStream));
NS_ENSURE_SUCCESS(rv, rv);
uint64_t rawLen;
rv = scriptStream->Available(&rawLen);
NS_ENSURE_SUCCESS(rv, rv);
if (!rawLen)
return NS_ERROR_FAILURE;
// Technically, this should be SIZE_MAX, but we don't run on machines
// where that would be less than UINT32_MAX, and the latter is already
// well beyond a reasonable limit.
if (rawLen > UINT32_MAX)
return NS_ERROR_FILE_TOO_BIG;
// Allocate an internal buf the size of the file.
nsAutoArrayPtr<unsigned char> buf(new unsigned char[rawLen]);
if (!buf)
return NS_ERROR_OUT_OF_MEMORY;
unsigned char *ptr = buf, *end = ptr + rawLen;
while (ptr < end) {
uint32_t bytesRead;
rv = scriptStream->Read(reinterpret_cast<char *>(ptr), end - ptr, &bytesRead);
if (NS_FAILED(rv))
return rv;
MOZ_ASSERT(bytesRead > 0, "stream promised more bytes before EOF");
ptr += bytesRead;
}
nsString decoded;
rv = nsScriptLoader::ConvertToUTF16(scriptChannel, buf, rawLen, EmptyString(), NULL, decoded);
NS_ENSURE_SUCCESS(rv, rv);
// Copy to JS engine.
*len = decoded.Length();
*src = static_cast<jschar *>(JS_malloc(cx, decoded.Length()*sizeof(jschar)));
if (!*src)
return NS_ERROR_FAILURE;
memcpy(*src, decoded.get(), decoded.Length()*sizeof(jschar));
// Only allow local reading.
nsCOMPtr<nsIURI> actualUri;
rv = scriptChannel->GetURI(getter_AddRefs(actualUri));
NS_ENSURE_SUCCESS(rv, rv);
nsCString scheme;
rv = actualUri->GetScheme(scheme);
NS_ENSURE_SUCCESS(rv, rv);
if (!scheme.EqualsLiteral("file") && !scheme.EqualsLiteral("jar"))
return NS_OK;
nsCOMPtr<nsIInputStream> scriptStream;
rv = scriptChannel->Open(getter_AddRefs(scriptStream));
NS_ENSURE_SUCCESS(rv, rv);
uint64_t rawLen;
rv = scriptStream->Available(&rawLen);
NS_ENSURE_SUCCESS(rv, rv);
if (!rawLen)
return NS_ERROR_FAILURE;
if (rawLen > UINT32_MAX)
return NS_ERROR_FILE_TOO_BIG;
// Allocate an internal buf the size of the file.
nsAutoArrayPtr<unsigned char> buf(new unsigned char[rawLen]);
if (!buf)
return NS_ERROR_OUT_OF_MEMORY;
unsigned char *ptr = buf, *end = ptr + rawLen;
while (ptr < end) {
uint32_t bytesRead;
rv = scriptStream->Read(reinterpret_cast<char *>(ptr), end - ptr, &bytesRead);
if (NS_FAILED(rv))
return rv;
MOZ_ASSERT(bytesRead > 0, "stream promised more bytes before EOF");
ptr += bytesRead;
}
nsString decoded;
rv = nsScriptLoader::ConvertToUTF16(scriptChannel, buf, rawLen, EmptyString(), NULL, decoded);
NS_ENSURE_SUCCESS(rv, rv);
// Copy to JS engine.
*len = decoded.Length();
*src = static_cast<jschar *>(JS_malloc(cx, decoded.Length()*sizeof(jschar)));
if (!*src)
return NS_ERROR_FAILURE;
memcpy(*src, decoded.get(), decoded.Length()*sizeof(jschar));
return NS_OK;
}
/*
The JS engine calls this function when it needs the source for a chrome JS
function. See the comment in the XPCJSRuntime constructor.
*/
static bool
SourceHook(JSContext *cx, const char *filename, jschar **src, uint32_t *length)
{
*src = NULL;
*length = 0;
// The JS engine calls this object's 'load' member function when it needs
// the source for a chrome JS function. See the comment in the XPCJSRuntime
// constructor.
class XPCJSSourceHook: public js::SourceHook {
bool load(JSContext *cx, const char *filename, jschar **src, size_t *length) {
*src = NULL;
*length = 0;
if (!nsContentUtils::IsCallerChrome())
return true;
if (!nsContentUtils::IsCallerChrome())
return true;
if (!filename)
return true;
if (!filename)
return true;
nsresult rv = ReadSourceFromFilename(cx, filename, src, length);
if (NS_FAILED(rv)) {
xpc::Throw(cx, rv);
return false;
}
nsresult rv = ReadSourceFromFilename(cx, filename, src, length);
if (NS_FAILED(rv)) {
xpc::Throw(cx, rv);
return false;
}
return true;
}
return true;
}
};
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
: CycleCollectedJSRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS),
@ -3036,7 +3039,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
// compileAndGo mode and compiled function bodies (from
// JS_CompileFunction*). In practice, this means content scripts and event
// handlers.
JS_SetSourceHook(runtime, SourceHook);
js::SetSourceHook(runtime, new XPCJSSourceHook);
// Set up locale information and callbacks for the newly-created runtime so
// that the various toLocaleString() methods, localeCompare(), and other

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

@ -5494,7 +5494,24 @@ nsLayoutUtils::UpdateImageVisibilityForFrame(nsIFrame* aImageFrame)
visible = false;
break;
}
rect = sf->GetScrollPortRect();
// Move transformedRect to be contained in the scrollport as best we can
// (it might not fit) to pretend that it was scrolled into view.
nsRect scrollPort = sf->GetScrollPortRect();
if (transformedRect.XMost() > scrollPort.XMost()) {
transformedRect.x -= transformedRect.XMost() - scrollPort.XMost();
}
if (transformedRect.x < scrollPort.x) {
transformedRect.x = scrollPort.x;
}
if (transformedRect.YMost() > scrollPort.YMost()) {
transformedRect.y -= transformedRect.YMost() - scrollPort.YMost();
}
if (transformedRect.y < scrollPort.y) {
transformedRect.y = scrollPort.y;
}
transformedRect.width = std::min(transformedRect.width, scrollPort.width);
transformedRect.height = std::min(transformedRect.height, scrollPort.height);
rect = transformedRect;
rectFrame = f;
}
nsIFrame* parent = f->GetParent();

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

@ -7,7 +7,6 @@
#define ArrayBufferInputStream_h
#include "nsIArrayBufferInputStream.h"
#include "mozilla/Util.h"
#include "js/Value.h"
#define NS_ARRAYBUFFERINPUTSTREAM_CONTRACTID "@mozilla.org/io/arraybuffer-input-stream;1"

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

@ -4,7 +4,6 @@
* 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/. */
#include "mozilla/RefPtr.h"
#include "pk11pub.h"
#include "ScopedNSSTypes.h"
#include "secoidt.h"
@ -13,7 +12,6 @@
#include "nsIPipe.h"
#include "nsNetUtil.h"
#include "nsThreadUtils.h"
#include "nsXPCOMStrings.h"
#include "BackgroundFileSaver.h"
#include "mozilla/Telemetry.h"

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

@ -7,9 +7,13 @@
#include "mozilla/net/HttpInfo.h"
#include "nsCxPusher.h"
#include "nsHttp.h"
#include "nsICancelable.h"
#include "nsIDNSService.h"
#include "nsIDNSRecord.h"
#include "nsIInputStream.h"
#include "nsISocketTransport.h"
#include "nsIThread.h"
#include "nsSocketTransport2.h"
#include "nsSocketTransportService2.h"
#include "nsThreadUtils.h"
using mozilla::AutoSafeJSContext;

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

@ -6,9 +6,13 @@
#include "EventTokenBucket.h"
#include "nsICancelable.h"
#include "nsNetUtil.h"
#include "nsSocketTransportService2.h"
#include "nsThreadUtils.h"
#ifdef DEBUG
#include "MainThreadUtils.h"
#endif
#ifdef XP_WIN
#include <windows.h>

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

@ -9,11 +9,12 @@
#include "nsCOMPtr.h"
#include "nsDeque.h"
#include "nsICancelable.h"
#include "nsITimer.h"
#include "mozilla/TimeStamp.h"
class nsICancelable;
namespace mozilla {
namespace net {

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

@ -9,7 +9,6 @@
#include "nsIDNSListener.h"
#include "nsIDNSRecord.h"
#include "nsIDNSService.h"
#include "nsNetUtil.h"
#include "nsThreadUtils.h"
#include "nsIConsoleService.h"
#include "nsJSUtils.h"
@ -17,6 +16,8 @@
#include "prnetdb.h"
#include "nsITimer.h"
#include "mozilla/net/DNS.h"
#include "nsServiceManagerUtils.h"
#include "nsNetCID.h"
namespace mozilla {
namespace net {
@ -326,6 +327,14 @@ bool PACResolve(const nsCString &aHostName, NetAddr *aNetAddr,
return sRunning->ResolveAddress(aHostName, aNetAddr, aTimeout);
}
ProxyAutoConfig::ProxyAutoConfig()
: mJSRuntime(nullptr)
, mJSNeedsSetup(false)
, mShutdown(false)
{
MOZ_COUNT_CTOR(ProxyAutoConfig);
}
bool
ProxyAutoConfig::ResolveAddress(const nsCString &aHostName,
NetAddr *aNetAddr,

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

@ -8,15 +8,17 @@
#define ProxyAutoConfig_h__
#include "nsString.h"
#include "prio.h"
#include "nsITimer.h"
#include "nsAutoPtr.h"
#include "mozilla/net/DNS.h"
#include "js/TypeDecls.h"
#include "nsCOMPtr.h"
class nsITimer;
namespace JS {
class Value;
}
namespace mozilla { namespace net {
class JSRuntimeWrapper;
union NetAddr;
// The ProxyAutoConfig class is meant to be created and run on a
// non main thread. It synchronously resolves PAC files by blocking that
@ -24,13 +26,7 @@ class JSRuntimeWrapper;
class ProxyAutoConfig {
public:
ProxyAutoConfig()
: mJSRuntime(nullptr)
, mJSNeedsSetup(false)
, mShutdown(false)
{
MOZ_COUNT_CTOR(ProxyAutoConfig);
}
ProxyAutoConfig();
~ProxyAutoConfig();
nsresult Init(const nsCString &aPACURI,

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

@ -3,15 +3,15 @@
* 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/. */
#include "Tickler.h"
#ifdef MOZ_USE_WIFI_TICKLER
#include "nsComponentManagerUtils.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsServiceManagerUtils.h"
#include "prnetdb.h"
#include "Tickler.h"
#include "nsThreadUtils.h"
#ifdef MOZ_USE_WIFI_TICKLER
#include "prnetdb.h"
#include "AndroidBridge.h"

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

@ -27,6 +27,15 @@
// The tickler only applies to wifi on mobile right now. Hopefully it
// can also be restricted to particular handset models in the future.
#if defined(ANDROID) && !defined(MOZ_B2G)
#define MOZ_USE_WIFI_TICKLER
#endif
#include "mozilla/Attributes.h"
#include "nsISupports.h"
#include <stdint.h>
#ifdef MOZ_USE_WIFI_TICKLER
#include "mozilla/Mutex.h"
#include "mozilla/TimeStamp.h"
#include "nsAutoPtr.h"
@ -34,16 +43,14 @@
#include "nsIThread.h"
#include "nsITimer.h"
#include "nsWeakReference.h"
#include "prio.h"
class nsIPrefBranch;
#endif
namespace mozilla {
namespace net {
#if defined(ANDROID) && !defined(MOZ_B2G)
#define MOZ_USE_WIFI_TICKLER
#endif
#ifdef MOZ_USE_WIFI_TICKLER
class Tickler MOZ_FINAL : public nsSupportsWeakReference

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

@ -2,11 +2,10 @@
* 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/. */
#include "nsIOService.h"
#include "nsAsyncStreamCopier.h"
#include "nsIOService.h"
#include "nsIEventTarget.h"
#include "nsStreamUtils.h"
#include "nsNetSegmentUtils.h"
#include "nsNetUtil.h"
#include "prlog.h"

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

@ -6,13 +6,12 @@
#define nsAsyncStreamCopier_h__
#include "nsIAsyncStreamCopier.h"
#include "nsIAsyncInputStream.h"
#include "nsIAsyncOutputStream.h"
#include "nsIRequestObserver.h"
#include "mozilla/Mutex.h"
#include "nsStreamUtils.h"
#include "nsCOMPtr.h"
class nsIRequestObserver;
//-----------------------------------------------------------------------------
class nsAsyncStreamCopier : public nsIAsyncStreamCopier

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

@ -4,11 +4,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsBaseChannel.h"
#include "nsChannelProperties.h"
#include "nsURLHelper.h"
#include "nsNetUtil.h"
#include "nsMimeTypes.h"
#include "nsIOService.h"
#include "nsIHttpEventSink.h"
#include "nsIHttpChannel.h"
#include "nsIChannelEventSink.h"

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

@ -13,7 +13,6 @@
#include "nsInputStreamPump.h"
#include "nsIChannel.h"
#include "nsIInputStream.h"
#include "nsIURI.h"
#include "nsILoadGroup.h"
#include "nsIStreamListener.h"
@ -25,6 +24,8 @@
#include "nsThreadUtils.h"
#include "nsNetUtil.h"
class nsIInputStream;
//-----------------------------------------------------------------------------
// nsBaseChannel is designed to be subclassed. The subclass is responsible for
// implementing the OpenContentStream method, which will be called by the

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

@ -5,10 +5,8 @@
#include "ipc/IPCMessageUtils.h"
#include "nsAlgorithm.h"
#include "nsBufferedStreams.h"
#include "nsStreamUtils.h"
#include "nsCRT.h"
#include "nsNetCID.h"
#include "nsIClassInfoImpl.h"
#include "mozilla/ipc/InputStreamUtils.h"

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

@ -6,7 +6,6 @@
#define nsChannelClassifier_h__
#include "nsIURIClassifier.h"
#include "nsIRunnable.h"
#include "nsCOMPtr.h"
#include "mozilla/Attributes.h"

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

@ -7,12 +7,10 @@
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsNetUtil.h"
#include "nsIDNSListener.h"
#include "nsIDNSRecord.h"
#include "nsIDNSService.h"
#include "nsICancelable.h"
#include "nsIURI.h"
static nsIDNSService *sDNSService = nullptr;

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

@ -6,7 +6,6 @@
#ifndef nsDNSPrefetch_h___
#define nsDNSPrefetch_h___
#include "nsCOMPtr.h"
#include "nsString.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Attributes.h"

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

@ -16,23 +16,20 @@
#include "nsEscape.h"
#include "nsDirectoryIndexStream.h"
#include "nsXPIDLString.h"
#include "prio.h"
#include "prlog.h"
#ifdef PR_LOGGING
static PRLogModuleInfo* gLog;
#endif
#include "nsISimpleEnumerator.h"
#ifdef THREADSAFE_I18N
#include "nsCollationCID.h"
#include "nsICollation.h"
#include "nsILocale.h"
#include "nsILocaleService.h"
#include "nsCollationCID.h"
#include "nsIPlatformCharset.h"
#include "nsReadableUtils.h"
#endif
#include "nsIFile.h"
#include "nsURLHelper.h"
#include "nsNetUtil.h"
#include "nsCRT.h"
#include "nsNativeCharsetUtils.h"
// NOTE: This runs on the _file transport_ thread.

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

@ -8,12 +8,11 @@
#include "mozilla/Attributes.h"
#include "nsIFile.h"
#include "nsString.h"
#include "nsIInputStream.h"
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsITextToSubURI.h"
class nsIFile;
class nsDirectoryIndexStream MOZ_FINAL : public nsIInputStream
{

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

@ -6,10 +6,11 @@
#define nsDownloader_h__
#include "nsIDownloader.h"
#include "nsIOutputStream.h"
#include "nsIFile.h"
#include "nsCOMPtr.h"
class nsIFile;
class nsIOutputStream;
class nsDownloader : public nsIDownloader
{
public:

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

@ -19,16 +19,11 @@
#include "private/pprio.h"
#include "nsFileStreams.h"
#include "nsXPIDLString.h"
#include "prerror.h"
#include "nsCRT.h"
#include "nsIFile.h"
#include "nsDirectoryIndexStream.h"
#include "nsMimeTypes.h"
#include "nsReadLine.h"
#include "nsNetUtil.h"
#include "nsIClassInfoImpl.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "nsNetCID.h"
#define NS_NO_INPUT_BUFFERING 1 // see http://bugzilla.mozilla.org/show_bug.cgi?id=41067

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

@ -6,7 +6,6 @@
#ifndef nsFileStreams_h__
#define nsFileStreams_h__
#include "nsAlgorithm.h"
#include "nsAutoPtr.h"
#include "nsIFileStreams.h"
#include "nsIFile.h"
@ -16,8 +15,6 @@
#include "nsISeekableStream.h"
#include "nsILineInputStream.h"
#include "nsCOMPtr.h"
#include "prlog.h"
#include "prio.h"
#include "nsIIPCSerializableInputStream.h"
#include "nsReadLine.h"
#include <algorithm>

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

@ -10,40 +10,33 @@
#include "nsIProtocolHandler.h"
#include "nsIFileProtocolHandler.h"
#include "nscore.h"
#include "nsIServiceManager.h"
#include "nsIURI.h"
#include "nsIStreamListener.h"
#include "prprf.h"
#include "prlog.h"
#include "nsLoadGroup.h"
#include "nsInputStreamChannel.h"
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "nsIErrorService.h"
#include "nsIErrorService.h"
#include "netCore.h"
#include "nsIObserverService.h"
#include "nsIPrefService.h"
#include "nsIPrefLocalizedString.h"
#include "nsICategoryManager.h"
#include "nsXPCOM.h"
#include "nsISupportsPrimitives.h"
#include "nsIProxiedProtocolHandler.h"
#include "nsIProxyInfo.h"
#include "nsEscape.h"
#include "nsNetCID.h"
#include "nsISocketTransport.h"
#include "nsCRT.h"
#include "nsSimpleNestedURI.h"
#include "nsNetUtil.h"
#include "nsThreadUtils.h"
#include "nsIPermissionManager.h"
#include "nsTArray.h"
#include "nsIConsoleService.h"
#include "nsIUploadChannel2.h"
#include "nsXULAppAPI.h"
#include "nsIProxiedChannel.h"
#include "nsIProtocolProxyCallback.h"
#include "nsICancelable.h"
#include "nsINetworkLinkService.h"
#include "nsPISocketTransportService.h"
#include "nsAsyncRedirectVerifyHelper.h"
#include "nsURLHelper.h"
#include "nsPIDNSService.h"
#include "nsIProtocolProxyService2.h"
#include "MainThreadUtils.h"
#if defined(XP_WIN)
#include "nsNativeConnectionHelper.h"

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

@ -6,26 +6,16 @@
#ifndef nsIOService_h__
#define nsIOService_h__
#include "necko-config.h"
#include "nsString.h"
#include "nsStringFwd.h"
#include "nsIIOService2.h"
#include "nsTArray.h"
#include "nsPISocketTransportService.h"
#include "nsPIDNSService.h"
#include "nsIProtocolProxyService2.h"
#include "nsCOMPtr.h"
#include "nsURLHelper.h"
#include "nsWeakPtr.h"
#include "nsIURLParser.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsINetUtil.h"
#include "nsIChannelEventSink.h"
#include "nsIContentSniffer.h"
#include "nsCategoryCache.h"
#include "nsINetworkLinkService.h"
#include "nsAsyncRedirectVerifyHelper.h"
#include "nsISpeculativeConnect.h"
#include "mozilla/Attributes.h"
@ -39,7 +29,13 @@
static const char gScheme[][sizeof("resource")] =
{"chrome", "file", "http", "jar", "resource"};
class nsAsyncRedirectVerifyHelper;
class nsINetworkLinkService;
class nsIPrefBranch;
class nsIProtocolProxyService2;
class nsIProxyInfo;
class nsPIDNSService;
class nsPISocketTransportService;
class nsIOService MOZ_FINAL : public nsIIOService2
, public nsIObserver

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

@ -14,14 +14,11 @@
#include "nsIInterfaceRequestor.h"
#include "nsIObserverService.h"
#include "nsIObserver.h"
#include "nsIPropertyBag2.h"
#include "nsIServiceManager.h"
#include "nsIFile.h"
#include "nsITimer.h"
#include "nsNetUtil.h"
#include "nsAutoPtr.h"
#include "nsWeakReference.h"
#include "nsChannelProperties.h"
#include "prio.h"
#include "prprf.h"
#include <algorithm>

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

@ -4,22 +4,19 @@
* 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/. */
#include "mozilla/DebugOnly.h"
#include "nsIOService.h"
#include "nsInputStreamPump.h"
#include "nsIServiceManager.h"
#include "nsIStreamTransportService.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsISeekableStream.h"
#include "nsITransport.h"
#include "nsIThreadRetargetableStreamListener.h"
#include "nsStreamUtils.h"
#include "nsNetUtil.h"
#include "nsThreadUtils.h"
#include "nsCOMPtr.h"
#include "prlog.h"
#include "nsPrintfCString.h"
#include "GeckoProfiler.h"
#include "nsIStreamListener.h"
#include "nsILoadGroup.h"
#include "nsNetCID.h"
#include <algorithm>
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);

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

@ -7,18 +7,15 @@
#define nsInputStreamPump_h__
#include "nsIInputStreamPump.h"
#include "nsIInputStream.h"
#include "nsIURI.h"
#include "nsILoadGroup.h"
#include "nsIStreamListener.h"
#include "nsIInterfaceRequestor.h"
#include "nsIProgressEventSink.h"
#include "nsIAsyncInputStream.h"
#include "nsIThread.h"
#include "nsIThreadRetargetableRequest.h"
#include "nsCOMPtr.h"
#include "mozilla/Attributes.h"
class nsIInputStream;
class nsILoadGroup;
class nsIStreamListener;
class nsInputStreamPump MOZ_FINAL : public nsIInputStreamPump
, public nsIInputStreamCallback
, public nsIThreadRetargetableRequest

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

@ -10,22 +10,17 @@
#include "nsArrayEnumerator.h"
#include "nsCOMArray.h"
#include "nsEnumeratorUtils.h"
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
#include "nsIURI.h"
#include "prlog.h"
#include "nsCRT.h"
#include "netCore.h"
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsIHttpChannelInternal.h"
#include "mozilla/Atomics.h"
#include "mozilla/Telemetry.h"
#include "nsAutoPtr.h"
#include "mozilla/net/PSpdyPush3.h"
#include "nsITimedChannel.h"
#include "nsIInterfaceRequestor.h"
#include "nsIRequestObserver.h"
using namespace mozilla;

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

@ -9,20 +9,16 @@
#include "nsILoadGroup.h"
#include "nsILoadGroupChild.h"
#include "nsPILoadGroupInternal.h"
#include "nsIChannel.h"
#include "nsIStreamListener.h"
#include "nsAgg.h"
#include "nsCOMPtr.h"
#include "nsWeakPtr.h"
#include "nsWeakReference.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsISupportsPriority.h"
#include "nsITimedChannel.h"
#include "pldhash.h"
#include "mozilla/TimeStamp.h"
class nsILoadGroupConnectionInfo;
class nsILoadGroupConnectionInfo;
class nsITimedChannel;
class nsLoadGroup : public nsILoadGroup,
public nsILoadGroupChild,

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

@ -7,6 +7,7 @@
#include "nsTArray.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsEscape.h"
#include "nsIURI.h"
#include <utility>
#include "nsMediaFragmentURIParser.h"

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

@ -7,10 +7,11 @@
#define nsMediaFragmentURIParser_h__
#include "mozilla/Maybe.h"
#include "nsIURI.h"
#include "nsString.h"
#include "nsStringFwd.h"
#include "nsRect.h"
class nsIURI;
// Class to handle parsing of a W3C media fragment URI as per
// spec at: http://www.w3.org/TR/media-frags/
// Only the temporaral URI portion of the spec is implemented.

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

@ -6,7 +6,6 @@
#include "nsNetAddr.h"
#include "nsString.h"
#include "prnetdb.h"
#include "mozilla/net/DNS.h"
using namespace mozilla::net;

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

@ -12,10 +12,8 @@
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsNetUtil.h"
#include "nsCRT.h"
#include "prmon.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsProxyRelease.h"
#include "nsISystemProxySettings.h"
//-----------------------------------------------------------------------------
using namespace mozilla;

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

@ -11,19 +11,18 @@
#include "nsIInterfaceRequestor.h"
#include "nsIChannelEventSink.h"
#include "ProxyAutoConfig.h"
#include "nsICancelable.h"
#include "nsThreadUtils.h"
#include "nsIURI.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "mozilla/Attributes.h"
#include "mozilla/LinkedList.h"
#include "nsIThread.h"
#include "nsAutoPtr.h"
#include "nsISystemProxySettings.h"
#include "mozilla/TimeStamp.h"
class nsPACMan;
class nsISystemProxySettings;
class nsIThread;
/**
* This class defines a callback interface used by AsyncGetProxyForURI.

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

@ -7,7 +7,6 @@
#include "nsIRunnable.h"
#include "nsThreadUtils.h"
#include "nsAlgorithm.h"
#include <algorithm>
namespace mozilla {

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

@ -10,8 +10,6 @@
#include "nsProtocolProxyService.h"
#include "nsProxyInfo.h"
#include "nsIClassInfoImpl.h"
#include "nsIServiceManager.h"
#include "nsXPIDLString.h"
#include "nsIIOService.h"
#include "nsIObserverService.h"
#include "nsIProtocolHandler.h"
@ -21,17 +19,16 @@
#include "nsPIDNSService.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsReadableUtils.h"
#include "nsThreadUtils.h"
#include "nsString.h"
#include "nsNetUtil.h"
#include "nsNetCID.h"
#include "nsCRT.h"
#include "prnetdb.h"
#include "nsPACMan.h"
#include "nsProxyRelease.h"
#include "mozilla/Mutex.h"
#include "mozilla/CondVar.h"
#include "nsISystemProxySettings.h"
//----------------------------------------------------------------------------

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

@ -10,16 +10,12 @@
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "nsIPrefBranch.h"
#include "nsIProtocolProxyService2.h"
#include "nsIProtocolProxyFilter.h"
#include "nsISystemProxySettings.h"
#include "nsIProxyInfo.h"
#include "nsIObserver.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsPACMan.h"
#include "prtime.h"
#include "prio.h"
#include "mozilla/Attributes.h"
@ -27,6 +23,9 @@ typedef nsDataHashtable<nsCStringHashKey, uint32_t> nsFailedProxyTable;
class nsProxyInfo;
struct nsProtocolInfo;
class nsIPrefBranch;
class nsISystemProxySettings;
class nsPACMan;
class nsProtocolProxyService MOZ_FINAL : public nsIProtocolProxyService2
, public nsIObserver

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

@ -8,9 +8,7 @@
#include "nscore.h"
#include "nsRequestObserverProxy.h"
#include "nsIRequest.h"
#include "nsIServiceManager.h"
#include "nsAutoPtr.h"
#include "nsString.h"
#include "prlog.h"
using namespace mozilla;

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

@ -14,7 +14,6 @@
#include "mozilla/Attributes.h"
class nsISerializable;
class nsISupports;
/**
* Serialize an object to an ASCII string.

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

@ -3,7 +3,6 @@
* 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/. */
#include "nsIServiceManager.h"
#include "nsSocketTransport2.h"
#include "nsServerSocket.h"
#include "nsProxyRelease.h"

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше