8ed94640dec56d4f6defde61430f7d2d478f3740
[platform/framework/web/crosswalk.git] / src / v8 / src / ic-inl.h
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_IC_INL_H_
29 #define V8_IC_INL_H_
30
31 #include "ic.h"
32
33 #include "compiler.h"
34 #include "debug.h"
35 #include "macro-assembler.h"
36
37 namespace v8 {
38 namespace internal {
39
40
41 Address IC::address() const {
42   // Get the address of the call.
43   Address result = Assembler::target_address_from_return_address(pc());
44
45 #ifdef ENABLE_DEBUGGER_SUPPORT
46   Debug* debug = isolate()->debug();
47   // First check if any break points are active if not just return the address
48   // of the call.
49   if (!debug->has_break_points()) return result;
50
51   // At least one break point is active perform additional test to ensure that
52   // break point locations are updated correctly.
53   if (debug->IsDebugBreak(Assembler::target_address_at(result))) {
54     // If the call site is a call to debug break then return the address in
55     // the original code instead of the address in the running code. This will
56     // cause the original code to be updated and keeps the breakpoint active in
57     // the running code.
58     return OriginalCodeAddress();
59   } else {
60     // No break point here just return the address of the call.
61     return result;
62   }
63 #else
64   return result;
65 #endif
66 }
67
68
69 Code* IC::GetTargetAtAddress(Address address) {
70   // Get the target address of the IC.
71   Address target = Assembler::target_address_at(address);
72   // Convert target address to the code object. Code::GetCodeFromTargetAddress
73   // is safe for use during GC where the map might be marked.
74   Code* result = Code::GetCodeFromTargetAddress(target);
75   ASSERT(result->is_inline_cache_stub());
76   return result;
77 }
78
79
80 void IC::SetTargetAtAddress(Address address, Code* target) {
81   ASSERT(target->is_inline_cache_stub() || target->is_compare_ic_stub());
82   Heap* heap = target->GetHeap();
83   Code* old_target = GetTargetAtAddress(address);
84 #ifdef DEBUG
85   // STORE_IC and KEYED_STORE_IC use Code::extra_ic_state() to mark
86   // ICs as strict mode. The strict-ness of the IC must be preserved.
87   if (old_target->kind() == Code::STORE_IC ||
88       old_target->kind() == Code::KEYED_STORE_IC) {
89     ASSERT(StoreIC::GetStrictMode(old_target->extra_ic_state()) ==
90            StoreIC::GetStrictMode(target->extra_ic_state()));
91   }
92 #endif
93   Assembler::set_target_address_at(address, target->instruction_start());
94   if (heap->gc_state() == Heap::MARK_COMPACT) {
95     heap->mark_compact_collector()->RecordCodeTargetPatch(address, target);
96   } else {
97     heap->incremental_marking()->RecordCodeTargetPatch(address, target);
98   }
99   PostPatching(address, target, old_target);
100 }
101
102
103 InlineCacheHolderFlag IC::GetCodeCacheForObject(Object* object) {
104   if (object->IsJSObject()) return OWN_MAP;
105
106   // If the object is a value, we use the prototype map for the cache.
107   ASSERT(object->IsString() || object->IsSymbol() ||
108          object->IsNumber() || object->IsFloat32x4() ||
109          object->IsInt32x4() || object->IsBoolean());
110   return PROTOTYPE_MAP;
111 }
112
113
114 HeapObject* IC::GetCodeCacheHolder(Isolate* isolate,
115                                    Object* object,
116                                    InlineCacheHolderFlag holder) {
117   if (object->IsSmi()) holder = PROTOTYPE_MAP;
118   Object* map_owner = holder == OWN_MAP
119       ? object : object->GetPrototype(isolate);
120   return HeapObject::cast(map_owner);
121 }
122
123
124 InlineCacheHolderFlag IC::GetCodeCacheFlag(HeapType* type) {
125   if (type->Is(HeapType::Boolean()) ||
126       type->Is(HeapType::Number()) ||
127       type->Is(HeapType::Float32x4()) ||
128       type->Is(HeapType::Int32x4()) ||
129       type->Is(HeapType::String()) ||
130       type->Is(HeapType::Symbol())) {
131     return PROTOTYPE_MAP;
132   }
133   return OWN_MAP;
134 }
135
136
137 Handle<Map> IC::GetCodeCacheHolder(InlineCacheHolderFlag flag,
138                                    HeapType* type,
139                                    Isolate* isolate) {
140   if (flag == PROTOTYPE_MAP) {
141     Context* context = isolate->context()->native_context();
142     JSFunction* constructor;
143     if (type->Is(HeapType::Boolean())) {
144       constructor = context->boolean_function();
145     } else if (type->Is(HeapType::Number())) {
146       constructor = context->number_function();
147     } else if (type->Is(HeapType::Float32x4())) {
148       constructor = context->float32x4_function();
149     } else if (type->Is(HeapType::Int32x4())) {
150       constructor = context->int32x4_function();
151     } else if (type->Is(HeapType::String())) {
152       constructor = context->string_function();
153     } else {
154       ASSERT(type->Is(HeapType::Symbol()));
155       constructor = context->symbol_function();
156     }
157     return handle(JSObject::cast(constructor->instance_prototype())->map());
158   }
159   return TypeToMap(type, isolate);
160 }
161
162
163 } }  // namespace v8::internal
164
165 #endif  // V8_IC_INL_H_