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

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

Issue 136643008: A64: Synchronize with r18256. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 Handle<Code> PlatformCodeStub::GenerateCode(Isolate* isolate) { 103 Handle<Code> PlatformCodeStub::GenerateCode(Isolate* isolate) {
104 Factory* factory = isolate->factory(); 104 Factory* factory = isolate->factory();
105 105
106 // Generate the new code. 106 // Generate the new code.
107 MacroAssembler masm(isolate, NULL, 256); 107 MacroAssembler masm(isolate, NULL, 256);
108 108
109 { 109 {
110 // Update the static counter each time a new code stub is generated. 110 // Update the static counter each time a new code stub is generated.
111 isolate->counters()->code_stubs()->Increment(); 111 isolate->counters()->code_stubs()->Increment();
112 112
113 // Nested stubs are not allowed for leaves.
114 AllowStubCallsScope allow_scope(&masm, false);
115
116 // Generate the code for the stub. 113 // Generate the code for the stub.
117 masm.set_generating_stub(true); 114 masm.set_generating_stub(true);
118 NoCurrentFrameScope scope(&masm); 115 NoCurrentFrameScope scope(&masm);
119 Generate(&masm); 116 Generate(&masm);
120 } 117 }
121 118
122 // Create the code object. 119 // Create the code object.
123 CodeDesc desc; 120 CodeDesc desc;
124 masm.GetCode(&desc); 121 masm.GetCode(&desc);
125 122
(...skipping 15 matching lines...) Expand all
141 } 138 }
142 139
143 140
144 Handle<Code> CodeStub::GetCode(Isolate* isolate) { 141 Handle<Code> CodeStub::GetCode(Isolate* isolate) {
145 Factory* factory = isolate->factory(); 142 Factory* factory = isolate->factory();
146 Heap* heap = isolate->heap(); 143 Heap* heap = isolate->heap();
147 Code* code; 144 Code* code;
148 if (UseSpecialCache() 145 if (UseSpecialCache()
149 ? FindCodeInSpecialCache(&code, isolate) 146 ? FindCodeInSpecialCache(&code, isolate)
150 : FindCodeInCache(&code, isolate)) { 147 : FindCodeInCache(&code, isolate)) {
151 ASSERT(IsPregenerated(isolate) == code->is_pregenerated());
152 ASSERT(GetCodeKind() == code->kind()); 148 ASSERT(GetCodeKind() == code->kind());
153 return Handle<Code>(code); 149 return Handle<Code>(code);
154 } 150 }
155 151
156 #ifdef DEBUG 152 #ifdef DEBUG
157 VerifyPlatformFeatures(isolate); 153 VerifyPlatformFeatures(isolate);
158 #endif 154 #endif
159 155
160 { 156 {
161 HandleScope scope(isolate); 157 HandleScope scope(isolate);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 stream->Add("%s", MajorName(MajorKey(), false)); 210 stream->Add("%s", MajorName(MajorKey(), false));
215 } 211 }
216 212
217 213
218 void CodeStub::PrintName(StringStream* stream) { 214 void CodeStub::PrintName(StringStream* stream) {
219 PrintBaseName(stream); 215 PrintBaseName(stream);
220 PrintState(stream); 216 PrintState(stream);
221 } 217 }
222 218
223 219
224 void BinaryOpStub::PrintBaseName(StringStream* stream) { 220 // static
225 const char* op_name = Token::Name(op_); 221 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
226 const char* ovr = ""; 222 // Generate the uninitialized versions of the stub.
227 if (mode_ == OVERWRITE_LEFT) ovr = "_ReuseLeft"; 223 for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
228 if (mode_ == OVERWRITE_RIGHT) ovr = "_ReuseRight"; 224 for (int mode = NO_OVERWRITE; mode <= OVERWRITE_RIGHT; ++mode) {
229 stream->Add("BinaryOpStub_%s%s", op_name, ovr); 225 BinaryOpICStub stub(static_cast<Token::Value>(op),
226 static_cast<OverwriteMode>(mode));
227 stub.GetCode(isolate);
228 }
229 }
230
231 // Generate special versions of the stub.
232 BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
230 } 233 }
231 234
232 235
233 void BinaryOpStub::PrintState(StringStream* stream) { 236 void BinaryOpICStub::PrintState(StringStream* stream) {
234 stream->Add("("); 237 state_.Print(stream);
235 stream->Add(StateToName(left_state_));
236 stream->Add("*");
237 if (fixed_right_arg_.has_value) {
238 stream->Add("%d", fixed_right_arg_.value);
239 } else {
240 stream->Add(StateToName(right_state_));
241 }
242 stream->Add("->");
243 stream->Add(StateToName(result_state_));
244 stream->Add(")");
245 } 238 }
246 239
247 240
248 Maybe<Handle<Object> > BinaryOpStub::Result(Handle<Object> left, 241 // static
249 Handle<Object> right, 242 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate,
250 Isolate* isolate) { 243 const BinaryOpIC::State& state) {
251 Handle<JSBuiltinsObject> builtins(isolate->js_builtins_object()); 244 BinaryOpICStub stub(state);
252 Builtins::JavaScript func = BinaryOpIC::TokenToJSBuiltin(op_);
253 Object* builtin = builtins->javascript_builtin(func);
254 Handle<JSFunction> builtin_function =
255 Handle<JSFunction>(JSFunction::cast(builtin), isolate);
256 bool caught_exception;
257 Handle<Object> result = Execution::Call(isolate, builtin_function, left,
258 1, &right, &caught_exception);
259 return Maybe<Handle<Object> >(!caught_exception, result);
260 }
261
262
263 void BinaryOpStub::Initialize() {
264 fixed_right_arg_.has_value = false;
265 left_state_ = right_state_ = result_state_ = NONE;
266 }
267
268
269 void BinaryOpStub::Generate(Token::Value op,
270 State left,
271 State right,
272 State result,
273 OverwriteMode mode,
274 Isolate* isolate) {
275 BinaryOpStub stub(INITIALIZED);
276 stub.op_ = op;
277 stub.left_state_ = left;
278 stub.right_state_ = right;
279 stub.result_state_ = result;
280 stub.mode_ = mode;
281 stub.GetCode(isolate); 245 stub.GetCode(isolate);
282 } 246 }
283 247
284 248
285 void BinaryOpStub::Generate(Token::Value op,
286 State left,
287 int right,
288 State result,
289 OverwriteMode mode,
290 Isolate* isolate) {
291 BinaryOpStub stub(INITIALIZED);
292 stub.op_ = op;
293 stub.left_state_ = left;
294 stub.fixed_right_arg_.has_value = true;
295 stub.fixed_right_arg_.value = right;
296 stub.right_state_ = SMI;
297 stub.result_state_ = result;
298 stub.mode_ = mode;
299 stub.GetCode(isolate);
300 }
301
302
303 void BinaryOpStub::GenerateAheadOfTime(Isolate* isolate) {
304 Token::Value binop[] = {Token::SUB, Token::MOD, Token::DIV, Token::MUL,
305 Token::ADD, Token::SAR, Token::BIT_OR, Token::BIT_AND,
306 Token::BIT_XOR, Token::SHL, Token::SHR};
307 for (unsigned i = 0; i < ARRAY_SIZE(binop); i++) {
308 BinaryOpStub stub(UNINITIALIZED);
309 stub.op_ = binop[i];
310 stub.GetCode(isolate);
311 }
312
313 // TODO(olivf) We should investigate why adding stubs to the snapshot is so
314 // expensive at runtime. When solved we should be able to add most binops to
315 // the snapshot instead of hand-picking them.
316 // Generated list of commonly used stubs
317 Generate(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE, isolate);
318 Generate(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
319 Generate(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
320 Generate(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT, isolate);
321 Generate(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
322 Generate(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
323 Generate(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
324 Generate(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE, isolate);
325 Generate(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
326 Generate(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
327 Generate(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
328 Generate(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
329 Generate(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT, isolate);
330 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
331 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
332 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
333 Generate(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
334 Generate(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
335 Generate(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
336 Generate(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE, isolate);
337 Generate(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
338 Generate(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
339 Generate(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
340 Generate(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
341 Generate(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
342 Generate(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT, isolate);
343 Generate(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
344 Generate(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE, isolate);
345 Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
346 Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
347 Generate(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE, isolate);
348 Generate(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT, isolate);
349 Generate(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE, isolate);
350 Generate(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
351 Generate(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE, isolate);
352 Generate(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT, isolate);
353 Generate(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
354 Generate(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT, isolate);
355 Generate(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
356 Generate(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
357 Generate(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE, isolate);
358 Generate(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT, isolate);
359 Generate(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT, isolate);
360 Generate(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE, isolate);
361 Generate(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
362 Generate(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
363 Generate(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
364 Generate(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
365 Generate(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT, isolate);
366 Generate(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE, isolate);
367 Generate(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
368 Generate(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
369 Generate(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
370 Generate(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
371 Generate(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE, isolate);
372 Generate(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT, isolate);
373 Generate(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT, isolate);
374 Generate(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
375 Generate(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT, isolate);
376 Generate(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
377 Generate(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT, isolate);
378 Generate(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT, isolate);
379 Generate(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
380 Generate(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
381 Generate(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE, isolate);
382 Generate(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
383 Generate(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
384 Generate(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE, isolate);
385 Generate(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT, isolate);
386 Generate(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE, isolate);
387 Generate(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE, isolate);
388 Generate(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
389 Generate(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
390 Generate(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE, isolate);
391 Generate(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE, isolate);
392 Generate(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
393 Generate(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE, isolate);
394 Generate(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
395 Generate(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT, isolate);
396 Generate(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE, isolate);
397 Generate(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
398 Generate(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
399 Generate(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE, isolate);
400 Generate(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
401 Generate(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
402 Generate(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
403 Generate(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE, isolate);
404 Generate(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE, isolate);
405 Generate(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
406 Generate(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
407 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
408 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
409 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
410 Generate(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
411 Generate(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
412 Generate(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE, isolate);
413 Generate(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
414 Generate(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT, isolate);
415 Generate(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
416 Generate(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
417 Generate(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
418 Generate(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE, isolate);
419 Generate(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT, isolate);
420 Generate(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
421 Generate(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE, isolate);
422 Generate(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
423 Generate(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
424 Generate(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
425 Generate(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT, isolate);
426 Generate(Token::MOD, SMI, 2, SMI, NO_OVERWRITE, isolate);
427 Generate(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE, isolate);
428 Generate(Token::MOD, SMI, 32, SMI, NO_OVERWRITE, isolate);
429 Generate(Token::MOD, SMI, 4, SMI, NO_OVERWRITE, isolate);
430 Generate(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT, isolate);
431 Generate(Token::MOD, SMI, 8, SMI, NO_OVERWRITE, isolate);
432 Generate(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE, isolate);
433 Generate(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
434 Generate(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE, isolate);
435 Generate(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
436 Generate(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
437 Generate(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
438 Generate(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE, isolate);
439 Generate(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
440 Generate(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE, isolate);
441 Generate(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
442 Generate(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
443 Generate(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT, isolate);
444 Generate(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
445 Generate(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
446 Generate(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
447 Generate(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
448 Generate(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
449 Generate(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE, isolate);
450 Generate(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
451 Generate(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
452 Generate(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
453 Generate(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
454 Generate(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
455 Generate(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE, isolate);
456 Generate(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE, isolate);
457 Generate(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT, isolate);
458 Generate(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE, isolate);
459 Generate(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
460 Generate(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
461 Generate(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
462 Generate(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
463 Generate(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
464 Generate(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
465 Generate(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
466 Generate(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
467 Generate(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
468 Generate(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE, isolate);
469 Generate(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
470 Generate(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE, isolate);
471 Generate(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
472 Generate(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
473 Generate(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE, isolate);
474 Generate(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT, isolate);
475 Generate(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT, isolate);
476 Generate(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE, isolate);
477 Generate(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
478 Generate(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
479 Generate(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
480 Generate(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT, isolate);
481 Generate(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
482 Generate(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
483 Generate(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT, isolate);
484 Generate(Token::SHR, NUMBER, SMI, INT32, OVERWRITE_RIGHT, isolate);
485 Generate(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE, isolate);
486 Generate(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
487 Generate(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
488 Generate(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE, isolate);
489 Generate(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
490 Generate(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
491 Generate(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
492 Generate(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
493 Generate(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
494 Generate(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
495 Generate(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
496 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
497 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
498 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
499 Generate(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
500 Generate(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
501 Generate(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
502 Generate(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE, isolate);
503 Generate(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
504 Generate(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
505 Generate(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
506 Generate(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE, isolate);
507 Generate(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
508 Generate(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
509 }
510
511
512 bool BinaryOpStub::can_encode_arg_value(int32_t value) const {
513 return op_ == Token::MOD && value > 0 && IsPowerOf2(value) &&
514 FixedRightArgValueBits::is_valid(WhichPowerOf2(value));
515 }
516
517
518 int BinaryOpStub::encode_arg_value(int32_t value) const {
519 ASSERT(can_encode_arg_value(value));
520 return WhichPowerOf2(value);
521 }
522
523
524 int32_t BinaryOpStub::decode_arg_value(int value) const {
525 return 1 << value;
526 }
527
528
529 int BinaryOpStub::encode_token(Token::Value op) const {
530 ASSERT(op >= FIRST_TOKEN && op <= LAST_TOKEN);
531 return op - FIRST_TOKEN;
532 }
533
534
535 Token::Value BinaryOpStub::decode_token(int op) const {
536 int res = op + FIRST_TOKEN;
537 ASSERT(res >= FIRST_TOKEN && res <= LAST_TOKEN);
538 return static_cast<Token::Value>(res);
539 }
540
541
542 const char* BinaryOpStub::StateToName(State state) {
543 switch (state) {
544 case NONE:
545 return "None";
546 case SMI:
547 return "Smi";
548 case INT32:
549 return "Int32";
550 case NUMBER:
551 return "Number";
552 case STRING:
553 return "String";
554 case GENERIC:
555 return "Generic";
556 }
557 return "";
558 }
559
560
561 void BinaryOpStub::UpdateStatus(Handle<Object> left,
562 Handle<Object> right,
563 Maybe<Handle<Object> > result) {
564 int old_state = GetExtraICState();
565
566 UpdateStatus(left, &left_state_);
567 UpdateStatus(right, &right_state_);
568
569 int32_t value;
570 bool new_has_fixed_right_arg =
571 right->ToInt32(&value) && can_encode_arg_value(value) &&
572 (left_state_ == SMI || left_state_ == INT32) &&
573 (result_state_ == NONE || !fixed_right_arg_.has_value);
574
575 fixed_right_arg_ = Maybe<int32_t>(new_has_fixed_right_arg, value);
576
577 if (result.has_value) UpdateStatus(result.value, &result_state_);
578
579 State max_input = Max(left_state_, right_state_);
580
581 if (!has_int_result() && op_ != Token::SHR &&
582 max_input <= NUMBER && max_input > result_state_) {
583 result_state_ = max_input;
584 }
585
586 ASSERT(result_state_ <= (has_int_result() ? INT32 : NUMBER) ||
587 op_ == Token::ADD);
588
589 // Reset overwrite mode unless we can actually make use of it, or may be able
590 // to make use of it at some point in the future.
591 if ((mode_ == OVERWRITE_LEFT && left_state_ > NUMBER) ||
592 (mode_ == OVERWRITE_RIGHT && right_state_ > NUMBER) ||
593 result_state_ > NUMBER) {
594 mode_ = NO_OVERWRITE;
595 }
596
597 if (old_state == GetExtraICState()) {
598 // Tagged operations can lead to non-truncating HChanges
599 if (left->IsUndefined() || left->IsBoolean()) {
600 left_state_ = GENERIC;
601 } else if (right->IsUndefined() || right->IsBoolean()) {
602 right_state_ = GENERIC;
603 } else {
604 // Since the fpu is to precise, we might bail out on numbers which
605 // actually would truncate with 64 bit precision.
606 ASSERT(!CpuFeatures::IsSupported(SSE2) &&
607 result_state_ <= INT32);
608 result_state_ = NUMBER;
609 }
610 }
611 }
612
613
614 void BinaryOpStub::UpdateStatus(Handle<Object> object,
615 State* state) {
616 bool is_truncating = (op_ == Token::BIT_AND || op_ == Token::BIT_OR ||
617 op_ == Token::BIT_XOR || op_ == Token::SAR ||
618 op_ == Token::SHL || op_ == Token::SHR);
619 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(object);
620 if (object->IsBoolean() && is_truncating) {
621 // Booleans are converted by truncating by HChange.
622 type = TypeInfo::Integer32();
623 }
624 if (object->IsUndefined()) {
625 // Undefined will be automatically truncated for us by HChange.
626 type = is_truncating ? TypeInfo::Integer32() : TypeInfo::Double();
627 }
628 State int_state = SmiValuesAre32Bits() ? NUMBER : INT32;
629 State new_state = NONE;
630 if (type.IsSmi()) {
631 new_state = SMI;
632 } else if (type.IsInteger32()) {
633 new_state = int_state;
634 } else if (type.IsNumber()) {
635 new_state = NUMBER;
636 } else if (object->IsString() && operation() == Token::ADD) {
637 new_state = STRING;
638 } else {
639 new_state = GENERIC;
640 }
641 if ((new_state <= NUMBER && *state > NUMBER) ||
642 (new_state > NUMBER && *state <= NUMBER && *state != NONE)) {
643 new_state = GENERIC;
644 }
645 *state = Max(*state, new_state);
646 }
647
648
649 Handle<Type> BinaryOpStub::StateToType(State state,
650 Isolate* isolate) {
651 Handle<Type> t = handle(Type::None(), isolate);
652 switch (state) {
653 case NUMBER:
654 t = handle(Type::Union(t, handle(Type::Double(), isolate)), isolate);
655 // Fall through.
656 case INT32:
657 t = handle(Type::Union(t, handle(Type::Signed32(), isolate)), isolate);
658 // Fall through.
659 case SMI:
660 t = handle(Type::Union(t, handle(Type::Smi(), isolate)), isolate);
661 break;
662
663 case STRING:
664 t = handle(Type::Union(t, handle(Type::String(), isolate)), isolate);
665 break;
666 case GENERIC:
667 return handle(Type::Any(), isolate);
668 break;
669 case NONE:
670 break;
671 }
672 return t;
673 }
674
675
676 Handle<Type> BinaryOpStub::GetLeftType(Isolate* isolate) const {
677 return StateToType(left_state_, isolate);
678 }
679
680
681 Handle<Type> BinaryOpStub::GetRightType(Isolate* isolate) const {
682 return StateToType(right_state_, isolate);
683 }
684
685
686 Handle<Type> BinaryOpStub::GetResultType(Isolate* isolate) const {
687 if (HasSideEffects(isolate)) return StateToType(NONE, isolate);
688 if (result_state_ == GENERIC && op_ == Token::ADD) {
689 return handle(Type::Union(handle(Type::Number(), isolate),
690 handle(Type::String(), isolate)), isolate);
691 }
692 ASSERT(result_state_ != GENERIC);
693 if (result_state_ == NUMBER && op_ == Token::SHR) {
694 return handle(Type::Unsigned32(), isolate);
695 }
696 return StateToType(result_state_, isolate);
697 }
698
699
700 void NewStringAddStub::PrintBaseName(StringStream* stream) { 249 void NewStringAddStub::PrintBaseName(StringStream* stream) {
701 stream->Add("NewStringAddStub"); 250 stream->Add("NewStringAddStub");
702 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) { 251 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
703 stream->Add("_CheckBoth"); 252 stream->Add("_CheckBoth");
704 } else if ((flags() & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) { 253 } else if ((flags() & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
705 stream->Add("_CheckLeft"); 254 stream->Add("_CheckLeft");
706 } else if ((flags() & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { 255 } else if ((flags() & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) {
707 stream->Add("_CheckRight"); 256 stream->Add("_CheckRight");
708 } 257 }
709 if (pretenure_flag() == TENURED) { 258 if (pretenure_flag() == TENURED) {
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 520
972 521
973 void KeyedLoadDictionaryElementPlatformStub::Generate( 522 void KeyedLoadDictionaryElementPlatformStub::Generate(
974 MacroAssembler* masm) { 523 MacroAssembler* masm) {
975 KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); 524 KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm);
976 } 525 }
977 526
978 527
979 void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) { 528 void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
980 CreateAllocationSiteStub stub; 529 CreateAllocationSiteStub stub;
981 stub.GetCode(isolate)->set_is_pregenerated(true); 530 stub.GetCode(isolate);
982 } 531 }
983 532
984 533
985 void KeyedStoreElementStub::Generate(MacroAssembler* masm) { 534 void KeyedStoreElementStub::Generate(MacroAssembler* masm) {
986 switch (elements_kind_) { 535 switch (elements_kind_) {
987 case FAST_ELEMENTS: 536 case FAST_ELEMENTS:
988 case FAST_HOLEY_ELEMENTS: 537 case FAST_HOLEY_ELEMENTS:
989 case FAST_SMI_ELEMENTS: 538 case FAST_SMI_ELEMENTS:
990 case FAST_HOLEY_SMI_ELEMENTS: 539 case FAST_HOLEY_SMI_ELEMENTS:
991 case FAST_DOUBLE_ELEMENTS: 540 case FAST_DOUBLE_ELEMENTS:
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 659
1111 bool ToBooleanStub::Types::CanBeUndetectable() const { 660 bool ToBooleanStub::Types::CanBeUndetectable() const {
1112 return Contains(ToBooleanStub::SPEC_OBJECT) 661 return Contains(ToBooleanStub::SPEC_OBJECT)
1113 || Contains(ToBooleanStub::STRING); 662 || Contains(ToBooleanStub::STRING);
1114 } 663 }
1115 664
1116 665
1117 void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) { 666 void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) {
1118 StubFailureTrampolineStub stub1(NOT_JS_FUNCTION_STUB_MODE); 667 StubFailureTrampolineStub stub1(NOT_JS_FUNCTION_STUB_MODE);
1119 StubFailureTrampolineStub stub2(JS_FUNCTION_STUB_MODE); 668 StubFailureTrampolineStub stub2(JS_FUNCTION_STUB_MODE);
1120 stub1.GetCode(isolate)->set_is_pregenerated(true); 669 stub1.GetCode(isolate);
1121 stub2.GetCode(isolate)->set_is_pregenerated(true); 670 stub2.GetCode(isolate);
1122 } 671 }
1123 672
1124 673
1125 void StubFailureTailCallTrampolineStub::GenerateAheadOfTime(Isolate* isolate) { 674 void StubFailureTailCallTrampolineStub::GenerateAheadOfTime(Isolate* isolate) {
1126 StubFailureTailCallTrampolineStub stub; 675 StubFailureTailCallTrampolineStub stub;
1127 stub.GetCode(isolate)->set_is_pregenerated(true); 676 stub.GetCode(isolate);
1128 } 677 }
1129 678
1130 679
1131 void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function, 680 void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function,
1132 intptr_t stack_pointer, 681 intptr_t stack_pointer,
1133 Isolate* isolate) { 682 Isolate* isolate) {
1134 FunctionEntryHook entry_hook = isolate->function_entry_hook(); 683 FunctionEntryHook entry_hook = isolate->function_entry_hook();
1135 ASSERT(entry_hook != NULL); 684 ASSERT(entry_hook != NULL);
1136 entry_hook(function, stack_pointer); 685 entry_hook(function, stack_pointer);
1137 } 686 }
(...skipping 25 matching lines...) Expand all
1163 } 712 }
1164 713
1165 714
1166 void FastNewClosureStub::InstallDescriptors(Isolate* isolate) { 715 void FastNewClosureStub::InstallDescriptors(Isolate* isolate) {
1167 FastNewClosureStub stub(STRICT_MODE, false); 716 FastNewClosureStub stub(STRICT_MODE, false);
1168 InstallDescriptor(isolate, &stub); 717 InstallDescriptor(isolate, &stub);
1169 } 718 }
1170 719
1171 720
1172 // static 721 // static
722 void BinaryOpICStub::InstallDescriptors(Isolate* isolate) {
723 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
724 InstallDescriptor(isolate, &stub);
725 }
726
727
728 // static
1173 void NewStringAddStub::InstallDescriptors(Isolate* isolate) { 729 void NewStringAddStub::InstallDescriptors(Isolate* isolate) {
1174 NewStringAddStub stub(STRING_ADD_CHECK_NONE, NOT_TENURED); 730 NewStringAddStub stub(STRING_ADD_CHECK_NONE, NOT_TENURED);
1175 InstallDescriptor(isolate, &stub); 731 InstallDescriptor(isolate, &stub);
1176 } 732 }
1177 733
1178 734
1179 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate) 735 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
1180 : argument_count_(ANY) { 736 : argument_count_(ANY) {
1181 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); 737 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
1182 } 738 }
(...skipping 23 matching lines...) Expand all
1206 InstallDescriptor(isolate, &stub3); 762 InstallDescriptor(isolate, &stub3);
1207 } 763 }
1208 764
1209 InternalArrayConstructorStub::InternalArrayConstructorStub( 765 InternalArrayConstructorStub::InternalArrayConstructorStub(
1210 Isolate* isolate) { 766 Isolate* isolate) {
1211 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); 767 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
1212 } 768 }
1213 769
1214 770
1215 } } // namespace v8::internal 771 } } // 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