| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2016 the V8 project authors. All rights reserved. | 
|  | 2 // Use of this source code is governed by a BSD-style license that can be | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 #include "src/builtins/builtins-constructor.h" | 
|  | 6 #include "src/builtins/builtins-utils.h" | 
|  | 7 #include "src/builtins/builtins.h" | 
|  | 8 #include "src/code-factory.h" | 
|  | 9 #include "src/code-stub-assembler.h" | 
|  | 10 #include "src/interface-descriptors.h" | 
|  | 11 | 
|  | 12 namespace v8 { | 
|  | 13 namespace internal { | 
|  | 14 | 
|  | 15 typedef compiler::Node Node; | 
|  | 16 | 
|  | 17 Node* ConstructorBuiltinsAssembler::EmitFastNewClosure(Node* shared_info, | 
|  | 18                                                        Node* context) { | 
|  | 19   typedef compiler::CodeAssembler::Label Label; | 
|  | 20   typedef compiler::CodeAssembler::Variable Variable; | 
|  | 21 | 
|  | 22   Isolate* isolate = this->isolate(); | 
|  | 23   Factory* factory = isolate->factory(); | 
|  | 24   IncrementCounter(isolate->counters()->fast_new_closure_total(), 1); | 
|  | 25 | 
|  | 26   // Create a new closure from the given function info in new space | 
|  | 27   Node* result = Allocate(JSFunction::kSize); | 
|  | 28 | 
|  | 29   // Calculate the index of the map we should install on the function based on | 
|  | 30   // the FunctionKind and LanguageMode of the function. | 
|  | 31   // Note: Must be kept in sync with Context::FunctionMapIndex | 
|  | 32   Node* compiler_hints = | 
|  | 33       LoadObjectField(shared_info, SharedFunctionInfo::kCompilerHintsOffset, | 
|  | 34                       MachineType::Uint32()); | 
|  | 35   Node* is_strict = Word32And( | 
|  | 36       compiler_hints, Int32Constant(1 << SharedFunctionInfo::kStrictModeBit)); | 
|  | 37 | 
|  | 38   Label if_normal(this), if_generator(this), if_async(this), | 
|  | 39       if_class_constructor(this), if_function_without_prototype(this), | 
|  | 40       load_map(this); | 
|  | 41   Variable map_index(this, MachineType::PointerRepresentation()); | 
|  | 42 | 
|  | 43   STATIC_ASSERT(FunctionKind::kNormalFunction == 0); | 
|  | 44   Node* is_not_normal = | 
|  | 45       Word32And(compiler_hints, | 
|  | 46                 Int32Constant(SharedFunctionInfo::kAllFunctionKindBitsMask)); | 
|  | 47   GotoUnless(is_not_normal, &if_normal); | 
|  | 48 | 
|  | 49   Node* is_generator = Word32And( | 
|  | 50       compiler_hints, Int32Constant(FunctionKind::kGeneratorFunction | 
|  | 51                                     << SharedFunctionInfo::kFunctionKindShift)); | 
|  | 52   GotoIf(is_generator, &if_generator); | 
|  | 53 | 
|  | 54   Node* is_async = Word32And( | 
|  | 55       compiler_hints, Int32Constant(FunctionKind::kAsyncFunction | 
|  | 56                                     << SharedFunctionInfo::kFunctionKindShift)); | 
|  | 57   GotoIf(is_async, &if_async); | 
|  | 58 | 
|  | 59   Node* is_class_constructor = Word32And( | 
|  | 60       compiler_hints, Int32Constant(FunctionKind::kClassConstructor | 
|  | 61                                     << SharedFunctionInfo::kFunctionKindShift)); | 
|  | 62   GotoIf(is_class_constructor, &if_class_constructor); | 
|  | 63 | 
|  | 64   if (FLAG_debug_code) { | 
|  | 65     // Function must be a function without a prototype. | 
|  | 66     CSA_ASSERT( | 
|  | 67         this, | 
|  | 68         Word32And(compiler_hints, | 
|  | 69                   Int32Constant((FunctionKind::kAccessorFunction | | 
|  | 70                                  FunctionKind::kArrowFunction | | 
|  | 71                                  FunctionKind::kConciseMethod) | 
|  | 72                                 << SharedFunctionInfo::kFunctionKindShift))); | 
|  | 73   } | 
|  | 74   Goto(&if_function_without_prototype); | 
|  | 75 | 
|  | 76   Bind(&if_normal); | 
|  | 77   { | 
|  | 78     map_index.Bind(SelectIntPtrConstant(is_strict, | 
|  | 79                                         Context::STRICT_FUNCTION_MAP_INDEX, | 
|  | 80                                         Context::SLOPPY_FUNCTION_MAP_INDEX)); | 
|  | 81     Goto(&load_map); | 
|  | 82   } | 
|  | 83 | 
|  | 84   Bind(&if_generator); | 
|  | 85   { | 
|  | 86     map_index.Bind(SelectIntPtrConstant( | 
|  | 87         is_strict, Context::STRICT_GENERATOR_FUNCTION_MAP_INDEX, | 
|  | 88         Context::SLOPPY_GENERATOR_FUNCTION_MAP_INDEX)); | 
|  | 89     Goto(&load_map); | 
|  | 90   } | 
|  | 91 | 
|  | 92   Bind(&if_async); | 
|  | 93   { | 
|  | 94     map_index.Bind(SelectIntPtrConstant( | 
|  | 95         is_strict, Context::STRICT_ASYNC_FUNCTION_MAP_INDEX, | 
|  | 96         Context::SLOPPY_ASYNC_FUNCTION_MAP_INDEX)); | 
|  | 97     Goto(&load_map); | 
|  | 98   } | 
|  | 99 | 
|  | 100   Bind(&if_class_constructor); | 
|  | 101   { | 
|  | 102     map_index.Bind(IntPtrConstant(Context::CLASS_FUNCTION_MAP_INDEX)); | 
|  | 103     Goto(&load_map); | 
|  | 104   } | 
|  | 105 | 
|  | 106   Bind(&if_function_without_prototype); | 
|  | 107   { | 
|  | 108     map_index.Bind( | 
|  | 109         IntPtrConstant(Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); | 
|  | 110     Goto(&load_map); | 
|  | 111   } | 
|  | 112 | 
|  | 113   Bind(&load_map); | 
|  | 114 | 
|  | 115   // Get the function map in the current native context and set that | 
|  | 116   // as the map of the allocated object. | 
|  | 117   Node* native_context = LoadNativeContext(context); | 
|  | 118   Node* map_slot_value = | 
|  | 119       LoadFixedArrayElement(native_context, map_index.value()); | 
|  | 120   StoreMapNoWriteBarrier(result, map_slot_value); | 
|  | 121 | 
|  | 122   // Initialize the rest of the function. | 
|  | 123   Node* empty_fixed_array = HeapConstant(factory->empty_fixed_array()); | 
|  | 124   Node* empty_literals_array = HeapConstant(factory->empty_literals_array()); | 
|  | 125   StoreObjectFieldNoWriteBarrier(result, JSObject::kPropertiesOffset, | 
|  | 126                                  empty_fixed_array); | 
|  | 127   StoreObjectFieldNoWriteBarrier(result, JSObject::kElementsOffset, | 
|  | 128                                  empty_fixed_array); | 
|  | 129   StoreObjectFieldNoWriteBarrier(result, JSFunction::kLiteralsOffset, | 
|  | 130                                  empty_literals_array); | 
|  | 131   StoreObjectFieldNoWriteBarrier( | 
|  | 132       result, JSFunction::kPrototypeOrInitialMapOffset, TheHoleConstant()); | 
|  | 133   StoreObjectFieldNoWriteBarrier(result, JSFunction::kSharedFunctionInfoOffset, | 
|  | 134                                  shared_info); | 
|  | 135   StoreObjectFieldNoWriteBarrier(result, JSFunction::kContextOffset, context); | 
|  | 136   Handle<Code> lazy_builtin_handle( | 
|  | 137       isolate->builtins()->builtin(Builtins::kCompileLazy)); | 
|  | 138   Node* lazy_builtin = HeapConstant(lazy_builtin_handle); | 
|  | 139   Node* lazy_builtin_entry = | 
|  | 140       IntPtrAdd(BitcastTaggedToWord(lazy_builtin), | 
|  | 141                 IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); | 
|  | 142   StoreObjectFieldNoWriteBarrier(result, JSFunction::kCodeEntryOffset, | 
|  | 143                                  lazy_builtin_entry, | 
|  | 144                                  MachineType::PointerRepresentation()); | 
|  | 145   StoreObjectFieldNoWriteBarrier(result, JSFunction::kNextFunctionLinkOffset, | 
|  | 146                                  UndefinedConstant()); | 
|  | 147 | 
|  | 148   return result; | 
|  | 149 } | 
|  | 150 | 
|  | 151 TF_BUILTIN(FastNewClosure, ConstructorBuiltinsAssembler) { | 
|  | 152   Node* shared = Parameter(FastNewClosureDescriptor::kSharedFunctionInfo); | 
|  | 153   Node* context = Parameter(FastNewClosureDescriptor::kContext); | 
|  | 154   Return(EmitFastNewClosure(shared, context)); | 
|  | 155 } | 
|  | 156 | 
|  | 157 }  // namespace internal | 
|  | 158 }  // namespace v8 | 
| OLD | NEW | 
|---|