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

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

Issue 151163005: A64: Synchronize with r16356. (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/a64/builtins-a64.cc ('k') | src/a64/cpu-a64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 20 matching lines...) Expand all
31 31
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "code-stubs.h" 33 #include "code-stubs.h"
34 #include "regexp-macro-assembler.h" 34 #include "regexp-macro-assembler.h"
35 #include "stub-cache.h" 35 #include "stub-cache.h"
36 36
37 namespace v8 { 37 namespace v8 {
38 namespace internal { 38 namespace internal {
39 39
40 40
41 void FastNewClosureStub::InitializeInterfaceDescriptor(
42 Isolate* isolate,
43 CodeStubInterfaceDescriptor* descriptor) {
44 // x2: function info
45 static Register registers[] = { x2 };
46 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
47 descriptor->register_params_ = registers;
48 descriptor->deoptimization_handler_ =
49 Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry;
50 }
51
52
41 void ToNumberStub::InitializeInterfaceDescriptor( 53 void ToNumberStub::InitializeInterfaceDescriptor(
42 Isolate* isolate, 54 Isolate* isolate,
43 CodeStubInterfaceDescriptor* descriptor) { 55 CodeStubInterfaceDescriptor* descriptor) {
44 // x0: value 56 // x0: value
45 static Register registers[] = { x0 }; 57 static Register registers[] = { x0 };
46 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]); 58 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
47 descriptor->register_params_ = registers; 59 descriptor->register_params_ = registers;
48 descriptor->deoptimization_handler_ = NULL; 60 descriptor->deoptimization_handler_ = NULL;
49 } 61 }
50 62
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 __ Push(descriptor->register_params_[i]); 324 __ Push(descriptor->register_params_[i]);
313 } 325 }
314 ExternalReference miss = descriptor->miss_handler(); 326 ExternalReference miss = descriptor->miss_handler();
315 __ CallExternalReference(miss, descriptor->register_param_count_); 327 __ CallExternalReference(miss, descriptor->register_param_count_);
316 } 328 }
317 329
318 __ Ret(); 330 __ Ret();
319 } 331 }
320 332
321 333
322 void FastNewClosureStub::Generate(MacroAssembler* masm) {
323 // Create a new closure from the given function info in new space. Set the
324 // context to the current context in cp.
325 Register new_fn = x0;
326 Register function = x1;
327
328 Counters* counters = masm->isolate()->counters();
329
330 Label gc;
331
332 // Pop the function info from the stack.
333 __ Pop(function);
334
335 // Attempt to allocate new JSFunction in new space.
336 __ Allocate(JSFunction::kSize, new_fn, x6, x7, &gc, TAG_OBJECT);
337
338 __ IncrementCounter(counters->fast_new_closure_total(), 1, x6, x7);
339
340 int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
341
342 // Compute the function map in the current native context and set that as the
343 // map of the allocated object.
344 Register global_object = x2;
345 Register global_ctx = x5;
346 Register global_fn_map = x2;
347 __ Ldr(global_object, GlobalObjectMemOperand());
348 __ Ldr(global_ctx, FieldMemOperand(global_object,
349 GlobalObject::kNativeContextOffset));
350 __ Ldr(global_fn_map, ContextMemOperand(global_ctx, map_index));
351 __ Str(global_fn_map, FieldMemOperand(new_fn, HeapObject::kMapOffset));
352
353 // Initialize the rest of the function. We don't have to update the write
354 // barrier because the allocated object is in new space.
355 Register empty_array = x2;
356 Register the_hole = x3;
357 __ LoadRoot(empty_array, Heap::kEmptyFixedArrayRootIndex);
358 __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex);
359
360 __ Str(empty_array, FieldMemOperand(new_fn, JSObject::kPropertiesOffset));
361 __ Str(empty_array, FieldMemOperand(new_fn, JSObject::kElementsOffset));
362 __ Str(the_hole, FieldMemOperand(new_fn,
363 JSFunction::kPrototypeOrInitialMapOffset));
364 __ Str(function, FieldMemOperand(new_fn,
365 JSFunction::kSharedFunctionInfoOffset));
366 __ Str(cp, FieldMemOperand(new_fn, JSFunction::kContextOffset));
367 __ Str(empty_array, FieldMemOperand(new_fn, JSFunction::kLiteralsOffset));
368
369 // Initialize the code pointer in the new function to be the one found in the
370 // shared function info object.
371 // But first check if there is an optimized version for our context.
372 Label check_optimized;
373 Label install_unoptimized;
374 Register opt_code_map = x4;
375 if (FLAG_cache_optimized_code) {
376 __ Ldr(opt_code_map,
377 FieldMemOperand(function,
378 SharedFunctionInfo::kOptimizedCodeMapOffset));
379 __ Cbnz(opt_code_map, &check_optimized);
380 }
381
382 __ Bind(&install_unoptimized);
383 Register undef = x4;
384 __ LoadRoot(undef, Heap::kUndefinedValueRootIndex);
385 __ Str(undef, FieldMemOperand(new_fn, JSFunction::kNextFunctionLinkOffset));
386
387 Register fn_code = x2;
388 __ Ldr(fn_code, FieldMemOperand(function, SharedFunctionInfo::kCodeOffset));
389 __ Add(fn_code, fn_code, Code::kHeaderSize - kHeapObjectTag);
390 __ Str(fn_code, FieldMemOperand(new_fn, JSFunction::kCodeEntryOffset));
391
392 // Return result. The argument function info has been popped already.
393 __ Ret();
394
395 // This code is never reached if FLAG_cache_optimized_code is false.
396 __ Bind(&check_optimized);
397
398 __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1, x6, x7);
399
400 // x4 opt_code_map pointer to optimized code map
401 // x5 global_ctx pointer to global context
402
403 // The optimized code map must never be empty, so check the first elements.
404 Label install_optimized;
405 // Speculatively move code object into opt_code.
406 Register opt_code = x11;
407 Register opt_code_ctx = x12;
408 __ Ldr(opt_code, FieldMemOperand(opt_code_map,
409 SharedFunctionInfo::kFirstCodeSlot));
410 __ Ldr(opt_code_ctx, FieldMemOperand(opt_code_map,
411 SharedFunctionInfo::kFirstContextSlot));
412 __ Cmp(opt_code_ctx, global_ctx);
413 __ B(eq, &install_optimized);
414
415 // Iterate through the rest of the map backwards.
416 Label loop;
417 Register index = x10;
418 Register array_base = x13;
419 Register entry = x14;
420 __ Ldrsw(index, UntagSmiFieldMemOperand(opt_code_map,
421 FixedArray::kLengthOffset));
422 __ Add(array_base, opt_code_map, FixedArray::kHeaderSize - kHeapObjectTag);
423 __ Bind(&loop);
424
425 // Do not double check first entry.
426 __ Cmp(index, SharedFunctionInfo::kSecondEntryIndex);
427 __ B(eq, &install_unoptimized);
428 // TODO(all) Optimise this to use addressing mode to update the pointer.
429 __ Sub(index, index, SharedFunctionInfo::kEntryLength);
430 __ Add(entry, array_base, Operand(index, LSL, kPointerSizeLog2));
431 __ Ldr(opt_code_ctx, MemOperand(entry));
432 __ Cmp(global_ctx, opt_code_ctx);
433 __ B(ne, &loop);
434
435 // Hit: fetch the optimized code. Register entry already contains pointer to
436 // the first element (context) of the triple.
437 __ Ldr(opt_code, MemOperand(entry, kPointerSize));
438
439 __ Bind(&install_optimized);
440 __ IncrementCounter(counters->fast_new_closure_install_optimized(),
441 1, x6, x7);
442
443 Register opt_code_entry = x10;
444 __ Add(opt_code_entry, opt_code, Code::kHeaderSize - kHeapObjectTag);
445 __ Str(opt_code_entry, FieldMemOperand(new_fn, JSFunction::kCodeEntryOffset));
446
447 // Now link a function into a list of optimized functions.
448 Register opt_fn_list = x10;
449 __ Ldr(opt_fn_list, ContextMemOperand(global_ctx,
450 Context::OPTIMIZED_FUNCTIONS_LIST));
451 __ Str(opt_fn_list, FieldMemOperand(new_fn,
452 JSFunction::kNextFunctionLinkOffset));
453 // No need for write barrier as JSFunction is in the new space.
454
455 // Store JSFunction before issuing write barrier as it clobbers all of the
456 // registers passed.
457 __ Str(new_fn, ContextMemOperand(global_ctx,
458 Context::OPTIMIZED_FUNCTIONS_LIST));
459
460 // Move value to a temporary, to prevent RecordWriteContextSlot()
461 // corrupting the return value.
462 __ Mov(x4, new_fn);
463 __ RecordWriteContextSlot(
464 global_ctx,
465 Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
466 x4,
467 x1,
468 kLRHasNotBeenSaved,
469 kDontSaveFPRegs);
470
471 // Return result. The argument function info has been popped already.
472 __ Ret();
473
474 // Create a new closure through the slower runtime call.
475 __ Bind(&gc);
476 Register false_val = x2;
477 __ LoadRoot(false_val, Heap::kFalseValueRootIndex);
478 __ Push(cp, function, false_val);
479 __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
480 }
481
482
483 void FastNewContextStub::Generate(MacroAssembler* masm) { 334 void FastNewContextStub::Generate(MacroAssembler* masm) {
484 Register function = x0; 335 Register function = x0;
485 Register allocated = x1; 336 Register allocated = x1;
486 Label gc; 337 Label gc;
487 338
488 // Pop the function from the stack. 339 // Pop the function from the stack.
489 __ Pop(function); 340 __ Pop(function);
490 341
491 // Attempt to allocate the context in new space. 342 // Attempt to allocate the context in new space.
492 int context_length = slots_ + Context::MIN_CONTEXT_SLOTS; 343 int context_length = slots_ + Context::MIN_CONTEXT_SLOTS;
(...skipping 6566 matching lines...) Expand 10 before | Expand all | Expand 10 after
7059 __ Bind(&fast_elements_case); 6910 __ Bind(&fast_elements_case);
7060 GenerateCase(masm, FAST_ELEMENTS); 6911 GenerateCase(masm, FAST_ELEMENTS);
7061 } 6912 }
7062 6913
7063 6914
7064 #undef __ 6915 #undef __
7065 6916
7066 } } // namespace v8::internal 6917 } } // namespace v8::internal
7067 6918
7068 #endif // V8_TARGET_ARCH_A64 6919 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/builtins-a64.cc ('k') | src/a64/cpu-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698