Merge remote-tracking branch 'origin/master' into custom

This commit is contained in:
roytam1 2021-08-12 11:21:55 +08:00
commit 90e43f0c90
55 changed files with 479 additions and 442 deletions

View file

@ -193,7 +193,13 @@ HTMLObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
// attributes before inserting the node into the document. // attributes before inserting the node into the document.
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren && if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
aName == nsGkAtoms::data) { aName == nsGkAtoms::data) {
return LoadObject(aNotify, true); nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
[self = RefPtr<HTMLObjectElement>(this), aNotify]() {
if (self->IsInComposedDoc()) {
self->LoadObject(aNotify, true);
}
}));
return NS_OK;
} }
} }

View file

@ -177,8 +177,13 @@ HTMLSharedObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
// a document, just in case that the caller wants to set additional // a document, just in case that the caller wants to set additional
// attributes before inserting the node into the document. // attributes before inserting the node into the document.
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren) { if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren) {
nsresult rv = LoadObject(aNotify, true); nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
NS_ENSURE_SUCCESS(rv, rv); [self = RefPtr<HTMLSharedObjectElement>(this), aNotify]() {
if (self->IsInComposedDoc()) {
self->LoadObject(aNotify, true);
}
}));
return NS_OK;
} }
} }
} }

View file

