Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / v8 / src / ic-inl.h
1 // Copyright 2012 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 #ifndef V8_IC_INL_H_
6 #define V8_IC_INL_H_
7
8 #include "ic.h"
9
10 #include "compiler.h"
11 #include "debug.h"
12 #include "macro-assembler.h"
13
14 namespace v8 {
15 namespace internal {
16
17
18 Address IC::address() const {
19   // Get the address of the call.
20   Address result = Assembler::target_address_from_return_address(pc());
21
22   Debug* debug = isolate()->debug();
23   // First check if any break points are active if not just return the address
24   // of the call.
25   if (!debug->has_break_points()) return result;
26
27   // At least one break point is active perform additional test to ensure that
28   // break point locations are updated correctly.
29   if (debug->IsDebugBreak(Assembler::target_address_at(result,
30                                                        raw_constant_pool()))) {
31     // If the call site is a call to debug break then return the address in
32     // the original code instead of the address in the running code. This will
33     // cause the original code to be updated and keeps the breakpoint active in
34     // the running code.
35     Code* code = GetCode();
36     Code* original_code = GetOriginalCode();
37     intptr_t delta =
38         original_code->instruction_start() - code->instruction_start();
39     // Return the address in the original code. This is the place where
40     // the call which has been overwritten by the DebugBreakXXX resides
41     // and the place where the inline cache system should look.
42     return result + delta;
43   } else {
44     // No break point here just return the address of the call.
45     return result;
46   }
47 }
48
49
50 ConstantPoolArray* IC::constant_pool() const {
51   if (!FLAG_enable_ool_constant_pool) {
52     return NULL;
53   } else {
54     Handle<ConstantPoolArray> result = raw_constant_pool_;
55     Debug* debug = isolate()->debug();
56     // First check if any break points are active if not just return the
57     // original constant pool.
58     if (!debug->has_break_points()) return *result;
59
60     // At least one break point is active perform additional test to ensure that
61     // break point locations are updated correctly.
62     Address target = Assembler::target_address_from_return_address(pc());
63     if (debug->IsDebugBreak(
64             Assembler::target_address_at(target, raw_constant_pool()))) {
65       // If the call site is a call to debug break then we want to return the
66       // constant pool for the original code instead of the breakpointed code.
67       return GetOriginalCode()->constant_pool();
68     }
69     return *result;
70   }
71 }
72
73
74 ConstantPoolArray* IC::raw_constant_pool() const {
75   if (FLAG_enable_ool_constant_pool) {
76     return *raw_constant_pool_;
77   } else {
78     return NULL;
79   }
80 }
81
82
83 Code* IC::GetTargetAtAddress(Address address,
84                              ConstantPoolArray* constant_pool) {
85   // Get the target address of the IC.
86   Address target = Assembler::target_address_at(address, constant_pool);
87   // Convert target address to the code object. Code::GetCodeFromTargetAddress
88   // is safe for use during GC where the map might be marked.
89   Code* result = Code::GetCodeFromTargetAddress(target);
90   ASSERT(result->is_inline_cache_stub());
91   return result;
92 }
93
94
95 void IC::SetTargetAtAddress(Address address,
96                             Code* target,
97                             ConstantPoolArray* constant_pool) {
98   ASSERT(target->is_inline_cache_stub() || target->is_compare_ic_stub());
99   Heap* heap = target->GetHeap();
100   Code* old_target = GetTargetAtAddress(address, constant_pool);
101 #ifdef DEBUG
102   // STORE_IC and KEYED_STORE_IC use Code::extra_ic_state() to mark
103   // ICs as strict mode. The strict-ness of the IC must be preserved.
104   if (old_target->kind() == Code::STORE_IC ||
105       old_target->kind() == Code::KEYED_STORE_IC) {
106     ASSERT(StoreIC::GetStrictMode(old_target->extra_ic_state()) ==
107            StoreIC::GetStrictMode(target->extra_ic_state()));
108   }
109 #endif
110   Assembler::set_target_address_at(
111       address, constant_pool, target->instruction_start());
112   if (heap->gc_state() == Heap::MARK_COMPACT) {
113     heap->mark_compact_collector()->RecordCodeTargetPatch(address, target);
114   } else {
115     heap->incremental_marking()->RecordCodeTargetPatch(address, target);
116   }
117   PostPatching(address, target, old_target);
118 }
119
120
121 InlineCacheHolderFlag IC::GetCodeCacheForObject(Object* object) {
122   if (object->IsJSObject()) return OWN_MAP;
123
124   // If the object is a value, we use the prototype map for the cache.
125   ASSERT(object->IsString() || object->IsSymbol() ||
126          object->IsNumber() || object->IsFloat32x4() || object->IsFloat64x2() ||
127          object->IsInt32x4() || object->IsBoolean());
128   return PROTOTYPE_MAP;
129 }
130
131
132 HeapObject* IC::GetCodeCacheHolder(Isolate* isolate,
133                                    Object* object,
134                                    InlineCacheHolderFlag holder) {
135   if (object->IsSmi()) holder = PROTOTYPE_MAP;
136   Object* map_owner = holder == OWN_MAP
137       ? object : object->GetPrototype(isolate);
138   return HeapObject::cast(map_owner);
139 }
140
141
142 InlineCacheHolderFlag IC::GetCodeCacheFlag(HeapType* type) {
143   if (type->Is(HeapType::Boolean()) ||
144       type->Is(HeapType::Number()) ||
145       type->Is(HeapType::Float32x4()) ||
146       type->Is(HeapType::Float64x2()) ||
147       type->Is(HeapType::Int32x4()) ||
148       type->Is(HeapType::String()) ||
149       type->Is(HeapType::Symbol())) {
150     return PROTOTYPE_MAP;
151   }
152   return OWN_MAP;
153 }
154
155
156 Handle<Map> IC::GetCodeCacheHolder(InlineCacheHolderFlag flag,
157                                    HeapType* type,
158                                    Isolate* isolate) {
159   if (flag == PROTOTYPE_MAP) {
160     Context* context = isolate->context()->native_context();
161     JSFunction* constructor;
162     if (type->Is(HeapType::Boolean())) {
163       constructor = context->boolean_function();
164     } else if (type->Is(HeapType::Number())) {
165       constructor = context->number_function();
166     } else if (type->Is(HeapType::Float32x4())) {
167       constructor = context->float32x4_function();
168     } else if (type->Is(HeapType::Float64x2())) {
169       constructor = context->float64x2_function();
170     } else if (type->Is(HeapType::Int32x4())) {
171       constructor = context->int32x4_function();
172     } else if (type->Is(HeapType::String())) {
173       constructor = context->string_function();
174     } else {
175       ASSERT(type->Is(HeapType::Symbol()));
176       constructor = context->symbol_function();
177     }
178     return handle(JSObject::cast(constructor->instance_prototype())->map());
179   }
180   return TypeToMap(type, isolate);
181 }
182
183
184 } }  // namespace v8::internal
185
186 #endif  // V8_IC_INL_H_