Skip to content

Instantly share code, notes, and snippets.

@tzafrir
Created January 31, 2016 11:59
Show Gist options
  • Select an option

  • Save tzafrir/e59eea40bdff03436f4a to your computer and use it in GitHub Desktop.

Select an option

Save tzafrir/e59eea40bdff03436f4a to your computer and use it in GitHub Desktop.

Revisions

  1. tzafrir created this gist Jan 31, 2016.
    97 changes: 97 additions & 0 deletions AddToOptimizedCodeMapInternal.cc
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,97 @@
    // from https://raw.githubusercontent.com/v8/v8/master/src/objects.cc

    void SharedFunctionInfo::AddToOptimizedCodeMapInternal(
    Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
    Handle<HeapObject> code, Handle<LiteralsArray> literals,
    BailoutId osr_ast_id) {
    Isolate* isolate = shared->GetIsolate();
    if (isolate->serializer_enabled()) return;
    DCHECK(*code == isolate->heap()->undefined_value() ||
    !shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code);
    DCHECK(*code == isolate->heap()->undefined_value() ||
    Code::cast(*code)->kind() == Code::OPTIMIZED_FUNCTION);
    DCHECK(native_context->IsNativeContext());
    STATIC_ASSERT(kEntryLength == 4);
    Handle<FixedArray> new_code_map;
    int entry;

    if (shared->OptimizedCodeMapIsCleared()) {
    new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
    new_code_map->set(kSharedCodeIndex, *isolate->factory()->empty_weak_cell(),
    SKIP_WRITE_BARRIER);
    entry = kEntriesStart;
    } else {
    Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
    entry = shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id);
    if (entry > kSharedCodeIndex) {
    // Found an existing context-specific entry. If the user provided valid
    // code, it must not contain any code.
    DCHECK(code->IsUndefined() ||
    WeakCell::cast(old_code_map->get(entry + kCachedCodeOffset))
    ->cleared());

    // Just set the code and literals to the entry.
    if (!code->IsUndefined()) {
    Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code);
    old_code_map->set(entry + kCachedCodeOffset, *code_cell);
    }
    Handle<WeakCell> literals_cell =
    isolate->factory()->NewWeakCell(literals);
    old_code_map->set(entry + kLiteralsOffset, *literals_cell);
    return;
    }

    // Can we reuse an entry?
    DCHECK(entry < kEntriesStart);
    int length = old_code_map->length();
    for (int i = kEntriesStart; i < length; i += kEntryLength) {
    if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) {
    new_code_map = old_code_map;
    entry = i;
    break;
    }
    }

    if (entry < kEntriesStart) {
    // Copy old optimized code map and append one new entry.
    new_code_map = isolate->factory()->CopyFixedArrayAndGrow(
    old_code_map, kEntryLength, TENURED);
    // TODO(mstarzinger): Temporary workaround. The allocation above might
    // have flushed the optimized code map and the copy we created is full of
    // holes. For now we just give up on adding the entry and pretend it got
    // flushed.
    if (shared->OptimizedCodeMapIsCleared()) return;
    entry = old_code_map->length();
    }
    }

    Handle<WeakCell> code_cell = code->IsUndefined()
    ? isolate->factory()->empty_weak_cell()
    : isolate->factory()->NewWeakCell(code);
    Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals);
    WeakCell* context_cell = native_context->self_weak_cell();

    new_code_map->set(entry + kContextOffset, context_cell);
    new_code_map->set(entry + kCachedCodeOffset, *code_cell);
    new_code_map->set(entry + kLiteralsOffset, *literals_cell);
    new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt()));

    #ifdef DEBUG
    for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
    WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset));
    DCHECK(cell->cleared() || cell->value()->IsNativeContext());
    cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset));
    DCHECK(cell->cleared() ||
    (cell->value()->IsCode() &&
    Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION));
    cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset));
    DCHECK(cell->cleared() || cell->value()->IsFixedArray());
    DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi());
    }
    #endif

    FixedArray* old_code_map = shared->optimized_code_map();
    if (old_code_map != *new_code_map) {
    shared->set_optimized_code_map(*new_code_map);
    }
    }