blob: 068113779910f4d5215b6599757bd412189a9dc4 [file] [log] [blame]
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// 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"
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000032#include "cpu-profiler.h"
ager@chromium.orgea91cc52011-05-23 06:06:11 +000033#include "stub-cache.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000034#include "factory.h"
erik.corry@gmail.com0511e242011-01-19 11:11:08 +000035#include "gdb-jit.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036#include "macro-assembler.h"
37
kasperl@chromium.org71affb52009-05-26 05:44:31 +000038namespace v8 {
39namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000041
42CodeStubInterfaceDescriptor::CodeStubInterfaceDescriptor()
43 : register_param_count_(-1),
44 stack_parameter_count_(NULL),
danno@chromium.orgca29dd82013-04-26 11:59:48 +000045 hint_stack_parameter_count_(-1),
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000046 function_mode_(NOT_JS_FUNCTION_STUB_MODE),
47 register_params_(NULL),
48 deoptimization_handler_(NULL),
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +000049 miss_handler_(),
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +000050 has_miss_handler_(false) { }
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000051
52
ulan@chromium.org8e8d8822012-11-23 14:36:46 +000053bool CodeStub::FindCodeInCache(Code** code_out, Isolate* isolate) {
54 UnseededNumberDictionary* stubs = isolate->heap()->code_stubs();
55 int index = stubs->FindEntry(GetKey());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +000056 if (index != UnseededNumberDictionary::kNotFound) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +000057 *code_out = Code::cast(stubs->ValueAt(index));
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +000058 return true;
ager@chromium.orgc4c92722009-11-18 14:12:51 +000059 }
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +000060 return false;
61}
ager@chromium.orgc4c92722009-11-18 14:12:51 +000062
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +000063
kmillikin@chromium.org83e16822011-09-13 08:21:47 +000064SmartArrayPointer<const char> CodeStub::GetName() {
whesse@chromium.org030d38e2011-07-13 13:23:34 +000065 char buffer[100];
66 NoAllocationStringAllocator allocator(buffer,
67 static_cast<unsigned>(sizeof(buffer)));
68 StringStream stream(&allocator);
69 PrintName(&stream);
70 return stream.ToCString();
71}
72
73
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000074void CodeStub::RecordCodeGeneration(Code* code, Isolate* isolate) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +000075 SmartArrayPointer<const char> name = GetName();
whesse@chromium.org030d38e2011-07-13 13:23:34 +000076 PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name));
77 GDBJIT(AddCode(GDBJITInterface::STUB, *name, code));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000078 Counters* counters = isolate->counters();
79 counters->total_stubs_code_size()->Increment(code->instruction_size());
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +000080}
81
82
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +000083Code::Kind CodeStub::GetCodeKind() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000084 return Code::STUB;
85}
86
87
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +000088Handle<Code> CodeStub::GetCodeCopyFromTemplate(Isolate* isolate) {
89 Handle<Code> ic = GetCode(isolate);
90 ic = isolate->factory()->CopyCode(ic);
91 RecordCodeGeneration(*ic, isolate);
92 return ic;
93}
94
95
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +000096Handle<Code> PlatformCodeStub::GenerateCode(Isolate* isolate) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000097 Factory* factory = isolate->factory();
98
99 // Generate the new code.
100 MacroAssembler masm(isolate, NULL, 256);
101
102 {
103 // Update the static counter each time a new code stub is generated.
104 isolate->counters()->code_stubs()->Increment();
105
106 // Nested stubs are not allowed for leaves.
107 AllowStubCallsScope allow_scope(&masm, false);
108
109 // Generate the code for the stub.
110 masm.set_generating_stub(true);
111 NoCurrentFrameScope scope(&masm);
112 Generate(&masm);
113 }
114
115 // Create the code object.
116 CodeDesc desc;
117 masm.GetCode(&desc);
118
119 // Copy the generated code into a heap object.
120 Code::Flags flags = Code::ComputeFlags(
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000121 GetCodeKind(),
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000122 GetICState(),
123 GetExtraICState(),
ulan@chromium.org750145a2013-03-07 15:14:13 +0000124 GetStubType(),
125 GetStubFlags());
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000126 Handle<Code> new_object = factory->NewCode(
127 desc, flags, masm.CodeObject(), NeedsImmovableCode());
128 return new_object;
129}
130
131
mvstanton@chromium.org63ea3d22013-10-10 09:24:12 +0000132void CodeStub::VerifyPlatformFeatures(Isolate* isolate) {
133 ASSERT(CpuFeatures::VerifyCrossCompiling());
134}
135
136
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000137Handle<Code> CodeStub::GetCode(Isolate* isolate) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000138 Factory* factory = isolate->factory();
139 Heap* heap = isolate->heap();
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000140 Code* code;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000141 if (UseSpecialCache()
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000142 ? FindCodeInSpecialCache(&code, isolate)
143 : FindCodeInCache(&code, isolate)) {
dslomov@chromium.orge97852d2013-09-12 09:02:59 +0000144 ASSERT(IsPregenerated(isolate) == code->is_pregenerated());
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000145 ASSERT(GetCodeKind() == code->kind());
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000146 return Handle<Code>(code);
147 }
148
mvstanton@chromium.org63ea3d22013-10-10 09:24:12 +0000149#ifdef DEBUG
150 VerifyPlatformFeatures(isolate);
151#endif
152
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000153 {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000154 HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000155
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000156 Handle<Code> new_object = GenerateCode(isolate);
danno@chromium.org1044a4d2012-04-30 12:34:39 +0000157 new_object->set_major_key(MajorKey());
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000158 FinishCode(new_object);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000159 RecordCodeGeneration(*new_object, isolate);
danno@chromium.org1044a4d2012-04-30 12:34:39 +0000160
161#ifdef ENABLE_DISASSEMBLER
162 if (FLAG_print_code_stubs) {
163 new_object->Disassemble(*GetName());
164 PrintF("\n");
165 }
166#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000167
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000168 if (UseSpecialCache()) {
169 AddToSpecialCache(new_object);
170 } else {
171 // Update the dictionary and the root in Heap.
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000172 Handle<UnseededNumberDictionary> dict =
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000173 factory->DictionaryAtNumberPut(
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000174 Handle<UnseededNumberDictionary>(heap->code_stubs()),
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000175 GetKey(),
176 new_object);
177 heap->public_set_code_stubs(*dict);
178 }
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000179 code = *new_object;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000180 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000181
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000182 Activate(code);
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000183 ASSERT(!NeedsImmovableCode() ||
184 heap->lo_space()->Contains(code) ||
185 heap->code_space()->FirstPage()->Contains(code->address()));
lrn@chromium.org7516f052011-03-30 08:52:27 +0000186 return Handle<Code>(code, isolate);
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000187}
188
189
ager@chromium.org5c838252010-02-19 08:53:10 +0000190const char* CodeStub::MajorName(CodeStub::Major major_key,
191 bool allow_unknown_keys) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000192 switch (major_key) {
sgjesse@chromium.org6db88712011-07-11 11:41:22 +0000193#define DEF_CASE(name) case name: return #name "Stub";
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000194 CODE_STUB_LIST(DEF_CASE)
ager@chromium.org3811b432009-10-28 14:53:37 +0000195#undef DEF_CASE
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000196 default:
ager@chromium.org5c838252010-02-19 08:53:10 +0000197 if (!allow_unknown_keys) {
198 UNREACHABLE();
199 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000200 return NULL;
201 }
202}
203
204
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000205void CodeStub::PrintBaseName(StringStream* stream) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000206 stream->Add("%s", MajorName(MajorKey(), false));
207}
208
209
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000210void CodeStub::PrintName(StringStream* stream) {
211 PrintBaseName(stream);
212 PrintState(stream);
213}
214
215
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000216void BinaryOpStub::PrintBaseName(StringStream* stream) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000217 const char* op_name = Token::Name(op_);
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000218 const char* ovr = "";
219 if (mode_ == OVERWRITE_LEFT) ovr = "_ReuseLeft";
220 if (mode_ == OVERWRITE_RIGHT) ovr = "_ReuseRight";
221 stream->Add("BinaryOpStub_%s%s", op_name, ovr);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000222}
223
224
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000225void BinaryOpStub::PrintState(StringStream* stream) {
226 stream->Add("(");
227 stream->Add(StateToName(left_state_));
228 stream->Add("*");
229 if (fixed_right_arg_.has_value) {
230 stream->Add("%d", fixed_right_arg_.value);
231 } else {
232 stream->Add(StateToName(right_state_));
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000233 }
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000234 stream->Add("->");
235 stream->Add(StateToName(result_state_));
236 stream->Add(")");
237}
238
239
240Maybe<Handle<Object> > BinaryOpStub::Result(Handle<Object> left,
241 Handle<Object> right,
242 Isolate* isolate) {
243 Handle<JSBuiltinsObject> builtins(isolate->js_builtins_object());
244 Builtins::JavaScript func = BinaryOpIC::TokenToJSBuiltin(op_);
245 Object* builtin = builtins->javascript_builtin(func);
246 Handle<JSFunction> builtin_function =
247 Handle<JSFunction>(JSFunction::cast(builtin), isolate);
248 bool caught_exception;
249 Handle<Object> result = Execution::Call(isolate, builtin_function, left,
250 1, &right, &caught_exception);
251 return Maybe<Handle<Object> >(!caught_exception, result);
252}
253
254
255void BinaryOpStub::Initialize() {
256 fixed_right_arg_.has_value = false;
257 left_state_ = right_state_ = result_state_ = NONE;
258}
259
260
261void BinaryOpStub::Generate(Token::Value op,
262 State left,
263 State right,
264 State result,
265 OverwriteMode mode,
266 Isolate* isolate) {
267 BinaryOpStub stub(INITIALIZED);
268 stub.op_ = op;
269 stub.left_state_ = left;
270 stub.right_state_ = right;
271 stub.result_state_ = result;
272 stub.mode_ = mode;
273 stub.GetCode(isolate);
274}
275
276
277void BinaryOpStub::Generate(Token::Value op,
278 State left,
279 int right,
280 State result,
281 OverwriteMode mode,
282 Isolate* isolate) {
283 BinaryOpStub stub(INITIALIZED);
284 stub.op_ = op;
285 stub.left_state_ = left;
286 stub.fixed_right_arg_.has_value = true;
287 stub.fixed_right_arg_.value = right;
288 stub.right_state_ = SMI;
289 stub.result_state_ = result;
290 stub.mode_ = mode;
291 stub.GetCode(isolate);
292}
293
294
295void BinaryOpStub::GenerateAheadOfTime(Isolate* isolate) {
296 Token::Value binop[] = {Token::SUB, Token::MOD, Token::DIV, Token::MUL,
297 Token::ADD, Token::SAR, Token::BIT_OR, Token::BIT_AND,
298 Token::BIT_XOR, Token::SHL, Token::SHR};
299 for (unsigned i = 0; i < ARRAY_SIZE(binop); i++) {
300 BinaryOpStub stub(UNINITIALIZED);
301 stub.op_ = binop[i];
302 stub.GetCode(isolate);
303 }
304
305 // TODO(olivf) We should investigate why adding stubs to the snapshot is so
306 // expensive at runtime. When solved we should be able to add most binops to
307 // the snapshot instead of hand-picking them.
308 // Generated list of commonly used stubs
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000309 Generate(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE, isolate);
310 Generate(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
311 Generate(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
312 Generate(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT, isolate);
313 Generate(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
314 Generate(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
315 Generate(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
316 Generate(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE, isolate);
317 Generate(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
318 Generate(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
319 Generate(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
320 Generate(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
321 Generate(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT, isolate);
322 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
323 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
324 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
325 Generate(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
326 Generate(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
327 Generate(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
328 Generate(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE, isolate);
329 Generate(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
330 Generate(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
331 Generate(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
332 Generate(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
333 Generate(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
334 Generate(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT, isolate);
335 Generate(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000336 Generate(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE, isolate);
337 Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
338 Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
339 Generate(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE, isolate);
340 Generate(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT, isolate);
341 Generate(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE, isolate);
342 Generate(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
343 Generate(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE, isolate);
344 Generate(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT, isolate);
345 Generate(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
346 Generate(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT, isolate);
347 Generate(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
348 Generate(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
349 Generate(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE, isolate);
350 Generate(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT, isolate);
351 Generate(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT, isolate);
352 Generate(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE, isolate);
353 Generate(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
354 Generate(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
355 Generate(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
356 Generate(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
357 Generate(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT, isolate);
358 Generate(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE, isolate);
359 Generate(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
360 Generate(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
361 Generate(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
362 Generate(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
363 Generate(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE, isolate);
364 Generate(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT, isolate);
365 Generate(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT, isolate);
366 Generate(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
367 Generate(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT, isolate);
368 Generate(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
369 Generate(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT, isolate);
370 Generate(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT, isolate);
371 Generate(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
372 Generate(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
373 Generate(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE, isolate);
374 Generate(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
375 Generate(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
376 Generate(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE, isolate);
377 Generate(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT, isolate);
378 Generate(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE, isolate);
379 Generate(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE, isolate);
380 Generate(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
381 Generate(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
382 Generate(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE, isolate);
383 Generate(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE, isolate);
384 Generate(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
385 Generate(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE, isolate);
386 Generate(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
387 Generate(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT, isolate);
388 Generate(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE, isolate);
389 Generate(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
390 Generate(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
391 Generate(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE, isolate);
392 Generate(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
393 Generate(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
394 Generate(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
395 Generate(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE, isolate);
396 Generate(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE, isolate);
397 Generate(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
398 Generate(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
399 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
400 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
401 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
402 Generate(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
403 Generate(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
404 Generate(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE, isolate);
405 Generate(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
406 Generate(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT, isolate);
407 Generate(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
408 Generate(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
409 Generate(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
410 Generate(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE, isolate);
411 Generate(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT, isolate);
412 Generate(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
413 Generate(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE, isolate);
414 Generate(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
415 Generate(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
416 Generate(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
417 Generate(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT, isolate);
418 Generate(Token::MOD, SMI, 2, SMI, NO_OVERWRITE, isolate);
419 Generate(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE, isolate);
420 Generate(Token::MOD, SMI, 32, SMI, NO_OVERWRITE, isolate);
421 Generate(Token::MOD, SMI, 4, SMI, NO_OVERWRITE, isolate);
422 Generate(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT, isolate);
423 Generate(Token::MOD, SMI, 8, SMI, NO_OVERWRITE, isolate);
424 Generate(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE, isolate);
425 Generate(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
426 Generate(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE, isolate);
427 Generate(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
428 Generate(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
429 Generate(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
430 Generate(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE, isolate);
431 Generate(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
432 Generate(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE, isolate);
433 Generate(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
434 Generate(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
435 Generate(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT, isolate);
436 Generate(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
437 Generate(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
438 Generate(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
439 Generate(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
440 Generate(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
441 Generate(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE, isolate);
442 Generate(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
443 Generate(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
444 Generate(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
445 Generate(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
446 Generate(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
447 Generate(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE, isolate);
448 Generate(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE, isolate);
449 Generate(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT, isolate);
450 Generate(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE, isolate);
451 Generate(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
452 Generate(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
453 Generate(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
454 Generate(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
455 Generate(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
456 Generate(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
457 Generate(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
458 Generate(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
459 Generate(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
460 Generate(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE, isolate);
461 Generate(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
462 Generate(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE, isolate);
463 Generate(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
464 Generate(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
465 Generate(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE, isolate);
466 Generate(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT, isolate);
467 Generate(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT, isolate);
468 Generate(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE, isolate);
469 Generate(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
470 Generate(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
471 Generate(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
472 Generate(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT, isolate);
473 Generate(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
474 Generate(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
475 Generate(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT, isolate);
mstarzinger@chromium.orgb4968be2013-10-16 09:00:56 +0000476 Generate(Token::SHR, NUMBER, SMI, INT32, OVERWRITE_RIGHT, isolate);
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000477 Generate(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE, isolate);
478 Generate(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
479 Generate(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
480 Generate(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE, isolate);
481 Generate(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
482 Generate(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
483 Generate(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
484 Generate(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
485 Generate(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
486 Generate(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
487 Generate(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
488 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
489 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
490 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
491 Generate(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
492 Generate(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
493 Generate(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
494 Generate(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE, isolate);
495 Generate(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
496 Generate(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
497 Generate(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
498 Generate(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE, isolate);
499 Generate(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
500 Generate(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
501}
502
503
504bool BinaryOpStub::can_encode_arg_value(int32_t value) const {
505 return op_ == Token::MOD && value > 0 && IsPowerOf2(value) &&
506 FixedRightArgValueBits::is_valid(WhichPowerOf2(value));
507}
508
509
510int BinaryOpStub::encode_arg_value(int32_t value) const {
511 ASSERT(can_encode_arg_value(value));
512 return WhichPowerOf2(value);
513}
514
515
516int32_t BinaryOpStub::decode_arg_value(int value) const {
517 return 1 << value;
518}
519
520
521int BinaryOpStub::encode_token(Token::Value op) const {
522 ASSERT(op >= FIRST_TOKEN && op <= LAST_TOKEN);
523 return op - FIRST_TOKEN;
524}
525
526
527Token::Value BinaryOpStub::decode_token(int op) const {
528 int res = op + FIRST_TOKEN;
529 ASSERT(res >= FIRST_TOKEN && res <= LAST_TOKEN);
530 return static_cast<Token::Value>(res);
531}
532
533
534const char* BinaryOpStub::StateToName(State state) {
535 switch (state) {
536 case NONE:
537 return "None";
538 case SMI:
539 return "Smi";
540 case INT32:
541 return "Int32";
542 case NUMBER:
543 return "Number";
544 case STRING:
545 return "String";
546 case GENERIC:
547 return "Generic";
548 }
549 return "";
550}
551
552
553void BinaryOpStub::UpdateStatus(Handle<Object> left,
554 Handle<Object> right,
555 Maybe<Handle<Object> > result) {
556 int old_state = GetExtraICState();
557
558 UpdateStatus(left, &left_state_);
559 UpdateStatus(right, &right_state_);
560
561 int32_t value;
562 bool new_has_fixed_right_arg =
563 right->ToInt32(&value) && can_encode_arg_value(value) &&
564 (left_state_ == SMI || left_state_ == INT32) &&
565 (result_state_ == NONE || !fixed_right_arg_.has_value);
566
567 fixed_right_arg_ = Maybe<int32_t>(new_has_fixed_right_arg, value);
568
569 if (result.has_value) UpdateStatus(result.value, &result_state_);
570
571 State max_input = Max(left_state_, right_state_);
572
mvstanton@chromium.orgdd6d9ee2013-10-11 10:35:37 +0000573 // TODO(olivf) Instead of doing this normalization we should have a Hydrogen
574 // version of the LookupNumberStringCache to avoid a converting StringAddStub.
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000575 if (left_state_ == STRING && right_state_ < STRING) {
576 right_state_ = GENERIC;
577 } else if (right_state_ == STRING && left_state_ < STRING) {
578 left_state_ = GENERIC;
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000579 } else if (!has_int_result() && op_ != Token::SHR &&
580 max_input <= NUMBER && max_input > result_state_) {
581 result_state_ = max_input;
582 }
583
584 ASSERT(result_state_ <= (has_int_result() ? INT32 : NUMBER) ||
585 op_ == Token::ADD);
586
587 if (old_state == GetExtraICState()) {
mvstanton@chromium.orgdd6d9ee2013-10-11 10:35:37 +0000588 // Tagged operations can lead to non-truncating HChanges
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000589 if (left->IsUndefined() || left->IsBoolean()) {
mvstanton@chromium.orgdd6d9ee2013-10-11 10:35:37 +0000590 left_state_ = GENERIC;
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000591 } else if (right->IsUndefined() || right->IsBoolean()) {
mvstanton@chromium.orgdd6d9ee2013-10-11 10:35:37 +0000592 right_state_ = GENERIC;
593 } else {
594 // Since the fpu is to precise, we might bail out on numbers which
595 // actually would truncate with 64 bit precision.
596 ASSERT(!CpuFeatures::IsSupported(SSE2) &&
597 result_state_ <= INT32);
598 result_state_ = NUMBER;
599 }
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000600 }
601}
602
603
604void BinaryOpStub::UpdateStatus(Handle<Object> object,
605 State* state) {
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000606 bool is_truncating = (op_ == Token::BIT_AND || op_ == Token::BIT_OR ||
607 op_ == Token::BIT_XOR || op_ == Token::SAR ||
608 op_ == Token::SHL || op_ == Token::SHR);
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000609 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(object);
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000610 if (object->IsBoolean() && is_truncating) {
611 // Booleans are converted by truncating by HChange.
612 type = TypeInfo::Integer32();
613 }
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000614 if (object->IsUndefined()) {
615 // Undefined will be automatically truncated for us by HChange.
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000616 type = is_truncating ? TypeInfo::Integer32() : TypeInfo::Double();
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +0000617 }
618 State int_state = SmiValuesAre32Bits() ? NUMBER : INT32;
619 State new_state = NONE;
620 if (type.IsSmi()) {
621 new_state = SMI;
622 } else if (type.IsInteger32()) {
623 new_state = int_state;
624 } else if (type.IsNumber()) {
625 new_state = NUMBER;
626 } else if (object->IsString() && operation() == Token::ADD) {
627 new_state = STRING;
628 } else {
629 new_state = GENERIC;
630 }
631 if ((new_state <= NUMBER && *state > NUMBER) ||
632 (new_state > NUMBER && *state <= NUMBER && *state != NONE)) {
633 new_state = GENERIC;
634 }
635 *state = Max(*state, new_state);
636}
637
638
639Handle<Type> BinaryOpStub::StateToType(State state,
640 Isolate* isolate) {
641 Handle<Type> t = handle(Type::None(), isolate);
642 switch (state) {
643 case NUMBER:
644 t = handle(Type::Union(t, handle(Type::Double(), isolate)), isolate);
645 // Fall through.
646 case INT32:
647 t = handle(Type::Union(t, handle(Type::Signed32(), isolate)), isolate);
648 // Fall through.
649 case SMI:
650 t = handle(Type::Union(t, handle(Type::Smi(), isolate)), isolate);
651 break;
652
653 case STRING:
654 t = handle(Type::Union(t, handle(Type::String(), isolate)), isolate);
655 break;
656 case GENERIC:
657 return handle(Type::Any(), isolate);
658 break;
659 case NONE:
660 break;
661 }
662 return t;
663}
664
665
666Handle<Type> BinaryOpStub::GetLeftType(Isolate* isolate) const {
667 return StateToType(left_state_, isolate);
668}
669
670
671Handle<Type> BinaryOpStub::GetRightType(Isolate* isolate) const {
672 return StateToType(right_state_, isolate);
673}
674
675
676Handle<Type> BinaryOpStub::GetResultType(Isolate* isolate) const {
677 if (HasSideEffects(isolate)) return StateToType(NONE, isolate);
678 if (result_state_ == GENERIC && op_ == Token::ADD) {
679 return handle(Type::Union(handle(Type::Number(), isolate),
680 handle(Type::String(), isolate)), isolate);
681 }
682 ASSERT(result_state_ != GENERIC);
683 if (result_state_ == NUMBER && op_ == Token::SHR) {
684 return handle(Type::Unsigned32(), isolate);
685 }
686 return StateToType(result_state_, isolate);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000687}
688
689
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000690InlineCacheState ICCompareStub::GetICState() {
691 CompareIC::State state = Max(left_, right_);
692 switch (state) {
693 case CompareIC::UNINITIALIZED:
694 return ::v8::internal::UNINITIALIZED;
695 case CompareIC::SMI:
696 case CompareIC::NUMBER:
697 case CompareIC::INTERNALIZED_STRING:
698 case CompareIC::STRING:
699 case CompareIC::UNIQUE_NAME:
700 case CompareIC::OBJECT:
701 case CompareIC::KNOWN_OBJECT:
702 return MONOMORPHIC;
703 case CompareIC::GENERIC:
704 return ::v8::internal::GENERIC;
705 }
706 UNREACHABLE();
707 return ::v8::internal::UNINITIALIZED;
708}
709
710
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000711void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) {
712 ASSERT(*known_map_ != NULL);
713 Isolate* isolate = new_object->GetIsolate();
714 Factory* factory = isolate->factory();
715 return Map::UpdateCodeCache(known_map_,
verwaest@chromium.orgde64f722012-08-16 15:44:54 +0000716 strict() ?
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000717 factory->strict_compare_ic_string() :
718 factory->compare_ic_string(),
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000719 new_object);
720}
721
722
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000723bool ICCompareStub::FindCodeInSpecialCache(Code** code_out, Isolate* isolate) {
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000724 Factory* factory = isolate->factory();
725 Code::Flags flags = Code::ComputeFlags(
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000726 GetCodeKind(),
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000727 UNINITIALIZED);
verwaest@chromium.orgde64f722012-08-16 15:44:54 +0000728 ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000729 Handle<Object> probe(
730 known_map_->FindInCodeCache(
731 strict() ?
732 *factory->strict_compare_ic_string() :
733 *factory->compare_ic_string(),
734 flags),
735 isolate);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000736 if (probe->IsCode()) {
737 *code_out = Code::cast(*probe);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000738#ifdef DEBUG
739 Token::Value cached_op;
740 ICCompareStub::DecodeMinorKey((*code_out)->stub_info(), NULL, NULL, NULL,
741 &cached_op);
742 ASSERT(op_ == cached_op);
743#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000744 return true;
745 }
746 return false;
747}
748
749
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000750int ICCompareStub::MinorKey() {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000751 return OpField::encode(op_ - Token::EQ) |
752 LeftStateField::encode(left_) |
753 RightStateField::encode(right_) |
754 HandlerStateField::encode(state_);
755}
756
757
758void ICCompareStub::DecodeMinorKey(int minor_key,
759 CompareIC::State* left_state,
760 CompareIC::State* right_state,
761 CompareIC::State* handler_state,
762 Token::Value* op) {
763 if (left_state) {
764 *left_state =
765 static_cast<CompareIC::State>(LeftStateField::decode(minor_key));
766 }
767 if (right_state) {
768 *right_state =
769 static_cast<CompareIC::State>(RightStateField::decode(minor_key));
770 }
771 if (handler_state) {
772 *handler_state =
773 static_cast<CompareIC::State>(HandlerStateField::decode(minor_key));
774 }
775 if (op) {
776 *op = static_cast<Token::Value>(OpField::decode(minor_key) + Token::EQ);
777 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000778}
779
780
781void ICCompareStub::Generate(MacroAssembler* masm) {
782 switch (state_) {
783 case CompareIC::UNINITIALIZED:
784 GenerateMiss(masm);
785 break;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000786 case CompareIC::SMI:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000787 GenerateSmis(masm);
788 break;
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000789 case CompareIC::NUMBER:
790 GenerateNumbers(masm);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000791 break;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000792 case CompareIC::STRING:
lrn@chromium.org1c092762011-05-09 09:42:16 +0000793 GenerateStrings(masm);
794 break;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000795 case CompareIC::INTERNALIZED_STRING:
796 GenerateInternalizedStrings(masm);
797 break;
798 case CompareIC::UNIQUE_NAME:
799 GenerateUniqueNames(masm);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000800 break;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000801 case CompareIC::OBJECT:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000802 GenerateObjects(masm);
803 break;
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000804 case CompareIC::KNOWN_OBJECT:
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000805 ASSERT(*known_map_ != NULL);
806 GenerateKnownObjects(masm);
807 break;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000808 case CompareIC::GENERIC:
809 GenerateGeneric(masm);
810 break;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000811 }
812}
813
814
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000815void CompareNilICStub::UpdateStatus(Handle<Object> object) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000816 ASSERT(!state_.Contains(GENERIC));
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000817 State old_state(state_);
ulan@chromium.org837a67e2013-06-11 15:39:48 +0000818 if (object->IsNull()) {
danno@chromium.org41728482013-06-12 22:31:22 +0000819 state_.Add(NULL_TYPE);
ulan@chromium.org837a67e2013-06-11 15:39:48 +0000820 } else if (object->IsUndefined()) {
danno@chromium.org41728482013-06-12 22:31:22 +0000821 state_.Add(UNDEFINED);
ulan@chromium.org837a67e2013-06-11 15:39:48 +0000822 } else if (object->IsUndetectableObject() ||
823 object->IsOddball() ||
824 !object->IsHeapObject()) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000825 state_.RemoveAll();
826 state_.Add(GENERIC);
ulan@chromium.org837a67e2013-06-11 15:39:48 +0000827 } else if (IsMonomorphic()) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000828 state_.RemoveAll();
829 state_.Add(GENERIC);
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000830 } else {
danno@chromium.org41728482013-06-12 22:31:22 +0000831 state_.Add(MONOMORPHIC_MAP);
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000832 }
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000833 TraceTransition(old_state, state_);
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000834}
835
836
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000837template<class StateType>
838void HydrogenCodeStub::TraceTransition(StateType from, StateType to) {
danno@chromium.org59400602013-08-13 17:09:37 +0000839 // Note: Although a no-op transition is semantically OK, it is hinting at a
840 // bug somewhere in our state transition machinery.
841 ASSERT(from != to);
svenpanne@chromium.org53ad1752013-05-27 12:20:38 +0000842 #ifdef DEBUG
843 if (!FLAG_trace_ic) return;
844 char buffer[100];
845 NoAllocationStringAllocator allocator(buffer,
846 static_cast<unsigned>(sizeof(buffer)));
847 StringStream stream(&allocator);
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000848 stream.Add("[");
849 PrintBaseName(&stream);
850 stream.Add(": ");
851 from.Print(&stream);
svenpanne@chromium.org53ad1752013-05-27 12:20:38 +0000852 stream.Add("=>");
853 to.Print(&stream);
854 stream.Add("]\n");
855 stream.OutputToStdOut();
856 #endif
857}
858
859
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000860void CompareNilICStub::PrintBaseName(StringStream* stream) {
861 CodeStub::PrintBaseName(stream);
862 stream->Add((nil_value_ == kNullValue) ? "(NullValue)":
863 "(UndefinedValue)");
864}
865
866
867void CompareNilICStub::PrintState(StringStream* stream) {
danno@chromium.org41728482013-06-12 22:31:22 +0000868 state_.Print(stream);
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000869}
870
871
danno@chromium.org41728482013-06-12 22:31:22 +0000872void CompareNilICStub::State::Print(StringStream* stream) const {
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000873 stream->Add("(");
874 SimpleListPrinter printer(stream);
875 if (IsEmpty()) printer.Add("None");
876 if (Contains(UNDEFINED)) printer.Add("Undefined");
877 if (Contains(NULL_TYPE)) printer.Add("Null");
878 if (Contains(MONOMORPHIC_MAP)) printer.Add("MonomorphicMap");
danno@chromium.org41728482013-06-12 22:31:22 +0000879 if (Contains(GENERIC)) printer.Add("Generic");
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000880 stream->Add(")");
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000881}
882
883
danno@chromium.org169691d2013-07-15 08:01:13 +0000884Handle<Type> CompareNilICStub::GetType(
danno@chromium.org41728482013-06-12 22:31:22 +0000885 Isolate* isolate,
danno@chromium.org41728482013-06-12 22:31:22 +0000886 Handle<Map> map) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000887 if (state_.Contains(CompareNilICStub::GENERIC)) {
danno@chromium.org41728482013-06-12 22:31:22 +0000888 return handle(Type::Any(), isolate);
889 }
890
891 Handle<Type> result(Type::None(), isolate);
danno@chromium.org169691d2013-07-15 08:01:13 +0000892 if (state_.Contains(CompareNilICStub::UNDEFINED)) {
danno@chromium.org41728482013-06-12 22:31:22 +0000893 result = handle(Type::Union(result, handle(Type::Undefined(), isolate)),
894 isolate);
895 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000896 if (state_.Contains(CompareNilICStub::NULL_TYPE)) {
danno@chromium.org41728482013-06-12 22:31:22 +0000897 result = handle(Type::Union(result, handle(Type::Null(), isolate)),
898 isolate);
899 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000900 if (state_.Contains(CompareNilICStub::MONOMORPHIC_MAP)) {
danno@chromium.org41728482013-06-12 22:31:22 +0000901 Type* type = map.is_null() ? Type::Detectable() : Type::Class(map);
902 result = handle(Type::Union(result, handle(type, isolate)), isolate);
903 }
904
905 return result;
906}
907
908
danno@chromium.org169691d2013-07-15 08:01:13 +0000909Handle<Type> CompareNilICStub::GetInputType(
910 Isolate* isolate,
911 Handle<Map> map) {
912 Handle<Type> output_type = GetType(isolate, map);
913 Handle<Type> nil_type = handle(nil_value_ == kNullValue
914 ? Type::Null() : Type::Undefined(), isolate);
915 return handle(Type::Union(output_type, nil_type), isolate);
916}
917
918
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000919void InstanceofStub::PrintName(StringStream* stream) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000920 const char* args = "";
921 if (HasArgsInRegisters()) {
922 args = "_REGS";
923 }
924
925 const char* inline_check = "";
926 if (HasCallSiteInlineCheck()) {
927 inline_check = "_INLINE";
928 }
929
930 const char* return_true_false_object = "";
931 if (ReturnTrueFalseObject()) {
932 return_true_false_object = "_TRUEFALSE";
933 }
934
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000935 stream->Add("InstanceofStub%s%s%s",
936 args,
937 inline_check,
938 return_true_false_object);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000939}
940
941
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000942void JSEntryStub::FinishCode(Handle<Code> code) {
943 Handle<FixedArray> handler_table =
944 code->GetIsolate()->factory()->NewFixedArray(1, TENURED);
945 handler_table->set(0, Smi::FromInt(handler_offset_));
946 code->set_handler_table(*handler_table);
947}
948
949
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000950void KeyedLoadDictionaryElementStub::Generate(MacroAssembler* masm) {
951 KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm);
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000952}
953
954
danno@chromium.orgbee51992013-07-10 14:57:15 +0000955void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
956 CreateAllocationSiteStub stub;
957 stub.GetCode(isolate)->set_is_pregenerated(true);
958}
959
960
sgjesse@chromium.org6db88712011-07-11 11:41:22 +0000961void KeyedStoreElementStub::Generate(MacroAssembler* masm) {
962 switch (elements_kind_) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000963 case FAST_ELEMENTS:
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000964 case FAST_HOLEY_ELEMENTS:
965 case FAST_SMI_ELEMENTS:
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000966 case FAST_HOLEY_SMI_ELEMENTS:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000967 case FAST_DOUBLE_ELEMENTS:
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000968 case FAST_HOLEY_DOUBLE_ELEMENTS:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000969 case EXTERNAL_BYTE_ELEMENTS:
970 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
971 case EXTERNAL_SHORT_ELEMENTS:
972 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
973 case EXTERNAL_INT_ELEMENTS:
974 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
975 case EXTERNAL_FLOAT_ELEMENTS:
976 case EXTERNAL_DOUBLE_ELEMENTS:
977 case EXTERNAL_PIXEL_ELEMENTS:
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000978 UNREACHABLE();
sgjesse@chromium.org6db88712011-07-11 11:41:22 +0000979 break;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000980 case DICTIONARY_ELEMENTS:
sgjesse@chromium.org6db88712011-07-11 11:41:22 +0000981 KeyedStoreStubCompiler::GenerateStoreDictionaryElement(masm);
982 break;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000983 case NON_STRICT_ARGUMENTS_ELEMENTS:
sgjesse@chromium.org6db88712011-07-11 11:41:22 +0000984 UNREACHABLE();
985 break;
986 }
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000987}
988
989
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000990void ArgumentsAccessStub::PrintName(StringStream* stream) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000991 stream->Add("ArgumentsAccessStub_");
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000992 switch (type_) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000993 case READ_ELEMENT: stream->Add("ReadElement"); break;
994 case NEW_NON_STRICT_FAST: stream->Add("NewNonStrictFast"); break;
995 case NEW_NON_STRICT_SLOW: stream->Add("NewNonStrictSlow"); break;
996 case NEW_STRICT: stream->Add("NewStrict"); break;
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000997 }
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000998}
999
1000
1001void CallFunctionStub::PrintName(StringStream* stream) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001002 stream->Add("CallFunctionStub_Args%d", argc_);
1003 if (ReceiverMightBeImplicit()) stream->Add("_Implicit");
1004 if (RecordCallTarget()) stream->Add("_Recording");
whesse@chromium.org030d38e2011-07-13 13:23:34 +00001005}
1006
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001007
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001008void CallConstructStub::PrintName(StringStream* stream) {
1009 stream->Add("CallConstructStub");
1010 if (RecordCallTarget()) stream->Add("_Recording");
1011}
1012
1013
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001014bool ToBooleanStub::UpdateStatus(Handle<Object> object) {
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +00001015 Types old_types(types_);
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001016 bool to_boolean_value = types_.UpdateStatus(object);
1017 TraceTransition(old_types, types_);
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +00001018 return to_boolean_value;
1019}
1020
1021
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001022void ToBooleanStub::PrintState(StringStream* stream) {
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001023 types_.Print(stream);
1024}
1025
1026
vegorov@chromium.org7943d462011-08-01 11:41:52 +00001027void ToBooleanStub::Types::Print(StringStream* stream) const {
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001028 stream->Add("(");
1029 SimpleListPrinter printer(stream);
1030 if (IsEmpty()) printer.Add("None");
1031 if (Contains(UNDEFINED)) printer.Add("Undefined");
1032 if (Contains(BOOLEAN)) printer.Add("Bool");
1033 if (Contains(NULL_TYPE)) printer.Add("Null");
1034 if (Contains(SMI)) printer.Add("Smi");
1035 if (Contains(SPEC_OBJECT)) printer.Add("SpecObject");
1036 if (Contains(STRING)) printer.Add("String");
1037 if (Contains(SYMBOL)) printer.Add("Symbol");
1038 if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber");
1039 stream->Add(")");
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001040}
1041
1042
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001043bool ToBooleanStub::Types::UpdateStatus(Handle<Object> object) {
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001044 if (object->IsUndefined()) {
1045 Add(UNDEFINED);
1046 return false;
1047 } else if (object->IsBoolean()) {
1048 Add(BOOLEAN);
1049 return object->IsTrue();
1050 } else if (object->IsNull()) {
1051 Add(NULL_TYPE);
1052 return false;
1053 } else if (object->IsSmi()) {
1054 Add(SMI);
1055 return Smi::cast(*object)->value() != 0;
1056 } else if (object->IsSpecObject()) {
1057 Add(SPEC_OBJECT);
1058 return !object->IsUndetectableObject();
1059 } else if (object->IsString()) {
1060 Add(STRING);
1061 return !object->IsUndetectableObject() &&
1062 String::cast(*object)->length() != 0;
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001063 } else if (object->IsSymbol()) {
1064 Add(SYMBOL);
1065 return true;
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001066 } else if (object->IsHeapNumber()) {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001067 ASSERT(!object->IsUndetectableObject());
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001068 Add(HEAP_NUMBER);
1069 double value = HeapNumber::cast(*object)->value();
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00001070 return value != 0 && !std::isnan(value);
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001071 } else {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001072 // We should never see an internal object at runtime here!
1073 UNREACHABLE();
1074 return true;
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001075 }
1076}
1077
1078
vegorov@chromium.org7943d462011-08-01 11:41:52 +00001079bool ToBooleanStub::Types::NeedsMap() const {
1080 return Contains(ToBooleanStub::SPEC_OBJECT)
1081 || Contains(ToBooleanStub::STRING)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001082 || Contains(ToBooleanStub::SYMBOL)
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001083 || Contains(ToBooleanStub::HEAP_NUMBER);
1084}
1085
1086
1087bool ToBooleanStub::Types::CanBeUndetectable() const {
1088 return Contains(ToBooleanStub::SPEC_OBJECT)
1089 || Contains(ToBooleanStub::STRING);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00001090}
1091
1092
hpayer@chromium.org8432c912013-02-28 15:55:26 +00001093void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001094 StubFailureTrampolineStub stub1(NOT_JS_FUNCTION_STUB_MODE);
1095 StubFailureTrampolineStub stub2(JS_FUNCTION_STUB_MODE);
1096 stub1.GetCode(isolate)->set_is_pregenerated(true);
1097 stub2.GetCode(isolate)->set_is_pregenerated(true);
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00001098}
1099
1100
verwaest@chromium.org753aee42012-07-17 16:15:42 +00001101void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function,
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +00001102 intptr_t stack_pointer,
1103 Isolate* isolate) {
1104 FunctionEntryHook entry_hook = isolate->function_entry_hook();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001105 ASSERT(entry_hook != NULL);
1106 entry_hook(function, stack_pointer);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00001107}
1108
1109
danno@chromium.orgca29dd82013-04-26 11:59:48 +00001110static void InstallDescriptor(Isolate* isolate, HydrogenCodeStub* stub) {
1111 int major_key = stub->MajorKey();
1112 CodeStubInterfaceDescriptor* descriptor =
1113 isolate->code_stub_interface_descriptor(major_key);
1114 if (!descriptor->initialized()) {
1115 stub->InitializeInterfaceDescriptor(isolate, descriptor);
1116 }
1117}
1118
1119
1120void ArrayConstructorStubBase::InstallDescriptors(Isolate* isolate) {
1121 ArrayNoArgumentConstructorStub stub1(GetInitialFastElementsKind());
1122 InstallDescriptor(isolate, &stub1);
1123 ArraySingleArgumentConstructorStub stub2(GetInitialFastElementsKind());
1124 InstallDescriptor(isolate, &stub2);
1125 ArrayNArgumentsConstructorStub stub3(GetInitialFastElementsKind());
1126 InstallDescriptor(isolate, &stub3);
1127}
1128
1129
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001130void FastNewClosureStub::InstallDescriptors(Isolate* isolate) {
1131 FastNewClosureStub stub(STRICT_MODE, false);
1132 InstallDescriptor(isolate, &stub);
1133}
1134
1135
danno@chromium.orgca29dd82013-04-26 11:59:48 +00001136ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
1137 : argument_count_(ANY) {
1138 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
1139}
1140
1141
1142ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate,
1143 int argument_count) {
1144 if (argument_count == 0) {
1145 argument_count_ = NONE;
1146 } else if (argument_count == 1) {
1147 argument_count_ = ONE;
1148 } else if (argument_count >= 2) {
1149 argument_count_ = MORE_THAN_ONE;
1150 } else {
1151 UNREACHABLE();
1152 }
1153 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
1154}
1155
1156
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00001157void InternalArrayConstructorStubBase::InstallDescriptors(Isolate* isolate) {
1158 InternalArrayNoArgumentConstructorStub stub1(FAST_ELEMENTS);
1159 InstallDescriptor(isolate, &stub1);
1160 InternalArraySingleArgumentConstructorStub stub2(FAST_ELEMENTS);
1161 InstallDescriptor(isolate, &stub2);
1162 InternalArrayNArgumentsConstructorStub stub3(FAST_ELEMENTS);
1163 InstallDescriptor(isolate, &stub3);
1164}
1165
1166InternalArrayConstructorStub::InternalArrayConstructorStub(
1167 Isolate* isolate) {
1168 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
1169}
1170
1171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001172} } // namespace v8::internal