Home | History | Annotate | Download | only in cctest
      1 // Copyright 2016 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/v8.h"
      6 
      7 #include "src/list.h"
      8 #include "src/objects.h"
      9 #include "test/cctest/cctest.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 namespace {
     15 
     16 static Handle<Code> GetDummyCode(Isolate* isolate) {
     17   CodeDesc desc = {nullptr,   // buffer
     18                    0,         // buffer_size
     19                    0,         // instr_size
     20                    0,         // reloc_size
     21                    0,         // constant_pool_size
     22                    nullptr,   // unwinding_info
     23                    0,         // unwinding_info_size
     24                    nullptr};  // origin
     25   Code::Flags flags =
     26       Code::ComputeFlags(Code::LOAD_IC, kNoExtraICState, kCacheOnReceiver);
     27   Handle<Code> self_ref;
     28   return isolate->factory()->NewCode(desc, flags, self_ref);
     29 }
     30 
     31 }  // namespace
     32 
     33 TEST(CodeCache) {
     34   CcTest::InitializeVM();
     35   Isolate* isolate = CcTest::i_isolate();
     36   Factory* factory = isolate->factory();
     37   HandleScope handle_scope(isolate);
     38 
     39   Handle<Map> map =
     40       factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize, FAST_ELEMENTS);
     41 
     42   // This number should be large enough to cause the code cache to use its
     43   // hash table storage format.
     44   static const int kEntries = 150;
     45 
     46   // Prepare name/code pairs.
     47   List<Handle<Name>> names(kEntries);
     48   List<Handle<Code>> codes(kEntries);
     49   for (int i = 0; i < kEntries; i++) {
     50     names.Add(isolate->factory()->NewSymbol());
     51     codes.Add(GetDummyCode(isolate));
     52   }
     53   Handle<Name> bad_name = isolate->factory()->NewSymbol();
     54   Code::Flags bad_flags =
     55       Code::ComputeFlags(Code::LOAD_IC, kNoExtraICState, kCacheOnPrototype);
     56   DCHECK(bad_flags != codes[0]->flags());
     57 
     58   // Cache name/code pairs.
     59   for (int i = 0; i < kEntries; i++) {
     60     Handle<Name> name = names.at(i);
     61     Handle<Code> code = codes.at(i);
     62     Map::UpdateCodeCache(map, name, code);
     63     CHECK_EQ(*code, map->LookupInCodeCache(*name, code->flags()));
     64     CHECK_NULL(map->LookupInCodeCache(*name, bad_flags));
     65   }
     66   CHECK_NULL(map->LookupInCodeCache(*bad_name, bad_flags));
     67 
     68   // Check that lookup works not only right after storing.
     69   for (int i = 0; i < kEntries; i++) {
     70     Handle<Name> name = names.at(i);
     71     Handle<Code> code = codes.at(i);
     72     CHECK_EQ(*code, map->LookupInCodeCache(*name, code->flags()));
     73   }
     74 }
     75 
     76 }  // namespace internal
     77 }  // namespace v8
     78