| Index: src/runtime-profiler.cc | 
| =================================================================== | 
| --- src/runtime-profiler.cc	(revision 6981) | 
| +++ src/runtime-profiler.cc	(working copy) | 
| @@ -35,6 +35,7 @@ | 
| #include "deoptimizer.h" | 
| #include "execution.h" | 
| #include "global-handles.h" | 
| +#include "mark-compact.h" | 
| #include "scopeinfo.h" | 
| #include "top.h" | 
|  | 
| @@ -100,11 +101,6 @@ | 
| // The ratio of ticks spent in JS code in percent. | 
| static Atomic32 js_ratio; | 
|  | 
| -// The JSFunctions in the sampler window are not GC safe. Old-space | 
| -// pointers are not cleared during mark-sweep collection and therefore | 
| -// the window might contain stale pointers. The window is updated on | 
| -// scavenges and (parts of it) cleared on mark-sweep and | 
| -// mark-sweep-compact. | 
| static Object* sampler_window[kSamplerWindowSize] = { NULL, }; | 
| static int sampler_window_position = 0; | 
| static int sampler_window_weight[kSamplerWindowSize] = { 0, }; | 
| @@ -134,7 +130,6 @@ | 
|  | 
|  | 
| static bool IsOptimizable(JSFunction* function) { | 
| -  if (Heap::InNewSpace(function)) return false; | 
| Code* code = function->code(); | 
| return code->kind() == Code::FUNCTION && code->optimizable(); | 
| } | 
| @@ -208,16 +203,6 @@ | 
| } | 
|  | 
|  | 
| -static void ClearSampleBufferNewSpaceEntries() { | 
| -  for (int i = 0; i < kSamplerWindowSize; i++) { | 
| -    if (Heap::InNewSpace(sampler_window[i])) { | 
| -      sampler_window[i] = NULL; | 
| -      sampler_window_weight[i] = 0; | 
| -    } | 
| -  } | 
| -} | 
| - | 
| - | 
| static int LookupSample(JSFunction* function) { | 
| int weight = 0; | 
| for (int i = 0; i < kSamplerWindowSize; i++) { | 
| @@ -372,24 +357,6 @@ | 
| } | 
|  | 
|  | 
| -void RuntimeProfiler::MarkCompactPrologue(bool is_compacting) { | 
| -  if (is_compacting) { | 
| -    // Clear all samples before mark-sweep-compact because every | 
| -    // function might move. | 
| -    ClearSampleBuffer(); | 
| -  } else { | 
| -    // Clear only new space entries on mark-sweep since none of the | 
| -    // old-space functions will move. | 
| -    ClearSampleBufferNewSpaceEntries(); | 
| -  } | 
| -} | 
| - | 
| - | 
| -bool IsEqual(void* first, void* second) { | 
| -  return first == second; | 
| -} | 
| - | 
| - | 
| void RuntimeProfiler::Setup() { | 
| ClearSampleBuffer(); | 
| // If the ticker hasn't already started, make sure to do so to get | 
| @@ -411,16 +378,44 @@ | 
| } | 
|  | 
|  | 
| -Object** RuntimeProfiler::SamplerWindowAddress() { | 
| -  return sampler_window; | 
| +int RuntimeProfiler::SamplerWindowSize() { | 
| +  return kSamplerWindowSize; | 
| } | 
|  | 
|  | 
| -int RuntimeProfiler::SamplerWindowSize() { | 
| -  return kSamplerWindowSize; | 
| +// Update the pointers in the sampler window after a GC. | 
| +void RuntimeProfiler::UpdateSamplesAfterScavenge() { | 
| +  for (int i = 0; i < kSamplerWindowSize; i++) { | 
| +    Object* function = sampler_window[i]; | 
| +    if (function != NULL && Heap::InNewSpace(function)) { | 
| +      MapWord map_word = HeapObject::cast(function)->map_word(); | 
| +      if (map_word.IsForwardingAddress()) { | 
| +        sampler_window[i] = map_word.ToForwardingAddress(); | 
| +      } else { | 
| +        sampler_window[i] = NULL; | 
| +      } | 
| +    } | 
| +  } | 
| } | 
|  | 
|  | 
| +void RuntimeProfiler::RemoveDeadSamples() { | 
| +  for (int i = 0; i < kSamplerWindowSize; i++) { | 
| +    Object* function = sampler_window[i]; | 
| +    if (function != NULL && !HeapObject::cast(function)->IsMarked()) { | 
| +      sampler_window[i] = NULL; | 
| +    } | 
| +  } | 
| +} | 
| + | 
| + | 
| +void RuntimeProfiler::UpdateSamplesAfterCompact(ObjectVisitor* visitor) { | 
| +  for (int i = 0; i < kSamplerWindowSize; i++) { | 
| +    visitor->VisitPointer(&sampler_window[i]); | 
| +  } | 
| +} | 
| + | 
| + | 
| bool RuntimeProfilerRateLimiter::SuspendIfNecessary() { | 
| #ifdef ENABLE_LOGGING_AND_PROFILING | 
| static const int kNonJSTicksThreshold = 100; | 
|  |