blob: 2ecd3361f6ce99efa1257ec02a3531fec58d17e0 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "bootstrapper.h"
31#include "code-stubs.h"
32#include "factory.h"
Ben Murdochb8e0da22011-05-16 14:20:40 +010033#include "gdb-jit.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000034#include "macro-assembler.h"
35
36namespace v8 {
37namespace internal {
38
Leon Clarkee46be812010-01-19 14:06:41 +000039bool CodeStub::FindCodeInCache(Code** code_out) {
Steve Block44f0eee2011-05-26 01:26:41 +010040 Heap* heap = Isolate::Current()->heap();
41 int index = heap->code_stubs()->FindEntry(GetKey());
Leon Clarkee46be812010-01-19 14:06:41 +000042 if (index != NumberDictionary::kNotFound) {
Steve Block44f0eee2011-05-26 01:26:41 +010043 *code_out = Code::cast(heap->code_stubs()->ValueAt(index));
Leon Clarkee46be812010-01-19 14:06:41 +000044 return true;
Steve Blockd0582a62009-12-15 09:54:21 +000045 }
Leon Clarkee46be812010-01-19 14:06:41 +000046 return false;
47}
Steve Blockd0582a62009-12-15 09:54:21 +000048
Leon Clarkee46be812010-01-19 14:06:41 +000049
50void CodeStub::GenerateCode(MacroAssembler* masm) {
51 // Update the static counter each time a new code stub is generated.
Steve Block44f0eee2011-05-26 01:26:41 +010052 masm->isolate()->counters()->code_stubs()->Increment();
Ben Murdoch086aeea2011-05-13 15:57:08 +010053
Leon Clarkee46be812010-01-19 14:06:41 +000054 // Nested stubs are not allowed for leafs.
Ben Murdoch086aeea2011-05-13 15:57:08 +010055 AllowStubCallsScope allow_scope(masm, AllowsStubCalls());
56
Leon Clarkee46be812010-01-19 14:06:41 +000057 // Generate the code for the stub.
58 masm->set_generating_stub(true);
59 Generate(masm);
60}
61
62
63void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
64 code->set_major_key(MajorKey());
65
Steve Block44f0eee2011-05-26 01:26:41 +010066 Isolate* isolate = masm->isolate();
67 PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
Ben Murdochb8e0da22011-05-16 14:20:40 +010068 GDBJIT(AddCode(GDBJITInterface::STUB, GetName(), code));
Steve Block44f0eee2011-05-26 01:26:41 +010069 Counters* counters = isolate->counters();
70 counters->total_stubs_code_size()->Increment(code->instruction_size());
Leon Clarkee46be812010-01-19 14:06:41 +000071
72#ifdef ENABLE_DISASSEMBLER
73 if (FLAG_print_code_stubs) {
74#ifdef DEBUG
75 Print();
76#endif
77 code->Disassemble(GetName());
78 PrintF("\n");
79 }
80#endif
81}
82
83
Steve Block6ded16b2010-05-10 14:33:55 +010084int CodeStub::GetCodeKind() {
85 return Code::STUB;
86}
87
88
Leon Clarkee46be812010-01-19 14:06:41 +000089Handle<Code> CodeStub::GetCode() {
Steve Block44f0eee2011-05-26 01:26:41 +010090 Isolate* isolate = Isolate::Current();
91 Factory* factory = isolate->factory();
92 Heap* heap = isolate->heap();
Leon Clarkee46be812010-01-19 14:06:41 +000093 Code* code;
94 if (!FindCodeInCache(&code)) {
Steve Block44f0eee2011-05-26 01:26:41 +010095 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +000096
Steve Blocka7e24c12009-10-30 11:49:00 +000097 // Generate the new code.
98 MacroAssembler masm(NULL, 256);
Leon Clarkee46be812010-01-19 14:06:41 +000099 GenerateCode(&masm);
Steve Blocka7e24c12009-10-30 11:49:00 +0000100
101 // Create the code object.
102 CodeDesc desc;
103 masm.GetCode(&desc);
104
Leon Clarkee46be812010-01-19 14:06:41 +0000105 // Copy the generated code into a heap object.
Steve Block6ded16b2010-05-10 14:33:55 +0100106 Code::Flags flags = Code::ComputeFlags(
107 static_cast<Code::Kind>(GetCodeKind()),
108 InLoop(),
109 GetICState());
Steve Block44f0eee2011-05-26 01:26:41 +0100110 Handle<Code> new_object = factory->NewCode(
111 desc, flags, masm.CodeObject(), NeedsImmovableCode());
Leon Clarkee46be812010-01-19 14:06:41 +0000112 RecordCodeGeneration(*new_object, &masm);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100113 FinishCode(*new_object);
Steve Blocka7e24c12009-10-30 11:49:00 +0000114
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800115 // Update the dictionary and the root in Heap.
116 Handle<NumberDictionary> dict =
Steve Block44f0eee2011-05-26 01:26:41 +0100117 factory->DictionaryAtNumberPut(
118 Handle<NumberDictionary>(heap->code_stubs()),
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800119 GetKey(),
120 new_object);
Steve Block44f0eee2011-05-26 01:26:41 +0100121 heap->public_set_code_stubs(*dict);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800122
Leon Clarkee46be812010-01-19 14:06:41 +0000123 code = *new_object;
Steve Blocka7e24c12009-10-30 11:49:00 +0000124 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000125
Steve Block44f0eee2011-05-26 01:26:41 +0100126 ASSERT(!NeedsImmovableCode() || heap->lo_space()->Contains(code));
127 return Handle<Code>(code, isolate);
Leon Clarkee46be812010-01-19 14:06:41 +0000128}
129
130
John Reck59135872010-11-02 12:39:01 -0700131MaybeObject* CodeStub::TryGetCode() {
Leon Clarkee46be812010-01-19 14:06:41 +0000132 Code* code;
133 if (!FindCodeInCache(&code)) {
134 // Generate the new code.
135 MacroAssembler masm(NULL, 256);
136 GenerateCode(&masm);
Steve Block44f0eee2011-05-26 01:26:41 +0100137 Heap* heap = masm.isolate()->heap();
Leon Clarkee46be812010-01-19 14:06:41 +0000138
139 // Create the code object.
140 CodeDesc desc;
141 masm.GetCode(&desc);
142
143 // Try to copy the generated code into a heap object.
Steve Block6ded16b2010-05-10 14:33:55 +0100144 Code::Flags flags = Code::ComputeFlags(
145 static_cast<Code::Kind>(GetCodeKind()),
146 InLoop(),
147 GetICState());
John Reck59135872010-11-02 12:39:01 -0700148 Object* new_object;
149 { MaybeObject* maybe_new_object =
Steve Block44f0eee2011-05-26 01:26:41 +0100150 heap->CreateCode(desc, flags, masm.CodeObject());
John Reck59135872010-11-02 12:39:01 -0700151 if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
152 }
Leon Clarkee46be812010-01-19 14:06:41 +0000153 code = Code::cast(new_object);
154 RecordCodeGeneration(code, &masm);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100155 FinishCode(code);
Leon Clarkee46be812010-01-19 14:06:41 +0000156
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800157 // Try to update the code cache but do not fail if unable.
158 MaybeObject* maybe_new_object =
Steve Block44f0eee2011-05-26 01:26:41 +0100159 heap->code_stubs()->AtNumberPut(GetKey(), code);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800160 if (maybe_new_object->ToObject(&new_object)) {
Steve Block44f0eee2011-05-26 01:26:41 +0100161 heap->public_set_code_stubs(NumberDictionary::cast(new_object));
Leon Clarkee46be812010-01-19 14:06:41 +0000162 }
163 }
164
165 return code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000166}
167
168
Andrei Popescu31002712010-02-23 13:46:05 +0000169const char* CodeStub::MajorName(CodeStub::Major major_key,
170 bool allow_unknown_keys) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000171 switch (major_key) {
Steve Blockd0582a62009-12-15 09:54:21 +0000172#define DEF_CASE(name) case name: return #name;
173 CODE_STUB_LIST(DEF_CASE)
174#undef DEF_CASE
Steve Blocka7e24c12009-10-30 11:49:00 +0000175 default:
Andrei Popescu31002712010-02-23 13:46:05 +0000176 if (!allow_unknown_keys) {
177 UNREACHABLE();
178 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000179 return NULL;
180 }
181}
182
183
Ben Murdochb0fe1622011-05-05 13:52:32 +0100184int ICCompareStub::MinorKey() {
185 return OpField::encode(op_ - Token::EQ) | StateField::encode(state_);
186}
187
188
189void ICCompareStub::Generate(MacroAssembler* masm) {
190 switch (state_) {
191 case CompareIC::UNINITIALIZED:
192 GenerateMiss(masm);
193 break;
194 case CompareIC::SMIS:
195 GenerateSmis(masm);
196 break;
197 case CompareIC::HEAP_NUMBERS:
198 GenerateHeapNumbers(masm);
199 break;
200 case CompareIC::OBJECTS:
201 GenerateObjects(masm);
202 break;
203 default:
204 UNREACHABLE();
205 }
206}
207
208
Ben Murdoch086aeea2011-05-13 15:57:08 +0100209const char* InstanceofStub::GetName() {
210 if (name_ != NULL) return name_;
211 const int kMaxNameLength = 100;
Steve Block44f0eee2011-05-26 01:26:41 +0100212 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
213 kMaxNameLength);
Ben Murdoch086aeea2011-05-13 15:57:08 +0100214 if (name_ == NULL) return "OOM";
215
216 const char* args = "";
217 if (HasArgsInRegisters()) {
218 args = "_REGS";
219 }
220
221 const char* inline_check = "";
222 if (HasCallSiteInlineCheck()) {
223 inline_check = "_INLINE";
224 }
225
226 const char* return_true_false_object = "";
227 if (ReturnTrueFalseObject()) {
228 return_true_false_object = "_TRUEFALSE";
229 }
230
231 OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
232 "InstanceofStub%s%s%s",
233 args,
234 inline_check,
235 return_true_false_object);
236 return name_;
237}
238
239
Steve Blocka7e24c12009-10-30 11:49:00 +0000240} } // namespace v8::internal