Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: src/code-stubs.cc

Issue 26236004: Rollback of r17108, r17106, r17104 in trunk branch. (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/code-stubs.h ('k') | src/code-stubs-hydrogen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 130
131 131
132 Handle<Code> CodeStub::GetCode(Isolate* isolate) { 132 Handle<Code> CodeStub::GetCode(Isolate* isolate) {
133 Factory* factory = isolate->factory(); 133 Factory* factory = isolate->factory();
134 Heap* heap = isolate->heap(); 134 Heap* heap = isolate->heap();
135 Code* code; 135 Code* code;
136 if (UseSpecialCache() 136 if (UseSpecialCache()
137 ? FindCodeInSpecialCache(&code, isolate) 137 ? FindCodeInSpecialCache(&code, isolate)
138 : FindCodeInCache(&code, isolate)) { 138 : FindCodeInCache(&code, isolate)) {
139 ASSERT(IsPregenerated(isolate) == code->is_pregenerated()); 139 ASSERT(IsPregenerated(isolate) == code->is_pregenerated());
140 ASSERT(GetCodeKind() == code->kind());
141 return Handle<Code>(code); 140 return Handle<Code>(code);
142 } 141 }
143 142
144 { 143 {
145 HandleScope scope(isolate); 144 HandleScope scope(isolate);
146 145
147 Handle<Code> new_object = GenerateCode(isolate); 146 Handle<Code> new_object = GenerateCode(isolate);
148 new_object->set_major_key(MajorKey()); 147 new_object->set_major_key(MajorKey());
149 FinishCode(new_object); 148 FinishCode(new_object);
150 RecordCodeGeneration(*new_object, isolate); 149 RecordCodeGeneration(*new_object, isolate);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 stream->Add("%s", MajorName(MajorKey(), false)); 196 stream->Add("%s", MajorName(MajorKey(), false));
198 } 197 }
199 198
200 199
201 void CodeStub::PrintName(StringStream* stream) { 200 void CodeStub::PrintName(StringStream* stream) {
202 PrintBaseName(stream); 201 PrintBaseName(stream);
203 PrintState(stream); 202 PrintState(stream);
204 } 203 }
205 204
206 205
207 void BinaryOpStub::PrintBaseName(StringStream* stream) { 206 void BinaryOpStub::Generate(MacroAssembler* masm) {
208 const char* op_name = Token::Name(op_); 207 // Explicitly allow generation of nested stubs. It is safe here because
209 const char* ovr = ""; 208 // generation code does not use any raw pointers.
210 if (mode_ == OVERWRITE_LEFT) ovr = "_ReuseLeft"; 209 AllowStubCallsScope allow_stub_calls(masm, true);
211 if (mode_ == OVERWRITE_RIGHT) ovr = "_ReuseRight";
212 stream->Add("BinaryOpStub_%s%s", op_name, ovr);
213 }
214 210
215 211 BinaryOpIC::TypeInfo operands_type = Max(left_type_, right_type_);
216 void BinaryOpStub::PrintState(StringStream* stream) { 212 if (left_type_ == BinaryOpIC::ODDBALL && right_type_ == BinaryOpIC::ODDBALL) {
217 stream->Add("("); 213 // The OddballStub handles a number and an oddball, not two oddballs.
218 stream->Add(StateToName(left_state_)); 214 operands_type = BinaryOpIC::GENERIC;
219 stream->Add("*");
220 if (fixed_right_arg_.has_value) {
221 stream->Add("%d", fixed_right_arg_.value);
222 } else {
223 stream->Add(StateToName(right_state_));
224 } 215 }
225 stream->Add("->"); 216 switch (operands_type) {
226 stream->Add(StateToName(result_state_)); 217 case BinaryOpIC::UNINITIALIZED:
227 stream->Add(")"); 218 GenerateTypeTransition(masm);
228 } 219 break;
229 220 case BinaryOpIC::SMI:
230 221 GenerateSmiStub(masm);
231 Maybe<Handle<Object> > BinaryOpStub::Result(Handle<Object> left, 222 break;
232 Handle<Object> right, 223 case BinaryOpIC::INT32:
233 Isolate* isolate) { 224 GenerateInt32Stub(masm);
234 Handle<JSBuiltinsObject> builtins(isolate->js_builtins_object()); 225 break;
235 Builtins::JavaScript func = BinaryOpIC::TokenToJSBuiltin(op_); 226 case BinaryOpIC::NUMBER:
236 Object* builtin = builtins->javascript_builtin(func); 227 GenerateNumberStub(masm);
237 Handle<JSFunction> builtin_function = 228 break;
238 Handle<JSFunction>(JSFunction::cast(builtin), isolate); 229 case BinaryOpIC::ODDBALL:
239 bool caught_exception; 230 GenerateOddballStub(masm);
240 Handle<Object> result = Execution::Call(isolate, builtin_function, left, 231 break;
241 1, &right, &caught_exception); 232 case BinaryOpIC::STRING:
242 return Maybe<Handle<Object> >(!caught_exception, result); 233 GenerateStringStub(masm);
243 } 234 break;
244 235 case BinaryOpIC::GENERIC:
245 236 GenerateGeneric(masm);
246 void BinaryOpStub::Initialize() { 237 break;
247 fixed_right_arg_.has_value = false; 238 default:
248 left_state_ = right_state_ = result_state_ = NONE; 239 UNREACHABLE();
249 }
250
251
252 void BinaryOpStub::Generate(Token::Value op,
253 State left,
254 State right,
255 State result,
256 OverwriteMode mode,
257 Isolate* isolate) {
258 BinaryOpStub stub(INITIALIZED);
259 stub.op_ = op;
260 stub.left_state_ = left;
261 stub.right_state_ = right;
262 stub.result_state_ = result;
263 stub.mode_ = mode;
264 stub.GetCode(isolate);
265 }
266
267
268 void BinaryOpStub::Generate(Token::Value op,
269 State left,
270 int right,
271 State result,
272 OverwriteMode mode,
273 Isolate* isolate) {
274 BinaryOpStub stub(INITIALIZED);
275 stub.op_ = op;
276 stub.left_state_ = left;
277 stub.fixed_right_arg_.has_value = true;
278 stub.fixed_right_arg_.value = right;
279 stub.right_state_ = SMI;
280 stub.result_state_ = result;
281 stub.mode_ = mode;
282 stub.GetCode(isolate);
283 }
284
285
286 void BinaryOpStub::GenerateAheadOfTime(Isolate* isolate) {
287 Token::Value binop[] = {Token::SUB, Token::MOD, Token::DIV, Token::MUL,
288 Token::ADD, Token::SAR, Token::BIT_OR, Token::BIT_AND,
289 Token::BIT_XOR, Token::SHL, Token::SHR};
290 for (unsigned i = 0; i < ARRAY_SIZE(binop); i++) {
291 BinaryOpStub stub(UNINITIALIZED);
292 stub.op_ = binop[i];
293 stub.GetCode(isolate);
294 }
295
296 // TODO(olivf) We should investigate why adding stubs to the snapshot is so
297 // expensive at runtime. When solved we should be able to add most binops to
298 // the snapshot instead of hand-picking them.
299 // Generated list of commonly used stubs
300 Generate(Token::ADD, GENERIC, STRING, STRING, NO_OVERWRITE, isolate);
301 Generate(Token::ADD, GENERIC, STRING, STRING, OVERWRITE_RIGHT, isolate);
302 Generate(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE, isolate);
303 Generate(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
304 Generate(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
305 Generate(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT, isolate);
306 Generate(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
307 Generate(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
308 Generate(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
309 Generate(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE, isolate);
310 Generate(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
311 Generate(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
312 Generate(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
313 Generate(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
314 Generate(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT, isolate);
315 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
316 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
317 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
318 Generate(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
319 Generate(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
320 Generate(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
321 Generate(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE, isolate);
322 Generate(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
323 Generate(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
324 Generate(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
325 Generate(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
326 Generate(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
327 Generate(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT, isolate);
328 Generate(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
329 Generate(Token::ADD, STRING, GENERIC, STRING, NO_OVERWRITE, isolate);
330 Generate(Token::ADD, STRING, GENERIC, STRING, OVERWRITE_LEFT, isolate);
331 Generate(Token::ADD, STRING, GENERIC, STRING, OVERWRITE_RIGHT, isolate);
332 Generate(Token::ADD, STRING, STRING, STRING, NO_OVERWRITE, isolate);
333 Generate(Token::ADD, STRING, STRING, STRING, OVERWRITE_LEFT, isolate);
334 Generate(Token::ADD, STRING, STRING, STRING, OVERWRITE_RIGHT, isolate);
335 Generate(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE, isolate);
336 Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
337 Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
338 Generate(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE, isolate);
339 Generate(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT, isolate);
340 Generate(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE, isolate);
341 Generate(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
342 Generate(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE, isolate);
343 Generate(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT, isolate);
344 Generate(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
345 Generate(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT, isolate);
346 Generate(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
347 Generate(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
348 Generate(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE, isolate);
349 Generate(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT, isolate);
350 Generate(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT, isolate);
351 Generate(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE, isolate);
352 Generate(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
353 Generate(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
354 Generate(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
355 Generate(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
356 Generate(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT, isolate);
357 Generate(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE, isolate);
358 Generate(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
359 Generate(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
360 Generate(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
361 Generate(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
362 Generate(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE, isolate);
363 Generate(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT, isolate);
364 Generate(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT, isolate);
365 Generate(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
366 Generate(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT, isolate);
367 Generate(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
368 Generate(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT, isolate);
369 Generate(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT, isolate);
370 Generate(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
371 Generate(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
372 Generate(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE, isolate);
373 Generate(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
374 Generate(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
375 Generate(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE, isolate);
376 Generate(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT, isolate);
377 Generate(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE, isolate);
378 Generate(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE, isolate);
379 Generate(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
380 Generate(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
381 Generate(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE, isolate);
382 Generate(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE, isolate);
383 Generate(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
384 Generate(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE, isolate);
385 Generate(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
386 Generate(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT, isolate);
387 Generate(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE, isolate);
388 Generate(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
389 Generate(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
390 Generate(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE, isolate);
391 Generate(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
392 Generate(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
393 Generate(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
394 Generate(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE, isolate);
395 Generate(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE, isolate);
396 Generate(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
397 Generate(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
398 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
399 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
400 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
401 Generate(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
402 Generate(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
403 Generate(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE, isolate);
404 Generate(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
405 Generate(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT, isolate);
406 Generate(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
407 Generate(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
408 Generate(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
409 Generate(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE, isolate);
410 Generate(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT, isolate);
411 Generate(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
412 Generate(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE, isolate);
413 Generate(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
414 Generate(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
415 Generate(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
416 Generate(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT, isolate);
417 Generate(Token::MOD, SMI, 2, SMI, NO_OVERWRITE, isolate);
418 Generate(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE, isolate);
419 Generate(Token::MOD, SMI, 32, SMI, NO_OVERWRITE, isolate);
420 Generate(Token::MOD, SMI, 4, SMI, NO_OVERWRITE, isolate);
421 Generate(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT, isolate);
422 Generate(Token::MOD, SMI, 8, SMI, NO_OVERWRITE, isolate);
423 Generate(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE, isolate);
424 Generate(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
425 Generate(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE, isolate);
426 Generate(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
427 Generate(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
428 Generate(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
429 Generate(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE, isolate);
430 Generate(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
431 Generate(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE, isolate);
432 Generate(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
433 Generate(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
434 Generate(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT, isolate);
435 Generate(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
436 Generate(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
437 Generate(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
438 Generate(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
439 Generate(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
440 Generate(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE, isolate);
441 Generate(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
442 Generate(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
443 Generate(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
444 Generate(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
445 Generate(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
446 Generate(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE, isolate);
447 Generate(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE, isolate);
448 Generate(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT, isolate);
449 Generate(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE, isolate);
450 Generate(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
451 Generate(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
452 Generate(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
453 Generate(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
454 Generate(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
455 Generate(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
456 Generate(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
457 Generate(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
458 Generate(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
459 Generate(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE, isolate);
460 Generate(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
461 Generate(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE, isolate);
462 Generate(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
463 Generate(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
464 Generate(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE, isolate);
465 Generate(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT, isolate);
466 Generate(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT, isolate);
467 Generate(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE, isolate);
468 Generate(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
469 Generate(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
470 Generate(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
471 Generate(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT, isolate);
472 Generate(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
473 Generate(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
474 Generate(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT, isolate);
475 Generate(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE, isolate);
476 Generate(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
477 Generate(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
478 Generate(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE, isolate);
479 Generate(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
480 Generate(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
481 Generate(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
482 Generate(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
483 Generate(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
484 Generate(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
485 Generate(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
486 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
487 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
488 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
489 Generate(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
490 Generate(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
491 Generate(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
492 Generate(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE, isolate);
493 Generate(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
494 Generate(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
495 Generate(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
496 Generate(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE, isolate);
497 Generate(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
498 Generate(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
499 }
500
501
502 bool BinaryOpStub::can_encode_arg_value(int32_t value) const {
503 return op_ == Token::MOD && value > 0 && IsPowerOf2(value) &&
504 FixedRightArgValueBits::is_valid(WhichPowerOf2(value));
505 }
506
507
508 int BinaryOpStub::encode_arg_value(int32_t value) const {
509 ASSERT(can_encode_arg_value(value));
510 return WhichPowerOf2(value);
511 }
512
513
514 int32_t BinaryOpStub::decode_arg_value(int value) const {
515 return 1 << value;
516 }
517
518
519 int BinaryOpStub::encode_token(Token::Value op) const {
520 ASSERT(op >= FIRST_TOKEN && op <= LAST_TOKEN);
521 return op - FIRST_TOKEN;
522 }
523
524
525 Token::Value BinaryOpStub::decode_token(int op) const {
526 int res = op + FIRST_TOKEN;
527 ASSERT(res >= FIRST_TOKEN && res <= LAST_TOKEN);
528 return static_cast<Token::Value>(res);
529 }
530
531
532 const char* BinaryOpStub::StateToName(State state) {
533 switch (state) {
534 case NONE:
535 return "None";
536 case SMI:
537 return "Smi";
538 case INT32:
539 return "Int32";
540 case NUMBER:
541 return "Number";
542 case STRING:
543 return "String";
544 case GENERIC:
545 return "Generic";
546 }
547 return "";
548 }
549
550
551 void BinaryOpStub::UpdateStatus(Handle<Object> left,
552 Handle<Object> right,
553 Maybe<Handle<Object> > result) {
554 int old_state = GetExtraICState();
555
556 UpdateStatus(left, &left_state_);
557 UpdateStatus(right, &right_state_);
558
559 int32_t value;
560 bool new_has_fixed_right_arg =
561 right->ToInt32(&value) && can_encode_arg_value(value) &&
562 (left_state_ == SMI || left_state_ == INT32) &&
563 (result_state_ == NONE || !fixed_right_arg_.has_value);
564
565 fixed_right_arg_ = Maybe<int32_t>(new_has_fixed_right_arg, value);
566
567 if (result.has_value) UpdateStatus(result.value, &result_state_);
568
569 State max_input = Max(left_state_, right_state_);
570
571 // Avoid unnecessary Representation changes.
572 if (left_state_ == STRING && right_state_ < STRING) {
573 right_state_ = GENERIC;
574 } else if (right_state_ == STRING && left_state_ < STRING) {
575 left_state_ = GENERIC;
576 } else if ((right_state_ == GENERIC && left_state_ != STRING) ||
577 (left_state_ == GENERIC && right_state_ != STRING)) {
578 left_state_ = right_state_ = GENERIC;
579 } 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()) {
588 // Since the fpu is to precise, we might bail out on numbers which
589 // actually would truncate with 64 bit precision.
590 ASSERT(!CpuFeatures::IsSupported(SSE2) &&
591 result_state_ <= INT32);
592 result_state_ = NUMBER;
593 } 240 }
594 } 241 }
595 242
596 243
597 void BinaryOpStub::UpdateStatus(Handle<Object> object, 244 #define __ ACCESS_MASM(masm)
598 State* state) { 245
599 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(object); 246
600 if (object->IsUndefined()) { 247 void BinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
601 // Undefined will be automatically truncated for us by HChange. 248 switch (op_) {
602 type = (op_ == Token::BIT_AND || op_ == Token::BIT_OR || 249 case Token::ADD:
603 op_ == Token::BIT_XOR || op_ == Token::SAR || 250 __ InvokeBuiltin(Builtins::ADD, CALL_FUNCTION);
604 op_ == Token::SHL || op_ == Token::SHR) 251 break;
605 ? TypeInfo::Integer32() 252 case Token::SUB:
606 : TypeInfo::Double(); 253 __ InvokeBuiltin(Builtins::SUB, CALL_FUNCTION);
254 break;
255 case Token::MUL:
256 __ InvokeBuiltin(Builtins::MUL, CALL_FUNCTION);
257 break;
258 case Token::DIV:
259 __ InvokeBuiltin(Builtins::DIV, CALL_FUNCTION);
260 break;
261 case Token::MOD:
262 __ InvokeBuiltin(Builtins::MOD, CALL_FUNCTION);
263 break;
264 case Token::BIT_OR:
265 __ InvokeBuiltin(Builtins::BIT_OR, CALL_FUNCTION);
266 break;
267 case Token::BIT_AND:
268 __ InvokeBuiltin(Builtins::BIT_AND, CALL_FUNCTION);
269 break;
270 case Token::BIT_XOR:
271 __ InvokeBuiltin(Builtins::BIT_XOR, CALL_FUNCTION);
272 break;
273 case Token::SAR:
274 __ InvokeBuiltin(Builtins::SAR, CALL_FUNCTION);
275 break;
276 case Token::SHR:
277 __ InvokeBuiltin(Builtins::SHR, CALL_FUNCTION);
278 break;
279 case Token::SHL:
280 __ InvokeBuiltin(Builtins::SHL, CALL_FUNCTION);
281 break;
282 default:
283 UNREACHABLE();
607 } 284 }
608 State int_state = SmiValuesAre32Bits() ? NUMBER : INT32;
609 State new_state = NONE;
610 if (type.IsSmi()) {
611 new_state = SMI;
612 } else if (type.IsInteger32()) {
613 new_state = int_state;
614 } else if (type.IsNumber()) {
615 new_state = NUMBER;
616 } else if (object->IsString() && operation() == Token::ADD) {
617 new_state = STRING;
618 } else {
619 new_state = GENERIC;
620 }
621 if ((new_state <= NUMBER && *state > NUMBER) ||
622 (new_state > NUMBER && *state <= NUMBER && *state != NONE)) {
623 new_state = GENERIC;
624 }
625 *state = Max(*state, new_state);
626 } 285 }
627 286
628 287
629 Handle<Type> BinaryOpStub::StateToType(State state, 288 #undef __
630 Isolate* isolate) {
631 Handle<Type> t = handle(Type::None(), isolate);
632 switch (state) {
633 case NUMBER:
634 t = handle(Type::Union(t, handle(Type::Double(), isolate)), isolate);
635 // Fall through.
636 case INT32:
637 t = handle(Type::Union(t, handle(Type::Signed32(), isolate)), isolate);
638 // Fall through.
639 case SMI:
640 t = handle(Type::Union(t, handle(Type::Smi(), isolate)), isolate);
641 break;
642 289
643 case STRING: 290
644 t = handle(Type::Union(t, handle(Type::String(), isolate)), isolate); 291 void BinaryOpStub::PrintName(StringStream* stream) {
645 break; 292 const char* op_name = Token::Name(op_);
646 case GENERIC: 293 const char* overwrite_name;
647 return handle(Type::Any(), isolate); 294 switch (mode_) {
648 break; 295 case NO_OVERWRITE: overwrite_name = "Alloc"; break;
649 case NONE: 296 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break;
650 break; 297 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
298 default: overwrite_name = "UnknownOverwrite"; break;
651 } 299 }
652 return t; 300 stream->Add("BinaryOpStub_%s_%s_%s+%s",
301 op_name,
302 overwrite_name,
303 BinaryOpIC::GetName(left_type_),
304 BinaryOpIC::GetName(right_type_));
653 } 305 }
654 306
655 307
656 Handle<Type> BinaryOpStub::GetLeftType(Isolate* isolate) const { 308 void BinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
657 return StateToType(left_state_, isolate); 309 ASSERT(left_type_ == BinaryOpIC::STRING || right_type_ == BinaryOpIC::STRING);
310 ASSERT(op_ == Token::ADD);
311 if (left_type_ == BinaryOpIC::STRING && right_type_ == BinaryOpIC::STRING) {
312 GenerateBothStringStub(masm);
313 return;
314 }
315 // Try to add arguments as strings, otherwise, transition to the generic
316 // BinaryOpIC type.
317 GenerateAddStrings(masm);
318 GenerateTypeTransition(masm);
658 } 319 }
659 320
660 321
661 Handle<Type> BinaryOpStub::GetRightType(Isolate* isolate) const {
662 return StateToType(right_state_, isolate);
663 }
664
665
666 Handle<Type> BinaryOpStub::GetResultType(Isolate* isolate) const {
667 if (HasSideEffects(isolate)) return StateToType(NONE, isolate);
668 if (result_state_ == GENERIC && op_ == Token::ADD) {
669 return handle(Type::Union(handle(Type::Number(), isolate),
670 handle(Type::String(), isolate)), isolate);
671 }
672 ASSERT(result_state_ != GENERIC);
673 if (result_state_ == NUMBER && op_ == Token::SHR) {
674 return handle(Type::Unsigned32(), isolate);
675 }
676 return StateToType(result_state_, isolate);
677 }
678
679
680 InlineCacheState ICCompareStub::GetICState() { 322 InlineCacheState ICCompareStub::GetICState() {
681 CompareIC::State state = Max(left_, right_); 323 CompareIC::State state = Max(left_, right_);
682 switch (state) { 324 switch (state) {
683 case CompareIC::UNINITIALIZED: 325 case CompareIC::UNINITIALIZED:
684 return ::v8::internal::UNINITIALIZED; 326 return ::v8::internal::UNINITIALIZED;
685 case CompareIC::SMI: 327 case CompareIC::SMI:
686 case CompareIC::NUMBER: 328 case CompareIC::NUMBER:
687 case CompareIC::INTERNALIZED_STRING: 329 case CompareIC::INTERNALIZED_STRING:
688 case CompareIC::STRING: 330 case CompareIC::STRING:
689 case CompareIC::UNIQUE_NAME: 331 case CompareIC::UNIQUE_NAME:
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 InstallDescriptor(isolate, &stub3); 795 InstallDescriptor(isolate, &stub3);
1154 } 796 }
1155 797
1156 InternalArrayConstructorStub::InternalArrayConstructorStub( 798 InternalArrayConstructorStub::InternalArrayConstructorStub(
1157 Isolate* isolate) { 799 Isolate* isolate) {
1158 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); 800 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
1159 } 801 }
1160 802
1161 803
1162 } } // namespace v8::internal 804 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/code-stubs-hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698