| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "frames-inl.h" | 30 #include "frames-inl.h" |
| 31 #include "mark-compact.h" |
| 31 #include "scopeinfo.h" | 32 #include "scopeinfo.h" |
| 32 #include "string-stream.h" | 33 #include "string-stream.h" |
| 33 #include "top.h" | 34 #include "top.h" |
| 34 #include "zone-inl.h" | 35 #include "zone-inl.h" |
| 35 | 36 |
| 36 namespace v8 { namespace internal { | 37 namespace v8 { namespace internal { |
| 37 | 38 |
| 38 // Iterator that supports traversing the stack handlers of a | 39 // Iterator that supports traversing the stack handlers of a |
| 39 // particular frame. Needs to know the top of the handler chain. | 40 // particular frame. Needs to know the top of the handler chain. |
| 40 class StackHandlerIterator BASE_EMBEDDED { | 41 class StackHandlerIterator BASE_EMBEDDED { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 void JavaScriptFrameIterator::Reset() { | 156 void JavaScriptFrameIterator::Reset() { |
| 156 iterator_.Reset(); | 157 iterator_.Reset(); |
| 157 Advance(); | 158 Advance(); |
| 158 } | 159 } |
| 159 | 160 |
| 160 | 161 |
| 161 // ------------------------------------------------------------------------- | 162 // ------------------------------------------------------------------------- |
| 162 | 163 |
| 163 | 164 |
| 164 void StackHandler::Cook(Code* code) { | 165 void StackHandler::Cook(Code* code) { |
| 166 ASSERT(MarkCompactCollector::IsCompacting()); |
| 165 ASSERT(code->contains(pc())); | 167 ASSERT(code->contains(pc())); |
| 166 set_pc(AddressFrom<Address>(pc() - code->instruction_start())); | 168 set_pc(AddressFrom<Address>(pc() - code->instruction_start())); |
| 167 } | 169 } |
| 168 | 170 |
| 169 | 171 |
| 170 void StackHandler::Uncook(Code* code) { | 172 void StackHandler::Uncook(Code* code) { |
| 173 ASSERT(MarkCompactCollector::IsCompacting()); |
| 171 set_pc(code->instruction_start() + OffsetFrom(pc())); | 174 set_pc(code->instruction_start() + OffsetFrom(pc())); |
| 172 ASSERT(code->contains(pc())); | 175 ASSERT(code->contains(pc())); |
| 173 } | 176 } |
| 174 | 177 |
| 175 | 178 |
| 176 // ------------------------------------------------------------------------- | 179 // ------------------------------------------------------------------------- |
| 177 | 180 |
| 178 | 181 |
| 179 bool StackFrame::HasHandler() const { | 182 bool StackFrame::HasHandler() const { |
| 180 StackHandlerIterator it(this, top_handler()); | 183 StackHandlerIterator it(this, top_handler()); |
| 181 return !it.done(); | 184 return !it.done(); |
| 182 } | 185 } |
| 183 | 186 |
| 184 | 187 |
| 185 void StackFrame::CookFramesForThread(ThreadLocalTop* thread) { | 188 void StackFrame::CookFramesForThread(ThreadLocalTop* thread) { |
| 189 // Only cooking frames when the collector is compacting and thus moving code |
| 190 // around. |
| 191 ASSERT(MarkCompactCollector::IsCompacting()); |
| 186 ASSERT(!thread->stack_is_cooked()); | 192 ASSERT(!thread->stack_is_cooked()); |
| 187 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { | 193 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { |
| 188 it.frame()->Cook(); | 194 it.frame()->Cook(); |
| 189 } | 195 } |
| 190 thread->set_stack_is_cooked(true); | 196 thread->set_stack_is_cooked(true); |
| 191 } | 197 } |
| 192 | 198 |
| 193 | 199 |
| 194 void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) { | 200 void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) { |
| 201 // Only uncooking frames when the collector is compacting and thus moving code |
| 202 // around. |
| 203 ASSERT(MarkCompactCollector::IsCompacting()); |
| 195 ASSERT(thread->stack_is_cooked()); | 204 ASSERT(thread->stack_is_cooked()); |
| 196 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { | 205 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { |
| 197 it.frame()->Uncook(); | 206 it.frame()->Uncook(); |
| 198 } | 207 } |
| 199 thread->set_stack_is_cooked(false); | 208 thread->set_stack_is_cooked(false); |
| 200 } | 209 } |
| 201 | 210 |
| 202 | 211 |
| 203 void StackFrame::Cook() { | 212 void StackFrame::Cook() { |
| 204 Code* code = FindCode(); | 213 Code* code = this->code(); |
| 205 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { | 214 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { |
| 206 it.handler()->Cook(code); | 215 it.handler()->Cook(code); |
| 207 } | 216 } |
| 208 ASSERT(code->contains(pc())); | 217 ASSERT(code->contains(pc())); |
| 209 set_pc(AddressFrom<Address>(pc() - code->instruction_start())); | 218 set_pc(AddressFrom<Address>(pc() - code->instruction_start())); |
| 210 } | 219 } |
| 211 | 220 |
| 212 | 221 |
| 213 void StackFrame::Uncook() { | 222 void StackFrame::Uncook() { |
| 214 Code* code = FindCode(); | 223 Code* code = this->code(); |
| 215 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { | 224 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { |
| 216 it.handler()->Uncook(code); | 225 it.handler()->Uncook(code); |
| 217 } | 226 } |
| 218 set_pc(code->instruction_start() + OffsetFrom(pc())); | 227 set_pc(code->instruction_start() + OffsetFrom(pc())); |
| 219 ASSERT(code->contains(pc())); | 228 ASSERT(code->contains(pc())); |
| 220 } | 229 } |
| 221 | 230 |
| 222 | 231 |
| 223 Code* EntryFrame::FindCode() const { | 232 Code* EntryFrame::code() const { |
| 224 return Heap::js_entry_code(); | 233 return Heap::js_entry_code(); |
| 225 } | 234 } |
| 226 | 235 |
| 227 | 236 |
| 228 StackFrame::Type EntryFrame::GetCallerState(State* state) const { | 237 StackFrame::Type EntryFrame::GetCallerState(State* state) const { |
| 229 const int offset = EntryFrameConstants::kCallerFPOffset; | 238 const int offset = EntryFrameConstants::kCallerFPOffset; |
| 230 Address fp = Memory::Address_at(this->fp() + offset); | 239 Address fp = Memory::Address_at(this->fp() + offset); |
| 231 return ExitFrame::GetStateForFramePointer(fp, state); | 240 return ExitFrame::GetStateForFramePointer(fp, state); |
| 232 } | 241 } |
| 233 | 242 |
| 234 | 243 |
| 235 Code* EntryConstructFrame::FindCode() const { | 244 Code* EntryConstructFrame::code() const { |
| 236 return Heap::js_construct_entry_code(); | 245 return Heap::js_construct_entry_code(); |
| 237 } | 246 } |
| 238 | 247 |
| 239 | 248 |
| 240 Code* ExitFrame::FindCode() const { | 249 Code* ExitFrame::code() const { |
| 241 return Heap::c_entry_code(); | 250 return Heap::c_entry_code(); |
| 242 } | 251 } |
| 243 | 252 |
| 244 | 253 |
| 245 StackFrame::Type ExitFrame::GetCallerState(State* state) const { | 254 StackFrame::Type ExitFrame::GetCallerState(State* state) const { |
| 246 // Setup the caller state. | 255 // Setup the caller state. |
| 247 state->sp = pp(); | 256 state->sp = pp(); |
| 248 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); | 257 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); |
| 249 state->pc_address | 258 state->pc_address |
| 250 = reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset); | 259 = reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset); |
| 251 return ComputeType(state); | 260 return ComputeType(state); |
| 252 } | 261 } |
| 253 | 262 |
| 254 | 263 |
| 255 Address ExitFrame::GetCallerStackPointer() const { | 264 Address ExitFrame::GetCallerStackPointer() const { |
| 256 return fp() + ExitFrameConstants::kPPDisplacement; | 265 return fp() + ExitFrameConstants::kPPDisplacement; |
| 257 } | 266 } |
| 258 | 267 |
| 259 | 268 |
| 260 Code* ExitDebugFrame::FindCode() const { | 269 Code* ExitDebugFrame::code() const { |
| 261 return Heap::c_entry_debug_break_code(); | 270 return Heap::c_entry_debug_break_code(); |
| 262 } | 271 } |
| 263 | 272 |
| 264 | 273 |
| 265 Address StandardFrame::GetExpressionAddress(int n) const { | 274 Address StandardFrame::GetExpressionAddress(int n) const { |
| 266 const int offset = StandardFrameConstants::kExpressionsOffset; | 275 const int offset = StandardFrameConstants::kExpressionsOffset; |
| 267 return fp() + offset - n * kPointerSize; | 276 return fp() + offset - n * kPointerSize; |
| 268 } | 277 } |
| 269 | 278 |
| 270 | 279 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 bool JavaScriptFrame::IsConstructor() const { | 322 bool JavaScriptFrame::IsConstructor() const { |
| 314 Address fp = caller_fp(); | 323 Address fp = caller_fp(); |
| 315 if (has_adapted_arguments()) { | 324 if (has_adapted_arguments()) { |
| 316 // Skip the arguments adaptor frame and look at the real caller. | 325 // Skip the arguments adaptor frame and look at the real caller. |
| 317 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); | 326 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); |
| 318 } | 327 } |
| 319 return IsConstructFrame(fp); | 328 return IsConstructFrame(fp); |
| 320 } | 329 } |
| 321 | 330 |
| 322 | 331 |
| 323 Code* ArgumentsAdaptorFrame::FindCode() const { | 332 Code* JavaScriptFrame::code() const { |
| 333 JSFunction* function = JSFunction::cast(this->function()); |
| 334 return function->shared()->code(); |
| 335 } |
| 336 |
| 337 |
| 338 Code* ArgumentsAdaptorFrame::code() const { |
| 324 return Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline); | 339 return Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline); |
| 325 } | 340 } |
| 326 | 341 |
| 327 | 342 |
| 328 Code* InternalFrame::FindCode() const { | 343 Code* InternalFrame::code() const { |
| 329 const int offset = InternalFrameConstants::kCodeOffset; | 344 const int offset = InternalFrameConstants::kCodeOffset; |
| 330 Object* code = Memory::Object_at(fp() + offset); | 345 Object* code = Memory::Object_at(fp() + offset); |
| 331 if (code == NULL) { | |
| 332 // The code object isn't set; find it and set it. | |
| 333 code = Heap::FindCodeObject(pc()); | |
| 334 ASSERT(!code->IsFailure()); | |
| 335 Memory::Object_at(fp() + offset) = code; | |
| 336 } | |
| 337 ASSERT(code != NULL); | 346 ASSERT(code != NULL); |
| 338 return Code::cast(code); | 347 return Code::cast(code); |
| 339 } | 348 } |
| 340 | 349 |
| 341 | 350 |
| 342 void StackFrame::PrintIndex(StringStream* accumulator, | 351 void StackFrame::PrintIndex(StringStream* accumulator, |
| 343 PrintMode mode, | 352 PrintMode mode, |
| 344 int index) { | 353 int index) { |
| 345 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); | 354 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); |
| 346 } | 355 } |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 reg_code[i++] = r; | 589 reg_code[i++] = r; |
| 581 | 590 |
| 582 ASSERT(i == kNumJSCallerSaved); | 591 ASSERT(i == kNumJSCallerSaved); |
| 583 } | 592 } |
| 584 ASSERT(0 <= n && n < kNumJSCallerSaved); | 593 ASSERT(0 <= n && n < kNumJSCallerSaved); |
| 585 return reg_code[n]; | 594 return reg_code[n]; |
| 586 } | 595 } |
| 587 | 596 |
| 588 | 597 |
| 589 } } // namespace v8::internal | 598 } } // namespace v8::internal |
| OLD | NEW |