void CodeFlusher::ProcessJSFunctionCandidates() {
Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
+ Object* undefined = isolate_->heap()->undefined_value();
JSFunction* candidate = jsfunction_candidates_head_;
JSFunction* next_candidate;
while (candidate != NULL) {
next_candidate = GetNextCandidate(candidate);
+ ClearNextCandidate(candidate, undefined);
SharedFunctionInfo* shared = candidate->shared();
if (!code_mark.Get()) {
shared->set_code(lazy_compile);
candidate->set_code(lazy_compile);
- } else {
- candidate->set_code(shared->code());
+ } else if (code == lazy_compile) {
+ candidate->set_code(lazy_compile);
}
// We are in the middle of a GC cycle so the write barrier in the code
SharedFunctionInfo* next_candidate;
while (candidate != NULL) {
next_candidate = GetNextCandidate(candidate);
- SetNextCandidate(candidate, NULL);
+ ClearNextCandidate(candidate);
Code* code = candidate->code();
MarkBit code_mark = Marking::MarkBitFrom(code);
void AddCandidate(JSFunction* function) {
ASSERT(function->code() == function->shared()->code());
+ ASSERT(function->next_function_link()->IsUndefined());
SetNextCandidate(function, jsfunction_candidates_head_);
jsfunction_candidates_head_ = function;
}
void ProcessJSFunctionCandidates();
void ProcessSharedFunctionInfoCandidates();
- static JSFunction** GetNextCandidateField(JSFunction* candidate) {
- return reinterpret_cast<JSFunction**>(
- candidate->address() + JSFunction::kCodeEntryOffset);
- }
-
static JSFunction* GetNextCandidate(JSFunction* candidate) {
- return *GetNextCandidateField(candidate);
+ Object* next_candidate = candidate->next_function_link();
+ return reinterpret_cast<JSFunction*>(next_candidate);
}
static void SetNextCandidate(JSFunction* candidate,
JSFunction* next_candidate) {
- *GetNextCandidateField(candidate) = next_candidate;
+ candidate->set_next_function_link(next_candidate);
}
- static SharedFunctionInfo** GetNextCandidateField(
- SharedFunctionInfo* candidate) {
- Code* code = candidate->code();
- return reinterpret_cast<SharedFunctionInfo**>(
- code->address() + Code::kGCMetadataOffset);
+ static void ClearNextCandidate(JSFunction* candidate, Object* undefined) {
+ ASSERT(undefined->IsUndefined());
+ candidate->set_next_function_link(undefined, SKIP_WRITE_BARRIER);
}
static SharedFunctionInfo* GetNextCandidate(SharedFunctionInfo* candidate) {
- return reinterpret_cast<SharedFunctionInfo*>(
- candidate->code()->gc_metadata());
+ Object* next_candidate = candidate->code()->gc_metadata();
+ return reinterpret_cast<SharedFunctionInfo*>(next_candidate);
}
static void SetNextCandidate(SharedFunctionInfo* candidate,
candidate->code()->set_gc_metadata(next_candidate);
}
+ static void ClearNextCandidate(SharedFunctionInfo* candidate) {
+ candidate->code()->set_gc_metadata(NULL, SKIP_WRITE_BARRIER);
+ }
+
Isolate* isolate_;
JSFunction* jsfunction_candidates_head_;
SharedFunctionInfo* shared_function_info_candidates_head_;
// Set the code of the target function.
target->ReplaceCode(source_shared->code());
+ ASSERT(target->next_function_link()->IsUndefined());
// Make sure we get a fresh copy of the literal vector to avoid cross
// context contamination.
}
target->set_context(*context);
target->set_literals(*literals);
- target->set_next_function_link(isolate->heap()->undefined_value());
if (isolate->logger()->is_logging_code_events() ||
CpuProfiler::is_profiling(isolate)) {