12f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org// Copyright 2013 the V8 project authors. All rights reserved.
2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Redistribution and use in source and binary forms, with or without
3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// modification, are permitted provided that the following conditions are
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// met:
5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Redistributions of source code must retain the above copyright
7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       notice, this list of conditions and the following disclaimer.
8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Redistributions in binary form must reproduce the above
9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       copyright notice, this list of conditions and the following
10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       disclaimer in the documentation and/or other materials provided
11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       with the distribution.
12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Neither the name of Google Inc. nor the names of its
13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       contributors may be used to endorse or promote products derived
14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       from this software without specific prior written permission.
15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "v8.h"
29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org#include "accessors.h"
31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "codegen.h"
32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "deoptimizer.h"
33a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "disasm.h"
34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "full-codegen.h"
35a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "global-handles.h"
36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "macro-assembler.h"
37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "prettyprinter.h"
38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
39a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 {
41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal {
42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
43876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.orgstatic MemoryChunk* AllocateCodeChunk(MemoryAllocator* allocator) {
44876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  return allocator->AllocateChunk(Deoptimizer::GetMaxDeoptTableSize(),
45876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org                                  OS::CommitPageSize(),
46ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#if defined(__native_client__)
47ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // The Native Client port of V8 uses an interpreter,
48ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // so code pages don't need PROT_EXEC.
49ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                  NOT_EXECUTABLE,
50ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#else
51876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org                                  EXECUTABLE,
52ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#endif
53876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org                                  NULL);
54876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org}
55876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
56876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
57876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.orgDeoptimizerData::DeoptimizerData(MemoryAllocator* allocator)
58876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    : allocator_(allocator),
59876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      current_(NULL),
604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
61876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      deoptimized_frame_info_(NULL),
624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif
63aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      deoptimizing_code_list_(NULL) {
64aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  for (int i = 0; i < Deoptimizer::kBailoutTypesWithCodeEntry; ++i) {
65aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org    deopt_entry_code_entries_[i] = -1;
66aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org    deopt_entry_code_[i] = AllocateCodeChunk(allocator);
67aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  }
68aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org}
69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
71ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgDeoptimizerData::~DeoptimizerData() {
72aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  for (int i = 0; i < Deoptimizer::kBailoutTypesWithCodeEntry; ++i) {
73aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org    allocator_->Free(deopt_entry_code_[i]);
74aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org    deopt_entry_code_[i] = NULL;
75aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  }
76e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
7772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  DeoptimizingCodeListNode* current = deoptimizing_code_list_;
7872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  while (current != NULL) {
7972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    DeoptimizingCodeListNode* prev = current;
8072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    current = current->next();
8172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    delete prev;
8272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
8372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  deoptimizing_code_list_ = NULL;
84ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
85ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgvoid DeoptimizerData::Iterate(ObjectVisitor* v) {
894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (deoptimized_frame_info_ != NULL) {
904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    deoptimized_frame_info_->Iterate(v);
914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif
944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
96a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgCode* DeoptimizerData::FindDeoptimizingCode(Address addr) {
97a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (DeoptimizingCodeListNode* node = deoptimizing_code_list_;
98a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org       node != NULL;
99a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org       node = node->next()) {
100a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (node->code()->contains(addr)) return *node->code();
101a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
102a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return NULL;
103a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
104a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
105a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
106a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid DeoptimizerData::RemoveDeoptimizingCode(Code* code) {
107a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (DeoptimizingCodeListNode *prev = NULL, *cur = deoptimizing_code_list_;
108a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org       cur != NULL;
109a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org       prev = cur, cur = cur->next()) {
110a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (*cur->code() == code) {
111a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (prev == NULL) {
112a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        deoptimizing_code_list_ = cur->next();
113a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      } else {
114a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        prev->set_next(cur->next());
115a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
116a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      delete cur;
117a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return;
118a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
119a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
120a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Deoptimizing code is removed through weak callback. Each object is expected
121a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // to be removed once and only once.
122a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  UNREACHABLE();
123a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
124a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
125a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// We rely on this function not causing a GC.  It is called from generated code
127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// without having a real stack frame in place.
128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgDeoptimizer* Deoptimizer::New(JSFunction* function,
129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              BailoutType type,
130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              unsigned bailout_id,
131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              Address from,
132ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                              int fp_to_sp_delta,
133ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                              Isolate* isolate) {
134ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Deoptimizer* deoptimizer = new Deoptimizer(isolate,
135ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                             function,
136ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                             type,
137ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                             bailout_id,
138ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                             from,
1394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                             fp_to_sp_delta,
1404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                             NULL);
141ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(isolate->deoptimizer_data()->current_ == NULL);
142ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->deoptimizer_data()->current_ = deoptimizer;
143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return deoptimizer;
144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
147e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org// No larger than 2K on all platforms
148e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgstatic const int kDeoptTableMaxEpilogueCodeSize = 2 * KB;
149e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
150e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
151e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgsize_t Deoptimizer::GetMaxDeoptTableSize() {
152e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int entries_size =
153e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_;
154e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int commit_page_size = static_cast<int>(OS::CommitPageSize());
155e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) /
156e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                    commit_page_size) + 1;
157e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return static_cast<size_t>(commit_page_size * page_count);
158e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
159e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
160e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
161ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgDeoptimizer* Deoptimizer::Grab(Isolate* isolate) {
162ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Deoptimizer* result = isolate->deoptimizer_data()->current_;
163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(result != NULL);
164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  result->DeleteFrameDescriptions();
165ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->deoptimizer_data()->current_ = NULL;
166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return result;
167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
169659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
170659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgint Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) {
171659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (jsframe_index == 0) return 0;
172659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
173659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int frame_index = 0;
174659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  while (jsframe_index >= 0) {
175659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    FrameDescription* frame = output_[frame_index];
176659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT) {
177659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      jsframe_index--;
178659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
179659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    frame_index++;
180659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
181659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
182659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  return frame_index - 1;
183659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
184659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
185659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
1874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgDeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
1884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    JavaScriptFrame* frame,
189659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int jsframe_index,
1904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    Isolate* isolate) {
1914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ASSERT(frame->is_optimized());
1924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL);
1934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Get the function and code from the frame.
195169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  JSFunction* function = frame->function();
1964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Code* code = frame->LookupCode();
1974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Locate the deoptimization point in the code. As we are at a call the
1994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // return address must be at a place in the code with deoptimization support.
20027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc());
20127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  int deoptimization_index = safepoint_entry.deoptimization_index();
2024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ASSERT(deoptimization_index != Safepoint::kNoDeoptimizationIndex);
2034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Always use the actual stack slots when calculating the fp to sp
2054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // delta adding two for the function and context.
2064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  unsigned stack_slots = code->stack_slots();
2074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  unsigned fp_to_sp_delta = ((stack_slots + 2) * kPointerSize);
2084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Deoptimizer* deoptimizer = new Deoptimizer(isolate,
2104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                             function,
2114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                             Deoptimizer::DEBUGGER,
2124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                             deoptimization_index,
2134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                             frame->pc(),
2144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                             fp_to_sp_delta,
2154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                             code);
2164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Address tos = frame->fp() - fp_to_sp_delta;
2174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  deoptimizer->FillInputFrame(tos, frame);
2184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Calculate the output frames.
2204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Deoptimizer::ComputeOutputFrames(deoptimizer);
2214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Create the GC safe output frame information and register it for GC
2234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // handling.
224659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  ASSERT_LT(jsframe_index, deoptimizer->jsframe_count());
225659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
226659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  // Convert JS frame index into frame index.
227659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index);
228659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
229659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  bool has_arguments_adaptor =
230659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      frame_index > 0 &&
231659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      deoptimizer->output_[frame_index - 1]->GetFrameType() ==
232659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      StackFrame::ARGUMENTS_ADAPTOR;
233659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
234967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  int construct_offset = has_arguments_adaptor ? 2 : 1;
235967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  bool has_construct_stub =
236967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      frame_index >= construct_offset &&
237967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      deoptimizer->output_[frame_index - construct_offset]->GetFrameType() ==
238967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      StackFrame::CONSTRUCT;
239967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
240967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  DeoptimizedFrameInfo* info = new DeoptimizedFrameInfo(deoptimizer,
241967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                                        frame_index,
242967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                                        has_arguments_adaptor,
243967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                                        has_construct_stub);
2444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  isolate->deoptimizer_data()->deoptimized_frame_info_ = info;
2454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Get the "simulated" top and size for the requested frame.
247659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  FrameDescription* parameters_frame =
248659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      deoptimizer->output_[
249659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          has_arguments_adaptor ? (frame_index - 1) : frame_index];
250659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
251659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  uint32_t parameters_size = (info->parameters_count() + 1) * kPointerSize;
252659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  Address parameters_top = reinterpret_cast<Address>(
253659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      parameters_frame->GetTop() + (parameters_frame->GetFrameSize() -
254659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                    parameters_size));
255659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
256659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  uint32_t expressions_size = info->expression_count() * kPointerSize;
257659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  Address expressions_top = reinterpret_cast<Address>(
258659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      deoptimizer->output_[frame_index]->GetTop());
2594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Done with the GC-unsafe frame descriptions. This re-enables allocation.
2614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  deoptimizer->DeleteFrameDescriptions();
2624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Allocate a heap number for the doubles belonging to this frame.
2644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame(
265659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      parameters_top, parameters_size, expressions_top, expressions_size, info);
2664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Finished using the deoptimizer instance.
2684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  delete deoptimizer;
2694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return info;
2714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
2724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgvoid Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
2754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                                 Isolate* isolate) {
2764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == info);
2774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  delete info;
2784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  isolate->deoptimizer_data()->deoptimized_frame_info_ = NULL;
2794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
2804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif
281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                                int count,
284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                                BailoutType type) {
285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  TableEntryGenerator generator(masm, type, count);
286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  generator.Generate();
287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Deoptimizer::VisitAllOptimizedFunctionsForContext(
291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Context* context, OptimizedFunctionVisitor* visitor) {
2925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Isolate* isolate = context->GetIsolate();
2931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Zone zone(isolate);
29479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
29646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(context->IsNativeContext());
297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
298a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  visitor->EnterContext(context);
2995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
3005a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Create a snapshot of the optimized functions list. This is needed because
3015a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // visitors might remove more than one link from the list at once.
3021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ZoneList<JSFunction*> snapshot(1, &zone);
303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Object* element = context->OptimizedFunctionsListHead();
304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  while (!element->IsUndefined()) {
305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    JSFunction* element_function = JSFunction::cast(element);
3061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    snapshot.Add(element_function, &zone);
307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    element = element_function->next_function_link();
308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
3105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Run through the snapshot of optimized functions and visit them.
3115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  for (int i = 0; i < snapshot.length(); ++i) {
3125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    visitor->VisitFunction(snapshot.at(i));
3135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
3145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  visitor->LeaveContext(context);
316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
319a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid Deoptimizer::VisitAllOptimizedFunctions(
320876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    Isolate* isolate,
321a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    OptimizedFunctionVisitor* visitor) {
32279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
324a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Run through the list of all native contexts and deoptimize.
325876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  Object* context = isolate->heap()->native_contexts_list();
326a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  while (!context->IsUndefined()) {
327a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor);
328a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
329a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
330a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
331a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
332a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
333a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Removes the functions selected by the given filter from the optimized
334fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// function list of the given context and adds their code to the list of
335fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// code objects to be deoptimized.
336fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgstatic void SelectCodeToDeoptimize(Context* context,
337fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                                   OptimizedFunctionFilter* filter,
338fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                                   ZoneList<Code*>* codes,
339fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                                   Zone* zone,
340fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                                   Object* undefined) {
34179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
342a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Object* current = context->get(Context::OPTIMIZED_FUNCTIONS_LIST);
343a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Object* remainder_head = undefined;
344a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Object* remainder_tail = undefined;
345fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
346fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // TODO(titzer): rewrite to not modify unselected functions.
347a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  while (current != undefined) {
348a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    JSFunction* function = JSFunction::cast(current);
349a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    current = function->next_function_link();
350a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (filter->TakeFunction(function)) {
351fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      // Extract this function from the context's list and remember the code.
352a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      Code* code = function->code();
353fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
354fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      if (code->marked_for_deoptimization()) {
355fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        ASSERT(codes->Contains(code));
356a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      } else {
357fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        code->set_marked_for_deoptimization(true);
358fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        codes->Add(code, zone);
359fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      }
360fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      SharedFunctionInfo* shared = function->shared();
361fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      // Replace the function's code with the shared code.
362fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      function->set_code(shared->code());
363fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      // Evict the code from the optimized code map.
364fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      shared->EvictFromOptimizedCodeMap(code, "deoptimized function");
365fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      // Remove the function from the optimized functions list.
366fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      function->set_next_function_link(undefined);
367fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
368fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      if (FLAG_trace_deopt) {
369fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        PrintF("[forced deoptimization: ");
370fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        function->PrintName();
371fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
372a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
373a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    } else {
374fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      // Don't select this function; link it back into the list.
375a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (remainder_head == undefined) {
376a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        remainder_head = function;
377a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      } else {
378a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        JSFunction::cast(remainder_tail)->set_next_function_link(function);
379a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
380a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      remainder_tail = function;
381a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
382a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
383a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (remainder_tail != undefined) {
384a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    JSFunction::cast(remainder_tail)->set_next_function_link(undefined);
385a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
386a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  context->set(Context::OPTIMIZED_FUNCTIONS_LIST, remainder_head);
387a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
388a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
389a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
390a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass DeoptimizeAllFilter : public OptimizedFunctionFilter {
391a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org public:
392a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  virtual bool TakeFunction(JSFunction* function) {
393a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return true;
394a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
395a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org};
396a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
397a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
398a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass DeoptimizeWithMatchingCodeFilter : public OptimizedFunctionFilter {
399a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org public:
400a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  explicit DeoptimizeWithMatchingCodeFilter(Code* code) : code_(code) {}
401a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  virtual bool TakeFunction(JSFunction* function) {
402a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return function->code() == code_;
403a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
404a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org private:
405a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Code* code_;
406a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org};
407a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
408a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
409fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgclass DeoptimizeMarkedCodeFilter : public OptimizedFunctionFilter {
410fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org public:
411fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  virtual bool TakeFunction(JSFunction* function) {
412fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return function->code()->marked_for_deoptimization();
413fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
414fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org};
415fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
416fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
417876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.orgvoid Deoptimizer::DeoptimizeAll(Isolate* isolate) {
41879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
419a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
420a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (FLAG_trace_deopt) {
421a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    PrintF("[deoptimize all contexts]\n");
422a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
423a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
424a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  DeoptimizeAllFilter filter;
425876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  DeoptimizeAllFunctionsWith(isolate, &filter);
426a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
427a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
428a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
429a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid Deoptimizer::DeoptimizeGlobalObject(JSObject* object) {
43079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
431a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  DeoptimizeAllFilter filter;
432a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (object->IsJSGlobalProxy()) {
433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Object* proto = object->GetPrototype();
434a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(proto->IsJSGlobalObject());
435a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    DeoptimizeAllFunctionsForContext(
436a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        GlobalObject::cast(proto)->native_context(), &filter);
437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (object->IsGlobalObject()) {
438a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    DeoptimizeAllFunctionsForContext(
439a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        GlobalObject::cast(object)->native_context(), &filter);
440a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
444a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid Deoptimizer::DeoptimizeFunction(JSFunction* function) {
445a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Code* code = function->code();
446fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (code->kind() != Code::OPTIMIZED_FUNCTION) return;
447a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  DeoptimizeWithMatchingCodeFilter filter(code);
448fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  DeoptimizeAllFunctionsForContext(
449fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      function->context()->native_context(), &filter);
450a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
451a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
452a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
453a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid Deoptimizer::DeoptimizeAllFunctionsForContext(
454a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Context* context, OptimizedFunctionFilter* filter) {
455a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(context->IsNativeContext());
456a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Isolate* isolate = context->GetIsolate();
457a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Object* undefined = isolate->heap()->undefined_value();
4581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Zone zone(isolate);
459fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  ZoneList<Code*> codes(4, &zone);
460fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  SelectCodeToDeoptimize(context, filter, &codes, &zone, undefined);
461fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  for (int i = 0; i < codes.length(); i++) {
462fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    DeoptimizeCode(isolate, codes.at(i));
463a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
464a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
465a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
466a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
467876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.orgvoid Deoptimizer::DeoptimizeAllFunctionsWith(Isolate* isolate,
468876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org                                             OptimizedFunctionFilter* filter) {
46979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
470a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
47146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Run through the list of all native contexts and deoptimize.
472876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  Object* context = isolate->heap()->native_contexts_list();
4737ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org  while (!context->IsUndefined()) {
474a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    DeoptimizeAllFunctionsForContext(Context::cast(context), filter);
4757ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
479a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
480fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgvoid Deoptimizer::DeoptimizeCodeList(Isolate* isolate, ZoneList<Code*>* codes) {
481fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (codes->length() == 0) return;  // Nothing to do.
482fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
483fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Mark the code; any functions refering to this code will be selected.
484fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  for (int i = 0; i < codes->length(); i++) {
485fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    ASSERT(!codes->at(i)->marked_for_deoptimization());
486fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    codes->at(i)->set_marked_for_deoptimization(true);
487fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
488fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
489fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // For all contexts, remove optimized functions that refer to the selected
490fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // code from the optimized function lists.
491fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  Object* undefined = isolate->heap()->undefined_value();
492fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  Zone zone(isolate);
493fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  Object* list = isolate->heap()->native_contexts_list();
494fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  DeoptimizeMarkedCodeFilter filter;
495fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  while (!list->IsUndefined()) {
496fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    Context* context = Context::cast(list);
497fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // Note that selecting code unlinks the functions that refer to it.
498fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    SelectCodeToDeoptimize(context, &filter, codes, &zone, undefined);
499fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    list = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
500fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
501fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
502fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Now deoptimize all the code.
503fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  for (int i = 0; i < codes->length(); i++) {
504fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    DeoptimizeCode(isolate, codes->at(i));
505fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
506fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
507fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
508fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
509fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgvoid Deoptimizer::DeoptimizeCode(Isolate* isolate, Code* code) {
510fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  HandleScope scope(isolate);
511fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  DisallowHeapAllocation nha;
512fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
513fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Do platform-specific patching of the optimized code.
514fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  PatchCodeForDeoptimization(isolate, code);
515fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
516fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Add the deoptimizing code to the list.
517fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
518fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  DeoptimizerData* data = isolate->deoptimizer_data();
519fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  node->set_next(data->deoptimizing_code_list_);
520fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  data->deoptimizing_code_list_ = node;
521fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
522fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // We might be in the middle of incremental marking with compaction.
523fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Tell collector to treat this code object in a special way and
524fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // ignore all slots that might have been recorded on it.
525fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  isolate->heap()->mark_compact_collector()->InvalidateCode(code);
526fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
527fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
528fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
529d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.orgvoid Deoptimizer::HandleWeakDeoptimizedCode(v8::Isolate* isolate,
53079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org                                            v8::Persistent<v8::Value>* obj,
531a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                            void* parameter) {
532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeoptimizingCodeListNode* node =
533a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      reinterpret_cast<DeoptimizingCodeListNode*>(parameter);
534d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  DeoptimizerData* data =
535d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org      reinterpret_cast<Isolate*>(isolate)->deoptimizer_data();
536a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  data->RemoveDeoptimizingCode(*node->code());
537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
538a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (DeoptimizingCodeListNode* current = data->deoptimizing_code_list_;
539a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org       current != NULL;
540a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org       current = current->next()) {
541a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(current != node);
542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
543a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
547c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgvoid Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) {
548a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  deoptimizer->DoComputeOutputFrames();
549a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
550a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
551a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5522f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.orgbool Deoptimizer::TraceEnabledFor(BailoutType deopt_type,
5532f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org                                  StackFrame::Type frame_type) {
5542f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  switch (deopt_type) {
555a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case EAGER:
556aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org    case SOFT:
557a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case LAZY:
558a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case DEBUGGER:
5592f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      return (frame_type == StackFrame::STUB)
5602f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org          ? FLAG_trace_stub_failures
5612f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org          : FLAG_trace_deopt;
562a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case OSR:
563a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return FLAG_trace_osr;
564a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
565a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  UNREACHABLE();
566a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return false;
567a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
568a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
569a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
570a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst char* Deoptimizer::MessageFor(BailoutType type) {
571a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  switch (type) {
5724e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case EAGER: return "eager";
5734e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case SOFT: return "soft";
5744e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case LAZY: return "lazy";
5754e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case DEBUGGER: return "debugger";
5764e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case OSR: return "OSR";
577a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
578a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  UNREACHABLE();
5794121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org  return NULL;
580a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
581a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
582a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
583ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgDeoptimizer::Deoptimizer(Isolate* isolate,
584ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                         JSFunction* function,
585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                         BailoutType type,
586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                         unsigned bailout_id,
587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                         Address from,
5884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                         int fp_to_sp_delta,
5894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                         Code* optimized_code)
590ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    : isolate_(isolate),
591ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      function_(function),
592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      bailout_id_(bailout_id),
593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      bailout_type_(type),
594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      from_(from),
595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      fp_to_sp_delta_(fp_to_sp_delta),
5967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      has_alignment_padding_(0),
5974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      input_(NULL),
598a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output_count_(0),
599659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      jsframe_count_(0),
600a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output_(NULL),
601b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      deferred_objects_tagged_values_(0),
602b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      deferred_objects_double_values_(0),
603b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      deferred_objects_(0),
6042f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      deferred_heap_numbers_(0),
605594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      jsframe_functions_(0),
606594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      jsframe_has_adapted_arguments_(0),
607594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      materialized_values_(NULL),
608594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      materialized_objects_(NULL),
609594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      materialization_value_index_(0),
610594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      materialization_object_index_(0),
6112f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      trace_(false) {
612a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // For COMPILED_STUBs called from builtins, the function pointer is a SMI
613a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // indicating an internal frame.
614a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (function->IsSmi()) {
615a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    function = NULL;
616a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
617169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(from != NULL);
618a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (function != NULL && function->IsOptimized()) {
619a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    function->shared()->increment_deopt_count();
620aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org    if (bailout_type_ == Deoptimizer::SOFT) {
6211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      isolate->counters()->soft_deopts_executed()->Increment();
622aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      // Soft deopts shouldn't count against the overall re-optimization count
623aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      // that can eventually lead to disabling optimization for a function.
624aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      int opt_count = function->shared()->opt_count();
625aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      if (opt_count > 0) opt_count--;
626aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      function->shared()->set_opt_count(opt_count);
627aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org    }
628a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
629a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  compiled_code_ = FindOptimizedCode(function, optimized_code);
630068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  StackFrame::Type frame_type = function == NULL
631068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      ? StackFrame::STUB
632068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      : StackFrame::JAVA_SCRIPT;
6332f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  trace_ = TraceEnabledFor(type, frame_type);
63479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#ifdef DEBUG
63579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  CHECK(AllowHeapAllocation::IsAllowed());
63679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  disallow_heap_allocation_ = new DisallowHeapAllocation();
63779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#endif  // DEBUG
6382f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  unsigned size = ComputeInputFrameSize();
6392f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  input_ = new(size) FrameDescription(size, function);
640068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  input_->SetFrameType(frame_type);
641a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
642a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
643a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
644a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgCode* Deoptimizer::FindOptimizedCode(JSFunction* function,
645a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                     Code* optimized_code) {
646a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  switch (bailout_type_) {
647aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org    case Deoptimizer::SOFT:
648a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case Deoptimizer::EAGER:
649a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case Deoptimizer::LAZY: {
650a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      Code* compiled_code =
651a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          isolate_->deoptimizer_data()->FindDeoptimizingCode(from_);
652a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return (compiled_code == NULL)
653ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org          ? static_cast<Code*>(isolate_->FindCodeObject(from_))
654a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          : compiled_code;
655a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
656a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case Deoptimizer::OSR: {
657a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // The function has already been optimized and we're transitioning
658a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // from the unoptimized shared version to the optimized one in the
659a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // function. The return address (from_) points to unoptimized code.
660a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      Code* compiled_code = function->code();
661a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      ASSERT(compiled_code->kind() == Code::OPTIMIZED_FUNCTION);
662a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      ASSERT(!compiled_code->contains(from_));
663a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return compiled_code;
664a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
665a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case Deoptimizer::DEBUGGER:
666a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      ASSERT(optimized_code->contains(from_));
667a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return optimized_code;
668a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
669a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  UNREACHABLE();
670a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return NULL;
671a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
672a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
673a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
674a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid Deoptimizer::PrintFunctionName() {
675a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (function_->IsJSFunction()) {
676a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    function_->PrintName();
677a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
678a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    PrintF("%s", Code::Kind2String(compiled_code_->kind()));
679a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
680a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
681a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
682a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgDeoptimizer::~Deoptimizer() {
684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(input_ == NULL && output_ == NULL);
68579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  ASSERT(disallow_heap_allocation_ == NULL);
686a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
687a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
688a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Deoptimizer::DeleteFrameDescriptions() {
690a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  delete input_;
691a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < output_count_; ++i) {
692a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (output_[i] != input_) delete output_[i];
693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
694a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  delete[] output_;
695a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  input_ = NULL;
696a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  output_ = NULL;
69779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#ifdef DEBUG
69879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  CHECK(!AllowHeapAllocation::IsAllowed());
69979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  CHECK(disallow_heap_allocation_ != NULL);
70079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  delete disallow_heap_allocation_;
70179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  disallow_heap_allocation_ = NULL;
70279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#endif  // DEBUG
703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
704a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
705a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgAddress Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
7078432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org                                            int id,
708e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                                            BailoutType type,
709e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                                            GetEntryMode mode) {
710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(id >= 0);
711e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (id >= kMaxNumberOfEntries) return NULL;
712e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (mode == ENSURE_ENTRY_CODE) {
7138432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    EnsureCodeForDeoptimizationEntry(isolate, type, id);
714e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
715e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    ASSERT(mode == CALCULATE_ENTRY_ADDRESS);
716e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
7178432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  DeoptimizerData* data = isolate->deoptimizer_data();
718aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  ASSERT(type < kBailoutTypesWithCodeEntry);
719aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  MemoryChunk* base = data->deopt_entry_code_[type];
720068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  return base->area_start() + (id * table_entry_size_);
721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
724876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.orgint Deoptimizer::GetDeoptimizationId(Isolate* isolate,
725876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org                                     Address addr,
726876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org                                     BailoutType type) {
727876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  DeoptimizerData* data = isolate->deoptimizer_data();
728aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  MemoryChunk* base = data->deopt_entry_code_[type];
729068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  Address start = base->area_start();
730a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (base == NULL ||
731068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      addr < start ||
732068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      addr >= start + (kMaxNumberOfEntries * table_entry_size_)) {
733a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return kNotDeoptimizationEntry;
734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT_EQ(0,
736068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org            static_cast<int>(addr - start) % table_entry_size_);
737068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  return static_cast<int>(addr - start) / table_entry_size_;
738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgint Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
742471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                               BailoutId id,
7439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                               SharedFunctionInfo* shared) {
744a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // TODO(kasperl): For now, we do a simple linear search for the PC
745a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // offset associated with the given node id. This should probably be
746a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // changed to a binary search.
747a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int length = data->DeoptPoints();
748a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < length; i++) {
749471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (data->AstId(i) == id) {
750a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return data->PcAndState(i)->value();
751a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
752a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
753471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  PrintF("[couldn't find pc offset for node=%d]\n", id.ToInt());
754a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  PrintF("[method: %s]\n", *shared->DebugName()->ToCString());
755a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Print the source code if available.
756a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HeapStringAllocator string_allocator;
757a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  StringStream stream(&string_allocator);
758a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  shared->SourceCodePrint(&stream, -1);
759a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  PrintF("[source:\n%s\n]", *stream.ToCString());
760a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
76132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  FATAL("unable to find pc offset during deoptimization");
762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return -1;
763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
766ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) {
767a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int length = 0;
768ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  DeoptimizingCodeListNode* node =
769ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->deoptimizer_data()->deoptimizing_code_list_;
770a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  while (node != NULL) {
771a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    length++;
772a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    node = node->next();
773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
774a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return length;
775a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
776a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
778c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// We rely on this function not causing a GC.  It is called from generated code
779c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// without having a real stack frame in place.
780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Deoptimizer::DoComputeOutputFrames() {
781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (bailout_type_ == OSR) {
782a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DoComputeOsrOutputFrame();
783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return;
784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
785a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
786a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Print some helpful diagnostic information.
787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int64_t start = OS::Ticks();
788c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  if (FLAG_log_timer_events &&
789c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
790c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    LOG(isolate(), CodeDeoptEvent(compiled_code_));
791c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  }
7922f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  if (trace_) {
7934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF("[deoptimizing (DEOPT %s): begin 0x%08" V8PRIxPTR " ",
7944e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           MessageFor(bailout_type_),
795a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org           reinterpret_cast<intptr_t>(function_));
796a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    PrintFunctionName();
7974e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF(" @%d, FP to SP delta: %d]\n", bailout_id_, fp_to_sp_delta_);
7984e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (bailout_type_ == EAGER || bailout_type_ == SOFT) {
7994e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      compiled_code_->PrintDeoptLocation(bailout_id_);
8004e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    }
801a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Determine basic deoptimization information.  The optimized frame is
804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // described by the input data.
805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeoptimizationInputData* input_data =
806a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      DeoptimizationInputData::cast(compiled_code_->deoptimization_data());
807471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  BailoutId node_id = input_data->AstId(bailout_id_);
808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ByteArray* translations = input_data->TranslationByteArray();
809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  unsigned translation_index =
810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      input_data->TranslationIndex(bailout_id_)->value();
811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Do the input frame to output frame(s) translation.
813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  TranslationIterator iterator(translations, translation_index);
814a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Translation::Opcode opcode =
815a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      static_cast<Translation::Opcode>(iterator.Next());
816a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(Translation::BEGIN == opcode);
817a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  USE(opcode);
818a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Read the number of output frames and allocate an array for their
819a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // descriptions.
820a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int count = iterator.Next();
821659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  iterator.Next();  // Drop JS frames count.
822a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(output_ == NULL);
823a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  output_ = new FrameDescription*[count];
824a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < count; ++i) {
825a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    output_[i] = NULL;
826a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  output_count_ = count;
828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Translate each output frame.
830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < count; ++i) {
831659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // Read the ast node id, function, and frame height for this output frame.
832659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Translation::Opcode opcode =
833659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        static_cast<Translation::Opcode>(iterator.Next());
834659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    switch (opcode) {
835659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      case Translation::JS_FRAME:
836659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        DoComputeJSFrame(&iterator, i);
837659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        jsframe_count_++;
838659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        break;
839659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      case Translation::ARGUMENTS_ADAPTOR_FRAME:
840659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        DoComputeArgumentsAdaptorFrame(&iterator, i);
841659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        break;
842967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      case Translation::CONSTRUCT_STUB_FRAME:
843967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        DoComputeConstructStubFrame(&iterator, i);
844967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        break;
845de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      case Translation::GETTER_STUB_FRAME:
846de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org        DoComputeAccessorStubFrame(&iterator, i, false);
847de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org        break;
84846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::SETTER_STUB_FRAME:
849de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org        DoComputeAccessorStubFrame(&iterator, i, true);
85046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        break;
851a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      case Translation::COMPILED_STUB_FRAME:
85271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org        DoComputeCompiledStubFrame(&iterator, i);
853a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        break;
85446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::BEGIN:
85546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::REGISTER:
85646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::INT32_REGISTER:
85746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::UINT32_REGISTER:
85846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::DOUBLE_REGISTER:
85946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::STACK_SLOT:
86046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::INT32_STACK_SLOT:
86146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::UINT32_STACK_SLOT:
86246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::DOUBLE_STACK_SLOT:
86346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::LITERAL:
86446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      case Translation::ARGUMENTS_OBJECT:
865a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      default:
866659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        UNREACHABLE();
867659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        break;
868659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
869a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
870a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
871a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Print some helpful diagnostic information.
8722f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  if (trace_) {
873a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    double ms = static_cast<double>(OS::Ticks() - start) / 1000;
874a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int index = output_count_ - 1;  // Index of the topmost frame.
875a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    JSFunction* function = output_[index]->GetFunction();
8764e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF("[deoptimizing (%s): end 0x%08" V8PRIxPTR " ",
8774e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           MessageFor(bailout_type_),
878a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org           reinterpret_cast<intptr_t>(function));
8794e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintFunctionName();
8804e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF(" @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
8817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org           " took %0.3f ms]\n",
8824e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           bailout_id_,
883471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org           node_id.ToInt(),
884a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org           output_[index]->GetPc(),
885a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org           FullCodeGenerator::State2String(
886a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               static_cast<FullCodeGenerator::State>(
887a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                   output_[index]->GetState()->value())),
8887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org           has_alignment_padding_ ? "with padding" : "no padding",
889a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org           ms);
890a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
891a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
892a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
893a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8944e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
8954e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org                                   int frame_index) {
8964e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  BailoutId node_id = BailoutId(iterator->Next());
8974e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  JSFunction* function;
8984e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (frame_index != 0) {
8994e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    function = JSFunction::cast(ComputeLiteral(iterator->Next()));
9004e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  } else {
9014e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    int closure_id = iterator->Next();
9024e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    USE(closure_id);
9034e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
9044e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    function = function_;
9054e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
9064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  unsigned height = iterator->Next();
9074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  unsigned height_in_bytes = height * kPointerSize;
9084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (trace_) {
9094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF("  translating ");
9104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    function->PrintName();
9114e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
9124e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
9134e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
9144e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // The 'fixed' part of the frame consists of the incoming parameters and
9154e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // the part described by JavaScriptFrameConstants.
9164e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  unsigned fixed_frame_size = ComputeFixedSize(function);
9174e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  unsigned input_frame_size = input_->GetFrameSize();
9184e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
9194e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
9204e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // Allocate and store the output frame description.
9214e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  FrameDescription* output_frame =
9224e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      new(output_frame_size) FrameDescription(output_frame_size, function);
9234e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
9244e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
9254e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  bool is_bottommost = (0 == frame_index);
9264e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  bool is_topmost = (output_count_ - 1 == frame_index);
9274e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  ASSERT(frame_index >= 0 && frame_index < output_count_);
9284e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  ASSERT(output_[frame_index] == NULL);
9294e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_[frame_index] = output_frame;
9304e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
9314e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // The top address for the bottommost output frame can be computed from
9324e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // the input frame pointer and the output frame's height.  For all
9334e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // subsequent output frames, it can be computed from the previous one's
9344e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // top address and the current frame's size.
9354e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  Register fp_reg = JavaScriptFrame::fp_register();
9364e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  intptr_t top_address;
9374e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (is_bottommost) {
9384e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    // Determine whether the input frame contains alignment padding.
9394e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    has_alignment_padding_ = HasAlignmentPadding(function) ? 1 : 0;
9404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    // 2 = context and function in the frame.
9414e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    // If the optimized frame had alignment padding, adjust the frame pointer
9424e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    // to point to the new position of the old frame pointer after padding
9434e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    // is removed. Subtract 2 * kPointerSize for the context and function slots.
9444e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    top_address = input_->GetRegister(fp_reg.code()) - (2 * kPointerSize) -
9454e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org        height_in_bytes + has_alignment_padding_ * kPointerSize;
9464e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  } else {
9474e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
9484e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
9494e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_frame->SetTop(top_address);
9504e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
9514e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // Compute the incoming parameter translation.
9524e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  int parameter_count = function->shared()->formal_parameter_count() + 1;
9534e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  unsigned output_offset = output_frame_size;
9544e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  unsigned input_offset = input_frame_size;
9554e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  for (int i = 0; i < parameter_count; ++i) {
9564e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    output_offset -= kPointerSize;
9574e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    DoTranslateCommand(iterator, frame_index, output_offset);
9584e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
9594e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  input_offset -= (parameter_count * kPointerSize);
9604e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
9614e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // There are no translation commands for the caller's pc and fp, the
9624e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // context, and the function.  Synthesize their values and set them up
9634e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // explicitly.
9644e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  //
9654e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // The caller's pc for the bottommost output frame is the same as in the
9664e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // input frame.  For all subsequent output frames, it can be read from the
9674e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // previous one.  This frame's pc can be computed from the non-optimized
9684e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // function code and AST id of the bailout.
969c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_offset -= kPCOnStackSize;
970c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  input_offset -= kPCOnStackSize;
9714e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  intptr_t value;
9724e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (is_bottommost) {
9734e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    value = input_->GetFrameSlot(input_offset);
9744e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  } else {
9754e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    value = output_[frame_index - 1]->GetPc();
9764e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
977c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame->SetCallerPc(output_offset, value);
9784e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (trace_) {
9794e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
9804e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           V8PRIxPTR  " ; caller's pc\n",
9814e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           top_address + output_offset, output_offset, value);
9824e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
9834e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
9844e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // The caller's frame pointer for the bottommost output frame is the same
9854e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // as in the input frame.  For all subsequent output frames, it can be
9864e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // read from the previous one.  Also compute and set this frame's frame
9874e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // pointer.
988c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_offset -= kFPOnStackSize;
989c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  input_offset -= kFPOnStackSize;
9904e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (is_bottommost) {
9914e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    value = input_->GetFrameSlot(input_offset);
9924e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  } else {
9934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    value = output_[frame_index - 1]->GetFp();
9944e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
995c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame->SetCallerFp(output_offset, value);
9964e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  intptr_t fp_value = top_address + output_offset;
9974e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  ASSERT(!is_bottommost || (input_->GetRegister(fp_reg.code()) +
9984e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      has_alignment_padding_ * kPointerSize) == fp_value);
9994e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_frame->SetFp(fp_value);
10004e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
10014e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (trace_) {
10024e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
10034e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           V8PRIxPTR " ; caller's fp\n",
10044e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           fp_value, output_offset, value);
10054e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
10064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  ASSERT(!is_bottommost || !has_alignment_padding_ ||
10074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org         (fp_value & kPointerSize) != 0);
10084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
10094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // For the bottommost output frame the context can be gotten from the input
10104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // frame. For all subsequent output frames it can be gotten from the function
10114e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // so long as we don't inline functions that need local contexts.
10124e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  Register context_reg = JavaScriptFrame::context_register();
10134e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_offset -= kPointerSize;
10144e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  input_offset -= kPointerSize;
10154e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (is_bottommost) {
10164e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    value = input_->GetFrameSlot(input_offset);
10174e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  } else {
10184e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    value = reinterpret_cast<intptr_t>(function->context());
10194e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
10204e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_frame->SetFrameSlot(output_offset, value);
10214e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_frame->SetContext(value);
10224e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (is_topmost) output_frame->SetRegister(context_reg.code(), value);
10234e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (trace_) {
10244e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
10254e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           V8PRIxPTR "; context\n",
10264e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           top_address + output_offset, output_offset, value);
10274e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
10284e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
10294e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // The function was mentioned explicitly in the BEGIN_FRAME.
10304e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_offset -= kPointerSize;
10314e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  input_offset -= kPointerSize;
10324e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  value = reinterpret_cast<intptr_t>(function);
10334e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // The function for the bottommost output frame should also agree with the
10344e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // input frame.
10354e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
10364e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_frame->SetFrameSlot(output_offset, value);
10374e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (trace_) {
10384e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
10394e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           V8PRIxPTR "; function\n",
10404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org           top_address + output_offset, output_offset, value);
10414e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
10424e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
10434e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // Translate the rest of the frame.
10444e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  for (unsigned i = 0; i < height; ++i) {
10454e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    output_offset -= kPointerSize;
10464e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    DoTranslateCommand(iterator, frame_index, output_offset);
10474e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
10484e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  ASSERT(0 == output_offset);
10494e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
10504e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // Compute this frame's PC, state, and continuation.
10514e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  Code* non_optimized_code = function->shared()->code();
10524e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  FixedArray* raw_data = non_optimized_code->deoptimization_data();
10534e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
10544e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  Address start = non_optimized_code->instruction_start();
10554e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared());
10564e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
10574e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
10584e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_frame->SetPc(pc_value);
10594e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
10604e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  FullCodeGenerator::State state =
10614e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      FullCodeGenerator::StateField::decode(pc_and_state);
10624e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  output_frame->SetState(Smi::FromInt(state));
10634e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
10644e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // Set the continuation for the topmost frame.
10654e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (is_topmost && bailout_type_ != DEBUGGER) {
10664e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    Builtins* builtins = isolate_->builtins();
10674e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
10684e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (bailout_type_ == LAZY) {
10694e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
10704e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    } else if (bailout_type_ == SOFT) {
10714e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
10724e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    } else {
10734e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      ASSERT(bailout_type_ == EAGER);
10744e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    }
10754e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    output_frame->SetContinuation(
10764e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org        reinterpret_cast<intptr_t>(continuation->entry()));
10774e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
10784e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
10794e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
10804e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
10814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
10824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                                                 int frame_index) {
10834a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
10844a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  unsigned height = iterator->Next();
10854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  unsigned height_in_bytes = height * kPointerSize;
10864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
10874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("  translating arguments adaptor => height=%d\n", height_in_bytes);
10884a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
10894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
10904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
10914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
10924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
10934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate and store the output frame description.
10944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  FrameDescription* output_frame =
10954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      new(output_frame_size) FrameDescription(output_frame_size, function);
10964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
10974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
10984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Arguments adaptor can not be topmost or bottommost.
10994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
11004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(output_[frame_index] == NULL);
11014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_[frame_index] = output_frame;
11024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
11034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // The top address of the frame is computed from the previous
11044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // frame's top and this frame's size.
11054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t top_address;
11064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
11074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetTop(top_address);
11084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
11094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Compute the incoming parameter translation.
11104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int parameter_count = height;
11114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  unsigned output_offset = output_frame_size;
11124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  for (int i = 0; i < parameter_count; ++i) {
11134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    output_offset -= kPointerSize;
11144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    DoTranslateCommand(iterator, frame_index, output_offset);
11154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
11164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
11174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Read caller's PC from the previous frame.
1118c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_offset -= kPCOnStackSize;
11194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1120c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame->SetCallerPc(output_offset, callers_pc);
11214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
11224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
11234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           V8PRIxPTR " ; caller's pc\n",
11244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           top_address + output_offset, output_offset, callers_pc);
11254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
11264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
11274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Read caller's FP from the previous frame, and set this frame's FP.
1128c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_offset -= kFPOnStackSize;
11294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t value = output_[frame_index - 1]->GetFp();
1130c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame->SetCallerFp(output_offset, value);
11314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t fp_value = top_address + output_offset;
11324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetFp(fp_value);
11334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
11344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
11354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           V8PRIxPTR " ; caller's fp\n",
11364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           fp_value, output_offset, value);
11374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
11384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
11394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // A marker value is used in place of the context.
11404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_offset -= kPointerSize;
11414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t context = reinterpret_cast<intptr_t>(
11424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
11434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetFrameSlot(output_offset, context);
11444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
11454a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
11464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           V8PRIxPTR " ; context (adaptor sentinel)\n",
11474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           top_address + output_offset, output_offset, context);
11484a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
11494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
11504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
11514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_offset -= kPointerSize;
11524a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  value = reinterpret_cast<intptr_t>(function);
11534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetFrameSlot(output_offset, value);
11544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
11554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
11564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           V8PRIxPTR " ; function\n",
11574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           top_address + output_offset, output_offset, value);
11584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
11594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
11604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Number of incoming arguments.
11614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_offset -= kPointerSize;
11624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
11634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetFrameSlot(output_offset, value);
11644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
11654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
11664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           V8PRIxPTR " ; argc (%d)\n",
11674a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           top_address + output_offset, output_offset, value, height - 1);
11684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
11694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
11704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(0 == output_offset);
11714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
11724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Builtins* builtins = isolate_->builtins();
11734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Code* adaptor_trampoline =
11744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
11754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t pc_value = reinterpret_cast<intptr_t>(
11764a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      adaptor_trampoline->instruction_start() +
11774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
11784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetPc(pc_value);
11794a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
11804a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
11814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
1182750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
1183750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                              int frame_index) {
1184750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Builtins* builtins = isolate_->builtins();
1185750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
1186750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
1187750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  unsigned height = iterator->Next();
1188750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  unsigned height_in_bytes = height * kPointerSize;
1189750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (trace_) {
1190750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    PrintF("  translating construct stub => height=%d\n", height_in_bytes);
1191750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
1192750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1193750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  unsigned fixed_frame_size = ConstructFrameConstants::kFrameSize;
1194750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1195750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1196750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Allocate and store the output frame description.
1197750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  FrameDescription* output_frame =
1198750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      new(output_frame_size) FrameDescription(output_frame_size, function);
1199750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_frame->SetFrameType(StackFrame::CONSTRUCT);
1200750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1201750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Construct stub can not be topmost or bottommost.
1202750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
1203750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(output_[frame_index] == NULL);
1204750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_[frame_index] = output_frame;
1205750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1206750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // The top address of the frame is computed from the previous
1207750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // frame's top and this frame's size.
1208750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  intptr_t top_address;
1209750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1210750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_frame->SetTop(top_address);
1211750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1212750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Compute the incoming parameter translation.
1213750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  int parameter_count = height;
1214750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  unsigned output_offset = output_frame_size;
1215750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  for (int i = 0; i < parameter_count; ++i) {
1216750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    output_offset -= kPointerSize;
1217594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int deferred_object_index = deferred_objects_.length();
1218750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    DoTranslateCommand(iterator, frame_index, output_offset);
1219594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // The allocated receiver of a construct stub frame is passed as the
1220594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // receiver parameter through the translation. It might be encoding
1221594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // a captured object, patch the slot address for a captured object.
1222594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (i == 0 && deferred_objects_.length() > deferred_object_index) {
1223594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      ASSERT(!deferred_objects_[deferred_object_index].is_arguments());
1224594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      deferred_objects_[deferred_object_index].patch_slot_address(top_address);
1225594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
1226750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
1227750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1228750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Read caller's PC from the previous frame.
1229c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_offset -= kPCOnStackSize;
1230750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1231c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame->SetCallerPc(output_offset, callers_pc);
1232750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (trace_) {
1233750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1234750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           V8PRIxPTR " ; caller's pc\n",
1235750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           top_address + output_offset, output_offset, callers_pc);
1236750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
1237750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1238750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Read caller's FP from the previous frame, and set this frame's FP.
1239c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_offset -= kFPOnStackSize;
1240750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  intptr_t value = output_[frame_index - 1]->GetFp();
1241c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame->SetCallerFp(output_offset, value);
1242750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  intptr_t fp_value = top_address + output_offset;
1243750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_frame->SetFp(fp_value);
1244750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (trace_) {
1245750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1246750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           V8PRIxPTR " ; caller's fp\n",
1247750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           fp_value, output_offset, value);
1248750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
1249750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1250750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // The context can be gotten from the previous frame.
1251750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_offset -= kPointerSize;
1252750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  value = output_[frame_index - 1]->GetContext();
1253750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_frame->SetFrameSlot(output_offset, value);
1254750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (trace_) {
1255750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1256750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           V8PRIxPTR " ; context\n",
1257750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           top_address + output_offset, output_offset, value);
1258750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
1259750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1260750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // A marker value is used in place of the function.
1261750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_offset -= kPointerSize;
1262750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
1263750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_frame->SetFrameSlot(output_offset, value);
1264750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (trace_) {
1265750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1266750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           V8PRIxPTR " ; function (construct sentinel)\n",
1267750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           top_address + output_offset, output_offset, value);
1268750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
1269750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1270750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // The output frame reflects a JSConstructStubGeneric frame.
1271750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_offset -= kPointerSize;
1272750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  value = reinterpret_cast<intptr_t>(construct_stub);
1273750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_frame->SetFrameSlot(output_offset, value);
1274750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (trace_) {
1275750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1276750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           V8PRIxPTR " ; code object\n",
1277750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           top_address + output_offset, output_offset, value);
1278750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
1279750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1280750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Number of incoming arguments.
1281750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_offset -= kPointerSize;
1282750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
1283750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_frame->SetFrameSlot(output_offset, value);
1284750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (trace_) {
1285750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1286750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           V8PRIxPTR " ; argc (%d)\n",
1287750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           top_address + output_offset, output_offset, value, height - 1);
1288750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
1289750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1290750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Constructor function being invoked by the stub (only present on some
1291750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // architectures, indicated by kConstructorOffset).
1292750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (ConstructFrameConstants::kConstructorOffset != kMinInt) {
1293750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    output_offset -= kPointerSize;
1294750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    value = reinterpret_cast<intptr_t>(function);
1295750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    output_frame->SetFrameSlot(output_offset, value);
1296750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (trace_) {
1297750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1298750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org             V8PRIxPTR " ; constructor function\n",
1299750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org             top_address + output_offset, output_offset, value);
1300750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
1301750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
1302750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1303750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // The newly allocated object was passed as receiver in the artificial
1304750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // constructor stub environment created by HEnvironment::CopyForInlining().
1305750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_offset -= kPointerSize;
1306750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
1307750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_frame->SetFrameSlot(output_offset, value);
1308750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (trace_) {
1309750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1310750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           V8PRIxPTR " ; allocated receiver\n",
1311750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org           top_address + output_offset, output_offset, value);
1312750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
1313750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1314750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(0 == output_offset);
1315750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1316750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  intptr_t pc = reinterpret_cast<intptr_t>(
1317750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      construct_stub->instruction_start() +
1318750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      isolate_->heap()->construct_stub_deopt_pc_offset()->value());
1319750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  output_frame->SetPc(pc);
1320750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
1321750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1322750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
13234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
13244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                                             int frame_index,
13254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                                             bool is_setter_stub_frame) {
13264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next()));
13274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // The receiver (and the implicit return value, if any) are expected in
13284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // registers by the LoadIC/StoreIC, so they don't belong to the output stack
13294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // frame. This means that we have to use a height of 0.
13304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  unsigned height = 0;
13314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  unsigned height_in_bytes = height * kPointerSize;
13324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  const char* kind = is_setter_stub_frame ? "setter" : "getter";
13334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
13344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("  translating %s stub => height=%u\n", kind, height_in_bytes);
13354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
13364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
13374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // We need 1 stack entry for the return address + 4 stack entries from
13384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // StackFrame::INTERNAL (FP, context, frame type, code object, see
13394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // MacroAssembler::EnterFrame). For a setter stub frame we need one additional
13404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // entry for the implicit return value, see
13414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // StoreStubCompiler::CompileStoreViaSetter.
1342c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  unsigned fixed_frame_entries = (kPCOnStackSize / kPointerSize) +
1343c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org                                 (kFPOnStackSize / kPointerSize) + 3 +
1344c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org                                 (is_setter_stub_frame ? 1 : 0);
13454a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
13464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
13474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
13484a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate and store the output frame description.
13494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  FrameDescription* output_frame =
13504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      new(output_frame_size) FrameDescription(output_frame_size, accessor);
13514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetFrameType(StackFrame::INTERNAL);
13524a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
13534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // A frame for an accessor stub can not be the topmost or bottommost one.
13544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
13554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(output_[frame_index] == NULL);
13564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_[frame_index] = output_frame;
13574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
13584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // The top address of the frame is computed from the previous frame's top and
13594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // this frame's size.
13604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
13614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetTop(top_address);
13624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
13634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  unsigned output_offset = output_frame_size;
13644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
13654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Read caller's PC from the previous frame.
1366c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_offset -= kPCOnStackSize;
13674a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1368c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame->SetCallerPc(output_offset, callers_pc);
13694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
13704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
13714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           " ; caller's pc\n",
13724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           top_address + output_offset, output_offset, callers_pc);
13734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
13744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
13754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Read caller's FP from the previous frame, and set this frame's FP.
1376c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_offset -= kFPOnStackSize;
13774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t value = output_[frame_index - 1]->GetFp();
1378c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame->SetCallerFp(output_offset, value);
13794a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t fp_value = top_address + output_offset;
13804a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetFp(fp_value);
13814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
13824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
13834a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           " ; caller's fp\n",
13844a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           fp_value, output_offset, value);
13854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
13864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
13874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // The context can be gotten from the previous frame.
13884a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_offset -= kPointerSize;
13894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  value = output_[frame_index - 1]->GetContext();
13904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetFrameSlot(output_offset, value);
13914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
13924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
13934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           " ; context\n",
13944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           top_address + output_offset, output_offset, value);
13954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
13964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
13974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // A marker value is used in place of the function.
13984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_offset -= kPointerSize;
13994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
14004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetFrameSlot(output_offset, value);
14014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
14024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
14034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           " ; function (%s sentinel)\n",
14044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           top_address + output_offset, output_offset, value, kind);
14054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
14064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
14074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Get Code object from accessor stub.
14084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_offset -= kPointerSize;
14094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Builtins::Name name = is_setter_stub_frame ?
14104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      Builtins::kStoreIC_Setter_ForDeopt :
14114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      Builtins::kLoadIC_Getter_ForDeopt;
14124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Code* accessor_stub = isolate_->builtins()->builtin(name);
14134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  value = reinterpret_cast<intptr_t>(accessor_stub);
14144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetFrameSlot(output_offset, value);
14154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (trace_) {
14164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
14174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           " ; code object\n",
14184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org           top_address + output_offset, output_offset, value);
14194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
14204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
14214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Skip receiver.
14224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Translation::Opcode opcode =
14234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      static_cast<Translation::Opcode>(iterator->Next());
14244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  iterator->Skip(Translation::NumberOfOperandsFor(opcode));
14254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
14264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (is_setter_stub_frame) {
14274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // The implicit return value was part of the artificial setter stub
14284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // environment.
14294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    output_offset -= kPointerSize;
14304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    DoTranslateCommand(iterator, frame_index, output_offset);
14314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
14324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
14334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(0 == output_offset);
14344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
14354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Smi* offset = is_setter_stub_frame ?
14364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      isolate_->heap()->setter_stub_deopt_pc_offset() :
14374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      isolate_->heap()->getter_stub_deopt_pc_offset();
14384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  intptr_t pc = reinterpret_cast<intptr_t>(
14394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      accessor_stub->instruction_start() + offset->value());
14404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  output_frame->SetPc(pc);
14414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
14424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
14434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
14446e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgvoid Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
14456e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org                                             int frame_index) {
14466e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //
14476e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //               FROM                                  TO
14486e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //    |          ....           |          |          ....           |
14496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //    +-------------------------+          +-------------------------+
14506e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //    | JSFunction continuation |          | JSFunction continuation |
14516e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //    +-------------------------+          +-------------------------+
14526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // |  |    saved frame (FP)     |          |    saved frame (FP)     |
14536e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // |  +=========================+<-fpreg   +=========================+<-fpreg
14546e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // |  |   JSFunction context    |          |   JSFunction context    |
14556e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // v  +-------------------------+          +-------------------------|
14566e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //    |   COMPILED_STUB marker  |          |   STUB_FAILURE marker   |
14576e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //    +-------------------------+          +-------------------------+
14586e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //    |                         |          |  caller args.arguments_ |
14596e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //    | ...                     |          +-------------------------+
14606e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //    |                         |          |  caller args.length_    |
14616e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //    |-------------------------|<-spreg   +-------------------------+
14626e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //                                         |  caller args pointer    |
14636e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //                                         +-------------------------+
14646e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //                                         |  caller stack param 1   |
14656e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //      parameters in registers            +-------------------------+
14666e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //       and spilled to stack              |           ....          |
14676e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //                                         +-------------------------+
14686e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //                                         |  caller stack param n   |
14696e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //                                         +-------------------------+<-spreg
14706e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //                                         reg = number of parameters
14716e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //                                         reg = failure handler address
14726e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //                                         reg = saved frame
14736e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //                                         reg = JSFunction context
14746e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  //
14756e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
1476b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  ASSERT(compiled_code_->is_crankshafted() &&
1477b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org         compiled_code_->kind() != Code::OPTIMIZED_FUNCTION);
14786e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  int major_key = compiled_code_->major_key();
14796e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  CodeStubInterfaceDescriptor* descriptor =
14806e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      isolate_->code_stub_interface_descriptor(major_key);
14816e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
14826e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // The output frame must have room for all pushed register parameters
14836e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // and the standard stack frame slots.  Include space for an argument
14846e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // object to the callee and optionally the space to pass the argument
14856e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // object to the stub failure handler.
1486e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(descriptor->register_param_count_ >= 0);
14876e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  int height_in_bytes = kPointerSize * descriptor->register_param_count_ +
14886e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      sizeof(Arguments) + kPointerSize;
14896e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  int fixed_frame_size = StandardFrameConstants::kFixedFrameSize;
14906e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  int input_frame_size = input_->GetFrameSize();
14916e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  int output_frame_size = height_in_bytes + fixed_frame_size;
14926e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  if (trace_) {
14936e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    PrintF("  translating %s => StubFailureTrampolineStub, height=%d\n",
14946e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false),
14956e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           height_in_bytes);
14966e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
14976e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
14986e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // The stub failure trampoline is a single frame.
14996e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  FrameDescription* output_frame =
15006e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      new(output_frame_size) FrameDescription(output_frame_size, NULL);
15016e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
15026e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(frame_index == 0);
15036e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_[frame_index] = output_frame;
15046e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
15056e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // The top address for the output frame can be computed from the input
15066e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // frame pointer and the output frame's height. Subtract space for the
15076e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // context and function slots.
15086e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  Register fp_reg = StubFailureTrampolineFrame::fp_register();
15096e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  intptr_t top_address = input_->GetRegister(fp_reg.code()) -
15106e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      (2 * kPointerSize) - height_in_bytes;
15116e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetTop(top_address);
15126e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
15136e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // Read caller's PC (JSFunction continuation) from the input frame.
1514c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  unsigned input_frame_offset = input_frame_size - kPCOnStackSize;
1515c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  unsigned output_frame_offset = output_frame_size - kFPOnStackSize;
15166e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  intptr_t value = input_->GetFrameSlot(input_frame_offset);
1517c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame->SetCallerPc(output_frame_offset, value);
15186e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  if (trace_) {
15196e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
15206e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           V8PRIxPTR " ; caller's pc\n",
15216e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           top_address + output_frame_offset, output_frame_offset, value);
15226e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
15236e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
15246e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // Read caller's FP from the input frame, and set this frame's FP.
1525c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  input_frame_offset -= kFPOnStackSize;
15266e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  value = input_->GetFrameSlot(input_frame_offset);
1527c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame_offset -= kFPOnStackSize;
1528c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  output_frame->SetCallerFp(output_frame_offset, value);
15296e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  intptr_t frame_ptr = input_->GetRegister(fp_reg.code());
15306e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetRegister(fp_reg.code(), frame_ptr);
15316e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetFp(frame_ptr);
15326e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  if (trace_) {
15336e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
15346e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           V8PRIxPTR " ; caller's fp\n",
15356e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           top_address + output_frame_offset, output_frame_offset, value);
15366e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
15376e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
15386e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // The context can be gotten from the input frame.
15396e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  Register context_reg = StubFailureTrampolineFrame::context_register();
15406e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  input_frame_offset -= kPointerSize;
15416e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  value = input_->GetFrameSlot(input_frame_offset);
15426e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetRegister(context_reg.code(), value);
15436e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame_offset -= kPointerSize;
15446e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetFrameSlot(output_frame_offset, value);
15456e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  if (trace_) {
15466e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
15476e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           V8PRIxPTR " ; context\n",
15486e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           top_address + output_frame_offset, output_frame_offset, value);
15496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
15506e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
15516e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // A marker value is used in place of the function.
15526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame_offset -= kPointerSize;
15536e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  value = reinterpret_cast<intptr_t>(
15546e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE));
15556e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetFrameSlot(output_frame_offset, value);
15566e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  if (trace_) {
15576e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
15586e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           V8PRIxPTR " ; function (stub failure sentinel)\n",
15596e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           top_address + output_frame_offset, output_frame_offset, value);
15606e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
15616e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
15626e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  intptr_t caller_arg_count = 0;
1563f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  bool arg_count_known = descriptor->stack_parameter_count_ == NULL;
15646e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
15656e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // Build the Arguments object for the caller's parameters and a pointer to it.
15666e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame_offset -= kPointerSize;
1567f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  int args_arguments_offset = output_frame_offset;
1568f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  intptr_t the_hole = reinterpret_cast<intptr_t>(
1569f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      isolate_->heap()->the_hole_value());
1570f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (arg_count_known) {
1571f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
1572f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        (caller_arg_count - 1) * kPointerSize;
1573f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else {
1574f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    value = the_hole;
1575f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
1576f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
1577f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  output_frame->SetFrameSlot(args_arguments_offset, value);
15786e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  if (trace_) {
15796e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1580f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           V8PRIxPTR " ; args.arguments %s\n",
1581f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           top_address + args_arguments_offset, args_arguments_offset, value,
1582f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           arg_count_known ? "" : "(the hole)");
15836e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
15846e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
15856e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame_offset -= kPointerSize;
1586f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  int length_frame_offset = output_frame_offset;
1587f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  value = arg_count_known ? caller_arg_count : the_hole;
1588f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  output_frame->SetFrameSlot(length_frame_offset, value);
15896e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  if (trace_) {
15906e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1591f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           V8PRIxPTR " ; args.length %s\n",
1592f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           top_address + length_frame_offset, length_frame_offset, value,
1593f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           arg_count_known ? "" : "(the hole)");
15946e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
15956e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
15966e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame_offset -= kPointerSize;
15971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  value = frame_ptr + StandardFrameConstants::kCallerSPOffset -
15981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      (output_frame_size - output_frame_offset) + kPointerSize;
15996e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetFrameSlot(output_frame_offset, value);
16006e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  if (trace_) {
16016e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
16026e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           V8PRIxPTR " ; args*\n",
16036e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org           top_address + output_frame_offset, output_frame_offset, value);
16046e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
16056e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
16066e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // Copy the register parameters to the failure frame.
16076e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  for (int i = 0; i < descriptor->register_param_count_; ++i) {
16086e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    output_frame_offset -= kPointerSize;
16096e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    DoTranslateCommand(iterator, 0, output_frame_offset);
16106e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
16116e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
1612f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (!arg_count_known) {
1613f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    DoTranslateCommand(iterator, 0, length_frame_offset,
1614f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                       TRANSLATED_VALUE_IS_NATIVE);
1615f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    caller_arg_count = output_frame->GetFrameSlot(length_frame_offset);
1616f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
1617f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        (caller_arg_count - 1) * kPointerSize;
1618f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    output_frame->SetFrameSlot(args_arguments_offset, value);
1619f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    if (trace_) {
1620f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1621f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org             V8PRIxPTR " ; args.arguments\n",
1622f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org             top_address + args_arguments_offset, args_arguments_offset, value);
1623f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    }
1624f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
1625f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
16266e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(0 == output_frame_offset);
16276e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
16286e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // Copy the double registers from the input into the output frame.
16296e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  CopyDoubleRegisters(output_frame);
16306e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
16316e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // Fill registers containing handler and number of parameters.
16326e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  SetPlatformCompiledStubRegisters(output_frame, descriptor);
16336e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
16346e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // Compute this frame's PC, state, and continuation.
16356e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  Code* trampoline = NULL;
1636f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  StubFunctionMode function_mode = descriptor->function_mode_;
1637f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline,
1638f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                                           isolate_);
16396e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(trampoline != NULL);
16406e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetPc(reinterpret_cast<intptr_t>(
16416e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      trampoline->instruction_start()));
16426e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
16436e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  Code* notify_failure =
16446e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      isolate_->builtins()->builtin(Builtins::kNotifyStubFailure);
16456e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  output_frame->SetContinuation(
16466e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      reinterpret_cast<intptr_t>(notify_failure->entry()));
16476e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org}
16486e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
16496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
1650594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgHandle<Object> Deoptimizer::MaterializeNextHeapObject() {
1651594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int object_index = materialization_object_index_++;
1652594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ObjectMaterializationDescriptor desc = deferred_objects_[object_index];
1653594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  const int length = desc.object_length();
1654594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1655594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (desc.duplicate_object() >= 0) {
1656594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Found a previously materialized object by de-duplication.
1657594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    object_index = desc.duplicate_object();
1658594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    materialized_objects_->Add(Handle<Object>());
1659594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else if (desc.is_arguments() && ArgumentsObjectIsAdapted(object_index)) {
1660594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Use the arguments adapter frame we just built to materialize the
1661594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // arguments object. FunctionGetArguments can't throw an exception.
1662594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Handle<JSFunction> function = ArgumentsObjectFunction(object_index);
1663594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Handle<JSObject> arguments = Handle<JSObject>::cast(
1664594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        Accessors::FunctionGetArguments(function));
1665594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    materialized_objects_->Add(arguments);
1666594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    materialization_value_index_ += length;
1667594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else if (desc.is_arguments()) {
1668594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Construct an arguments object and copy the parameters to a newly
1669594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // allocated arguments object backing store.
1670594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Handle<JSFunction> function = ArgumentsObjectFunction(object_index);
1671594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Handle<JSObject> arguments =
1672594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        isolate_->factory()->NewArgumentsObject(function, length);
1673594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
1674594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(array->length() == length);
1675594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    arguments->set_elements(*array);
1676594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    materialized_objects_->Add(arguments);
1677594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    for (int i = 0; i < length; ++i) {
1678594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Handle<Object> value = MaterializeNextValue();
1679594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      array->set(i, *value);
1680594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
1681594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else {
1682594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Dispatch on the instance type of the object to be materialized.
1683594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Handle<Map> map = Handle<Map>::cast(MaterializeNextValue());
1684594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    switch (map->instance_type()) {
1685594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      case HEAP_NUMBER_TYPE: {
1686594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        Handle<HeapNumber> number =
1687594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            Handle<HeapNumber>::cast(MaterializeNextValue());
1688594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        materialized_objects_->Add(number);
1689594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        materialization_value_index_ += kDoubleSize / kPointerSize - 1;
1690594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        break;
1691594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
1692594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      case JS_OBJECT_TYPE: {
1693594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        Handle<JSObject> object =
1694594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED, false);
1695594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        materialized_objects_->Add(object);
1696594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        Handle<Object> properties = MaterializeNextValue();
1697594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        Handle<Object> elements = MaterializeNextValue();
1698594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        object->set_properties(FixedArray::cast(*properties));
1699594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        object->set_elements(FixedArray::cast(*elements));
1700594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        for (int i = 0; i < length - 3; ++i) {
1701594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          Handle<Object> value = MaterializeNextValue();
1702594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          object->FastPropertyAtPut(i, *value);
1703594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        }
1704594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        break;
1705594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
1706594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      default:
1707594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        PrintF("[couldn't handle instance type %d]\n", map->instance_type());
1708594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        UNREACHABLE();
1709594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
1710594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
1711594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1712594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return materialized_objects_->at(object_index);
1713594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
1714594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1715594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1716594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgHandle<Object> Deoptimizer::MaterializeNextValue() {
1717594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int value_index = materialization_value_index_++;
1718594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<Object> value = materialized_values_->at(value_index);
1719594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (*value == isolate_->heap()->arguments_marker()) {
1720594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    value = MaterializeNextHeapObject();
1721594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
1722594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return value;
1723594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
1724594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1725594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
172656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.orgvoid Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
17274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ASSERT_NE(DEBUGGER, bailout_type_);
172856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
1729594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Walk all JavaScript output frames with the given frame iterator.
1730594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) {
1731594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (frame_index != 0) it->Advance();
1732594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    JavaScriptFrame* frame = it->frame();
1733594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    jsframe_functions_.Add(handle(frame->function(), isolate_));
1734594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    jsframe_has_adapted_arguments_.Add(frame->has_adapted_arguments());
1735594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
1736594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1737b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // Handlify all tagged object values before triggering any allocation.
1738b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  List<Handle<Object> > values(deferred_objects_tagged_values_.length());
1739b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  for (int i = 0; i < deferred_objects_tagged_values_.length(); ++i) {
1740b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    values.Add(Handle<Object>(deferred_objects_tagged_values_[i], isolate_));
174156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  }
174256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
174356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  // Play it safe and clear all unhandlified values before we continue.
1744b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  deferred_objects_tagged_values_.Clear();
174556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
174656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  // Materialize all heap numbers before looking at arguments because when the
174756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  // output frames are used to materialize arguments objects later on they need
174856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  // to already contain valid heap numbers.
174944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
175044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
175144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    Handle<Object> num = isolate_->factory()->NewNumber(d.value());
17522f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org    if (trace_) {
1753594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      PrintF("Materialized a new heap number %p [%e] in slot %p\n",
175444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org             reinterpret_cast<void*>(*num),
175544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org             d.value(),
175644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org             d.slot_address());
175744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    }
175844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    Memory::Object_at(d.slot_address()) = *num;
1759a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
176056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
1761594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Materialize all heap numbers required for arguments/captured objects.
1762b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  for (int i = 0; i < values.length(); i++) {
1763b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (!values.at(i)->IsTheHole()) continue;
1764b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    double double_value = deferred_objects_double_values_[i];
1765b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    Handle<Object> num = isolate_->factory()->NewNumber(double_value);
1766b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (trace_) {
1767594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      PrintF("Materialized a new heap number %p [%e] for object\n",
1768b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org             reinterpret_cast<void*>(*num), double_value);
1769b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
1770b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    values.Set(i, num);
1771b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
1772b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1773594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Materialize arguments/captured objects.
1774594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!deferred_objects_.is_empty()) {
1775594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    List<Handle<Object> > materialized_objects(deferred_objects_.length());
1776594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    materialized_objects_ = &materialized_objects;
1777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    materialized_values_ = &values;
1778594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1779594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    while (materialization_object_index_ < deferred_objects_.length()) {
1780594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      int object_index = materialization_object_index_;
1781594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      ObjectMaterializationDescriptor descriptor =
1782594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          deferred_objects_.at(object_index);
1783594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1784594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // Find a previously materialized object by de-duplication or
1785594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // materialize a new instance of the object if necessary. Store
1786594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // the materialized object into the frame slot.
1787594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Handle<Object> object = MaterializeNextHeapObject();
1788594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Memory::Object_at(descriptor.slot_address()) = *object;
1789594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (trace_) {
1790594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        if (descriptor.is_arguments()) {
1791594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          PrintF("Materialized %sarguments object of length %d for %p: ",
1792594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "",
1793594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                 Handle<JSObject>::cast(object)->elements()->length(),
1794594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                 reinterpret_cast<void*>(descriptor.slot_address()));
1795594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        } else {
1796594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          PrintF("Materialized captured object of size %d for %p: ",
1797594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                 Handle<HeapObject>::cast(object)->Size(),
179856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org                 reinterpret_cast<void*>(descriptor.slot_address()));
179956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        }
1800594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        object->ShortPrint();
1801594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        PrintF("\n");
180256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      }
180356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    }
1804594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1805594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(materialization_object_index_ == materialized_objects_->length());
1806594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(materialization_value_index_ == materialized_values_->length());
180756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  }
1808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
18114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
18124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgvoid Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
1813659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Address parameters_top,
1814659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    uint32_t parameters_size,
1815659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Address expressions_top,
1816659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    uint32_t expressions_size,
1817659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    DeoptimizedFrameInfo* info) {
18184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ASSERT_EQ(DEBUGGER, bailout_type_);
1819659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  Address parameters_bottom = parameters_top + parameters_size;
1820659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  Address expressions_bottom = expressions_top + expressions_size;
18214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
18224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
18234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
18244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // Check of the heap number to materialize actually belong to the frame
18254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // being extracted.
18264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    Address slot = d.slot_address();
1827659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (parameters_top <= slot && slot < parameters_bottom) {
18284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      Handle<Object> num = isolate_->factory()->NewNumber(d.value());
1829659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1830659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      int index = (info->parameters_count() - 1) -
1831659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          static_cast<int>(slot - parameters_top) / kPointerSize;
1832659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
18332f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
18344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        PrintF("Materializing a new heap number %p [%e] in slot %p"
1835659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org               "for parameter slot #%d\n",
18364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org               reinterpret_cast<void*>(*num),
18374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org               d.value(),
18384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org               d.slot_address(),
18396db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org               index);
18406db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org      }
1841659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1842659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      info->SetParameter(index, *num);
1843659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    } else if (expressions_top <= slot && slot < expressions_bottom) {
1844659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      Handle<Object> num = isolate_->factory()->NewNumber(d.value());
1845659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1846659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      int index = info->expression_count() - 1 -
1847659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          static_cast<int>(slot - expressions_top) / kPointerSize;
1848659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
18492f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
1850659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        PrintF("Materializing a new heap number %p [%e] in slot %p"
1851659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org               "for expression slot #%d\n",
1852659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org               reinterpret_cast<void*>(*num),
1853659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org               d.value(),
1854659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org               d.slot_address(),
1855659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org               index);
18564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      }
1857659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1858659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      info->SetExpression(index, *num);
18594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    }
18604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
18614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
18624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif
18634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
18644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1865b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgstatic const char* TraceValueType(bool is_smi, bool is_native = false) {
1866f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (is_native) {
1867f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return "native";
1868f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else if (is_smi) {
1869f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return "smi";
1870f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
1871f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
1872f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return "heap number";
1873f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
1874f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
1875f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
1876b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgvoid Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
1877594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                    int object_index,
1878b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                    int field_index) {
1879b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  disasm::NameConverter converter;
1880594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Address object_slot = deferred_objects_[object_index].slot_address();
1881b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1882b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  Translation::Opcode opcode =
1883b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      static_cast<Translation::Opcode>(iterator->Next());
1884b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1885b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  switch (opcode) {
1886b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::BEGIN:
1887b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::JS_FRAME:
1888b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::ARGUMENTS_ADAPTOR_FRAME:
1889b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::CONSTRUCT_STUB_FRAME:
1890b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::GETTER_STUB_FRAME:
1891b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::SETTER_STUB_FRAME:
1892b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::COMPILED_STUB_FRAME:
1893b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      UNREACHABLE();
1894b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
1895b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1896b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::REGISTER: {
1897b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      int input_reg = iterator->Next();
1898b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      intptr_t input_value = input_->GetRegister(input_reg);
1899b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (trace_) {
1900b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1901b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               reinterpret_cast<intptr_t>(object_slot),
1902b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               field_index);
1903b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("0x%08" V8PRIxPTR " ; %s ", input_value,
1904b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               converter.NameOfCPURegister(input_reg));
1905b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        reinterpret_cast<Object*>(input_value)->ShortPrint();
1906b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("\n");
1907b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
1908b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      AddObjectTaggedValue(input_value);
1909b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
1910b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
1911b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1912b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::INT32_REGISTER: {
1913b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      int input_reg = iterator->Next();
1914b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      intptr_t value = input_->GetRegister(input_reg);
1915b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      bool is_smi = Smi::IsValid(value);
1916b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (trace_) {
1917b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1918b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               reinterpret_cast<intptr_t>(object_slot),
1919b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               field_index);
1920b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("%" V8PRIdPTR " ; %s (%s)\n", value,
1921b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               converter.NameOfCPURegister(input_reg),
1922b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               TraceValueType(is_smi));
1923b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
1924b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (is_smi) {
1925b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        intptr_t tagged_value =
1926b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org            reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
1927b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        AddObjectTaggedValue(tagged_value);
1928b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      } else {
1929b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        double double_value = static_cast<double>(static_cast<int32_t>(value));
1930b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        AddObjectDoubleValue(double_value);
1931b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
1932b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
1933b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
1934b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1935b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::UINT32_REGISTER: {
1936b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      int input_reg = iterator->Next();
1937b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg));
1938b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
1939b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (trace_) {
1940b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1941b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               reinterpret_cast<intptr_t>(object_slot),
1942b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               field_index);
1943b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("%" V8PRIdPTR " ; uint %s (%s)\n", value,
1944b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               converter.NameOfCPURegister(input_reg),
1945b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               TraceValueType(is_smi));
1946b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
1947b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (is_smi) {
1948b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        intptr_t tagged_value =
1949b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org            reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
1950b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        AddObjectTaggedValue(tagged_value);
1951b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      } else {
1952b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        double double_value = static_cast<double>(static_cast<uint32_t>(value));
1953b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        AddObjectDoubleValue(double_value);
1954b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
1955b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
1956b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
1957b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1958b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::DOUBLE_REGISTER: {
1959b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      int input_reg = iterator->Next();
1960b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      double value = input_->GetDoubleRegister(input_reg);
1961b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (trace_) {
1962b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1963b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               reinterpret_cast<intptr_t>(object_slot),
1964b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               field_index);
1965b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("%e ; %s\n", value,
1966b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               DoubleRegister::AllocationIndexToString(input_reg));
1967b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
1968b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      AddObjectDoubleValue(value);
1969b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
1970b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
1971b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1972b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::STACK_SLOT: {
1973b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      int input_slot_index = iterator->Next();
1974b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
1975b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      intptr_t input_value = input_->GetFrameSlot(input_offset);
1976b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (trace_) {
1977b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1978b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               reinterpret_cast<intptr_t>(object_slot),
1979b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               field_index);
1980b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset);
1981b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        reinterpret_cast<Object*>(input_value)->ShortPrint();
1982b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("\n");
1983b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
1984b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      AddObjectTaggedValue(input_value);
1985b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
1986b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
1987b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1988b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::INT32_STACK_SLOT: {
1989b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      int input_slot_index = iterator->Next();
1990b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
1991b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      intptr_t value = input_->GetFrameSlot(input_offset);
1992b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      bool is_smi = Smi::IsValid(value);
1993b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (trace_) {
1994b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1995b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               reinterpret_cast<intptr_t>(object_slot),
1996b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               field_index);
1997b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("%" V8PRIdPTR " ; [sp + %d] (%s)\n",
1998b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               value, input_offset, TraceValueType(is_smi));
1999b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
2000b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (is_smi) {
2001b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        intptr_t tagged_value =
2002b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org            reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
2003b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        AddObjectTaggedValue(tagged_value);
2004b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      } else {
2005b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        double double_value = static_cast<double>(static_cast<int32_t>(value));
2006b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        AddObjectDoubleValue(double_value);
2007b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
2008b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
2009b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
2010b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2011b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::UINT32_STACK_SLOT: {
2012b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      int input_slot_index = iterator->Next();
2013b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
2014b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      uintptr_t value =
2015b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
2016b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
2017b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (trace_) {
2018b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2019b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               reinterpret_cast<intptr_t>(object_slot),
2020b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               field_index);
2021b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("%" V8PRIdPTR " ; [sp + %d] (uint %s)\n",
2022b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               value, input_offset, TraceValueType(is_smi));
2023b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
2024b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (is_smi) {
2025b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        intptr_t tagged_value =
2026b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org            reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
2027b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        AddObjectTaggedValue(tagged_value);
2028b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      } else {
2029b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        double double_value = static_cast<double>(static_cast<uint32_t>(value));
2030b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        AddObjectDoubleValue(double_value);
2031b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
2032b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
2033b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
2034b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2035b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::DOUBLE_STACK_SLOT: {
2036b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      int input_slot_index = iterator->Next();
2037b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
2038b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      double value = input_->GetDoubleFrameSlot(input_offset);
2039b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (trace_) {
2040b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2041b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               reinterpret_cast<intptr_t>(object_slot),
2042b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               field_index);
2043b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("%e ; [sp + %d]\n", value, input_offset);
2044b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
2045b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      AddObjectDoubleValue(value);
2046b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
2047b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
2048b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2049b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case Translation::LITERAL: {
2050b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      Object* literal = ComputeLiteral(iterator->Next());
2051b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (trace_) {
2052b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2053b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               reinterpret_cast<intptr_t>(object_slot),
2054b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org               field_index);
2055b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        literal->ShortPrint();
2056b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF(" ; literal\n");
2057b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
2058b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      intptr_t value = reinterpret_cast<intptr_t>(literal);
2059b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      AddObjectTaggedValue(value);
2060b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
2061b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
2062594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2063594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::DUPLICATED_OBJECT: {
2064594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      int object_index = iterator->Next();
2065594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (trace_) {
2066594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        PrintF("      nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
2067594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org               reinterpret_cast<intptr_t>(object_slot),
2068594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org               field_index);
2069594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        isolate_->heap()->arguments_marker()->ShortPrint();
2070594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        PrintF(" ; duplicate of object #%d\n", object_index);
2071594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
2072594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // Use the materialization marker value as a sentinel and fill in
2073594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // the object after the deoptimized frame is built.
2074594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      intptr_t value = reinterpret_cast<intptr_t>(
2075594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          isolate_->heap()->arguments_marker());
2076594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      AddObjectDuplication(0, object_index);
2077594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      AddObjectTaggedValue(value);
2078594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return;
2079594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
2080594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2081594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::ARGUMENTS_OBJECT:
2082594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::CAPTURED_OBJECT: {
2083594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      int length = iterator->Next();
2084594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
2085594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (trace_) {
2086594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        PrintF("      nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
2087594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org               reinterpret_cast<intptr_t>(object_slot),
2088594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org               field_index);
2089594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        isolate_->heap()->arguments_marker()->ShortPrint();
2090594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args);
2091594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
2092594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // Use the materialization marker value as a sentinel and fill in
2093594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // the object after the deoptimized frame is built.
2094594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      intptr_t value = reinterpret_cast<intptr_t>(
2095594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          isolate_->heap()->arguments_marker());
2096594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      AddObjectStart(0, length, is_args);
2097594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      AddObjectTaggedValue(value);
2098594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // We save the object values on the side and materialize the actual
2099594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // object after the deoptimized frame is built.
2100594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      int object_index = deferred_objects_.length() - 1;
2101594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      for (int i = 0; i < length; i++) {
2102594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        DoTranslateObject(iterator, object_index, i);
2103594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
2104594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return;
2105594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
2106b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
2107b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org}
2108b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2109b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
2111f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    int frame_index,
2112f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    unsigned output_offset,
2113f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    DeoptimizerTranslatedValueType value_type) {
2114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  disasm::NameConverter converter;
2115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // A GC-safe temporary placeholder that we can put in the output frame.
2116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0));
2117f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE;
2118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Translation::Opcode opcode =
2120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      static_cast<Translation::Opcode>(iterator->Next());
2121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  switch (opcode) {
2123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::BEGIN:
2124659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case Translation::JS_FRAME:
2125659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case Translation::ARGUMENTS_ADAPTOR_FRAME:
2126967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    case Translation::CONSTRUCT_STUB_FRAME:
2127de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    case Translation::GETTER_STUB_FRAME:
212846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case Translation::SETTER_STUB_FRAME:
2129a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case Translation::COMPILED_STUB_FRAME:
2130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      UNREACHABLE();
2131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
2132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::REGISTER: {
2134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int input_reg = iterator->Next();
2135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      intptr_t input_value = input_->GetRegister(input_reg);
21362f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
2137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        PrintF(
2138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ",
2139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            output_[frame_index]->GetTop() + output_offset,
2140a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            output_offset,
2141a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            input_value,
2142a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            converter.NameOfCPURegister(input_reg));
2143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        reinterpret_cast<Object*>(input_value)->ShortPrint();
2144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        PrintF("\n");
2145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output_[frame_index]->SetFrameSlot(output_offset, input_value);
2147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
2148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2149a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::INT32_REGISTER: {
2151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int input_reg = iterator->Next();
2152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      intptr_t value = input_->GetRegister(input_reg);
2153f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
2154f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          Smi::IsValid(value);
21552f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
2156a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        PrintF(
2157a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            "    0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n",
2158a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            output_[frame_index]->GetTop() + output_offset,
2159a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            output_offset,
2160a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            value,
2161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            converter.NameOfCPURegister(input_reg),
2162f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org            TraceValueType(is_smi, is_native));
2163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (is_smi) {
2165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        intptr_t tagged_value =
2166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
2167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
2168f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
2169f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, value);
2170a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      } else {
2171a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // We save the untagged value on the side and store a GC-safe
2172a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // temporary placeholder in the frame.
2173f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
217444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org        AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
217544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                       static_cast<double>(static_cast<int32_t>(value)));
2176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
2177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2178a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
2179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
218146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case Translation::UINT32_REGISTER: {
218246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      int input_reg = iterator->Next();
218346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg));
2184f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
2185f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          (value <= static_cast<uintptr_t>(Smi::kMaxValue));
21862f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
218746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        PrintF(
218846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org            "    0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR
218946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org            " ; uint %s (%s)\n",
219046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org            output_[frame_index]->GetTop() + output_offset,
219146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org            output_offset,
219246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org            value,
219346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org            converter.NameOfCPURegister(input_reg),
2194f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org            TraceValueType(is_smi, is_native));
219546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      }
219646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      if (is_smi) {
219746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        intptr_t tagged_value =
219846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org            reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
219946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
2200f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
2201f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, value);
220246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      } else {
220346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        // We save the untagged value on the side and store a GC-safe
220446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        // temporary placeholder in the frame.
2205f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
220646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
220746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                       static_cast<double>(static_cast<uint32_t>(value)));
220846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
220946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      }
221046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      return;
221146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
221246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
2213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::DOUBLE_REGISTER: {
2214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int input_reg = iterator->Next();
2215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      double value = input_->GetDoubleRegister(input_reg);
22162f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
2217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n",
2218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_[frame_index]->GetTop() + output_offset,
2219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_offset,
2220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               value,
2221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               DoubleRegister::AllocationIndexToString(input_reg));
2222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // We save the untagged value on the side and store a GC-safe
2224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // temporary placeholder in the frame.
222544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
2226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
2227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
2228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::STACK_SLOT: {
2231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int input_slot_index = iterator->Next();
2232b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
2233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      intptr_t input_value = input_->GetFrameSlot(input_offset);
22342f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
2235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        PrintF("    0x%08" V8PRIxPTR ": ",
2236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_[frame_index]->GetTop() + output_offset);
22377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ",
2238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_offset,
2239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               input_value,
2240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               input_offset);
2241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        reinterpret_cast<Object*>(input_value)->ShortPrint();
2242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        PrintF("\n");
2243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2244a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output_[frame_index]->SetFrameSlot(output_offset, input_value);
2245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
2246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::INT32_STACK_SLOT: {
2249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int input_slot_index = iterator->Next();
2250b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
2251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      intptr_t value = input_->GetFrameSlot(input_offset);
2252f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
2253f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          Smi::IsValid(value);
22542f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
2255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        PrintF("    0x%08" V8PRIxPTR ": ",
2256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_[frame_index]->GetTop() + output_offset);
22577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        PrintF("[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n",
2258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_offset,
2259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               value,
2260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               input_offset,
2261f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org               TraceValueType(is_smi, is_native));
2262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (is_smi) {
2264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        intptr_t tagged_value =
2265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
2266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
2267f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
2268f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, value);
2269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      } else {
2270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // We save the untagged value on the side and store a GC-safe
2271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // temporary placeholder in the frame.
2272f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
227344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org        AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
227444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                       static_cast<double>(static_cast<int32_t>(value)));
2275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
2276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
2278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
228046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case Translation::UINT32_STACK_SLOT: {
228146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      int input_slot_index = iterator->Next();
2282b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
228346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      uintptr_t value =
228446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
2285f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
2286f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          (value <= static_cast<uintptr_t>(Smi::kMaxValue));
22872f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
228846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        PrintF("    0x%08" V8PRIxPTR ": ",
228946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org               output_[frame_index]->GetTop() + output_offset);
229046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n",
229146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org               output_offset,
229246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org               value,
229346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org               input_offset,
2294f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org               TraceValueType(is_smi, is_native));
229546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      }
229646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      if (is_smi) {
229746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        intptr_t tagged_value =
229846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org            reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
229946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
2300f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
2301f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, value);
230246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      } else {
230346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        // We save the untagged value on the side and store a GC-safe
230446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        // temporary placeholder in the frame.
2305f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
230646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
230746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                       static_cast<double>(static_cast<uint32_t>(value)));
230846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
230946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      }
231046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      return;
231146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
231246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
2313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::DOUBLE_STACK_SLOT: {
2314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int input_slot_index = iterator->Next();
2315b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
2316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      double value = input_->GetDoubleFrameSlot(input_offset);
23172f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
23187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n",
2319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_[frame_index]->GetTop() + output_offset,
2320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_offset,
2321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               value,
2322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               input_offset);
2323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2324a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // We save the untagged value on the side and store a GC-safe
2325a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // temporary placeholder in the frame.
232644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
2327a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
2328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
2329a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::LITERAL: {
2332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      Object* literal = ComputeLiteral(iterator->Next());
23332f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
2334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- ",
2335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_[frame_index]->GetTop() + output_offset,
2336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_offset);
2337a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        literal->ShortPrint();
2338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        PrintF(" ; literal\n");
2339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      intptr_t value = reinterpret_cast<intptr_t>(literal);
2341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output_[frame_index]->SetFrameSlot(output_offset, value);
2342a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
2343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2345594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::DUPLICATED_OBJECT: {
2346594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      int object_index = iterator->Next();
2347594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (trace_) {
2348594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- ",
2349594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org               output_[frame_index]->GetTop() + output_offset,
2350594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org               output_offset);
2351594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        isolate_->heap()->arguments_marker()->ShortPrint();
2352594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        PrintF(" ; duplicate of object #%d\n", object_index);
2353594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
2354594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // Use the materialization marker value as a sentinel and fill in
2355594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // the object after the deoptimized frame is built.
2356594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      intptr_t value = reinterpret_cast<intptr_t>(
2357594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          isolate_->heap()->arguments_marker());
2358594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      AddObjectDuplication(output_[frame_index]->GetTop() + output_offset,
2359594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                           object_index);
2360594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      output_[frame_index]->SetFrameSlot(output_offset, value);
2361594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return;
2362594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
2363594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2364594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::ARGUMENTS_OBJECT:
2365594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::CAPTURED_OBJECT: {
2366b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      int length = iterator->Next();
2367594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
23682f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      if (trace_) {
2369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- ",
2370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_[frame_index]->GetTop() + output_offset,
2371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_offset);
2372ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate_->heap()->arguments_marker()->ShortPrint();
2373594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args);
2374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2375594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // Use the materialization marker value as a sentinel and fill in
2376594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // the object after the deoptimized frame is built.
2377ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      intptr_t value = reinterpret_cast<intptr_t>(
2378ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate_->heap()->arguments_marker());
2379594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      AddObjectStart(output_[frame_index]->GetTop() + output_offset,
2380594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     length, is_args);
2381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output_[frame_index]->SetFrameSlot(output_offset, value);
2382594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // We save the object values on the side and materialize the actual
2383594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // object after the deoptimized frame is built.
2384594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      int object_index = deferred_objects_.length() - 1;
2385b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      for (int i = 0; i < length; i++) {
2386594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        DoTranslateObject(iterator, object_index, i);
238756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      }
2388a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
2389a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2390a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2391a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2394a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
2395a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                        int* input_offset) {
2396a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  disasm::NameConverter converter;
2397a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  FrameDescription* output = output_[0];
2398a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2399a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // The input values are all part of the unoptimized frame so they
2400a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // are all tagged pointers.
2401a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  uintptr_t input_value = input_->GetFrameSlot(*input_offset);
2402a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Object* input_object = reinterpret_cast<Object*>(input_value);
2403a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Translation::Opcode opcode =
2405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      static_cast<Translation::Opcode>(iterator->Next());
2406a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2407a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  switch (opcode) {
2408a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::BEGIN:
2409659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case Translation::JS_FRAME:
2410659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case Translation::ARGUMENTS_ADAPTOR_FRAME:
2411967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    case Translation::CONSTRUCT_STUB_FRAME:
2412de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    case Translation::GETTER_STUB_FRAME:
241346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case Translation::SETTER_STUB_FRAME:
2414a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case Translation::COMPILED_STUB_FRAME:
2415a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      UNREACHABLE();  // Malformed input.
24161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      return false;
24171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
24181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    case Translation::REGISTER: {
24191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      int output_reg = iterator->Next();
24201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      if (FLAG_trace_osr) {
24211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        PrintF("    %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n",
24221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org               converter.NameOfCPURegister(output_reg),
24231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org               input_value,
24241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org               *input_offset);
24251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      }
24261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      output->SetRegister(output_reg, input_value);
24271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      break;
24281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }
2429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2430a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::INT32_REGISTER: {
243146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      int32_t int32_value = 0;
2432d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      if (!input_object->ToInt32(&int32_value)) return false;
2433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2434a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int output_reg = iterator->Next();
2435a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (FLAG_trace_osr) {
2436496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org        PrintF("    %s <- %d (int32) ; [sp + %d]\n",
2437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               converter.NameOfCPURegister(output_reg),
2438a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               int32_value,
2439a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               *input_offset);
2440a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output->SetRegister(output_reg, int32_value);
2442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
244546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case Translation::UINT32_REGISTER: {
244646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      uint32_t uint32_value = 0;
2447d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      if (!input_object->ToUint32(&uint32_value)) return false;
244846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
244946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      int output_reg = iterator->Next();
245046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      if (FLAG_trace_osr) {
245146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        PrintF("    %s <- %u (uint32) ; [sp + %d]\n",
245246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org               converter.NameOfCPURegister(output_reg),
245346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org               uint32_value,
245446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org               *input_offset);
245546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      }
245646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      output->SetRegister(output_reg, static_cast<int32_t>(uint32_value));
245746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
245846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
245946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
2460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::DOUBLE_REGISTER: {
2461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Abort OSR if we don't have a number.
2462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (!input_object->IsNumber()) return false;
2463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int output_reg = iterator->Next();
2465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      double double_value = input_object->Number();
2466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (FLAG_trace_osr) {
2467496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org        PrintF("    %s <- %g (double) ; [sp + %d]\n",
2468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               DoubleRegister::AllocationIndexToString(output_reg),
2469a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               double_value,
2470a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               *input_offset);
2471a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2472a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output->SetDoubleRegister(output_reg, double_value);
2473a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2474a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::STACK_SLOT: {
2477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int output_index = iterator->Next();
2478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      unsigned output_offset =
2479659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          output->GetOffsetFromSlotIndex(output_index);
2480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (FLAG_trace_osr) {
2481394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        PrintF("    [sp + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ",
2482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_offset,
2483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               input_value,
2484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               *input_offset);
2485394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        reinterpret_cast<Object*>(input_value)->ShortPrint();
2486394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        PrintF("\n");
2487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output->SetFrameSlot(output_offset, input_value);
2489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::INT32_STACK_SLOT: {
249346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      int32_t int32_value = 0;
2494d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      if (!input_object->ToInt32(&int32_value)) return false;
2495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int output_index = iterator->Next();
2497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      unsigned output_offset =
2498659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          output->GetOffsetFromSlotIndex(output_index);
2499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (FLAG_trace_osr) {
2500496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org        PrintF("    [sp + %d] <- %d (int32) ; [sp + %d]\n",
2501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_offset,
2502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               int32_value,
2503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               *input_offset);
2504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output->SetFrameSlot(output_offset, int32_value);
2506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
250946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case Translation::UINT32_STACK_SLOT: {
251046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      uint32_t uint32_value = 0;
2511d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      if (!input_object->ToUint32(&uint32_value)) return false;
251246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
251346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      int output_index = iterator->Next();
251446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      unsigned output_offset =
251546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          output->GetOffsetFromSlotIndex(output_index);
251646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      if (FLAG_trace_osr) {
251746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        PrintF("    [sp + %d] <- %u (uint32) ; [sp + %d]\n",
251846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org               output_offset,
251946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org               uint32_value,
252046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org               *input_offset);
252146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      }
252246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      output->SetFrameSlot(output_offset, static_cast<int32_t>(uint32_value));
252346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      break;
252446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
252546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
2526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::DOUBLE_STACK_SLOT: {
2527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      static const int kLowerOffset = 0 * kPointerSize;
2528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      static const int kUpperOffset = 1 * kPointerSize;
2529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Abort OSR if we don't have a number.
2531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (!input_object->IsNumber()) return false;
2532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int output_index = iterator->Next();
2534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      unsigned output_offset =
2535659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          output->GetOffsetFromSlotIndex(output_index);
2536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      double double_value = input_object->Number();
2537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      uint64_t int_value = BitCast<uint64_t, double>(double_value);
2538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int32_t lower = static_cast<int32_t>(int_value);
2539a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int32_t upper = static_cast<int32_t>(int_value >> kBitsPerInt);
2540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (FLAG_trace_osr) {
2541496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org        PrintF("    [sp + %d] <- 0x%08x (upper bits of %g) ; [sp + %d]\n",
2542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_offset + kUpperOffset,
2543a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               upper,
2544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               double_value,
2545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               *input_offset);
2546496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org        PrintF("    [sp + %d] <- 0x%08x (lower bits of %g) ; [sp + %d]\n",
2547a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               output_offset + kLowerOffset,
2548a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               lower,
2549a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               double_value,
2550a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               *input_offset);
2551a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
2552a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output->SetFrameSlot(output_offset + kLowerOffset, lower);
2553a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      output->SetFrameSlot(output_offset + kUpperOffset, upper);
2554a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2555a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2556a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Translation::LITERAL: {
2558a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Just ignore non-materialized literals.
2559a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      iterator->Next();
2560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2563594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::DUPLICATED_OBJECT:
2564594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::ARGUMENTS_OBJECT:
2565594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::CAPTURED_OBJECT: {
2566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Optimized code assumes that the argument object has not been
2567a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // materialized and so bypasses it when doing arguments access.
2568a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // We should have bailed out before starting the frame
2569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // translation.
2570a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      UNREACHABLE();
2571a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return false;
2572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2573a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2574a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
25751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  *input_offset -= kPointerSize;
2576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return true;
2577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2580e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid Deoptimizer::PatchInterruptCode(Code* unoptimized_code,
2581e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                     Code* interrupt_code,
2582e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                     Code* replacement_code) {
2583e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Iterate over the back edge table and patch every interrupt
258431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  // call to an unconditional call to the replacement code.
2585e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int loop_nesting_level = unoptimized_code->allow_osr_at_loop_nesting_level();
2586594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2587594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  for (FullCodeGenerator::BackEdgeTableIterator back_edges(unoptimized_code);
2588594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org       !back_edges.Done();
2589594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org       back_edges.Next()) {
2590594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (static_cast<int>(back_edges.loop_depth()) == loop_nesting_level) {
2591e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      PatchInterruptCodeAt(unoptimized_code,
2592594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                           back_edges.pc(),
2593e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                           interrupt_code,
2594e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                           replacement_code);
2595e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
259631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  }
2597594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2598e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  unoptimized_code->set_back_edges_patched_for_osr(true);
2599e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#ifdef DEBUG
2600e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Deoptimizer::VerifyInterruptCode(
2601e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      unoptimized_code, interrupt_code, replacement_code, loop_nesting_level);
2602e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif  // DEBUG
260331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org}
260431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
260531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
2606e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid Deoptimizer::RevertInterruptCode(Code* unoptimized_code,
2607e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                      Code* interrupt_code,
2608e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                      Code* replacement_code) {
2609e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Iterate over the back edge table and revert the patched interrupt calls.
2610e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(unoptimized_code->back_edges_patched_for_osr());
2611e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int loop_nesting_level = unoptimized_code->allow_osr_at_loop_nesting_level();
2612594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2613594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  for (FullCodeGenerator::BackEdgeTableIterator back_edges(unoptimized_code);
2614594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org       !back_edges.Done();
2615594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org       back_edges.Next()) {
2616594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (static_cast<int>(back_edges.loop_depth()) <= loop_nesting_level) {
2617e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      RevertInterruptCodeAt(unoptimized_code,
2618594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                            back_edges.pc(),
2619e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                            interrupt_code,
2620e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                            replacement_code);
2621e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
2622e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
2623594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2624e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  unoptimized_code->set_back_edges_patched_for_osr(false);
2625fee992bb82f8bc64bb35d7133567a2f6d2671b64jkummerow@chromium.org  unoptimized_code->set_allow_osr_at_loop_nesting_level(0);
2626e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#ifdef DEBUG
2627e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Assert that none of the back edges are patched anymore.
2628e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Deoptimizer::VerifyInterruptCode(
2629e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      unoptimized_code, interrupt_code, replacement_code, -1);
2630e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif  // DEBUG
2631e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
2632e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2633e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2634e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#ifdef DEBUG
2635e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid Deoptimizer::VerifyInterruptCode(Code* unoptimized_code,
2636e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                      Code* interrupt_code,
2637e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                      Code* replacement_code,
2638e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                      int loop_nesting_level) {
2639594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  for (FullCodeGenerator::BackEdgeTableIterator back_edges(unoptimized_code);
2640594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org       !back_edges.Done();
2641594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org       back_edges.Next()) {
2642594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uint32_t loop_depth = back_edges.loop_depth();
2643ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    CHECK_LE(static_cast<int>(loop_depth), Code::kMaxLoopNestingMarker);
2644e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Assert that all back edges for shallower loops (and only those)
2645e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // have already been patched.
2646ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    CHECK_EQ((static_cast<int>(loop_depth) <= loop_nesting_level),
2647e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org             InterruptCodeIsPatched(unoptimized_code,
2648594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                    back_edges.pc(),
2649e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                    interrupt_code,
2650e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                    replacement_code));
265131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  }
265231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org}
2653e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif  // DEBUG
265431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
265531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
2656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgunsigned Deoptimizer::ComputeInputFrameSize() const {
2657a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  unsigned fixed_size = ComputeFixedSize(function_);
2658a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // The fp-to-sp delta already takes the context and the function
2659a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // into account so we have to avoid double counting them (-2).
2660a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  unsigned result = fixed_size + fp_to_sp_delta_ - (2 * kPointerSize);
2661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
2662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (bailout_type_ == OSR) {
2663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // TODO(kasperl): It would be nice if we could verify that the
2664a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // size matches with the stack height we can compute based on the
2665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // environment at the OSR entry. The code for that his built into
2666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // the DoComputeOsrOutputFrame function for now.
2667b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  } else if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
2668a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    unsigned stack_slots = compiled_code_->stack_slots();
26692f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org    unsigned outgoing_size = ComputeOutgoingArgumentSize();
2670a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size);
2671a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2672a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
2673a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return result;
2674a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2675a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2676a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2677a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgunsigned Deoptimizer::ComputeFixedSize(JSFunction* function) const {
2678a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // The fixed part of the frame consists of the return address, frame
2679a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // pointer, function, context, and all the incoming arguments.
2680659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  return ComputeIncomingArgumentSize(function) +
2681659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      StandardFrameConstants::kFixedFrameSize;
2682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2685a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgunsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const {
2686a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // The incoming arguments is the values for formal parameters and
2687a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // the receiver. Every slot contains a pointer.
2688a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (function->IsSmi()) {
2689a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(Smi::cast(function) == Smi::FromInt(StackFrame::STUB));
2690a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return 0;
2691a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
2692a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  unsigned arguments = function->shared()->formal_parameter_count() + 1;
2693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return arguments * kPointerSize;
2694a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2695a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2696a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2697a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgunsigned Deoptimizer::ComputeOutgoingArgumentSize() const {
2698a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeoptimizationInputData* data = DeoptimizationInputData::cast(
2699a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      compiled_code_->deoptimization_data());
2700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  unsigned height = data->ArgumentsStackHeight(bailout_id_)->value();
2701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return height * kPointerSize;
2702a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2704a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2705a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgObject* Deoptimizer::ComputeLiteral(int index) const {
2706a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeoptimizationInputData* data = DeoptimizationInputData::cast(
2707a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      compiled_code_->deoptimization_data());
2708a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  FixedArray* literals = data->LiteralArray();
2709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return literals->get(index);
2710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2711a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2712a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2713594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid Deoptimizer::AddObjectStart(intptr_t slot, int length, bool is_args) {
2714b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  ObjectMaterializationDescriptor object_desc(
2715594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      reinterpret_cast<Address>(slot), jsframe_count_, length, -1, is_args);
2716594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  deferred_objects_.Add(object_desc);
2717594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
2718594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2719594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2720594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid Deoptimizer::AddObjectDuplication(intptr_t slot, int object_index) {
2721594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ObjectMaterializationDescriptor object_desc(
2722594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      reinterpret_cast<Address>(slot), jsframe_count_, -1, object_index, false);
2723b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  deferred_objects_.Add(object_desc);
272456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org}
272556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
272656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
2727b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgvoid Deoptimizer::AddObjectTaggedValue(intptr_t value) {
2728b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  deferred_objects_tagged_values_.Add(reinterpret_cast<Object*>(value));
2729b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  deferred_objects_double_values_.Add(isolate()->heap()->nan_value()->value());
2730b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org}
2731b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2732b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2733b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgvoid Deoptimizer::AddObjectDoubleValue(double value) {
2734b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value());
2735b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  deferred_objects_double_values_.Add(value);
273656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org}
273756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
273856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
273956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.orgvoid Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) {
274044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  HeapNumberMaterializationDescriptor value_desc(
274144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      reinterpret_cast<Address>(slot_address), value);
274244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  deferred_heap_numbers_.Add(value_desc);
2743a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2744a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2745a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27468432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgvoid Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
27478432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org                                                   BailoutType type,
2748e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                                                   int max_entry_id) {
2749a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // We cannot run this if the serializer is enabled because this will
2750a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // cause us to emit relocation information for the external
2751a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // references. This is fine because the deoptimizer's code section
2752a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // isn't meant to be serialized at all.
2753aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  ASSERT(type == EAGER || type == SOFT || type == LAZY);
27548432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  DeoptimizerData* data = isolate->deoptimizer_data();
2755aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  int entry_count = data->deopt_entry_code_entries_[type];
2756e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (max_entry_id < entry_count) return;
2757a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  entry_count = Max(entry_count, Deoptimizer::kMinNumberOfEntries);
2758a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  while (max_entry_id >= entry_count) entry_count *= 2;
2759a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(entry_count <= Deoptimizer::kMaxNumberOfEntries);
2760e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
27618432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  MacroAssembler masm(isolate, NULL, 16 * KB);
2762badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  masm.set_emit_debug_code(false);
2763e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  GenerateDeoptimizationEntries(&masm, entry_count, type);
2764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CodeDesc desc;
2765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  masm.GetCode(&desc);
27662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  ASSERT(!RelocInfo::RequiresRelocation(desc));
2767a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2768aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  MemoryChunk* chunk = data->deopt_entry_code_[type];
2769068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  ASSERT(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >=
2770068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org         desc.instr_size);
2771068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  chunk->CommitArea(desc.instr_size);
2772f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CopyBytes(chunk->area_start(), desc.buffer,
2773f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      static_cast<size_t>(desc.instr_size));
2774068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  CPU::FlushICache(chunk->area_start(), desc.instr_size);
2775e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
2776aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  data->deopt_entry_code_entries_[type] = entry_count;
2777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2778a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgFrameDescription::FrameDescription(uint32_t frame_size,
2781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                   JSFunction* function)
2782a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    : frame_size_(frame_size),
2783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      function_(function),
2784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      top_(kZapUint32),
2785a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      pc_(kZapUint32),
2786967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      fp_(kZapUint32),
2787967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      context_(kZapUint32) {
2788a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Zap all the registers.
2789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int r = 0; r < Register::kNumRegisters; r++) {
2790a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    SetRegister(r, kZapUint32);
2791a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Zap all the slots.
2794a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (unsigned o = 0; o < frame_size; o += kPointerSize) {
2795a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    SetFrameSlot(o, kZapUint32);
2796a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2797a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2798a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2799a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2800659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgint FrameDescription::ComputeFixedSize() {
2801659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  return StandardFrameConstants::kFixedFrameSize +
2802659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      (ComputeParametersCount() + 1) * kPointerSize;
2803659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
2804659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2805659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2806659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgunsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) {
2807a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (slot_index >= 0) {
2808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Local or spill slots. Skip the fixed part of the frame
2809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // including all arguments.
2810659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    unsigned base = GetFrameSize() - ComputeFixedSize();
2811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return base - ((slot_index + 1) * kPointerSize);
2812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
2813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Incoming parameter.
2814659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int arg_size = (ComputeParametersCount() + 1) * kPointerSize;
2815659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    unsigned base = GetFrameSize() - arg_size;
2816a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return base - ((slot_index + 1) * kPointerSize);
2817a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2818a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2819a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2820a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
28216db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgint FrameDescription::ComputeParametersCount() {
2822659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  switch (type_) {
2823659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case StackFrame::JAVA_SCRIPT:
2824659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      return function_->shared()->formal_parameter_count();
2825659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case StackFrame::ARGUMENTS_ADAPTOR: {
2826659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      // Last slot contains number of incomming arguments as a smi.
2827659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      // Can't use GetExpression(0) because it would cause infinite recursion.
2828659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value();
2829659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
2830068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    case StackFrame::STUB:
283109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      return -1;  // Minus receiver.
2832659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    default:
2833659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      UNREACHABLE();
2834659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      return 0;
2835659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
28366db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org}
28376db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
28386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
2839659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgObject* FrameDescription::GetParameter(int index) {
28406db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  ASSERT(index >= 0);
28416db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  ASSERT(index < ComputeParametersCount());
28426db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // The slot indexes for incoming arguments are negative.
2843659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount());
28446db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
28456db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org}
28466db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
28476db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
2848659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgunsigned FrameDescription::GetExpressionCount() {
2849659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
2850659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  unsigned size = GetFrameSize() - ComputeFixedSize();
28514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return size / kPointerSize;
28524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
28534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
28544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2855659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgObject* FrameDescription::GetExpression(int index) {
2856659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
2857659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  unsigned offset = GetOffsetFromSlotIndex(index);
28584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
28594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
28604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
28614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2862400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.orgvoid TranslationBuffer::Add(int32_t value, Zone* zone) {
2863a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Encode the sign bit in the least significant bit.
2864a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool is_negative = (value < 0);
2865a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  uint32_t bits = ((is_negative ? -value : value) << 1) |
2866a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      static_cast<int32_t>(is_negative);
2867a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Encode the individual bytes using the least significant bit of
2868a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // each byte to indicate whether or not more bytes follow.
2869a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  do {
2870a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    uint32_t next = bits >> 7;
2871400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org    contents_.Add(((bits << 1) & 0xFF) | (next != 0), zone);
2872a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    bits = next;
2873a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } while (bits != 0);
2874a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2875a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2876a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2877a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint32_t TranslationIterator::Next() {
2878a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Run through the bytes until we reach one with a least significant
2879a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // bit of zero (marks the end).
2880a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  uint32_t bits = 0;
2881a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; true; i += 7) {
28827c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    ASSERT(HasNext());
2883a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    uint8_t next = buffer_->get(index_++);
2884a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    bits |= (next >> 1) << i;
2885a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if ((next & 1) == 0) break;
2886a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2887a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // The bits encode the sign in the least significant bit.
2888a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool is_negative = (bits & 1) == 1;
2889a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int32_t result = bits >> 1;
2890a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return is_negative ? -result : result;
2891a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2892a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2893a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2894876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.orgHandle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) {
2895a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int length = contents_.length();
2896876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  Handle<ByteArray> result = factory->NewByteArray(length, TENURED);
2897e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemCopy(
2898e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      result->GetDataStartAddress(), contents_.ToVector().start(), length);
2899a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return result;
2900a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2902a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2903967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgvoid Translation::BeginConstructStubFrame(int literal_id, unsigned height) {
2904400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(CONSTRUCT_STUB_FRAME, zone());
2905400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(literal_id, zone());
2906400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(height, zone());
2907967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org}
2908967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
2909967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
2910de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.orgvoid Translation::BeginGetterStubFrame(int literal_id) {
2911de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  buffer_->Add(GETTER_STUB_FRAME, zone());
2912de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  buffer_->Add(literal_id, zone());
2913de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org}
2914de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
2915de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
291646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid Translation::BeginSetterStubFrame(int literal_id) {
291746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  buffer_->Add(SETTER_STUB_FRAME, zone());
291846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  buffer_->Add(literal_id, zone());
291946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
292046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
292146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
2922659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgvoid Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) {
2923400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(ARGUMENTS_ADAPTOR_FRAME, zone());
2924400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(literal_id, zone());
2925400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(height, zone());
2926659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
2927659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2928659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2929471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid Translation::BeginJSFrame(BailoutId node_id,
2930471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                               int literal_id,
2931471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                               unsigned height) {
2932400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(JS_FRAME, zone());
2933471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  buffer_->Add(node_id.ToInt(), zone());
2934400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(literal_id, zone());
2935400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(height, zone());
2936a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2937a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2938a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2939a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid Translation::BeginCompiledStubFrame() {
2940a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  buffer_->Add(COMPILED_STUB_FRAME, zone());
2941a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
2942a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
2943a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
2944b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgvoid Translation::BeginArgumentsObject(int args_length) {
2945b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  buffer_->Add(ARGUMENTS_OBJECT, zone());
2946b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  buffer_->Add(args_length, zone());
2947b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org}
2948b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2949b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2950594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid Translation::BeginCapturedObject(int length) {
2951594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  buffer_->Add(CAPTURED_OBJECT, zone());
2952594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  buffer_->Add(length, zone());
2953594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
2954594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2955594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2956594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid Translation::DuplicateObject(int object_index) {
2957594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  buffer_->Add(DUPLICATED_OBJECT, zone());
2958594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  buffer_->Add(object_index, zone());
2959594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
2960594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2961594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2962a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Translation::StoreRegister(Register reg) {
2963400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(REGISTER, zone());
2964400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(reg.code(), zone());
2965a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2966a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2967a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2968a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Translation::StoreInt32Register(Register reg) {
2969400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(INT32_REGISTER, zone());
2970400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(reg.code(), zone());
2971a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2972a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2973a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
297446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid Translation::StoreUint32Register(Register reg) {
297546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  buffer_->Add(UINT32_REGISTER, zone());
297646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  buffer_->Add(reg.code(), zone());
297746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
297846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
297946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
2980a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Translation::StoreDoubleRegister(DoubleRegister reg) {
2981400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(DOUBLE_REGISTER, zone());
2982400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(DoubleRegister::ToAllocationIndex(reg), zone());
2983a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2984a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2985a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2986a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Translation::StoreStackSlot(int index) {
2987400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(STACK_SLOT, zone());
2988400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(index, zone());
2989a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2990a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2991a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2992a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Translation::StoreInt32StackSlot(int index) {
2993400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(INT32_STACK_SLOT, zone());
2994400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(index, zone());
2995a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2996a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2997a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
299846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid Translation::StoreUint32StackSlot(int index) {
299946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  buffer_->Add(UINT32_STACK_SLOT, zone());
300046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  buffer_->Add(index, zone());
300146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
300246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
300346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
3004a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Translation::StoreDoubleStackSlot(int index) {
3005400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(DOUBLE_STACK_SLOT, zone());
3006400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(index, zone());
3007a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3008a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3009a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3010a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Translation::StoreLiteral(int literal_id) {
3011400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(LITERAL, zone());
3012400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  buffer_->Add(literal_id, zone());
3013a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3014a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3015a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
30161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Translation::StoreArgumentsObject(bool args_known,
30171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                       int args_index,
30181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                       int args_length) {
30191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  buffer_->Add(ARGUMENTS_OBJECT, zone());
30201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  buffer_->Add(args_known, zone());
30211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  buffer_->Add(args_index, zone());
30221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  buffer_->Add(args_length, zone());
3023a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3024a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3025a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3026a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint Translation::NumberOfOperandsFor(Opcode opcode) {
3027a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  switch (opcode) {
3028de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    case GETTER_STUB_FRAME:
302946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case SETTER_STUB_FRAME:
3030594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case DUPLICATED_OBJECT:
3031b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case ARGUMENTS_OBJECT:
3032594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case CAPTURED_OBJECT:
3033a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case REGISTER:
3034a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case INT32_REGISTER:
303546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case UINT32_REGISTER:
3036a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case DOUBLE_REGISTER:
3037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case STACK_SLOT:
3038a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case INT32_STACK_SLOT:
303946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case UINT32_STACK_SLOT:
3040a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case DOUBLE_STACK_SLOT:
3041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case LITERAL:
3042a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case COMPILED_STUB_FRAME:
3043a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return 1;
3044659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case BEGIN:
3045659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case ARGUMENTS_ADAPTOR_FRAME:
3046967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    case CONSTRUCT_STUB_FRAME:
3047659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      return 2;
3048659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case JS_FRAME:
3049a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return 3;
3050a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3051a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UNREACHABLE();
3052a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return -1;
3053a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3054a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3055a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
30567b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
3057a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3058a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgconst char* Translation::StringFor(Opcode opcode) {
3059a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  switch (opcode) {
3060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case BEGIN:
3061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return "BEGIN";
3062659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case JS_FRAME:
3063659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      return "JS_FRAME";
3064659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case ARGUMENTS_ADAPTOR_FRAME:
3065659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      return "ARGUMENTS_ADAPTOR_FRAME";
3066967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    case CONSTRUCT_STUB_FRAME:
3067967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      return "CONSTRUCT_STUB_FRAME";
3068de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    case GETTER_STUB_FRAME:
3069de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      return "GETTER_STUB_FRAME";
307046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case SETTER_STUB_FRAME:
307146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      return "SETTER_STUB_FRAME";
3072a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case COMPILED_STUB_FRAME:
3073a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return "COMPILED_STUB_FRAME";
3074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case REGISTER:
3075a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return "REGISTER";
3076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case INT32_REGISTER:
3077a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return "INT32_REGISTER";
307846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case UINT32_REGISTER:
307946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      return "UINT32_REGISTER";
3080a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case DOUBLE_REGISTER:
3081a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return "DOUBLE_REGISTER";
3082a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case STACK_SLOT:
3083a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return "STACK_SLOT";
3084a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case INT32_STACK_SLOT:
3085a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return "INT32_STACK_SLOT";
308646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case UINT32_STACK_SLOT:
308746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      return "UINT32_STACK_SLOT";
3088a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case DOUBLE_STACK_SLOT:
3089a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return "DOUBLE_STACK_SLOT";
3090a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case LITERAL:
3091a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return "LITERAL";
3092594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case DUPLICATED_OBJECT:
3093594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return "DUPLICATED_OBJECT";
3094a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case ARGUMENTS_OBJECT:
3095a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return "ARGUMENTS_OBJECT";
3096594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case CAPTURED_OBJECT:
3097594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return "CAPTURED_OBJECT";
3098a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3099a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UNREACHABLE();
3100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return "";
3101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
3104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgDeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) {
3107876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  GlobalHandles* global_handles = code->GetIsolate()->global_handles();
3108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Globalize the code object and make it weak.
3109ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  code_ = Handle<Code>::cast(global_handles->Create(code));
3110ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->MakeWeak(reinterpret_cast<Object**>(code_.location()),
3111ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           this,
3112ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           Deoptimizer::HandleWeakDeoptimizedCode);
3113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgDeoptimizingCodeListNode::~DeoptimizingCodeListNode() {
3117876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  GlobalHandles* global_handles = code_->GetIsolate()->global_handles();
3118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->Destroy(reinterpret_cast<Object**>(code_.location()));
3119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3122c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// We can't intermix stack decoding and allocations because
3123c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// deoptimization infrastracture is not GC safe.
3124c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// Thus we build a temporary structure in malloced space.
3125c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgSlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator,
3126c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                                            DeoptimizationInputData* data,
3127c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                                            JavaScriptFrame* frame) {
3128c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Translation::Opcode opcode =
3129c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      static_cast<Translation::Opcode>(iterator->Next());
3130c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3131c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  switch (opcode) {
3132c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    case Translation::BEGIN:
3133659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case Translation::JS_FRAME:
3134659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    case Translation::ARGUMENTS_ADAPTOR_FRAME:
3135967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    case Translation::CONSTRUCT_STUB_FRAME:
3136de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    case Translation::GETTER_STUB_FRAME:
313746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case Translation::SETTER_STUB_FRAME:
3138c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      // Peeled off before getting here.
3139c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      break;
3140c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3141594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::DUPLICATED_OBJECT:
3142c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    case Translation::ARGUMENTS_OBJECT:
3143594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    case Translation::CAPTURED_OBJECT:
3144c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      // This can be only emitted for local slots not for argument slots.
3145c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      break;
3146c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3147c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    case Translation::REGISTER:
3148c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    case Translation::INT32_REGISTER:
314946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case Translation::UINT32_REGISTER:
3150c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    case Translation::DOUBLE_REGISTER:
3151c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      // We are at safepoint which corresponds to call.  All registers are
3152c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      // saved by caller so there would be no live registers at this
3153c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      // point. Thus these translation commands should not be used.
3154c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      break;
3155c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3156c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    case Translation::STACK_SLOT: {
3157c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      int slot_index = iterator->Next();
3158c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      Address slot_addr = SlotAddress(frame, slot_index);
3159c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      return SlotRef(slot_addr, SlotRef::TAGGED);
3160c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
3161c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3162c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    case Translation::INT32_STACK_SLOT: {
3163c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      int slot_index = iterator->Next();
3164c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      Address slot_addr = SlotAddress(frame, slot_index);
3165c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      return SlotRef(slot_addr, SlotRef::INT32);
3166c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
3167c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
316846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    case Translation::UINT32_STACK_SLOT: {
316946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      int slot_index = iterator->Next();
317046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      Address slot_addr = SlotAddress(frame, slot_index);
317146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      return SlotRef(slot_addr, SlotRef::UINT32);
317246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
317346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
3174c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    case Translation::DOUBLE_STACK_SLOT: {
3175c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      int slot_index = iterator->Next();
3176c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      Address slot_addr = SlotAddress(frame, slot_index);
3177c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      return SlotRef(slot_addr, SlotRef::DOUBLE);
3178c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
3179c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3180c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    case Translation::LITERAL: {
3181c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      int literal_index = iterator->Next();
318209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      return SlotRef(data->GetIsolate(),
318309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                     data->LiteralArray()->get(literal_index));
3184c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
3185a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
3186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case Translation::COMPILED_STUB_FRAME:
3187a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      UNREACHABLE();
3188a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      break;
3189c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
3190c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3191c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  UNREACHABLE();
3192c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  return SlotRef();
3193c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
3194c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3195c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3196659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgvoid SlotRef::ComputeSlotsForArguments(Vector<SlotRef>* args_slots,
3197659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                       TranslationIterator* it,
3198659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                       DeoptimizationInputData* data,
3199659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                       JavaScriptFrame* frame) {
3200659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  // Process the translation commands for the arguments.
3201659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
3202659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  // Skip the translation command for the receiver.
3203659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  it->Skip(Translation::NumberOfOperandsFor(
3204659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      static_cast<Translation::Opcode>(it->Next())));
3205659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
3206659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  // Compute slots for arguments.
3207659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  for (int i = 0; i < args_slots->length(); ++i) {
3208659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    (*args_slots)[i] = ComputeSlotForNextArgument(it, data, frame);
3209659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
3210659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
3211659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
3212659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
3213659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgVector<SlotRef> SlotRef::ComputeSlotMappingForArguments(
3214659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    JavaScriptFrame* frame,
3215659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int inlined_jsframe_index,
3216659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int formal_parameter_count) {
321779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
3218471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  int deopt_index = Safepoint::kNoDeoptimizationIndex;
3219c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  DeoptimizationInputData* data =
3220c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index);
3221c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  TranslationIterator it(data->TranslationByteArray(),
3222c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                         data->TranslationIndex(deopt_index)->value());
3223c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
3224c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  ASSERT(opcode == Translation::BEGIN);
3225659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  it.Next();  // Drop frame count.
3226659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int jsframe_count = it.Next();
3227659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  USE(jsframe_count);
3228659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  ASSERT(jsframe_count > inlined_jsframe_index);
3229659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int jsframes_to_skip = inlined_jsframe_index;
3230c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  while (true) {
3231c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    opcode = static_cast<Translation::Opcode>(it.Next());
3232659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) {
3233659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      if (jsframes_to_skip == 0) {
3234659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        ASSERT(Translation::NumberOfOperandsFor(opcode) == 2);
3235659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
3236659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        it.Skip(1);  // literal id
3237659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        int height = it.Next();
3238659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
3239659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        // We reached the arguments adaptor frame corresponding to the
3240659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        // inlined function in question.  Number of arguments is height - 1.
3241659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        Vector<SlotRef> args_slots =
3242659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org            Vector<SlotRef>::New(height - 1);  // Minus receiver.
3243659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        ComputeSlotsForArguments(&args_slots, &it, data, frame);
3244659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        return args_slots;
3245659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      }
3246659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    } else if (opcode == Translation::JS_FRAME) {
3247659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      if (jsframes_to_skip == 0) {
3248659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        // Skip over operands to advance to the next opcode.
3249659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        it.Skip(Translation::NumberOfOperandsFor(opcode));
3250659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
3251c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org        // We reached the frame corresponding to the inlined function
3252c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org        // in question.  Process the translation commands for the
3253659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        // arguments.  Number of arguments is equal to the number of
3254659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        // format parameter count.
3255659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        Vector<SlotRef> args_slots =
3256659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org            Vector<SlotRef>::New(formal_parameter_count);
3257659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        ComputeSlotsForArguments(&args_slots, &it, data, frame);
3258659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        return args_slots;
3259c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      }
3260659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      jsframes_to_skip--;
3261c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
3262659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
3263659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // Skip over operands to advance to the next opcode.
3264659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    it.Skip(Translation::NumberOfOperandsFor(opcode));
3265c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
3266c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3267c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  UNREACHABLE();
3268659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  return Vector<SlotRef>();
3269c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
3270c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
32717c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
3272c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3273967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgDeoptimizedFrameInfo::DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
3274967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                           int frame_index,
3275967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                           bool has_arguments_adaptor,
3276967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                           bool has_construct_stub) {
32774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  FrameDescription* output_frame = deoptimizer->output_[frame_index];
3278967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  function_ = output_frame->GetFunction();
3279967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  has_construct_stub_ = has_construct_stub;
3280659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  expression_count_ = output_frame->GetExpressionCount();
3281659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  expression_stack_ = new Object*[expression_count_];
3282fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Get the source position using the unoptimized code.
3283fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  Address pc = reinterpret_cast<Address>(output_frame->GetPc());
3284ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Code* code = Code::cast(deoptimizer->isolate()->FindCodeObject(pc));
3285fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  source_position_ = code->SourcePosition(pc);
3286fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
3287659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  for (int i = 0; i < expression_count_; i++) {
3288659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    SetExpression(i, output_frame->GetExpression(i));
3289659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
3290659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
3291659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (has_arguments_adaptor) {
3292659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    output_frame = deoptimizer->output_[frame_index - 1];
3293659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    ASSERT(output_frame->GetFrameType() == StackFrame::ARGUMENTS_ADAPTOR);
3294659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
3295659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
32966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  parameters_count_ = output_frame->ComputeParametersCount();
32976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  parameters_ = new Object*[parameters_count_];
32986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  for (int i = 0; i < parameters_count_; i++) {
3299659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    SetParameter(i, output_frame->GetParameter(i));
33004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
33014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
33024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
33034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
33044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgDeoptimizedFrameInfo::~DeoptimizedFrameInfo() {
33056db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  delete[] expression_stack_;
33066db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  delete[] parameters_;
33074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
33084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
3309fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
33104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgvoid DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
3311717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  v->VisitPointer(BitCast<Object**>(&function_));
33126db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  v->VisitPointers(parameters_, parameters_ + parameters_count_);
33134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
33144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
33154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
33167c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org#endif  // ENABLE_DEBUGGER_SUPPORT
33174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
3318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} }  // namespace v8::internal
3319