diff options
author | Allan Sandfeld Jensen <[email protected]> | 2015-09-28 18:37:14 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <[email protected]> | 2015-09-29 07:47:06 +0000 |
commit | 0e8ff63a407fe323e215bb1a2c423c09a4747c8a (patch) | |
tree | e27e357e125d2d705bd504e1e3c8a3da1ed20f1d /chromium/v8 | |
parent | c3d0bb5bb15d008606b18b865841e19cd9bb5847 (diff) |
BASELINE: Update chromium to 45.0.2454.101upstream-45
Also adds web_cache component
Change-Id: I51238ceea8ee99854cc4989ae70a4fc2fc6bedcb
Reviewed-by: Kai Koehne <[email protected]>
Diffstat (limited to 'chromium/v8')
-rw-r--r-- | chromium/v8/build/features.gypi | 4 | ||||
-rw-r--r-- | chromium/v8/codereview.settings | 2 | ||||
-rw-r--r-- | chromium/v8/include/v8-version.h | 2 | ||||
-rw-r--r-- | chromium/v8/src/arm/assembler-arm.cc | 3 | ||||
-rw-r--r-- | chromium/v8/src/arm64/assembler-arm64.cc | 3 | ||||
-rw-r--r-- | chromium/v8/src/ast.cc | 1 | ||||
-rw-r--r-- | chromium/v8/src/base/cpu.h | 3 | ||||
-rw-r--r-- | chromium/v8/src/flag-definitions.h | 2 | ||||
-rw-r--r-- | chromium/v8/src/heap/gc-tracer.cc | 8 | ||||
-rw-r--r-- | chromium/v8/src/heap/gc-tracer.h | 7 | ||||
-rw-r--r-- | chromium/v8/src/heap/heap.cc | 122 | ||||
-rw-r--r-- | chromium/v8/src/heap/heap.h | 17 | ||||
-rw-r--r-- | chromium/v8/src/heap/incremental-marking.cc | 24 | ||||
-rw-r--r-- | chromium/v8/src/heap/incremental-marking.h | 23 | ||||
-rw-r--r-- | chromium/v8/src/messages.h | 1 | ||||
-rw-r--r-- | chromium/v8/src/object-observe.js | 4 | ||||
-rw-r--r-- | chromium/v8/src/runtime/runtime-object.cc | 8 | ||||
-rw-r--r-- | chromium/v8/src/runtime/runtime.h | 3 | ||||
-rw-r--r-- | chromium/v8/src/scanner-character-streams.cc | 38 | ||||
-rw-r--r-- | chromium/v8/src/scanner-character-streams.h | 4 |
20 files changed, 231 insertions, 48 deletions
diff --git a/chromium/v8/build/features.gypi b/chromium/v8/build/features.gypi index 0e26969f646..59d15134ddf 100644 --- a/chromium/v8/build/features.gypi +++ b/chromium/v8/build/features.gypi @@ -108,7 +108,7 @@ 'DebugBaseCommon': { 'abstract': 1, 'variables': { - 'v8_enable_handle_zapping%': 0, + 'v8_enable_handle_zapping%': 1, }, 'conditions': [ ['v8_enable_handle_zapping==1', { @@ -118,7 +118,7 @@ }, # Debug 'Release': { 'variables': { - 'v8_enable_handle_zapping%': 1, + 'v8_enable_handle_zapping%': 0, }, 'conditions': [ ['v8_enable_handle_zapping==1', { diff --git a/chromium/v8/codereview.settings b/chromium/v8/codereview.settings index 7c4dd8e2556..532e4b4d7b0 100644 --- a/chromium/v8/codereview.settings +++ b/chromium/v8/codereview.settings @@ -1,5 +1,5 @@ CODE_REVIEW_SERVER: https://codereview.chromium.org -CC_LIST: [email protected] +CC_LIST: [email protected] VIEW_VC: https://chromium.googlesource.com/v8/v8/+/ STATUS: http://v8-status.appspot.com/status TRY_ON_UPLOAD: False diff --git a/chromium/v8/include/v8-version.h b/chromium/v8/include/v8-version.h index 66e8c6eaa58..98dca238c85 100644 --- a/chromium/v8/include/v8-version.h +++ b/chromium/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 4 #define V8_MINOR_VERSION 5 #define V8_BUILD_NUMBER 103 -#define V8_PATCH_LEVEL 28 +#define V8_PATCH_LEVEL 35 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/chromium/v8/src/arm/assembler-arm.cc b/chromium/v8/src/arm/assembler-arm.cc index 96bdf79face..481a3b5cedd 100644 --- a/chromium/v8/src/arm/assembler-arm.cc +++ b/chromium/v8/src/arm/assembler-arm.cc @@ -128,7 +128,8 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS; if (cpu.implementer() == base::CPU::NVIDIA && - cpu.variant() == base::CPU::NVIDIA_DENVER) { + cpu.variant() == base::CPU::NVIDIA_DENVER && + cpu.part() <= base::CPU::NVIDIA_DENVER_V10) { supported_ |= 1u << COHERENT_CACHE; } #endif diff --git a/chromium/v8/src/arm64/assembler-arm64.cc b/chromium/v8/src/arm64/assembler-arm64.cc index 5445fe1a1b1..f27d3b97b0f 100644 --- a/chromium/v8/src/arm64/assembler-arm64.cc +++ b/chromium/v8/src/arm64/assembler-arm64.cc @@ -53,7 +53,8 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { // Probe for runtime features base::CPU cpu; if (cpu.implementer() == base::CPU::NVIDIA && - cpu.variant() == base::CPU::NVIDIA_DENVER) { + cpu.variant() == base::CPU::NVIDIA_DENVER && + cpu.part() <= base::CPU::NVIDIA_DENVER_V10) { supported_ |= 1u << COHERENT_CACHE; } } diff --git a/chromium/v8/src/ast.cc b/chromium/v8/src/ast.cc index e52504a86fb..ec74e4afaf7 100644 --- a/chromium/v8/src/ast.cc +++ b/chromium/v8/src/ast.cc @@ -441,6 +441,7 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { if (position == boilerplate_properties_ * 2) { DCHECK(property->is_computed_name()); + is_simple = false; break; } DCHECK(!property->is_computed_name()); diff --git a/chromium/v8/src/base/cpu.h b/chromium/v8/src/base/cpu.h index f6c5a8506a0..1dc0a91f650 100644 --- a/chromium/v8/src/base/cpu.h +++ b/chromium/v8/src/base/cpu.h @@ -59,6 +59,9 @@ class CPU final { static const int ARM_CORTEX_A12 = 0xc0c; static const int ARM_CORTEX_A15 = 0xc0f; + // Denver-specific part code + static const int NVIDIA_DENVER_V10 = 0x002; + // PPC-specific part codes enum { PPC_POWER5, diff --git a/chromium/v8/src/flag-definitions.h b/chromium/v8/src/flag-definitions.h index a89c8e4d4ba..79611270dd4 100644 --- a/chromium/v8/src/flag-definitions.h +++ b/chromium/v8/src/flag-definitions.h @@ -613,6 +613,8 @@ DEFINE_INT(trace_allocation_stack_interval, -1, DEFINE_BOOL(trace_fragmentation, false, "report fragmentation for old space") DEFINE_BOOL(trace_fragmentation_verbose, false, "report fragmentation for old space (detailed)") +DEFINE_BOOL(trace_mutator_utilization, false, + "print mutator utilization, allocation speed, gc speed") DEFINE_BOOL(weak_embedded_maps_in_optimized_code, true, "make maps embedded in optimized code weak") DEFINE_BOOL(weak_embedded_objects_in_optimized_code, true, diff --git a/chromium/v8/src/heap/gc-tracer.cc b/chromium/v8/src/heap/gc-tracer.cc index 214bb8b24d6..6728f09bdad 100644 --- a/chromium/v8/src/heap/gc-tracer.cc +++ b/chromium/v8/src/heap/gc-tracer.cc @@ -682,11 +682,15 @@ size_t GCTracer::AllocationThroughputInBytesPerMillisecond( } +size_t GCTracer::CurrentAllocationThroughputInBytesPerMillisecond() const { + return AllocationThroughputInBytesPerMillisecond(kThroughputTimeFrameMs); +} + + size_t GCTracer::CurrentOldGenerationAllocationThroughputInBytesPerMillisecond() const { - static const double kThroughputTimeFrame = 5000; return OldGenerationAllocationThroughputInBytesPerMillisecond( - kThroughputTimeFrame); + kThroughputTimeFrameMs); } diff --git a/chromium/v8/src/heap/gc-tracer.h b/chromium/v8/src/heap/gc-tracer.h index 468fc9c0be7..e26fc898f99 100644 --- a/chromium/v8/src/heap/gc-tracer.h +++ b/chromium/v8/src/heap/gc-tracer.h @@ -291,6 +291,8 @@ class GCTracer { typedef RingBuffer<SurvivalEvent, kRingBufferMaxSize> SurvivalEventBuffer; + static const int kThroughputTimeFrameMs = 5000; + explicit GCTracer(Heap* heap); // Start collecting data. @@ -408,6 +410,11 @@ class GCTracer { // Returns 0 if no allocation events have been recorded. size_t AllocationThroughputInBytesPerMillisecond(double time_ms) const; + // Allocation throughput in heap in bytes/milliseconds in + // the last five seconds. + // Returns 0 if no allocation events have been recorded. + size_t CurrentAllocationThroughputInBytesPerMillisecond() const; + // Allocation throughput in old generation in bytes/milliseconds in // the last five seconds. // Returns 0 if no allocation events have been recorded. diff --git a/chromium/v8/src/heap/heap.cc b/chromium/v8/src/heap/heap.cc index fc36be8041f..3d953730013 100644 --- a/chromium/v8/src/heap/heap.cc +++ b/chromium/v8/src/heap/heap.cc @@ -775,7 +775,8 @@ void Heap::PreprocessStackTraces() { void Heap::HandleGCRequest() { if (incremental_marking()->request_type() == IncrementalMarking::COMPLETE_MARKING) { - CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt"); + CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt", + incremental_marking()->CallbackFlags()); return; } DCHECK(FLAG_overapproximate_weak_closure); @@ -985,7 +986,7 @@ bool Heap::CollectGarbage(GarbageCollector collector, const char* gc_reason, if (!mark_compact_collector()->abort_incremental_marking() && incremental_marking()->IsStopped() && incremental_marking()->ShouldActivateEvenWithoutIdleNotification()) { - incremental_marking()->Start(kNoGCFlags); + incremental_marking()->Start(kNoGCFlags, kNoGCCallbackFlags, "GC epilogue"); } return next_gc_likely_to_collect_more; @@ -1012,9 +1013,18 @@ int Heap::NotifyContextDisposed(bool dependant_context) { } +void Heap::StartIncrementalMarking(int gc_flags, + const GCCallbackFlags gc_callback_flags, + const char* reason) { + DCHECK(incremental_marking()->IsStopped()); + incremental_marking()->Start(gc_flags, gc_callback_flags, reason); +} + + void Heap::StartIdleIncrementalMarking() { gc_idle_time_handler_.ResetNoProgressCounter(); - incremental_marking()->Start(kReduceMemoryFootprintMask); + StartIncrementalMarking(kReduceMemoryFootprintMask, kNoGCCallbackFlags, + "idle"); } @@ -4762,27 +4772,63 @@ void Heap::MakeHeapIterable() { } -bool Heap::HasLowYoungGenerationAllocationRate() { - const double high_mutator_utilization = 0.993; +static double ComputeMutatorUtilization(double mutator_speed, double gc_speed) { + const double kMinMutatorUtilization = 0.0; + const double kConservativeGcSpeedInBytesPerMillisecond = 200000; + if (mutator_speed == 0) return kMinMutatorUtilization; + if (gc_speed == 0) gc_speed = kConservativeGcSpeedInBytesPerMillisecond; + // Derivation: + // mutator_utilization = mutator_time / (mutator_time + gc_time) + // mutator_time = 1 / mutator_speed + // gc_time = 1 / gc_speed + // mutator_utilization = (1 / mutator_speed) / + // (1 / mutator_speed + 1 / gc_speed) + // mutator_utilization = gc_speed / (mutator_speed + gc_speed) + return gc_speed / (mutator_speed + gc_speed); +} + + +double Heap::YoungGenerationMutatorUtilization() { double mutator_speed = static_cast<double>( tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond()); double gc_speed = static_cast<double>( tracer()->ScavengeSpeedInBytesPerMillisecond(kForSurvivedObjects)); - if (mutator_speed == 0 || gc_speed == 0) return false; - double mutator_utilization = gc_speed / (mutator_speed + gc_speed); - return mutator_utilization > high_mutator_utilization; + double result = ComputeMutatorUtilization(mutator_speed, gc_speed); + if (FLAG_trace_mutator_utilization) { + PrintIsolate(isolate(), + "Young generation mutator utilization = %.3f (" + "mutator_speed=%.f, gc_speed=%.f)\n", + result, mutator_speed, gc_speed); + } + return result; } -bool Heap::HasLowOldGenerationAllocationRate() { - const double high_mutator_utilization = 0.993; +double Heap::OldGenerationMutatorUtilization() { double mutator_speed = static_cast<double>( tracer()->OldGenerationAllocationThroughputInBytesPerMillisecond()); double gc_speed = static_cast<double>( tracer()->CombinedMarkCompactSpeedInBytesPerMillisecond()); - if (mutator_speed == 0 || gc_speed == 0) return false; - double mutator_utilization = gc_speed / (mutator_speed + gc_speed); - return mutator_utilization > high_mutator_utilization; + double result = ComputeMutatorUtilization(mutator_speed, gc_speed); + if (FLAG_trace_mutator_utilization) { + PrintIsolate(isolate(), + "Old generation mutator utilization = %.3f (" + "mutator_speed=%.f, gc_speed=%.f)\n", + result, mutator_speed, gc_speed); + } + return result; +} + + +bool Heap::HasLowYoungGenerationAllocationRate() { + const double high_mutator_utilization = 0.993; + return YoungGenerationMutatorUtilization() > high_mutator_utilization; +} + + +bool Heap::HasLowOldGenerationAllocationRate() { + const double high_mutator_utilization = 0.993; + return OldGenerationMutatorUtilization() > high_mutator_utilization; } @@ -4808,7 +4854,13 @@ bool Heap::HasHighFragmentation(intptr_t used, intptr_t committed) { void Heap::ReduceNewSpaceSize() { - if (!FLAG_predictable && HasLowAllocationRate()) { + // TODO(ulan): Unify this constant with the similar constant in + // GCIdleTimeHandler once the change is merged to 4.5. + static const size_t kLowAllocationThroughput = 1000; + size_t allocation_throughput = + tracer()->CurrentAllocationThroughputInBytesPerMillisecond(); + if (FLAG_predictable || allocation_throughput == 0) return; + if (allocation_throughput < kLowAllocationThroughput) { new_space_.Shrink(); UncommitFromSpace(); } @@ -4867,6 +4919,32 @@ GCIdleTimeHandler::HeapState Heap::ComputeHeapState() { } +double Heap::AdvanceIncrementalMarking( + intptr_t step_size_in_bytes, double deadline_in_ms, + IncrementalMarking::StepActions step_actions) { + DCHECK(!incremental_marking()->IsStopped()); + + if (step_size_in_bytes == 0) { + step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( + static_cast<size_t>(GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs), + static_cast<size_t>( + tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond())); + } + + double remaining_time_in_ms = 0.0; + do { + incremental_marking()->Step( + step_size_in_bytes, step_actions.completion_action, + step_actions.force_marking, step_actions.force_completion); + remaining_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); + } while (remaining_time_in_ms >= + 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && + !incremental_marking()->IsComplete() && + !mark_compact_collector_.marking_deque()->IsEmpty()); + return remaining_time_in_ms; +} + + bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, GCIdleTimeHandler::HeapState heap_state, double deadline_in_ms) { @@ -4876,19 +4954,9 @@ bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, result = true; break; case DO_INCREMENTAL_MARKING: { - DCHECK(!incremental_marking()->IsStopped()); - double remaining_idle_time_in_ms = 0.0; - do { - incremental_marking()->Step( - action.parameter, IncrementalMarking::NO_GC_VIA_STACK_GUARD, - IncrementalMarking::FORCE_MARKING, - IncrementalMarking::DO_NOT_FORCE_COMPLETION); - remaining_idle_time_in_ms = - deadline_in_ms - MonotonicallyIncreasingTimeInMs(); - } while (remaining_idle_time_in_ms >= - 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && - !incremental_marking()->IsComplete() && - !mark_compact_collector_.marking_deque()->IsEmpty()); + const double remaining_idle_time_in_ms = + AdvanceIncrementalMarking(action.parameter, deadline_in_ms, + IncrementalMarking::IdleStepActions()); if (remaining_idle_time_in_ms > 0.0) { action.additional_work = TryFinalizeIdleIncrementalMarking( remaining_idle_time_in_ms, heap_state.size_of_objects, diff --git a/chromium/v8/src/heap/heap.h b/chromium/v8/src/heap/heap.h index 6fb429ae7d6..4c9e3ad1448 100644 --- a/chromium/v8/src/heap/heap.h +++ b/chromium/v8/src/heap/heap.h @@ -837,6 +837,21 @@ class Heap { // incremental steps. void StartIdleIncrementalMarking(); + // Starts incremental marking assuming incremental marking is currently + // stopped. + void StartIncrementalMarking(int gc_flags, + const GCCallbackFlags gc_callback_flags, + const char* reason = nullptr); + + // Performs incremental marking steps of step_size_in_bytes as long as + // deadline_ins_ms is not reached. step_size_in_bytes can be 0 to compute + // an estimate increment. Returns the remaining time that cannot be used + // for incremental marking anymore because a single step would exceed the + // deadline. + double AdvanceIncrementalMarking( + intptr_t step_size_in_bytes, double deadline_in_ms, + IncrementalMarking::StepActions step_actions); + inline void increment_scan_on_scavenge_pages() { scan_on_scavenge_pages_++; if (FLAG_gc_verbose) { @@ -2267,6 +2282,8 @@ class Heap { bool HasLowYoungGenerationAllocationRate(); bool HasLowOldGenerationAllocationRate(); + double YoungGenerationMutatorUtilization(); + double OldGenerationMutatorUtilization(); void ReduceNewSpaceSize(); diff --git a/chromium/v8/src/heap/incremental-marking.cc b/chromium/v8/src/heap/incremental-marking.cc index 22051eaab2d..58eb0aa4097 100644 --- a/chromium/v8/src/heap/incremental-marking.cc +++ b/chromium/v8/src/heap/incremental-marking.cc @@ -16,22 +16,34 @@ namespace v8 { namespace internal { +IncrementalMarking::StepActions IncrementalMarking::IdleStepActions() { + return StepActions(IncrementalMarking::NO_GC_VIA_STACK_GUARD, + IncrementalMarking::FORCE_MARKING, + IncrementalMarking::DO_NOT_FORCE_COMPLETION); +} + + IncrementalMarking::IncrementalMarking(Heap* heap) : heap_(heap), state_(STOPPED), + is_compacting_(false), steps_count_(0), old_generation_space_available_at_start_of_incremental_(0), old_generation_space_used_at_start_of_incremental_(0), + bytes_rescanned_(0), should_hurry_(false), marking_speed_(0), + bytes_scanned_(0), allocated_(0), + write_barriers_invoked_since_last_step_(0), idle_marking_delay_counter_(0), no_marking_scope_depth_(0), unscanned_bytes_of_large_object_(0), was_activated_(false), weak_closure_was_overapproximated_(false), weak_closure_approximation_rounds_(0), - request_type_(COMPLETE_MARKING) {} + request_type_(COMPLETE_MARKING), + gc_callback_flags_(kNoGCCallbackFlags) {} void IncrementalMarking::RecordWriteSlow(HeapObject* obj, Object** slot, @@ -472,9 +484,12 @@ static void PatchIncrementalMarkingRecordWriteStubs( } -void IncrementalMarking::Start(int mark_compact_flags) { +void IncrementalMarking::Start(int mark_compact_flags, + const GCCallbackFlags gc_callback_flags, + const char* reason) { if (FLAG_trace_incremental_marking) { - PrintF("[IncrementalMarking] Start\n"); + PrintF("[IncrementalMarking] Start (%s)\n", + (reason == nullptr) ? "unknown reason" : reason); } DCHECK(FLAG_incremental_marking); DCHECK(FLAG_incremental_marking_steps); @@ -484,6 +499,7 @@ void IncrementalMarking::Start(int mark_compact_flags) { ResetStepCounters(); + gc_callback_flags_ = gc_callback_flags; was_activated_ = true; if (!heap_->mark_compact_collector()->sweeping_in_progress()) { @@ -826,7 +842,7 @@ void IncrementalMarking::Epilogue() { void IncrementalMarking::OldSpaceStep(intptr_t allocated) { if (IsStopped() && ShouldActivateEvenWithoutIdleNotification()) { - Start(Heap::kNoGCFlags); + Start(Heap::kNoGCFlags, kNoGCCallbackFlags, "old space step"); } else { Step(allocated * kFastMarking / kInitialMarkingSpeed, GC_VIA_STACK_GUARD); } diff --git a/chromium/v8/src/heap/incremental-marking.h b/chromium/v8/src/heap/incremental-marking.h index 8fe341154fa..706e3323270 100644 --- a/chromium/v8/src/heap/incremental-marking.h +++ b/chromium/v8/src/heap/incremental-marking.h @@ -26,6 +26,21 @@ class IncrementalMarking { enum GCRequestType { COMPLETE_MARKING, OVERAPPROXIMATION }; + struct StepActions { + StepActions(CompletionAction complete_action_, + ForceMarkingAction force_marking_, + ForceCompletionAction force_completion_) + : completion_action(complete_action_), + force_marking(force_marking_), + force_completion(force_completion_) {} + + CompletionAction completion_action; + ForceMarkingAction force_marking; + ForceCompletionAction force_completion; + }; + + static StepActions IdleStepActions(); + explicit IncrementalMarking(Heap* heap); static void Initialize(); @@ -67,7 +82,9 @@ class IncrementalMarking { bool WasActivated(); - void Start(int mark_compact_flags); + void Start(int mark_compact_flags, + const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags, + const char* reason = nullptr); void Stop(); @@ -185,6 +202,8 @@ class IncrementalMarking { Heap* heap() const { return heap_; } + GCCallbackFlags CallbackFlags() const { return gc_callback_flags_; } + private: int64_t SpaceLeftInOldSpace(); @@ -243,6 +262,8 @@ class IncrementalMarking { GCRequestType request_type_; + GCCallbackFlags gc_callback_flags_; + DISALLOW_IMPLICIT_CONSTRUCTORS(IncrementalMarking); }; } diff --git a/chromium/v8/src/messages.h b/chromium/v8/src/messages.h index 4072300bf6a..5c3e867933c 100644 --- a/chromium/v8/src/messages.h +++ b/chromium/v8/src/messages.h @@ -173,6 +173,7 @@ class CallSite { T(ObserveCallbackFrozen, \ "Object.observe cannot deliver to a frozen function object") \ T(ObserveGlobalProxy, "% cannot be called on the global proxy object") \ + T(ObserveAccessChecked, "% cannot be called on access-checked objects") \ T(ObserveInvalidAccept, \ "Third argument to Object.observe must be an array of strings.") \ T(ObserveNonFunction, "Object.% cannot deliver to non-function") \ diff --git a/chromium/v8/src/object-observe.js b/chromium/v8/src/object-observe.js index 56859a1c97b..9c49fd38fb6 100644 --- a/chromium/v8/src/object-observe.js +++ b/chromium/v8/src/object-observe.js @@ -389,6 +389,8 @@ function ObjectObserve(object, callback, acceptList) { throw MakeTypeError(kObserveNonObject, "observe", "observe"); if (%IsJSGlobalProxy(object)) throw MakeTypeError(kObserveGlobalProxy, "observe"); + if (%IsAccessCheckNeeded(object)) + throw MakeTypeError(kObserveAccessChecked, "observe"); if (!IS_SPEC_FUNCTION(callback)) throw MakeTypeError(kObserveNonFunction, "observe"); if (ObjectIsFrozen(callback)) @@ -617,6 +619,8 @@ function ObjectGetNotifier(object) { throw MakeTypeError(kObserveNonObject, "getNotifier", "getNotifier"); if (%IsJSGlobalProxy(object)) throw MakeTypeError(kObserveGlobalProxy, "getNotifier"); + if (%IsAccessCheckNeeded(object)) + throw MakeTypeError(kObserveAccessChecked, "getNotifier"); if (ObjectIsFrozen(object)) return null; diff --git a/chromium/v8/src/runtime/runtime-object.cc b/chromium/v8/src/runtime/runtime-object.cc index da1ec4977be..9536ec0cc40 100644 --- a/chromium/v8/src/runtime/runtime-object.cc +++ b/chromium/v8/src/runtime/runtime-object.cc @@ -1435,5 +1435,13 @@ RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) { setter, attrs)); return isolate->heap()->undefined_value(); } + + +RUNTIME_FUNCTION(Runtime_IsAccessCheckNeeded) { + SealHandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_CHECKED(Object, object, 0); + return isolate->heap()->ToBoolean(object->IsAccessCheckNeeded()); +} } // namespace internal } // namespace v8 diff --git a/chromium/v8/src/runtime/runtime.h b/chromium/v8/src/runtime/runtime.h index da1ae40ba06..c4f74e7de11 100644 --- a/chromium/v8/src/runtime/runtime.h +++ b/chromium/v8/src/runtime/runtime.h @@ -483,7 +483,8 @@ namespace internal { F(IsStrong, 1, 1) \ F(ClassOf, 1, 1) \ F(DefineGetterPropertyUnchecked, 4, 1) \ - F(DefineSetterPropertyUnchecked, 4, 1) + F(DefineSetterPropertyUnchecked, 4, 1) \ + F(IsAccessCheckNeeded, 1, 1) #define FOR_EACH_INTRINSIC_OBSERVE(F) \ diff --git a/chromium/v8/src/scanner-character-streams.cc b/chromium/v8/src/scanner-character-streams.cc index 442bc75d6cc..eaaa9bc1f72 100644 --- a/chromium/v8/src/scanner-character-streams.cc +++ b/chromium/v8/src/scanner-character-streams.cc @@ -346,6 +346,7 @@ size_t ExternalStreamingStream::FillBuffer(size_t position) { current_data_length_ = source_stream_->GetMoreData(¤t_data_); current_data_offset_ = 0; bool data_ends = current_data_length_ == 0; + bookmark_data_is_from_current_data_ = false; // A caveat: a data chunk might end with bytes from an incomplete UTF-8 // character (the rest of the bytes will be in the next chunk). @@ -405,6 +406,15 @@ bool ExternalStreamingStream::SetBookmark() { // - buffer_[buffer_cursor_ .. buffer_end_] => bookmark_buffer_ // - current_data_[.._offset_ .. .._length_] => bookmark_data_ // - utf8_split_char_buffer_* => bookmark_utf8_split... + // + // To make sure we don't unnecessarily copy data, we also maintain + // whether bookmark_data_ contains a copy of the current current_data_ + // block. This is done with: + // - bookmark_data_is_from_current_data_ + // - bookmark_data_offset_: offset into bookmark_data_ + // + // Note that bookmark_data_is_from_current_data_ must be maintained + // whenever current_data_ is updated. bookmark_ = pos_; @@ -414,10 +424,21 @@ bool ExternalStreamingStream::SetBookmark() { CopyCharsUnsigned(bookmark_buffer_.start(), buffer_cursor_, buffer_length); size_t data_length = current_data_length_ - current_data_offset_; - bookmark_data_.Dispose(); - bookmark_data_ = Vector<uint8_t>::New(static_cast<int>(data_length)); - CopyBytes(bookmark_data_.start(), current_data_ + current_data_offset_, - data_length); + size_t bookmark_data_length = static_cast<size_t>(bookmark_data_.length()); + if (bookmark_data_is_from_current_data_ && + data_length < bookmark_data_length) { + // Fast case: bookmark_data_ was previously copied from the current + // data block, and we have enough data for this bookmark. + bookmark_data_offset_ = bookmark_data_length - data_length; + } else { + // Slow case: We need to copy current_data_. + bookmark_data_.Dispose(); + bookmark_data_ = Vector<uint8_t>::New(static_cast<int>(data_length)); + CopyBytes(bookmark_data_.start(), current_data_ + current_data_offset_, + data_length); + bookmark_data_is_from_current_data_ = true; + bookmark_data_offset_ = 0; + } bookmark_utf8_split_char_buffer_length_ = utf8_split_char_buffer_length_; for (size_t i = 0; i < utf8_split_char_buffer_length_; i++) { @@ -436,12 +457,14 @@ void ExternalStreamingStream::ResetToBookmark() { // bookmark_data_* => current_data_* // (current_data_ assumes ownership of its memory.) - uint8_t* data = new uint8_t[bookmark_data_.length()]; current_data_offset_ = 0; - current_data_length_ = bookmark_data_.length(); - CopyCharsUnsigned(data, bookmark_data_.begin(), bookmark_data_.length()); + current_data_length_ = bookmark_data_.length() - bookmark_data_offset_; + uint8_t* data = new uint8_t[current_data_length_]; + CopyCharsUnsigned(data, bookmark_data_.begin() + bookmark_data_offset_, + current_data_length_); delete[] current_data_; current_data_ = data; + bookmark_data_is_from_current_data_ = true; // bookmark_buffer_ needs to be copied to buffer_. CopyCharsUnsigned(buffer_, bookmark_buffer_.begin(), @@ -462,6 +485,7 @@ void ExternalStreamingStream::FlushCurrent() { current_data_ = NULL; current_data_length_ = 0; current_data_offset_ = 0; + bookmark_data_is_from_current_data_ = false; } diff --git a/chromium/v8/src/scanner-character-streams.h b/chromium/v8/src/scanner-character-streams.h index 582165710db..f3ee20463af 100644 --- a/chromium/v8/src/scanner-character-streams.h +++ b/chromium/v8/src/scanner-character-streams.h @@ -94,6 +94,8 @@ class ExternalStreamingStream : public BufferedUtf16CharacterStream { current_data_length_(0), utf8_split_char_buffer_length_(0), bookmark_(0), + bookmark_data_is_from_current_data_(false), + bookmark_data_offset_(0), bookmark_utf8_split_char_buffer_length_(0) {} virtual ~ExternalStreamingStream() { @@ -134,6 +136,8 @@ class ExternalStreamingStream : public BufferedUtf16CharacterStream { size_t bookmark_; Vector<uint16_t> bookmark_buffer_; Vector<uint8_t> bookmark_data_; + bool bookmark_data_is_from_current_data_; + size_t bookmark_data_offset_; uint8_t bookmark_utf8_split_char_buffer_[4]; size_t bookmark_utf8_split_char_buffer_length_; }; |