vendor/v8/src/ia32/builtins-ia32.cc in mustang-0.0.1 vs vendor/v8/src/ia32/builtins-ia32.cc in mustang-0.1.0

- old
+ new

@@ -68,11 +68,11 @@ } // JumpToExternalReference expects eax to contain the number of arguments // including the receiver and the extra arguments. __ add(Operand(eax), Immediate(num_extra_args + 1)); - __ JumpToExternalReference(ExternalReference(id)); + __ JumpToExternalReference(ExternalReference(id, masm->isolate())); } void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { // ----------- S t a t e ------------- @@ -98,12 +98,13 @@ // eax: number of arguments __ bind(&non_function_call); // Set expected number of arguments to zero (not changing eax). __ Set(ebx, Immediate(0)); __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); - __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), - RelocInfo::CODE_TARGET); + Handle<Code> arguments_adaptor = + masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); + __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET); } static void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, @@ -126,11 +127,11 @@ Label rt_call, allocated; if (FLAG_inline_new) { Label undo_allocation; #ifdef ENABLE_DEBUGGER_SUPPORT ExternalReference debug_step_in_fp = - ExternalReference::debug_step_in_fp_address(); + ExternalReference::debug_step_in_fp_address(masm->isolate()); __ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0)); __ j(not_equal, &rt_call); #endif // Verified that the constructor is a JSFunction. @@ -182,23 +183,24 @@ // Allocated the JSObject, now initialize the fields. // eax: initial map // ebx: JSObject // edi: start of next object __ mov(Operand(ebx, JSObject::kMapOffset), eax); - __ mov(ecx, Factory::empty_fixed_array()); + Factory* factory = masm->isolate()->factory(); + __ mov(ecx, factory->empty_fixed_array()); __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx); __ mov(Operand(ebx, JSObject::kElementsOffset), ecx); // Set extra fields in the newly allocated object. // eax: initial map // ebx: JSObject // edi: start of next object { Label loop, entry; // To allow for truncation. if (count_constructions) { - __ mov(edx, Factory::one_pointer_filler_map()); + __ mov(edx, factory->one_pointer_filler_map()); } else { - __ mov(edx, Factory::undefined_value()); + __ mov(edx, factory->undefined_value()); } __ lea(ecx, Operand(ebx, JSObject::kHeaderSize)); __ jmp(&entry); __ bind(&loop); __ mov(Operand(ecx, 0), edx); @@ -250,21 +252,21 @@ // Initialize the FixedArray. // ebx: JSObject // edi: FixedArray // edx: number of elements // ecx: start of next object - __ mov(eax, Factory::fixed_array_map()); + __ mov(eax, factory->fixed_array_map()); __ mov(Operand(edi, FixedArray::kMapOffset), eax); // setup the map __ SmiTag(edx); __ mov(Operand(edi, FixedArray::kLengthOffset), edx); // and length // Initialize the fields to undefined. // ebx: JSObject // edi: FixedArray // ecx: start of next object { Label loop, entry; - __ mov(edx, Factory::undefined_value()); + __ mov(edx, factory->undefined_value()); __ lea(eax, Operand(edi, FixedArray::kHeaderSize)); __ jmp(&entry); __ bind(&loop); __ mov(Operand(eax, 0), edx); __ add(Operand(eax), Immediate(kPointerSize)); @@ -332,12 +334,12 @@ __ j(greater_equal, &loop); // Call the function. if (is_api_function) { __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); - Handle<Code> code = Handle<Code>( - Builtins::builtin(Builtins::HandleApiCallConstruct)); + Handle<Code> code = + masm->isolate()->builtins()->HandleApiCallConstruct(); ParameterCount expected(0); __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET, CALL_FUNCTION); } else { ParameterCount actual(eax); @@ -374,11 +376,11 @@ // Remove caller arguments from the stack and return. ASSERT(kSmiTagSize == 1 && kSmiTag == 0); __ pop(ecx); __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver __ push(ecx); - __ IncrementCounter(&Counters::constructed_objects, 1); + __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); __ ret(0); } void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { @@ -434,11 +436,11 @@ // Get the function from the stack and call it. __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize)); // +1 ~ receiver // Invoke the code. if (is_construct) { - __ call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)), + __ call(masm->isolate()->builtins()->JSConstructCall(), RelocInfo::CODE_TARGET); } else { ParameterCount actual(eax); __ InvokeFunction(edi, actual, CALL_FUNCTION); } @@ -559,16 +561,18 @@ __ ret(0); } void Builtins::Generate_FunctionCall(MacroAssembler* masm) { + Factory* factory = masm->isolate()->factory(); + // 1. Make sure we have at least one argument. { Label done; __ test(eax, Operand(eax)); __ j(not_zero, &done, taken); __ pop(ebx); - __ push(Immediate(Factory::undefined_value())); + __ push(Immediate(factory->undefined_value())); __ push(ebx); __ inc(eax); __ bind(&done); } @@ -598,13 +602,13 @@ // Compute the receiver in non-strict mode. __ mov(ebx, Operand(esp, eax, times_4, 0)); // First argument. __ test(ebx, Immediate(kSmiTagMask)); __ j(zero, &convert_to_object); - __ cmp(ebx, Factory::null_value()); + __ cmp(ebx, factory->null_value()); __ j(equal, &use_global_receiver); - __ cmp(ebx, Factory::undefined_value()); + __ cmp(ebx, factory->undefined_value()); __ j(equal, &use_global_receiver); // We don't use IsObjectJSObjectType here because we jump on success. __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); @@ -672,11 +676,11 @@ { Label function; __ test(edi, Operand(edi)); __ j(not_zero, &function, taken); __ Set(ebx, Immediate(0)); __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); - __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), + __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), RelocInfo::CODE_TARGET); __ bind(&function); } // 5b. Get the code to call from the function and check that the number of @@ -686,11 +690,12 @@ __ mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); __ SmiUntag(ebx); __ cmp(eax, Operand(ebx)); - __ j(not_equal, Handle<Code>(builtin(ArgumentsAdaptorTrampoline))); + __ j(not_equal, + masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); ParameterCount expected(0); __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION); } @@ -705,11 +710,11 @@ // Check the stack for overflow. We are not trying need to catch // interruptions (e.g. debug break and preemption) here, so the "real stack // limit" is checked. Label okay; ExternalReference real_stack_limit = - ExternalReference::address_of_real_stack_limit(); + ExternalReference::address_of_real_stack_limit(masm->isolate()); __ mov(edi, Operand::StaticVariable(real_stack_limit)); // Make ecx the space we have left. The stack might already be overflowed // here which will cause ecx to become negative. __ mov(ecx, Operand(esp)); __ sub(ecx, Operand(edi)); @@ -751,13 +756,14 @@ __ j(not_equal, &push_receiver); // Compute the receiver in non-strict mode. __ test(ebx, Immediate(kSmiTagMask)); __ j(zero, &call_to_object); - __ cmp(ebx, Factory::null_value()); + Factory* factory = masm->isolate()->factory(); + __ cmp(ebx, factory->null_value()); __ j(equal, &use_global_receiver); - __ cmp(ebx, Factory::undefined_value()); + __ cmp(ebx, factory->undefined_value()); __ j(equal, &use_global_receiver); // If given receiver is already a JavaScript object then there's no // reason for converting it. // We don't use IsObjectJSObjectType here because we jump on success. @@ -793,11 +799,11 @@ __ jmp(&entry); __ bind(&loop); __ mov(edx, Operand(ebp, 2 * kPointerSize)); // load arguments // Use inline caching to speed up access to arguments. - Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); + Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Initialize(); __ call(ic, RelocInfo::CODE_TARGET); // It is important that we do not have a test instruction after the // call. A test instruction after the call is used to indicate that // we have generated an inline version of the keyed load. In this // case, we know that we are not generating a test instruction next. @@ -864,20 +870,21 @@ // array. // result: JSObject // scratch1: initial map // scratch2: start of next object __ mov(FieldOperand(result, JSObject::kMapOffset), scratch1); + Factory* factory = masm->isolate()->factory(); __ mov(FieldOperand(result, JSArray::kPropertiesOffset), - Factory::empty_fixed_array()); + factory->empty_fixed_array()); // Field JSArray::kElementsOffset is initialized later. __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0)); // If no storage is requested for the elements array just set the empty // fixed array. if (initial_capacity == 0) { __ mov(FieldOperand(result, JSArray::kElementsOffset), - Factory::empty_fixed_array()); + factory->empty_fixed_array()); return; } // Calculate the location of the elements array and set elements array member // of the JSArray. @@ -890,32 +897,32 @@ // stored as a smi. // result: JSObject // scratch1: elements array // scratch2: start of next object __ mov(FieldOperand(scratch1, FixedArray::kMapOffset), - Factory::fixed_array_map()); + factory->fixed_array_map()); __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset), Immediate(Smi::FromInt(initial_capacity))); // Fill the FixedArray with the hole value. Inline the code if short. // Reconsider loop unfolding if kPreallocatedArrayElements gets changed. static const int kLoopUnfoldLimit = 4; ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit); if (initial_capacity <= kLoopUnfoldLimit) { // Use a scratch register here to have only one reloc info when unfolding // the loop. - __ mov(scratch3, Factory::the_hole_value()); + __ mov(scratch3, factory->the_hole_value()); for (int i = 0; i < initial_capacity; i++) { __ mov(FieldOperand(scratch1, FixedArray::kHeaderSize + i * kPointerSize), scratch3); } } else { Label loop, entry; __ jmp(&entry); __ bind(&loop); - __ mov(Operand(scratch1, 0), Factory::the_hole_value()); + __ mov(Operand(scratch1, 0), factory->the_hole_value()); __ add(Operand(scratch1), Immediate(kPointerSize)); __ bind(&entry); __ cmp(scratch1, Operand(scratch2)); __ j(below, &loop); } @@ -966,11 +973,12 @@ // result: JSObject // elements_array: initial map // elements_array_end: start of next object // array_size: size of array (smi) __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array); - __ mov(elements_array, Factory::empty_fixed_array()); + Factory* factory = masm->isolate()->factory(); + __ mov(elements_array, factory->empty_fixed_array()); __ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array); // Field JSArray::kElementsOffset is initialized later. __ mov(FieldOperand(result, JSArray::kLengthOffset), array_size); // Calculate the location of the elements array and set elements array member @@ -985,11 +993,11 @@ // result: JSObject // elements_array: elements array // elements_array_end: start of next object // array_size: size of array (smi) __ mov(FieldOperand(elements_array, FixedArray::kMapOffset), - Factory::fixed_array_map()); + factory->fixed_array_map()); // For non-empty JSArrays the length of the FixedArray and the JSArray is the // same. __ mov(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size); // Fill the allocated FixedArray with the hole value if requested. @@ -997,11 +1005,11 @@ // elements_array: elements array if (fill_with_hole) { __ SmiUntag(array_size); __ lea(edi, Operand(elements_array, FixedArray::kHeaderSize - kHeapObjectTag)); - __ mov(eax, Factory::the_hole_value()); + __ mov(eax, factory->the_hole_value()); __ cld(); // Do not use rep stos when filling less than kRepStosThreshold // words. const int kRepStosThreshold = 16; Label loop, entry, done; @@ -1061,11 +1069,11 @@ ebx, ecx, edi, kPreallocatedArrayElements, &prepare_generic_code_call); - __ IncrementCounter(&Counters::array_function_native, 1); + __ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1); __ pop(ebx); if (construct_call) { __ pop(edi); } __ ret(kPointerSize); @@ -1117,11 +1125,12 @@ eax, edx, edi, true, &prepare_generic_code_call); - __ IncrementCounter(&Counters::array_function_native, 1); + Counters* counters = masm->isolate()->counters(); + __ IncrementCounter(counters->array_function_native(), 1); __ mov(eax, ebx); __ pop(ebx); if (construct_call) { __ pop(edi); } @@ -1144,11 +1153,11 @@ ecx, edx, edi, false, &prepare_generic_code_call); - __ IncrementCounter(&Counters::array_function_native, 1); + __ IncrementCounter(counters->array_function_native(), 1); __ mov(eax, ebx); __ pop(ebx); if (construct_call) { __ pop(edi); } @@ -1230,12 +1239,12 @@ ArrayNativeCode(masm, false, &generic_array_code); // Jump to the generic array code in case the specialized code cannot handle // the construction. __ bind(&generic_array_code); - Code* code = Builtins::builtin(Builtins::ArrayCodeGeneric); - Handle<Code> array_code(code); + Handle<Code> array_code = + masm->isolate()->builtins()->ArrayCodeGeneric(); __ jmp(array_code, RelocInfo::CODE_TARGET); } void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) { @@ -1246,15 +1255,13 @@ // -- esp[4] : last argument // ----------------------------------- Label generic_constructor; if (FLAG_debug_code) { - // The array construct code is only set for the builtin Array function which - // does always have a map. - __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ebx); - __ cmp(edi, Operand(ebx)); - __ Assert(equal, "Unexpected Array function"); + // The array construct code is only set for the global and natives + // builtin Array functions which always have maps. + // Initial map for the builtin Array function should be a map. __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); // Will both indicate a NULL and a Smi. __ test(ebx, Immediate(kSmiTagMask)); __ Assert(not_zero, "Unexpected initial map for Array function"); @@ -1266,12 +1273,12 @@ ArrayNativeCode(masm, true, &generic_constructor); // Jump to the generic construct code in case the specialized code cannot // handle the construction. __ bind(&generic_constructor); - Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); - Handle<Code> generic_construct_stub(code); + Handle<Code> generic_construct_stub = + masm->isolate()->builtins()->JSConstructStubGeneric(); __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); } void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { @@ -1280,11 +1287,12 @@ // -- edi : constructor function // -- esp[0] : return address // -- esp[(argc - n) * 4] : arg[n] (zero-based) // -- esp[(argc + 1) * 4] : receiver // ----------------------------------- - __ IncrementCounter(&Counters::string_ctor_calls, 1); + Counters* counters = masm->isolate()->counters(); + __ IncrementCounter(counters->string_ctor_calls(), 1); if (FLAG_debug_code) { __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, ecx); __ cmp(edi, Operand(ecx)); __ Assert(equal, "Unexpected String function"); @@ -1309,11 +1317,11 @@ ebx, // Result. ecx, // Scratch 1. edx, // Scratch 2. false, // Input is known to be smi? &not_cached); - __ IncrementCounter(&Counters::string_ctor_cached_number, 1); + __ IncrementCounter(counters->string_ctor_cached_number(), 1); __ bind(&argument_is_string); // ----------- S t a t e ------------- // -- ebx : argument converted to string // -- edi : constructor function // -- esp[0] : return address @@ -1338,11 +1346,12 @@ __ Assert(equal, "Unexpected unused properties of string wrapper"); } __ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx); // Set properties and elements. - __ Set(ecx, Immediate(Factory::empty_fixed_array())); + Factory* factory = masm->isolate()->factory(); + __ Set(ecx, Immediate(factory->empty_fixed_array())); __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx); __ mov(FieldOperand(eax, JSObject::kElementsOffset), ecx); // Set the value. __ mov(FieldOperand(eax, JSValue::kValueOffset), ebx); @@ -1361,16 +1370,16 @@ __ test(eax, Immediate(kSmiTagMask)); __ j(zero, &convert_argument); Condition is_string = masm->IsObjectStringType(eax, ebx, ecx); __ j(NegateCondition(is_string), &convert_argument); __ mov(ebx, eax); - __ IncrementCounter(&Counters::string_ctor_string_value, 1); + __ IncrementCounter(counters->string_ctor_string_value(), 1); __ jmp(&argument_is_string); // Invoke the conversion builtin and put the result into ebx. __ bind(&convert_argument); - __ IncrementCounter(&Counters::string_ctor_conversions, 1); + __ IncrementCounter(counters->string_ctor_conversions(), 1); __ EnterInternalFrame(); __ push(edi); // Preserve the function. __ push(eax); __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); __ pop(edi); @@ -1379,20 +1388,20 @@ __ jmp(&argument_is_string); // Load the empty string into ebx, remove the receiver from the // stack, and jump back to the case where the argument is a string. __ bind(&no_arguments); - __ Set(ebx, Immediate(Factory::empty_string())); + __ Set(ebx, Immediate(factory->empty_string())); __ pop(ecx); __ lea(esp, Operand(esp, kPointerSize)); __ push(ecx); __ jmp(&argument_is_string); // At this point the argument is already a string. Call runtime to // create a string wrapper. __ bind(&gc_required); - __ IncrementCounter(&Counters::string_ctor_gc_required, 1); + __ IncrementCounter(counters->string_ctor_gc_required(), 1); __ EnterInternalFrame(); __ push(ebx); __ CallRuntime(Runtime::kNewStringWrapper, 1); __ LeaveInternalFrame(); __ ret(0); @@ -1439,11 +1448,11 @@ // -- ebx : expected number of arguments // -- edx : code entry to call // ----------------------------------- Label invoke, dont_adapt_arguments; - __ IncrementCounter(&Counters::arguments_adaptors, 1); + __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); Label enough, too_few; __ cmp(eax, Operand(ebx)); __ j(less, &too_few); __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); @@ -1487,11 +1496,11 @@ // Fill remaining expected arguments with undefined values. Label fill; __ bind(&fill); __ inc(ecx); - __ push(Immediate(Factory::undefined_value())); + __ push(Immediate(masm->isolate()->factory()->undefined_value())); __ cmp(ecx, Operand(ebx)); __ j(less, &fill); // Restore function pointer. __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); @@ -1512,14 +1521,11 @@ __ jmp(Operand(edx)); } void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { - // We shouldn't be performing on-stack replacement in the first - // place if the CPU features we need for the optimized Crankshaft - // code aren't supported. - CpuFeatures::Probe(false); + CpuFeatures::TryForceFeatureScope scope(SSE2); if (!CpuFeatures::IsSupported(SSE2)) { __ Abort("Unreachable code: Cannot optimize without SSE2 support."); return; } @@ -1560,11 +1566,11 @@ // If we decide not to perform on-stack replacement we perform a // stack guard check to enable interrupts. __ bind(&stack_check); NearLabel ok; ExternalReference stack_limit = - ExternalReference::address_of_stack_limit(); + ExternalReference::address_of_stack_limit(masm->isolate()); __ cmp(esp, Operand::StaticVariable(stack_limit)); __ j(above_equal, &ok, taken); StackCheckStub stub; __ TailCallStub(&stub); __ Abort("Unreachable code: returned from tail call."); @@ -1582,9 +1588,9 @@ generator.Generate(); } #undef __ - -} } // namespace v8::internal +} +} // namespace v8::internal #endif // V8_TARGET_ARCH_IA32