blob: 79d9cfc083878a352f9a9b97eec13e95b0a6dc92 [file] [log] [blame]
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001// Copyright 2006-2008 Google Inc. 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_FRAMES_INL_H_
29#define V8_FRAMES_INL_H_
30
31#include "frames.h"
32#if defined(ARM) || defined (__arm__) || defined(__thumb__)
33#include "frames-arm.h"
34#else
35#include "frames-ia32.h"
36#endif
37
38
39namespace v8 { namespace internal {
40
41
42inline Address StackHandler::address() const {
43 // NOTE: There's an obvious problem with the address of the NULL
44 // stack handler. Right now, it benefits us that the subtraction
45 // leads to a very high address (above everything else on the
46 // stack), but maybe we should stop relying on it?
47 const int displacement = StackHandlerConstants::kAddressDisplacement;
48 Address address = reinterpret_cast<Address>(const_cast<StackHandler*>(this));
49 return address + displacement;
50}
51
52
53inline StackHandler* StackHandler::next() const {
54 const int offset = StackHandlerConstants::kNextOffset;
55 return FromAddress(Memory::Address_at(address() + offset));
56}
57
58
59inline bool StackHandler::includes(Address address) const {
60 Address start = this->address();
61 Address end = start + StackHandlerConstants::kSize;
62 return start <= address && address <= end;
63}
64
65
66inline void StackHandler::Iterate(ObjectVisitor* v) const {
67 // Stack handlers do not contain any pointers that need to be
68 // traversed. The only field that have to worry about is the code
69 // field which is unused and should always be uninitialized.
70#ifdef DEBUG
71 const int offset = StackHandlerConstants::kCodeOffset;
72 Object* code = Memory::Object_at(address() + offset);
73 ASSERT(Smi::cast(code)->value() == StackHandler::kCodeNotPresent);
74#endif
75}
76
77
78inline StackHandler* StackHandler::FromAddress(Address address) {
79 return reinterpret_cast<StackHandler*>(address);
80}
81
82
83inline StackHandler::State StackHandler::state() const {
84 const int offset = StackHandlerConstants::kStateOffset;
85 return static_cast<State>(Memory::int_at(address() + offset));
86}
87
88
89inline Address StackHandler::pc() const {
90 const int offset = StackHandlerConstants::kPCOffset;
91 return Memory::Address_at(address() + offset);
92}
93
94
95inline void StackHandler::set_pc(Address value) {
96 const int offset = StackHandlerConstants::kPCOffset;
97 Memory::Address_at(address() + offset) = value;
98}
99
100
101inline StackHandler* StackFrame::top_handler() const {
102 return iterator_->handler();
103}
104
105
106inline Object** StackFrame::top_register_buffer() const {
107 return iterator_->register_buffer();
108}
109
110
111inline Object* StandardFrame::GetExpression(int index) const {
112 return Memory::Object_at(GetExpressionAddress(index));
113}
114
115
116inline void StandardFrame::SetExpression(int index, Object* value) {
117 Memory::Object_at(GetExpressionAddress(index)) = value;
118}
119
120
121inline Object* StandardFrame::context() const {
122 const int offset = StandardFrameConstants::kContextOffset;
123 return Memory::Object_at(fp() + offset);
124}
125
126
127inline Address StandardFrame::caller_sp() const {
128 return pp();
129}
130
131
132inline Address StandardFrame::caller_fp() const {
133 return Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset);
134}
135
136
137inline Address StandardFrame::caller_pc() const {
138 return Memory::Address_at(ComputePCAddress(fp()));
139}
140
141
142inline Address StandardFrame::ComputePCAddress(Address fp) {
143 return fp + StandardFrameConstants::kCallerPCOffset;
144}
145
146
147inline bool StandardFrame::IsArgumentsAdaptorFrame(Address fp) {
148 int context = Memory::int_at(fp + StandardFrameConstants::kContextOffset);
149 return context == ArgumentsAdaptorFrame::SENTINEL;
150}
151
152
153inline bool StandardFrame::IsConstructTrampolineFrame(Address pc) {
154 return Builtins::builtin(Builtins::JSConstructCall)->contains(pc);
155}
156
157
158inline Object* JavaScriptFrame::receiver() const {
159 const int offset = JavaScriptFrameConstants::kReceiverOffset;
160 return Memory::Object_at(pp() + offset);
161}
162
163
164inline void JavaScriptFrame::set_receiver(Object* value) {
165 const int offset = JavaScriptFrameConstants::kReceiverOffset;
166 Memory::Object_at(pp() + offset) = value;
167}
168
169
170inline bool JavaScriptFrame::has_adapted_arguments() const {
171 return IsArgumentsAdaptorFrame(caller_fp());
172}
173
174
175inline bool InternalFrame::is_construct_trampoline() const {
176 // TODO(1233795): This doesn't work when the stack frames have been
177 // cooked. We need to find another way of identifying construct
178 // trampoline frames possibly by manipulating the context field like
179 // we do for argument adaptor frames.
180 return IsConstructTrampolineFrame(pc());
181}
182
183
184inline JavaScriptFrame* JavaScriptFrameIterator::frame() const {
185 // TODO(1233797): The frame hierarchy needs to change. It's
186 // problematic that we can't use the safe-cast operator to cast to
187 // the JavaScript frame type, because we may encounter arguments
188 // adaptor frames.
189 StackFrame* frame = iterator_.frame();
190 ASSERT(frame->is_java_script() || frame->is_arguments_adaptor());
191 return static_cast<JavaScriptFrame*>(frame);
192}
193
194
195} } // namespace v8::internal
196
197#endif // V8_FRAMES_INL_H_