@ -2121,6 +2121,15 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void assertStackAlignment(uint32_t alignment, int32_t offset = 0); inline void assertStackAlignment(uint32_t alignment, int32_t offset = 0);
}; };
// StackMacroAssembler checks no GC will happen while it's on the stack.
class MOZ_RAII StackMacroAssembler : public MacroAssembler {
JS::AutoCheckCannotGC nogc;
public:
StackMacroAssembler() : MacroAssembler() {}
explicit StackMacroAssembler(JSContext* cx) : MacroAssembler(cx) {}
};
static inline Assembler::DoubleCondition static inline Assembler::DoubleCondition
JSOpToDoubleCondition(JSOp op) JSOpToDoubleCondition(JSOp op)
{ {

View file

@ -123,7 +123,7 @@ if CONFIG['JS_BUNDLED_EDITLINE']:
DIRS += ['editline'] DIRS += ['editline']
if CONFIG['JS_NEW_REGEXP']: if CONFIG['JS_NEW_REGEXP']:
DIRS += ['regexp'] DIRS += ['new-regexp']
if not CONFIG['JS_DISABLE_SHELL']: if not CONFIG['JS_DISABLE_SHELL']:
DIRS += ['shell'] DIRS += ['shell']

View file

@ -7,7 +7,7 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include "regexp/special-case.h" #include "new-regexp/special-case.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -34,4 +34,9 @@ if CONFIG['ENABLE_INTL_API']:
SOURCES += [ SOURCES += [
'property-sequences.cc', 'property-sequences.cc',
'special-case.cc' 'special-case.cc'
] ]
if CONFIG['_MSC_VER']:
# This is intended as a temporary workaround to unblock compilation
# on VS2015 in warnings as errors mode.
CXXFLAGS += ['-wd4275']

View file

@ -4,7 +4,7 @@
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "regexp/property-sequences.h" #include "new-regexp/property-sequences.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -7,7 +7,7 @@
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-ast.h" #include "new-regexp/regexp-ast.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -5,7 +5,7 @@
#ifndef V8_REGEXP_REGEXP_AST_H_ #ifndef V8_REGEXP_REGEXP_AST_H_
#define V8_REGEXP_REGEXP_AST_H_ #define V8_REGEXP_REGEXP_AST_H_
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -5,9 +5,9 @@
#ifndef V8_REGEXP_REGEXP_BYTECODE_GENERATOR_INL_H_ #ifndef V8_REGEXP_REGEXP_BYTECODE_GENERATOR_INL_H_
#define V8_REGEXP_REGEXP_BYTECODE_GENERATOR_INL_H_ #define V8_REGEXP_REGEXP_BYTECODE_GENERATOR_INL_H_
#include "regexp/regexp-bytecode-generator.h" #include "new-regexp/regexp-bytecode-generator.h"
#include "regexp/regexp-bytecodes.h" #include "new-regexp/regexp-bytecodes.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-bytecode-generator.h" #include "new-regexp/regexp-bytecode-generator.h"
#include "regexp/regexp-bytecode-generator-inl.h" #include "new-regexp/regexp-bytecode-generator-inl.h"
#include "regexp/regexp-bytecode-peephole.h" #include "new-regexp/regexp-bytecode-peephole.h"
#include "regexp/regexp-bytecodes.h" #include "new-regexp/regexp-bytecodes.h"
#include "regexp/regexp-macro-assembler.h" #include "new-regexp/regexp-macro-assembler.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -5,7 +5,7 @@
#ifndef V8_REGEXP_REGEXP_BYTECODE_GENERATOR_H_ #ifndef V8_REGEXP_REGEXP_BYTECODE_GENERATOR_H_
#define V8_REGEXP_REGEXP_BYTECODE_GENERATOR_H_ #define V8_REGEXP_REGEXP_BYTECODE_GENERATOR_H_
#include "regexp/regexp-macro-assembler.h" #include "new-regexp/regexp-macro-assembler.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-bytecode-peephole.h" #include "new-regexp/regexp-bytecode-peephole.h"
#include "regexp/regexp-bytecodes.h" #include "new-regexp/regexp-bytecodes.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -5,7 +5,7 @@
#ifndef V8_REGEXP_REGEXP_BYTECODE_PEEPHOLE_H_ #ifndef V8_REGEXP_REGEXP_BYTECODE_PEEPHOLE_H_
#define V8_REGEXP_REGEXP_BYTECODE_PEEPHOLE_H_ #define V8_REGEXP_REGEXP_BYTECODE_PEEPHOLE_H_
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-bytecodes.h" #include "new-regexp/regexp-bytecodes.h"
#include <cctype> #include <cctype>

View file

@ -5,7 +5,7 @@
#ifndef V8_REGEXP_REGEXP_BYTECODES_H_ #ifndef V8_REGEXP_REGEXP_BYTECODES_H_
#define V8_REGEXP_REGEXP_BYTECODES_H_ #define V8_REGEXP_REGEXP_BYTECODES_H_
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-compiler.h" #include "new-regexp/regexp-compiler.h"
#include "regexp/regexp.h" #include "new-regexp/regexp.h"
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "regexp/special-case.h" #include "new-regexp/special-case.h"
#endif // V8_INTL_SUPPORT #endif // V8_INTL_SUPPORT
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT

View file

@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-compiler.h" #include "new-regexp/regexp-compiler.h"
#include "regexp/regexp-macro-assembler-arch.h" #include "new-regexp/regexp-macro-assembler-arch.h"
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "regexp/special-case.h" #include "new-regexp/special-case.h"
#endif // V8_INTL_SUPPORT #endif // V8_INTL_SUPPORT
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT

View file

@ -7,7 +7,7 @@
#include <bitset> #include <bitset>
#include "regexp/regexp-nodes.h" #include "new-regexp/regexp-nodes.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-dotprinter.h" #include "new-regexp/regexp-dotprinter.h"
#include "regexp/regexp-compiler.h" #include "new-regexp/regexp-compiler.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -5,7 +5,7 @@
#ifndef V8_REGEXP_REGEXP_DOTPRINTER_H_ #ifndef V8_REGEXP_REGEXP_DOTPRINTER_H_
#define V8_REGEXP_REGEXP_DOTPRINTER_H_ #define V8_REGEXP_REGEXP_DOTPRINTER_H_
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-error.h" #include "new-regexp/regexp-error.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -4,12 +4,12 @@
// A simple interpreter for the Irregexp byte code. // A simple interpreter for the Irregexp byte code.
#include "regexp/regexp-interpreter.h" #include "new-regexp/regexp-interpreter.h"
#include "regexp/regexp-bytecodes.h" #include "new-regexp/regexp-bytecodes.h"
#include "regexp/regexp-macro-assembler.h" #include "new-regexp/regexp-macro-assembler.h"
#include "regexp/regexp-stack.h" // For kMaximumStackSize. #include "new-regexp/regexp-stack.h" // For kMaximumStackSize.
#include "regexp/regexp.h" #include "new-regexp/regexp.h"
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "unicode/uchar.h" #include "unicode/uchar.h"
@ -22,6 +22,7 @@
#define V8_USE_COMPUTED_GOTO 1 #define V8_USE_COMPUTED_GOTO 1
#endif // V8_HAS_COMPUTED_GOTO #endif // V8_HAS_COMPUTED_GOTO
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -7,7 +7,7 @@
#ifndef V8_REGEXP_REGEXP_INTERPRETER_H_ #ifndef V8_REGEXP_REGEXP_INTERPRETER_H_
#define V8_REGEXP_REGEXP_INTERPRETER_H_ #define V8_REGEXP_REGEXP_INTERPRETER_H_
#include "regexp/regexp.h" #include "new-regexp/regexp.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -16,7 +16,7 @@
#define RegexpMacroAssemblerArch_h #define RegexpMacroAssemblerArch_h
#include "jit/MacroAssembler.h" #include "jit/MacroAssembler.h"
#include "regexp/regexp-macro-assembler.h" #include "new-regexp/regexp-macro-assembler.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
@ -186,7 +186,7 @@ class SMRegExpMacroAssembler final : public NativeRegExpMacroAssembler {
if (num_registers_ <= register_index) { if (num_registers_ <= register_index) {
num_registers_ = register_index + 1; num_registers_ = register_index + 1;
} }
static_assert(alignof(uintptr_t) <= alignof(FrameData)); static_assert(alignof(uintptr_t) <= alignof(FrameData),"Regexp: Alignment of uintptr_t and FrameData mismatch");
return sizeof(FrameData) + register_index * sizeof(uintptr_t*); return sizeof(FrameData) + register_index * sizeof(uintptr_t*);
} }

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-macro-assembler-tracer.h" #include "new-regexp/regexp-macro-assembler-tracer.h"
namespace v8 { namespace v8 {

View file

@ -5,7 +5,7 @@
#ifndef V8_REGEXP_REGEXP_MACRO_ASSEMBLER_TRACER_H_ #ifndef V8_REGEXP_REGEXP_MACRO_ASSEMBLER_TRACER_H_
#define V8_REGEXP_REGEXP_MACRO_ASSEMBLER_TRACER_H_ #define V8_REGEXP_REGEXP_MACRO_ASSEMBLER_TRACER_H_
#include "regexp/regexp-macro-assembler.h" #include "new-regexp/regexp-macro-assembler.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-macro-assembler.h" #include "new-regexp/regexp-macro-assembler.h"
#include "regexp/regexp-stack.h" #include "new-regexp/regexp-stack.h"
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "unicode/uchar.h" #include "unicode/uchar.h"

View file

@ -5,9 +5,9 @@
#ifndef V8_REGEXP_REGEXP_MACRO_ASSEMBLER_H_ #ifndef V8_REGEXP_REGEXP_MACRO_ASSEMBLER_H_
#define V8_REGEXP_REGEXP_MACRO_ASSEMBLER_H_ #define V8_REGEXP_REGEXP_MACRO_ASSEMBLER_H_
#include "regexp/regexp-ast.h" #include "new-regexp/regexp-ast.h"
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
#include "regexp/regexp.h" #include "new-regexp/regexp.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -9,12 +9,17 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "jit/Linker.h" #include "jit/Linker.h"
#include "regexp/regexp-macro-assembler-arch.h" #include "gc/Zone.h"
#include "regexp/regexp-stack.h" #include "new-regexp/regexp-macro-assembler-arch.h"
#include "new-regexp/regexp-stack.h"
#include "vm/MatchPairs.h" #include "vm/MatchPairs.h"
#include "jit/MacroAssembler-inl.h" #include "jit/MacroAssembler-inl.h"
using namespace js;
using namespace js::irregexp;
using namespace js::jit;
namespace v8 { namespace v8 {
namespace internal { namespace internal {
@ -84,19 +89,9 @@ void SMRegExpMacroAssembler::AdvanceRegister(int reg, int by) {
} }
void SMRegExpMacroAssembler::Backtrack() { void SMRegExpMacroAssembler::Backtrack() {
// Check for an interrupt. We have to restart from the beginning if we // Pop code location from backtrack stack and jump to location.
// are interrupted, so we only check for urgent interrupts. Pop(temp0_);
js::jit::Label noInterrupt; masm_.jump(temp0_);
masm_.branchTest32(
Assembler::Zero, AbsoluteAddress(cx_->addressOfInterruptBits()),
Imm32(uint32_t(js::InterruptReason::CallbackUrgent)), &noInterrupt);
masm_.movePtr(ImmWord(js::RegExpRunStatus_Error), temp0_);
masm_.jump(&exit_label_);
masm_.bind(&noInterrupt);
// Pop code location from backtrack stack and jump to location.
Pop(temp0_);
masm_.jump(temp0_);
} }
void SMRegExpMacroAssembler::Bind(Label* label) { void SMRegExpMacroAssembler::Bind(Label* label) {
@ -546,7 +541,8 @@ bool SMRegExpMacroAssembler::CheckSpecialCharacterClass(uc16 type,
masm_.branch32(Assembler::Above, current_character_, Imm32('z'), masm_.branch32(Assembler::Above, current_character_, Imm32('z'),
no_match); no_match);
} }
static_assert(arraysize(word_character_map) > unibrow::Latin1::kMaxChar); static_assert(arraysize(word_character_map) > unibrow::Latin1::kMaxChar,
"regex: arraysize(word_character_map) > unibrow::Latin1::kMaxChar");
masm_.movePtr(ImmPtr(word_character_map), temp0_); masm_.movePtr(ImmPtr(word_character_map), temp0_);
masm_.load8ZeroExtend( masm_.load8ZeroExtend(
BaseIndex(temp0_, current_character_, js::jit::TimesOne), temp0_); BaseIndex(temp0_, current_character_, js::jit::TimesOne), temp0_);
@ -558,7 +554,8 @@ bool SMRegExpMacroAssembler::CheckSpecialCharacterClass(uc16 type,
if (mode_ != LATIN1) { if (mode_ != LATIN1) {
masm_.branch32(Assembler::Above, current_character_, Imm32('z'), &done); masm_.branch32(Assembler::Above, current_character_, Imm32('z'), &done);
} }
static_assert(arraysize(word_character_map) > unibrow::Latin1::kMaxChar); static_assert(arraysize(word_character_map) > unibrow::Latin1::kMaxChar,
"regex: arraysize(word_character_map) > unibrow::Latin1::kMaxChar");
masm_.movePtr(ImmPtr(word_character_map), temp0_); masm_.movePtr(ImmPtr(word_character_map), temp0_);
masm_.load8ZeroExtend( masm_.load8ZeroExtend(
BaseIndex(temp0_, current_character_, js::jit::TimesOne), temp0_); BaseIndex(temp0_, current_character_, js::jit::TimesOne), temp0_);
@ -824,7 +821,7 @@ static Handle<HeapObject> DummyCode() {
// Finalize code. This is called last, so that we know how many // Finalize code. This is called last, so that we know how many
// registers we need. // registers we need.
Handle<HeapObject> SMRegExpMacroAssembler::GetCode(Handle<String> source) { Handle<HeapObject> SMRegExpMacroAssembler::GetCode(Handle<String> source) {
if (!cx_->realm()->ensureJitRealmExists(cx_)) { if (!cx_->compartment()->ensureJitCompartmentExists(cx_)) {
return DummyCode(); return DummyCode();
} }
@ -841,8 +838,9 @@ Handle<HeapObject> SMRegExpMacroAssembler::GetCode(Handle<String> source) {
stackOverflowHandler(); stackOverflowHandler();
Linker linker(masm_); Linker linker(masm_);
JitCode* code = linker.newCode(cx_, js::jit::CodeKind::RegExp); JitCode* code = linker.newCode<NoGC>(cx_, REGEXP_CODE);
if (!code) { if (!code) {
ReportOutOfMemory(cx_);
return DummyCode(); return DummyCode();
} }
@ -1161,7 +1159,7 @@ SMRegExpMacroAssembler::Implementation() {
/*static */ /*static */
uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareStrings( uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareStrings(
const char16_t* substring1, const char16_t* substring2, size_t byteLength) { const char16_t* substring1, const char16_t* substring2, size_t byteLength) {
js::AutoUnsafeCallWithABI unsafe; JS::AutoCheckCannotGC nogc;
MOZ_ASSERT(byteLength % sizeof(char16_t) == 0); MOZ_ASSERT(byteLength % sizeof(char16_t) == 0);
size_t length = byteLength / sizeof(char16_t); size_t length = byteLength / sizeof(char16_t);
@ -1184,7 +1182,7 @@ uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareStrings(
/*static */ /*static */
uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareUCStrings( uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareUCStrings(
const char16_t* substring1, const char16_t* substring2, size_t byteLength) { const char16_t* substring1, const char16_t* substring2, size_t byteLength) {
js::AutoUnsafeCallWithABI unsafe; JS::AutoCheckCannotGC nogc;
MOZ_ASSERT(byteLength % sizeof(char16_t) == 0); MOZ_ASSERT(byteLength % sizeof(char16_t) == 0);
size_t length = byteLength / sizeof(char16_t); size_t length = byteLength / sizeof(char16_t);
@ -1206,7 +1204,7 @@ uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareUCStrings(
/* static */ /* static */
bool SMRegExpMacroAssembler::GrowBacktrackStack(RegExpStack* regexp_stack) { bool SMRegExpMacroAssembler::GrowBacktrackStack(RegExpStack* regexp_stack) {
js::AutoUnsafeCallWithABI unsafe; JS::AutoCheckCannotGC nogc;
size_t size = regexp_stack->stack_capacity(); size_t size = regexp_stack->stack_capacity();
return !!regexp_stack->EnsureCapacity(size * 2); return !!regexp_stack->EnsureCapacity(size * 2);
} }

View file

@ -5,7 +5,7 @@
#ifndef V8_REGEXP_REGEXP_NODES_H_ #ifndef V8_REGEXP_REGEXP_NODES_H_
#define V8_REGEXP_REGEXP_NODES_H_ #define V8_REGEXP_REGEXP_NODES_H_
#include "regexp/regexp-macro-assembler.h" #include "new-regexp/regexp-macro-assembler.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-parser.h" #include "new-regexp/regexp-parser.h"
#include <vector> #include <vector>
#include "regexp/property-sequences.h" #include "new-regexp/property-sequences.h"
#include "regexp/regexp-macro-assembler.h" #include "new-regexp/regexp-macro-assembler.h"
#include "regexp/regexp.h" #include "new-regexp/regexp.h"
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "unicode/uniset.h" #include "unicode/uniset.h"

View file

@ -5,8 +5,8 @@
#ifndef V8_REGEXP_REGEXP_PARSER_H_ #ifndef V8_REGEXP_REGEXP_PARSER_H_
#define V8_REGEXP_REGEXP_PARSER_H_ #define V8_REGEXP_REGEXP_PARSER_H_
#include "regexp/regexp-ast.h" #include "new-regexp/regexp-ast.h"
#include "regexp/regexp-error.h" #include "new-regexp/regexp-error.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
@ -327,7 +327,9 @@ class V8_EXPORT_PRIVATE RegExpParser {
bool operator()(const RegExpCapture* lhs, const RegExpCapture* rhs) const { bool operator()(const RegExpCapture* lhs, const RegExpCapture* rhs) const {
DCHECK_NOT_NULL(lhs); DCHECK_NOT_NULL(lhs);
DCHECK_NOT_NULL(rhs); DCHECK_NOT_NULL(rhs);
return *lhs->name() < *rhs->name(); ZoneVector<uc16> lhname = *lhs->name();
ZoneVector<uc16> rhname = *rhs->name();
return lhname < rhname;
} }
}; };

View file

@ -10,8 +10,10 @@
#include <iostream> #include <iostream>
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
#include "regexp/regexp-stack.h" #include "new-regexp/regexp-stack.h"
#include "mozilla/Sprintf.h" // for SprintfLiteral
namespace v8 { namespace v8 {
namespace internal { namespace internal {
@ -125,8 +127,6 @@ PseudoHandle<ByteArrayData> ByteArray::takeOwnership(Isolate* isolate) {
} }
void Isolate::trace(JSTracer* trc) { void Isolate::trace(JSTracer* trc) {
js::gc::AssertRootMarkingPhase(trc);
for (auto iter = handleArena_.Iter(); !iter.Done(); iter.Next()) { for (auto iter = handleArena_.Iter(); !iter.Done(); iter.Next()) {
auto& elem = iter.Get(); auto& elem = iter.Get();
JS::GCPolicy<JS::Value>::trace(trc, &elem, "Isolate handle arena"); JS::GCPolicy<JS::Value>::trace(trc, &elem, "Isolate handle arena");

View file

@ -20,14 +20,15 @@
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <iostream> // needed for gcc 10
#include "jit/Label.h" #include "jit/Label.h"
#include "jit/shared/Assembler-shared.h" #include "jit/shared/Assembler-shared.h"
#include "js/Value.h" #include "js/Value.h"
#include "regexp/RegExpTypes.h" #include "new-regexp/RegExpTypes.h"
#include "regexp/util/flags.h" #include "new-regexp/util/flags.h"
#include "regexp/util/vector.h" #include "new-regexp/util/vector.h"
#include "regexp/util/zone.h" #include "new-regexp/util/zone.h"
#include "vm/NativeObject.h" #include "vm/NativeObject.h"
// Forward declaration of classes // Forward declaration of classes
@ -1172,7 +1173,6 @@ extern bool FLAG_trace_regexp_bytecodes;
extern bool FLAG_trace_regexp_parser; extern bool FLAG_trace_regexp_parser;
extern bool FLAG_trace_regexp_peephole_optimization; extern bool FLAG_trace_regexp_peephole_optimization;
#define V8_USE_COMPUTED_GOTO 1
#define COMPILING_IRREGEXP_FOR_EXTERNAL_EMBEDDER #define COMPILING_IRREGEXP_FOR_EXTERNAL_EMBEDDER
} // namespace internal } // namespace internal

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "regexp/regexp-stack.h" #include "new-regexp/regexp-stack.h"
namespace v8 { namespace v8 {

View file

@ -5,7 +5,7 @@
#ifndef V8_REGEXP_REGEXP_STACK_H_ #ifndef V8_REGEXP_REGEXP_STACK_H_
#define V8_REGEXP_REGEXP_STACK_H_ #define V8_REGEXP_REGEXP_STACK_H_
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -5,8 +5,8 @@
#ifndef V8_REGEXP_REGEXP_H_ #ifndef V8_REGEXP_REGEXP_H_
#define V8_REGEXP_REGEXP_H_ #define V8_REGEXP_REGEXP_H_
#include "regexp/regexp-error.h" #include "new-regexp/regexp-error.h"
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

View file

@ -11,7 +11,7 @@
// Semantics: Canonicalize) step 3. // Semantics: Canonicalize) step 3.
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "regexp/special-case.h" #include "new-regexp/special-case.h"
#include "unicode/uniset.h" #include "unicode/uniset.h"
namespace v8 { namespace v8 {

View file

@ -6,7 +6,7 @@
#define V8_REGEXP_SPECIAL_CASE_H_ #define V8_REGEXP_SPECIAL_CASE_H_
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
#include "unicode/uchar.h" #include "unicode/uchar.h"
#include "unicode/uniset.h" #include "unicode/uniset.h"

View file

@ -5,7 +5,7 @@
// This file is a subset of: // This file is a subset of:
// https://github.com/v8/v8/blob/master/src/strings/unicode.cc // https://github.com/v8/v8/blob/master/src/strings/unicode.cc
#include "regexp/regexp-shim.h" #include "new-regexp/regexp-shim.h"
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "unicode/uchar.h" #include "unicode/uchar.h"

View file

@ -45,9 +45,9 @@ void DeleteArray(T* array) {
template <typename T> template <typename T>
class Vector { class Vector {
public: public:
constexpr Vector() : start_(nullptr), length_(0) {} Vector() : start_(nullptr), length_(0) {}
constexpr Vector(T* data, size_t length) : start_(data), length_(length) { Vector(T* data, size_t length) : start_(data), length_(length) {
MOZ_ASSERT_IF(length != 0, data != nullptr); MOZ_ASSERT_IF(length != 0, data != nullptr);
} }

View file

@ -13,7 +13,7 @@
#include "ds/LifoAlloc.h" #include "ds/LifoAlloc.h"
#include "ds/Sort.h" #include "ds/Sort.h"
#include "regexp/util/vector.h" #include "new-regexp/util/vector.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {

File diff suppressed because it is too large Load diff

View file

@ -93,6 +93,19 @@ static_assert(
sizeof(CacheIndexRecord::mFlags) == sizeof(CacheIndexRecord), sizeof(CacheIndexRecord::mFlags) == sizeof(CacheIndexRecord),
"Unexpected sizeof(CacheIndexRecord)!"); "Unexpected sizeof(CacheIndexRecord)!");
class CacheIndexRecordWrapper final
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheIndexRecordWrapper)
CacheIndexRecordWrapper() : mRec(MakeUnique<CacheIndexRecord>()) {}
CacheIndexRecord* Get() { return mRec.get(); }
private:
~CacheIndexRecordWrapper() = default;
UniquePtr<CacheIndexRecord> mRec;
};
class CacheIndexEntry : public PLDHashEntryHdr class CacheIndexEntry : public PLDHashEntryHdr
{ {
public: public:
@ -102,9 +115,9 @@ public:
explicit CacheIndexEntry(KeyTypePointer aKey) explicit CacheIndexEntry(KeyTypePointer aKey)
{ {
MOZ_COUNT_CTOR(CacheIndexEntry); MOZ_COUNT_CTOR(CacheIndexEntry);
mRec = new CacheIndexRecord(); mRec = new CacheIndexRecordWrapper();
LOG(("CacheIndexEntry::CacheIndexEntry() - Created record [rec=%p]", mRec.get())); LOG(("CacheIndexEntry::CacheIndexEntry() - Created record [rec=%p]", mRec->Get()));
memcpy(&mRec->mHash, aKey, sizeof(SHA1Sum::Hash)); memcpy(&mRec->Get()->mHash, aKey, sizeof(SHA1Sum::Hash));
} }
CacheIndexEntry(const CacheIndexEntry& aOther) CacheIndexEntry(const CacheIndexEntry& aOther)
{ {
@ -114,13 +127,13 @@ public:
{ {
MOZ_COUNT_DTOR(CacheIndexEntry); MOZ_COUNT_DTOR(CacheIndexEntry);
LOG(("CacheIndexEntry::~CacheIndexEntry() - Deleting record [rec=%p]", LOG(("CacheIndexEntry::~CacheIndexEntry() - Deleting record [rec=%p]",
mRec.get())); mRec->Get()));
} }
// KeyEquals(): does this entry match this key? // KeyEquals(): does this entry match this key?
bool KeyEquals(KeyTypePointer aKey) const bool KeyEquals(KeyTypePointer aKey) const
{ {
return memcmp(&mRec->mHash, aKey, sizeof(SHA1Sum::Hash)) == 0; return memcmp(&mRec->Get()->mHash, aKey, sizeof(SHA1Sum::Hash)) == 0;
} }
// KeyToPointer(): Convert KeyType to KeyTypePointer // KeyToPointer(): Convert KeyType to KeyTypePointer
@ -138,74 +151,74 @@ public:
bool operator==(const CacheIndexEntry& aOther) const bool operator==(const CacheIndexEntry& aOther) const
{ {
return KeyEquals(&aOther.mRec->mHash); return KeyEquals(&aOther.mRec->Get()->mHash);
} }
CacheIndexEntry& operator=(const CacheIndexEntry& aOther) CacheIndexEntry& operator=(const CacheIndexEntry& aOther)
{ {
MOZ_ASSERT(memcmp(&mRec->mHash, &aOther.mRec->mHash, MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aOther.mRec->Get()->mHash,
sizeof(SHA1Sum::Hash)) == 0); sizeof(SHA1Sum::Hash)) == 0);
mRec->mFrecency = aOther.mRec->mFrecency; mRec->Get()->mFrecency = aOther.mRec->Get()->mFrecency;
mRec->mExpirationTime = aOther.mRec->mExpirationTime; mRec->Get()->mExpirationTime = aOther.mRec->Get()->mExpirationTime;
mRec->mOriginAttrsHash = aOther.mRec->mOriginAttrsHash; mRec->Get()->mOriginAttrsHash = aOther.mRec->Get()->mOriginAttrsHash;
mRec->mFlags = aOther.mRec->mFlags; mRec->Get()->mFlags = aOther.mRec->Get()->mFlags;
return *this; return *this;
} }
void InitNew() void InitNew()
{ {
mRec->mFrecency = 0; mRec->Get()->mFrecency = 0;
mRec->mExpirationTime = nsICacheEntry::NO_EXPIRATION_TIME; mRec->Get()->mExpirationTime = nsICacheEntry::NO_EXPIRATION_TIME;
mRec->mOriginAttrsHash = 0; mRec->Get()->mOriginAttrsHash = 0;
mRec->mFlags = 0; mRec->Get()->mFlags = 0;
} }
void Init(OriginAttrsHash aOriginAttrsHash, bool aAnonymous, bool aPinned) void Init(OriginAttrsHash aOriginAttrsHash, bool aAnonymous, bool aPinned)
{ {
MOZ_ASSERT(mRec->mFrecency == 0); MOZ_ASSERT(mRec->Get()->mFrecency == 0);
MOZ_ASSERT(mRec->mExpirationTime == nsICacheEntry::NO_EXPIRATION_TIME); MOZ_ASSERT(mRec->Get()->mExpirationTime == nsICacheEntry::NO_EXPIRATION_TIME);
MOZ_ASSERT(mRec->mOriginAttrsHash == 0); MOZ_ASSERT(mRec->Get()->mOriginAttrsHash == 0);
// When we init the entry it must be fresh and may be dirty // When we init the entry it must be fresh and may be dirty
MOZ_ASSERT((mRec->mFlags & ~kDirtyMask) == kFreshMask); MOZ_ASSERT((mRec->Get()->mFlags & ~kDirtyMask) == kFreshMask);
mRec->mOriginAttrsHash = aOriginAttrsHash; mRec->Get()->mOriginAttrsHash = aOriginAttrsHash;
mRec->mFlags |= kInitializedMask; mRec->Get()->mFlags |= kInitializedMask;
if (aAnonymous) { if (aAnonymous) {
mRec->mFlags |= kAnonymousMask; mRec->Get()->mFlags |= kAnonymousMask;
} }
if (aPinned) { if (aPinned) {
mRec->mFlags |= kPinnedMask; mRec->Get()->mFlags |= kPinnedMask;
} }
} }
const SHA1Sum::Hash * Hash() const { return &mRec->mHash; } const SHA1Sum::Hash * Hash() const { return &mRec->Get()->mHash; }
bool IsInitialized() const { return !!(mRec->mFlags & kInitializedMask); } bool IsInitialized() const { return !!(mRec->Get()->mFlags & kInitializedMask); }
mozilla::net::OriginAttrsHash OriginAttrsHash() const { return mRec->mOriginAttrsHash; } mozilla::net::OriginAttrsHash OriginAttrsHash() const { return mRec->Get()->mOriginAttrsHash; }
bool Anonymous() const { return !!(mRec->mFlags & kAnonymousMask); } bool Anonymous() const { return !!(mRec->Get()->mFlags & kAnonymousMask); }
bool IsRemoved() const { return !!(mRec->mFlags & kRemovedMask); } bool IsRemoved() const { return !!(mRec->Get()->mFlags & kRemovedMask); }
void MarkRemoved() { mRec->mFlags |= kRemovedMask; } void MarkRemoved() { mRec->Get()->mFlags |= kRemovedMask; }
bool IsDirty() const { return !!(mRec->mFlags & kDirtyMask); } bool IsDirty() const { return !!(mRec->Get()->mFlags & kDirtyMask); }
void MarkDirty() { mRec->mFlags |= kDirtyMask; } void MarkDirty() { mRec->Get()->mFlags |= kDirtyMask; }
void ClearDirty() { mRec->mFlags &= ~kDirtyMask; } void ClearDirty() { mRec->Get()->mFlags &= ~kDirtyMask; }
bool IsFresh() const { return !!(mRec->mFlags & kFreshMask); } bool IsFresh() const { return !!(mRec->Get()->mFlags & kFreshMask); }
void MarkFresh() { mRec->mFlags |= kFreshMask; } void MarkFresh() { mRec->Get()->mFlags |= kFreshMask; }
bool IsPinned() const { return !!(mRec->mFlags & kPinnedMask); } bool IsPinned() const { return !!(mRec->Get()->mFlags & kPinnedMask); }
void SetFrecency(uint32_t aFrecency) { mRec->mFrecency = aFrecency; } void SetFrecency(uint32_t aFrecency) { mRec->Get()->mFrecency = aFrecency; }
uint32_t GetFrecency() const { return mRec->mFrecency; } uint32_t GetFrecency() const { return mRec->Get()->mFrecency; }
void SetExpirationTime(uint32_t aExpirationTime) void SetExpirationTime(uint32_t aExpirationTime)
{ {
mRec->mExpirationTime = aExpirationTime; mRec->Get()->mExpirationTime = aExpirationTime;
} }
uint32_t GetExpirationTime() const { return mRec->mExpirationTime; } uint32_t GetExpirationTime() const { return mRec->Get()->mExpirationTime; }
// Sets filesize in kilobytes. // Sets filesize in kilobytes.
void SetFileSize(uint32_t aFileSize) void SetFileSize(uint32_t aFileSize)
@ -215,11 +228,11 @@ public:
"truncating to %u", kFileSizeMask)); "truncating to %u", kFileSizeMask));
aFileSize = kFileSizeMask; aFileSize = kFileSizeMask;
} }
mRec->mFlags &= ~kFileSizeMask; mRec->Get()->mFlags &= ~kFileSizeMask;
mRec->mFlags |= aFileSize; mRec->Get()->mFlags |= aFileSize;
} }
// Returns filesize in kilobytes. // Returns filesize in kilobytes.
uint32_t GetFileSize() const { return GetFileSize(mRec); } uint32_t GetFileSize() const { return GetFileSize(mRec->Get()); }
static uint32_t GetFileSize(CacheIndexRecord *aRec) static uint32_t GetFileSize(CacheIndexRecord *aRec)
{ {
return aRec->mFlags & kFileSizeMask; return aRec->mFlags & kFileSizeMask;
@ -233,40 +246,48 @@ public:
void WriteToBuf(void *aBuf) void WriteToBuf(void *aBuf)
{ {
uint8_t* ptr = static_cast<uint8_t*>(aBuf); uint8_t* ptr = static_cast<uint8_t*>(aBuf);
memcpy(ptr, mRec->mHash, sizeof(SHA1Sum::Hash)); ptr += sizeof(SHA1Sum::Hash); memcpy(ptr, mRec->Get()->mHash, sizeof(SHA1Sum::Hash));
NetworkEndian::writeUint32(ptr, mRec->mFrecency); ptr += sizeof(uint32_t); ptr += sizeof(SHA1Sum::Hash);
NetworkEndian::writeUint64(ptr, mRec->mOriginAttrsHash); ptr += sizeof(uint64_t); NetworkEndian::writeUint32(ptr, mRec->Get()->mFrecency);
NetworkEndian::writeUint32(ptr, mRec->mExpirationTime); ptr += sizeof(uint32_t); ptr += sizeof(uint32_t);
NetworkEndian::writeUint64(ptr, mRec->Get()->mOriginAttrsHash);
ptr += sizeof(uint64_t);
NetworkEndian::writeUint32(ptr, mRec->Get()->mExpirationTime);
ptr += sizeof(uint32_t);
// Dirty and fresh flags should never go to disk, since they make sense only // Dirty and fresh flags should never go to disk, since they make sense only
// during current session. // during current session.
NetworkEndian::writeUint32(ptr, mRec->mFlags & ~(kDirtyMask | kFreshMask)); NetworkEndian::writeUint32(ptr, mRec->Get()->mFlags & ~(kDirtyMask | kFreshMask));
} }
void ReadFromBuf(void *aBuf) void ReadFromBuf(void *aBuf)
{ {
const uint8_t* ptr = static_cast<const uint8_t*>(aBuf); const uint8_t* ptr = static_cast<const uint8_t*>(aBuf);
MOZ_ASSERT(memcmp(&mRec->mHash, ptr, sizeof(SHA1Sum::Hash)) == 0); ptr += sizeof(SHA1Sum::Hash); MOZ_ASSERT(memcmp(&mRec->Get()->mHash, ptr, sizeof(SHA1Sum::Hash)) == 0);
mRec->mFrecency = NetworkEndian::readUint32(ptr); ptr += sizeof(uint32_t); ptr += sizeof(SHA1Sum::Hash);
mRec->mOriginAttrsHash = NetworkEndian::readUint64(ptr); ptr += sizeof(uint64_t); mRec->Get()->mFrecency = NetworkEndian::readUint32(ptr);
mRec->mExpirationTime = NetworkEndian::readUint32(ptr); ptr += sizeof(uint32_t); ptr += sizeof(uint32_t);
mRec->mFlags = NetworkEndian::readUint32(ptr); mRec->Get()->mOriginAttrsHash = NetworkEndian::readUint64(ptr);
ptr += sizeof(uint64_t);
mRec->Get()->mExpirationTime = NetworkEndian::readUint32(ptr);
ptr += sizeof(uint32_t);
mRec->Get()->mFlags = NetworkEndian::readUint32(ptr);
} }
void Log() const { void Log() const {
LOG(("CacheIndexEntry::Log() [this=%p, hash=%08x%08x%08x%08x%08x, fresh=%u," LOG(("CacheIndexEntry::Log() [this=%p, hash=%08x%08x%08x%08x%08x, fresh=%u,"
" initialized=%u, removed=%u, dirty=%u, anonymous=%u, " " initialized=%u, removed=%u, dirty=%u, anonymous=%u, "
"originAttrsHash=%llx, frecency=%u, expirationTime=%u, size=%u]", "originAttrsHash=%llx, frecency=%u, expirationTime=%u, size=%u]",
this, LOGSHA1(mRec->mHash), IsFresh(), IsInitialized(), IsRemoved(), this, LOGSHA1(mRec->Get()->mHash), IsFresh(), IsInitialized(),
IsDirty(), Anonymous(), OriginAttrsHash(), GetFrecency(), IsRemoved(), IsDirty(), Anonymous(), OriginAttrsHash(), GetFrecency(),
GetExpirationTime(), GetFileSize())); GetExpirationTime(), GetFileSize()));
} }
static bool RecordMatchesLoadContextInfo(CacheIndexRecord *aRec, static bool RecordMatchesLoadContextInfo(CacheIndexRecordWrapper *aRec,
nsILoadContextInfo *aInfo) nsILoadContextInfo *aInfo)
{ {
if (!aInfo->IsPrivate() && if (!aInfo->IsPrivate() &&
GetOriginAttrsHash(*aInfo->OriginAttributesPtr()) == aRec->mOriginAttrsHash && GetOriginAttrsHash(*aInfo->OriginAttributesPtr()) == aRec->Get()->mOriginAttrsHash &&
aInfo->IsAnonymous() == !!(aRec->mFlags & kAnonymousMask)) { aInfo->IsAnonymous() == !!(aRec->Get()->mFlags & kAnonymousMask)) {
return true; return true;
} }
@ -276,7 +297,7 @@ public:
// Memory reporting // Memory reporting
size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
{ {
return mallocSizeOf(mRec.get()); return mallocSizeOf(mRec->Get());
} }
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
@ -313,7 +334,7 @@ private:
// FileSize in kilobytes // FileSize in kilobytes
static const uint32_t kFileSizeMask = 0x00FFFFFF; static const uint32_t kFileSizeMask = 0x00FFFFFF;
nsAutoPtr<CacheIndexRecord> mRec; RefPtr<CacheIndexRecordWrapper> mRec;
}; };
class CacheIndexEntryUpdate : public CacheIndexEntry class CacheIndexEntryUpdate : public CacheIndexEntry
@ -334,7 +355,7 @@ public:
CacheIndexEntryUpdate& operator=(const CacheIndexEntry& aOther) CacheIndexEntryUpdate& operator=(const CacheIndexEntry& aOther)
{ {
MOZ_ASSERT(memcmp(&mRec->mHash, &aOther.mRec->mHash, MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aOther.mRec->Get()->mHash,
sizeof(SHA1Sum::Hash)) == 0); sizeof(SHA1Sum::Hash)) == 0);
mUpdateFlags = 0; mUpdateFlags = 0;
*(static_cast<CacheIndexEntry *>(this)) = aOther; *(static_cast<CacheIndexEntry *>(this)) = aOther;
@ -367,21 +388,21 @@ public:
} }
void ApplyUpdate(CacheIndexEntry *aDst) { void ApplyUpdate(CacheIndexEntry *aDst) {
MOZ_ASSERT(memcmp(&mRec->mHash, &aDst->mRec->mHash, MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aDst->mRec->Get()->mHash,
sizeof(SHA1Sum::Hash)) == 0); sizeof(SHA1Sum::Hash)) == 0);
if (mUpdateFlags & kFrecencyUpdatedMask) { if (mUpdateFlags & kFrecencyUpdatedMask) {
aDst->mRec->mFrecency = mRec->mFrecency; aDst->mRec->Get()->mFrecency = mRec->Get()->mFrecency;
} }
if (mUpdateFlags & kExpirationUpdatedMask) { if (mUpdateFlags & kExpirationUpdatedMask) {
aDst->mRec->mExpirationTime = mRec->mExpirationTime; aDst->mRec->Get()->mExpirationTime = mRec->Get()->mExpirationTime;
} }
aDst->mRec->mOriginAttrsHash = mRec->mOriginAttrsHash; aDst->mRec->Get()->mOriginAttrsHash = mRec->Get()->mOriginAttrsHash;
if (mUpdateFlags & kFileSizeUpdatedMask) { if (mUpdateFlags & kFileSizeUpdatedMask) {
aDst->mRec->mFlags = mRec->mFlags; aDst->mRec->Get()->mFlags = mRec->Get()->mFlags;
} else { } else {
// Copy all flags except file size. // Copy all flags except file size.
aDst->mRec->mFlags &= kFileSizeMask; aDst->mRec->Get()->mFlags &= kFileSizeMask;
aDst->mRec->mFlags |= (mRec->mFlags & ~kFileSizeMask); aDst->mRec->Get()->mFlags |= (mRec->Get()->mFlags & ~kFileSizeMask);
} }
} }
@ -698,7 +719,9 @@ private:
NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult) override; NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult) override;
nsresult OnFileOpenedInternal(FileOpenHelper *aOpener, nsresult OnFileOpenedInternal(FileOpenHelper *aOpener,
CacheFileHandle *aHandle, nsresult aResult); CacheFileHandle *aHandle,
nsresult aResult,
const StaticMutexAutoLock& aProofOfLock);
NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf,
nsresult aResult) override; nsresult aResult) override;
NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) override; NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) override;
@ -706,7 +729,7 @@ private:
NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) override; NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) override;
NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) override; NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) override;
nsresult InitInternal(nsIFile *aCacheDirectory); nsresult InitInternal(nsIFile *aCacheDirectory, const StaticMutexAutoLock& aProofOfLock);
void PreShutdownInternal(); void PreShutdownInternal();
// This method returns false when index is not initialized or is shut down. // This method returns false when index is not initialized or is shut down.
@ -727,7 +750,7 @@ private:
const uint32_t *aSize); const uint32_t *aSize);
// Merge all pending operations from mPendingUpdates into mIndex. // Merge all pending operations from mPendingUpdates into mIndex.
void ProcessPendingOperations(); void ProcessPendingOperations(const StaticMutexAutoLock& aProofOfLock);
// Following methods perform writing of the index file. // Following methods perform writing of the index file.
// //
@ -739,14 +762,14 @@ private:
// //
// Starts writing of index when both limits (minimal delay between writes and // Starts writing of index when both limits (minimal delay between writes and
// minimum number of changes in index) were exceeded. // minimum number of changes in index) were exceeded.
bool WriteIndexToDiskIfNeeded(); bool WriteIndexToDiskIfNeeded(const StaticMutexAutoLock& aProofOfLock);
// Starts writing of index file. // Starts writing of index file.
void WriteIndexToDisk(); void WriteIndexToDisk(const StaticMutexAutoLock& aProofOfLock);
// Serializes part of mIndex hashtable to the write buffer a writes the buffer // Serializes part of mIndex hashtable to the write buffer a writes the buffer
// to the file. // to the file.
void WriteRecords(); void WriteRecords(const StaticMutexAutoLock& aProofOfLock);
// Finalizes writing process. // Finalizes writing process.
void FinishWrite(bool aSucceeded); void FinishWrite(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock);
// Following methods perform writing of the journal during shutdown. All these // Following methods perform writing of the journal during shutdown. All these
// methods must be called only during shutdown since they write/delete files // methods must be called only during shutdown since they write/delete files
@ -799,17 +822,17 @@ private:
// FF crashes during parsing of the index. // FF crashes during parsing of the index.
// //
// Initiates reading index from disk. // Initiates reading index from disk.
void ReadIndexFromDisk(); void ReadIndexFromDisk(const StaticMutexAutoLock& aProofOfLock);
// Starts reading data from index file. // Starts reading data from index file.
void StartReadingIndex(); void StartReadingIndex(const StaticMutexAutoLock& aProofOfLock);
// Parses data read from index file. // Parses data read from index file.
void ParseRecords(); void ParseRecords(const StaticMutexAutoLock& aProofOfLock);
// Starts reading data from journal file. // Starts reading data from journal file.
void StartReadingJournal(); void StartReadingJournal(const StaticMutexAutoLock& aProofOfLock);
// Parses data read from journal file. // Parses data read from journal file.
void ParseJournal(); void ParseJournal(const StaticMutexAutoLock& aProofOfLock);
// Merges entries from journal into mIndex. // Merges entries from journal into mIndex.
void MergeJournal(); void MergeJournal(const StaticMutexAutoLock& aProofOfLock);
// In debug build this method checks that we have no fresh entry in mIndex // In debug build this method checks that we have no fresh entry in mIndex
// after we finish reading index and before we process pending operations. // after we finish reading index and before we process pending operations.
void EnsureNoFreshEntry(); void EnsureNoFreshEntry();
@ -817,12 +840,12 @@ private:
// to make sure mIndexStats contains correct information. // to make sure mIndexStats contains correct information.
void EnsureCorrectStats(); void EnsureCorrectStats();
// Finalizes reading process. // Finalizes reading process.
void FinishRead(bool aSucceeded); void FinishRead(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock);
// Following methods perform updating and building of the index. // Following methods perform updating and building of the index.
// Timer callback that starts update or build process. // Timer callback that starts update or build process.
static void DelayedUpdate(nsITimer *aTimer, void *aClosure); static void DelayedUpdate(nsITimer *aTimer, void *aClosure);
void DelayedUpdateLocked(); void DelayedUpdateLocked(const StaticMutexAutoLock& aProofOfLock);
// Posts timer event that start update or build process. // Posts timer event that start update or build process.
nsresult ScheduleUpdateTimer(uint32_t aDelay); nsresult ScheduleUpdateTimer(uint32_t aDelay);
nsresult SetupDirectoryEnumerator(); nsresult SetupDirectoryEnumerator();
@ -833,20 +856,22 @@ private:
bool IsUpdatePending(); bool IsUpdatePending();
// Iterates through all files in entries directory that we didn't create/open // Iterates through all files in entries directory that we didn't create/open
// during this session, parses them and adds the entries to the index. // during this session, parses them and adds the entries to the index.
void BuildIndex(); void BuildIndex(const StaticMutexAutoLock& aProofOfLock);
bool StartUpdatingIndexIfNeeded(bool aSwitchingToReadyState = false); bool StartUpdatingIndexIfNeeded(const StaticMutexAutoLock& aProofOfLock,
bool aSwitchingToReadyState = false);
// Starts update or build process or fires a timer when it is too early after // Starts update or build process or fires a timer when it is too early after
// startup. // startup.
void StartUpdatingIndex(bool aRebuild); void StartUpdatingIndex(bool aRebuild,
const StaticMutexAutoLock& aProofOfLock);
// Iterates through all files in entries directory that we didn't create/open // Iterates through all files in entries directory that we didn't create/open
// during this session and theirs last modified time is newer than timestamp // during this session and theirs last modified time is newer than timestamp
// in the index header. Parses the files and adds the entries to the index. // in the index header. Parses the files and adds the entries to the index.
void UpdateIndex(); void UpdateIndex(const StaticMutexAutoLock& aProofOfLock);
// Finalizes update or build process. // Finalizes update or build process.
void FinishUpdate(bool aSucceeded); void FinishUpdate(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock);
void RemoveNonFreshEntries(); void RemoveNonFreshEntries(const StaticMutexAutoLock& aProofOfLock);
enum EState { enum EState {
// Initial state in which the index is not usable // Initial state in which the index is not usable
@ -899,7 +924,7 @@ private:
}; };
static char const * StateString(EState aState); static char const * StateString(EState aState);
void ChangeState(EState aNewState); void ChangeState(EState aNewState, const StaticMutexAutoLock& aProofOfLock);
void NotifyAsyncGetDiskConsumptionCallbacks(); void NotifyAsyncGetDiskConsumptionCallbacks();
// Allocates and releases buffer used for reading and writing index. // Allocates and releases buffer used for reading and writing index.
@ -907,10 +932,13 @@ private:
void ReleaseBuffer(); void ReleaseBuffer();
// Methods used by CacheIndexEntryAutoManage to keep the iterators up to date. // Methods used by CacheIndexEntryAutoManage to keep the iterators up to date.
void AddRecordToIterators(CacheIndexRecord *aRecord); void AddRecordToIterators(CacheIndexRecordWrapper* aRecord,
void RemoveRecordFromIterators(CacheIndexRecord *aRecord); const StaticMutexAutoLock& aProofOfLock);
void ReplaceRecordInIterators(CacheIndexRecord *aOldRecord, void RemoveRecordFromIterators(CacheIndexRecordWrapper* aRecord,
CacheIndexRecord *aNewRecord); const StaticMutexAutoLock& aProofOfLock);
void ReplaceRecordInIterators(CacheIndexRecordWrapper* aOldRecord,
CacheIndexRecordWrapper* aNewRecord,
const StaticMutexAutoLock& aProofOfLock);
// Memory reporting (private part) // Memory reporting (private part)
size_t SizeOfExcludingThisInternal(mozilla::MallocSizeOf mallocSizeOf) const; size_t SizeOfExcludingThisInternal(mozilla::MallocSizeOf mallocSizeOf) const;
@ -1023,7 +1051,7 @@ private:
class Iterator class Iterator
{ {
public: public:
explicit Iterator(nsTArray<CacheIndexRecord *> *aRecs) explicit Iterator(nsTArray<RefPtr<CacheIndexRecordWrapper>>* aRecs)
: mRecs(aRecs) : mRecs(aRecs)
, mIdx(0) , mIdx(0)
{ {
@ -1034,7 +1062,7 @@ private:
bool Done() const { return mIdx == mRecs->Length(); } bool Done() const { return mIdx == mRecs->Length(); }
CacheIndexRecord* Get() const CacheIndexRecordWrapper* Get() const
{ {
MOZ_ASSERT(!Done()); MOZ_ASSERT(!Done());
return (*mRecs)[mIdx]; return (*mRecs)[mIdx];
@ -1050,7 +1078,7 @@ private:
} }
private: private:
nsTArray<CacheIndexRecord *> *mRecs; nsTArray<RefPtr<CacheIndexRecordWrapper>>* mRecs;
uint32_t mIdx; uint32_t mIdx;
}; };
@ -1061,19 +1089,22 @@ private:
, mRemovedElements(0) {} , mRemovedElements(0) {}
// Methods used by CacheIndexEntryAutoManage to keep the array up to date. // Methods used by CacheIndexEntryAutoManage to keep the array up to date.
void AppendRecord(CacheIndexRecord *aRecord); void AppendRecord(CacheIndexRecordWrapper* aRecord,
void RemoveRecord(CacheIndexRecord *aRecord); const StaticMutexAutoLock& aProofOfLock);
void ReplaceRecord(CacheIndexRecord *aOldRecord, void RemoveRecord(CacheIndexRecordWrapper* aRecord,
CacheIndexRecord *aNewRecord); const StaticMutexAutoLock& aProofOfLock);
void SortIfNeeded(); void ReplaceRecord(CacheIndexRecordWrapper* aOldRecord,
CacheIndexRecordWrapper* aNewRecord,
const StaticMutexAutoLock& aProofOfLock);
void SortIfNeeded(const StaticMutexAutoLock& aProofOfLock);
size_t Length() const { return mRecs.Length() - mRemovedElements; } size_t Length() const { return mRecs.Length() - mRemovedElements; }
void Clear() { mRecs.Clear(); } void Clear(const StaticMutexAutoLock& aProofOfLock) { mRecs.Clear(); }
private: private:
friend class CacheIndex; friend class CacheIndex;
nsTArray<CacheIndexRecord *> mRecs; nsTArray<RefPtr<CacheIndexRecordWrapper>> mRecs;
uint32_t mUnsortedElements; uint32_t mUnsortedElements;
// Instead of removing elements from the array immediately, we null them out // Instead of removing elements from the array immediately, we null them out
// and the iterator skips them when accessing the array. The null pointers // and the iterator skips them when accessing the array. The null pointers

View file

@ -24,20 +24,11 @@ CacheIndexContextIterator::~CacheIndexContextIterator()
} }
void void
CacheIndexContextIterator::AddRecord(CacheIndexRecord *aRecord) CacheIndexContextIterator::AddRecord(CacheIndexRecordWrapper* aRecord,
const StaticMutexAutoLock& aProofOfLock)
{ {
if (CacheIndexEntry::RecordMatchesLoadContextInfo(aRecord, mInfo)) { if (CacheIndexEntry::RecordMatchesLoadContextInfo(aRecord, mInfo)) {
CacheIndexIterator::AddRecord(aRecord); CacheIndexIterator::AddRecord(aRecord, aProofOfLock);
}
}
void
CacheIndexContextIterator::AddRecords(
const nsTArray<CacheIndexRecord *> &aRecords)
{
// We need to add one by one so that those with wrong context are ignored.
for (uint32_t i = 0; i < aRecords.Length(); ++i) {
AddRecord(aRecords[i]);
} }
} }

View file

@ -20,8 +20,8 @@ public:
virtual ~CacheIndexContextIterator(); virtual ~CacheIndexContextIterator();
private: private:
virtual void AddRecord(CacheIndexRecord *aRecord); virtual void AddRecord(CacheIndexRecordWrapper* aRecord,
virtual void AddRecords(const nsTArray<CacheIndexRecord *> &aRecords); const StaticMutexAutoLock& aProofOfLock) override;
nsCOMPtr<nsILoadContextInfo> mInfo; nsCOMPtr<nsILoadContextInfo> mInfo;
}; };

View file

@ -24,7 +24,9 @@ CacheIndexIterator::~CacheIndexIterator()
{ {
LOG(("CacheIndexIterator::~CacheIndexIterator() [this=%p]", this)); LOG(("CacheIndexIterator::~CacheIndexIterator() [this=%p]", this));
Close(); StaticMutexAutoLock lock(CacheIndex::sLock);
ClearRecords(lock);
CloseInternal(NS_ERROR_NOT_AVAILABLE);
} }
nsresult nsresult
@ -43,7 +45,7 @@ CacheIndexIterator::GetNextHash(SHA1Sum::Hash *aHash)
return mStatus; return mStatus;
} }
memcpy(aHash, mRecords[mRecords.Length() - 1]->mHash, sizeof(SHA1Sum::Hash)); memcpy(aHash, mRecords[mRecords.Length() - 1]->Get()->mHash, sizeof(SHA1Sum::Hash));
mRecords.RemoveElementAt(mRecords.Length() - 1); mRecords.RemoveElementAt(mRecords.Length() - 1);
return NS_OK; return NS_OK;
@ -82,8 +84,13 @@ CacheIndexIterator::CloseInternal(nsresult aStatus)
return NS_OK; return NS_OK;
} }
void void CacheIndexIterator::ClearRecords(const StaticMutexAutoLock& aProofOfLock)
CacheIndexIterator::AddRecord(CacheIndexRecord *aRecord) {
mRecords.Clear();
}
void CacheIndexIterator::AddRecord(CacheIndexRecordWrapper* aRecord,
const StaticMutexAutoLock& aProofOfLock)
{ {
LOG(("CacheIndexIterator::AddRecord() [this=%p, record=%p]", this, aRecord)); LOG(("CacheIndexIterator::AddRecord() [this=%p, record=%p]", this, aRecord));
@ -91,7 +98,8 @@ CacheIndexIterator::AddRecord(CacheIndexRecord *aRecord)
} }
bool bool
CacheIndexIterator::RemoveRecord(CacheIndexRecord *aRecord) CacheIndexIterator::RemoveRecord(CacheIndexRecordWrapper *aRecord,
const StaticMutexAutoLock& aProofOfLock)
{ {
LOG(("CacheIndexIterator::RemoveRecord() [this=%p, record=%p]", this, LOG(("CacheIndexIterator::RemoveRecord() [this=%p, record=%p]", this,
aRecord)); aRecord));
@ -100,14 +108,15 @@ CacheIndexIterator::RemoveRecord(CacheIndexRecord *aRecord)
} }
bool bool
CacheIndexIterator::ReplaceRecord(CacheIndexRecord *aOldRecord, CacheIndexIterator::ReplaceRecord(CacheIndexRecordWrapper* aOldRecord,
CacheIndexRecord *aNewRecord) CacheIndexRecordWrapper* aNewRecord,
const StaticMutexAutoLock& aProofOfLock)
{ {
LOG(("CacheIndexIterator::ReplaceRecord() [this=%p, oldRecord=%p, " LOG(("CacheIndexIterator::ReplaceRecord() [this=%p, oldRecord=%p, "
"newRecord=%p]", this, aOldRecord, aNewRecord)); "newRecord=%p]", this, aOldRecord, aNewRecord));
if (RemoveRecord(aOldRecord)) { if (RemoveRecord(aOldRecord, aProofOfLock)) {
AddRecord(aNewRecord); AddRecord(aNewRecord, aProofOfLock);
return true; return true;
} }

View file

@ -9,12 +9,13 @@
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "mozilla/SHA1.h" #include "mozilla/SHA1.h"
#include "mozilla/StaticMutex.h"
namespace mozilla { namespace mozilla {
namespace net { namespace net {
class CacheIndex; class CacheIndex;
struct CacheIndexRecord; class CacheIndexRecordWrapper;
class CacheIndexIterator class CacheIndexIterator
{ {
@ -42,14 +43,18 @@ protected:
nsresult CloseInternal(nsresult aStatus); nsresult CloseInternal(nsresult aStatus);
bool ShouldBeNewAdded() { return mAddNew; } bool ShouldBeNewAdded() { return mAddNew; }
virtual void AddRecord(CacheIndexRecord *aRecord); virtual void AddRecord(CacheIndexRecordWrapper* aRecord,
bool RemoveRecord(CacheIndexRecord *aRecord); const StaticMutexAutoLock& aProofOfLock);
bool ReplaceRecord(CacheIndexRecord *aOldRecord, bool RemoveRecord(CacheIndexRecordWrapper* aRecord,
CacheIndexRecord *aNewRecord); const StaticMutexAutoLock& aProofOfLock);
bool ReplaceRecord(CacheIndexRecordWrapper* aOldRecord,
CacheIndexRecordWrapper* aNewRecord,
const StaticMutexAutoLock& aProofOfLock);
void ClearRecords(const StaticMutexAutoLock& aProofOfLock);
nsresult mStatus; nsresult mStatus;
RefPtr<CacheIndex> mIndex; RefPtr<CacheIndex> mIndex;
nsTArray<CacheIndexRecord *> mRecords; nsTArray<RefPtr<CacheIndexRecordWrapper>> mRecords;
bool mAddNew; bool mAddNew;
}; };