• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetDummyCode(Isolate * isolate)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 
TEST(CodeCache)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